diff options
| -rw-r--r-- | fs/gfs2/file.c | 5 | ||||
| -rw-r--r-- | fs/gfs2/incore.h | 1 | ||||
| -rw-r--r-- | fs/gfs2/lock_dlm.c | 39 | ||||
| -rw-r--r-- | fs/gfs2/rgrp.c | 32 | 
4 files changed, 39 insertions, 38 deletions
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index 019f45e4509..d79c2dadc53 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c @@ -923,8 +923,11 @@ static int gfs2_lock(struct file *file, int cmd, struct file_lock *fl)  		cmd = F_SETLK;  		fl->fl_type = F_UNLCK;  	} -	if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) +	if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) { +		if (fl->fl_type == F_UNLCK) +			posix_lock_file_wait(file, fl);  		return -EIO; +	}  	if (IS_GETLK(cmd))  		return dlm_posix_get(ls->ls_dlm, ip->i_no_addr, file, fl);  	else if (fl->fl_type == F_UNLCK) diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 156e42ec84e..5c29216e9cc 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h @@ -588,6 +588,7 @@ struct lm_lockstruct {  	struct dlm_lksb ls_control_lksb; /* control_lock */  	char ls_control_lvb[GDLM_LVB_SIZE]; /* control_lock lvb */  	struct completion ls_sync_wait; /* {control,mounted}_{lock,unlock} */ +	char *ls_lvb_bits;  	spinlock_t ls_recover_spin; /* protects following fields */  	unsigned long ls_recover_flags; /* DFL_ */ diff --git a/fs/gfs2/lock_dlm.c b/fs/gfs2/lock_dlm.c index 9802de0f85e..c8423d6de6c 100644 --- a/fs/gfs2/lock_dlm.c +++ b/fs/gfs2/lock_dlm.c @@ -483,12 +483,8 @@ static void control_lvb_write(struct lm_lockstruct *ls, uint32_t lvb_gen,  static int all_jid_bits_clear(char *lvb)  { -	int i; -	for (i = JID_BITMAP_OFFSET; i < GDLM_LVB_SIZE; i++) { -		if (lvb[i]) -			return 0; -	} -	return 1; +	return !memchr_inv(lvb + JID_BITMAP_OFFSET, 0, +			GDLM_LVB_SIZE - JID_BITMAP_OFFSET);  }  static void sync_wait_cb(void *arg) @@ -580,7 +576,6 @@ static void gfs2_control_func(struct work_struct *work)  {  	struct gfs2_sbd *sdp = container_of(work, struct gfs2_sbd, sd_control_work.work);  	struct lm_lockstruct *ls = &sdp->sd_lockstruct; -	char lvb_bits[GDLM_LVB_SIZE];  	uint32_t block_gen, start_gen, lvb_gen, flags;  	int recover_set = 0;  	int write_lvb = 0; @@ -634,7 +629,7 @@ static void gfs2_control_func(struct work_struct *work)  		return;  	} -	control_lvb_read(ls, &lvb_gen, lvb_bits); +	control_lvb_read(ls, &lvb_gen, ls->ls_lvb_bits);  	spin_lock(&ls->ls_recover_spin);  	if (block_gen != ls->ls_recover_block || @@ -664,10 +659,10 @@ static void gfs2_control_func(struct work_struct *work)  			ls->ls_recover_result[i] = 0; -			if (!test_bit_le(i, lvb_bits + JID_BITMAP_OFFSET)) +			if (!test_bit_le(i, ls->ls_lvb_bits + JID_BITMAP_OFFSET))  				continue; -			__clear_bit_le(i, lvb_bits + JID_BITMAP_OFFSET); +			__clear_bit_le(i, ls->ls_lvb_bits + JID_BITMAP_OFFSET);  			write_lvb = 1;  		}  	} @@ -691,7 +686,7 @@ static void gfs2_control_func(struct work_struct *work)  				continue;  			if (ls->ls_recover_submit[i] < start_gen) {  				ls->ls_recover_submit[i] = 0; -				__set_bit_le(i, lvb_bits + JID_BITMAP_OFFSET); +				__set_bit_le(i, ls->ls_lvb_bits + JID_BITMAP_OFFSET);  			}  		}  		/* even if there are no bits to set, we need to write the @@ -705,7 +700,7 @@ static void gfs2_control_func(struct work_struct *work)  	spin_unlock(&ls->ls_recover_spin);  	if (write_lvb) { -		control_lvb_write(ls, start_gen, lvb_bits); +		control_lvb_write(ls, start_gen, ls->ls_lvb_bits);  		flags = DLM_LKF_CONVERT | DLM_LKF_VALBLK;  	} else {  		flags = DLM_LKF_CONVERT; @@ -725,7 +720,7 @@ static void gfs2_control_func(struct work_struct *work)  	 */  	for (i = 0; i < recover_size; i++) { -		if (test_bit_le(i, lvb_bits + JID_BITMAP_OFFSET)) { +		if (test_bit_le(i, ls->ls_lvb_bits + JID_BITMAP_OFFSET)) {  			fs_info(sdp, "recover generation %u jid %d\n",  				start_gen, i);  			gfs2_recover_set(sdp, i); @@ -758,7 +753,6 @@ static void gfs2_control_func(struct work_struct *work)  static int control_mount(struct gfs2_sbd *sdp)  {  	struct lm_lockstruct *ls = &sdp->sd_lockstruct; -	char lvb_bits[GDLM_LVB_SIZE];  	uint32_t start_gen, block_gen, mount_gen, lvb_gen;  	int mounted_mode;  	int retries = 0; @@ -857,7 +851,7 @@ locks_done:  	 * lvb_gen will be non-zero.  	 */ -	control_lvb_read(ls, &lvb_gen, lvb_bits); +	control_lvb_read(ls, &lvb_gen, ls->ls_lvb_bits);  	if (lvb_gen == 0xFFFFFFFF) {  		/* special value to force mount attempts to fail */ @@ -887,7 +881,7 @@ locks_done:  	 * and all lvb bits to be clear (no pending journal recoveries.)  	 */ -	if (!all_jid_bits_clear(lvb_bits)) { +	if (!all_jid_bits_clear(ls->ls_lvb_bits)) {  		/* journals need recovery, wait until all are clear */  		fs_info(sdp, "control_mount wait for journal recovery\n");  		goto restart; @@ -949,7 +943,6 @@ static int dlm_recovery_wait(void *word)  static int control_first_done(struct gfs2_sbd *sdp)  {  	struct lm_lockstruct *ls = &sdp->sd_lockstruct; -	char lvb_bits[GDLM_LVB_SIZE];  	uint32_t start_gen, block_gen;  	int error; @@ -991,8 +984,8 @@ restart:  	memset(ls->ls_recover_result, 0, ls->ls_recover_size*sizeof(uint32_t));  	spin_unlock(&ls->ls_recover_spin); -	memset(lvb_bits, 0, sizeof(lvb_bits)); -	control_lvb_write(ls, start_gen, lvb_bits); +	memset(ls->ls_lvb_bits, 0, GDLM_LVB_SIZE); +	control_lvb_write(ls, start_gen, ls->ls_lvb_bits);  	error = mounted_lock(sdp, DLM_LOCK_PR, DLM_LKF_CONVERT);  	if (error) @@ -1022,6 +1015,12 @@ static int set_recover_size(struct gfs2_sbd *sdp, struct dlm_slot *slots,  	uint32_t old_size, new_size;  	int i, max_jid; +	if (!ls->ls_lvb_bits) { +		ls->ls_lvb_bits = kzalloc(GDLM_LVB_SIZE, GFP_NOFS); +		if (!ls->ls_lvb_bits) +			return -ENOMEM; +	} +  	max_jid = 0;  	for (i = 0; i < num_slots; i++) {  		if (max_jid < slots[i].slot - 1) @@ -1057,6 +1056,7 @@ static int set_recover_size(struct gfs2_sbd *sdp, struct dlm_slot *slots,  static void free_recover_size(struct lm_lockstruct *ls)  { +	kfree(ls->ls_lvb_bits);  	kfree(ls->ls_recover_submit);  	kfree(ls->ls_recover_result);  	ls->ls_recover_submit = NULL; @@ -1205,6 +1205,7 @@ static int gdlm_mount(struct gfs2_sbd *sdp, const char *table)  	ls->ls_recover_size = 0;  	ls->ls_recover_submit = NULL;  	ls->ls_recover_result = NULL; +	ls->ls_lvb_bits = NULL;  	error = set_recover_size(sdp, NULL, 0);  	if (error) diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index d1f51fd73f8..5a51265a434 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c @@ -576,7 +576,7 @@ int gfs2_rs_alloc(struct gfs2_inode *ip)  	RB_CLEAR_NODE(&ip->i_res->rs_node);  out:  	up_write(&ip->i_rw_mutex); -	return 0; +	return error;  }  static void dump_rs(struct seq_file *seq, const struct gfs2_blkreserv *rs) @@ -1181,12 +1181,9 @@ int gfs2_rgrp_send_discards(struct gfs2_sbd *sdp, u64 offset,  			     const struct gfs2_bitmap *bi, unsigned minlen, u64 *ptrimmed)  {  	struct super_block *sb = sdp->sd_vfs; -	struct block_device *bdev = sb->s_bdev; -	const unsigned int sects_per_blk = sdp->sd_sb.sb_bsize / -					   bdev_logical_block_size(sb->s_bdev);  	u64 blk;  	sector_t start = 0; -	sector_t nr_sects = 0; +	sector_t nr_blks = 0;  	int rv;  	unsigned int x;  	u32 trimmed = 0; @@ -1206,35 +1203,34 @@ int gfs2_rgrp_send_discards(struct gfs2_sbd *sdp, u64 offset,  		if (diff == 0)  			continue;  		blk = offset + ((bi->bi_start + x) * GFS2_NBBY); -		blk *= sects_per_blk; /* convert to sectors */  		while(diff) {  			if (diff & 1) { -				if (nr_sects == 0) +				if (nr_blks == 0)  					goto start_new_extent; -				if ((start + nr_sects) != blk) { -					if (nr_sects >= minlen) { -						rv = blkdev_issue_discard(bdev, -							start, nr_sects, +				if ((start + nr_blks) != blk) { +					if (nr_blks >= minlen) { +						rv = sb_issue_discard(sb, +							start, nr_blks,  							GFP_NOFS, 0);  						if (rv)  							goto fail; -						trimmed += nr_sects; +						trimmed += nr_blks;  					} -					nr_sects = 0; +					nr_blks = 0;  start_new_extent:  					start = blk;  				} -				nr_sects += sects_per_blk; +				nr_blks++;  			}  			diff >>= 2; -			blk += sects_per_blk; +			blk++;  		}  	} -	if (nr_sects >= minlen) { -		rv = blkdev_issue_discard(bdev, start, nr_sects, GFP_NOFS, 0); +	if (nr_blks >= minlen) { +		rv = sb_issue_discard(sb, start, nr_blks, GFP_NOFS, 0);  		if (rv)  			goto fail; -		trimmed += nr_sects; +		trimmed += nr_blks;  	}  	if (ptrimmed)  		*ptrimmed = trimmed;  |