diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-04-05 15:22:02 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-04-05 15:22:02 -0400 |
commit | 00fa6fe963a97cc95e80a39a34a790bdce06cb4c (patch) | |
tree | be90848a4ecd4cef235123509417196fee202c70 /fs | |
parent | ff802e31b5e60a9a39f70479947a27cea5da701c (diff) | |
parent | b2c87cae0edb1a99f7dd2751d5beb2cb97926514 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-3.0-fixes
Pull GFS2 fixes from Steven Whitehouse:
"There are two patches which fix up a couple of minor issues in the DLM
interface code, a missing error path in gfs2_rs_alloc(), one patch
which fixes a problem during "withdraw" and a fix for discards/FITRIM
when using 4k sector sized devices."
* git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-3.0-fixes:
GFS2: Issue discards in 512b sectors
GFS2: Fix unlock of fcntl locks during withdrawn state
GFS2: return error if malloc failed in gfs2_rs_alloc()
GFS2: use memchr_inv
GFS2: use kmalloc for lvb bitmap
Diffstat (limited to 'fs')
-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 019f45e45097..d79c2dadc536 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) | |||
923 | cmd = F_SETLK; | 923 | cmd = F_SETLK; |
924 | fl->fl_type = F_UNLCK; | 924 | fl->fl_type = F_UNLCK; |
925 | } | 925 | } |
926 | if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) | 926 | if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) { |
927 | if (fl->fl_type == F_UNLCK) | ||
928 | posix_lock_file_wait(file, fl); | ||
927 | return -EIO; | 929 | return -EIO; |
930 | } | ||
928 | if (IS_GETLK(cmd)) | 931 | if (IS_GETLK(cmd)) |
929 | return dlm_posix_get(ls->ls_dlm, ip->i_no_addr, file, fl); | 932 | return dlm_posix_get(ls->ls_dlm, ip->i_no_addr, file, fl); |
930 | else if (fl->fl_type == F_UNLCK) | 933 | else if (fl->fl_type == F_UNLCK) |
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 156e42ec84ea..5c29216e9cc1 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h | |||
@@ -588,6 +588,7 @@ struct lm_lockstruct { | |||
588 | struct dlm_lksb ls_control_lksb; /* control_lock */ | 588 | struct dlm_lksb ls_control_lksb; /* control_lock */ |
589 | char ls_control_lvb[GDLM_LVB_SIZE]; /* control_lock lvb */ | 589 | char ls_control_lvb[GDLM_LVB_SIZE]; /* control_lock lvb */ |
590 | struct completion ls_sync_wait; /* {control,mounted}_{lock,unlock} */ | 590 | struct completion ls_sync_wait; /* {control,mounted}_{lock,unlock} */ |
591 | char *ls_lvb_bits; | ||
591 | 592 | ||
592 | spinlock_t ls_recover_spin; /* protects following fields */ | 593 | spinlock_t ls_recover_spin; /* protects following fields */ |
593 | unsigned long ls_recover_flags; /* DFL_ */ | 594 | unsigned long ls_recover_flags; /* DFL_ */ |
diff --git a/fs/gfs2/lock_dlm.c b/fs/gfs2/lock_dlm.c index 9802de0f85e6..c8423d6de6c3 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, | |||
483 | 483 | ||
484 | static int all_jid_bits_clear(char *lvb) | 484 | static int all_jid_bits_clear(char *lvb) |
485 | { | 485 | { |
486 | int i; | 486 | return !memchr_inv(lvb + JID_BITMAP_OFFSET, 0, |
487 | for (i = JID_BITMAP_OFFSET; i < GDLM_LVB_SIZE; i++) { | 487 | GDLM_LVB_SIZE - JID_BITMAP_OFFSET); |
488 | if (lvb[i]) | ||
489 | return 0; | ||
490 | } | ||
491 | return 1; | ||
492 | } | 488 | } |
493 | 489 | ||
494 | static void sync_wait_cb(void *arg) | 490 | static void sync_wait_cb(void *arg) |
@@ -580,7 +576,6 @@ static void gfs2_control_func(struct work_struct *work) | |||
580 | { | 576 | { |
581 | struct gfs2_sbd *sdp = container_of(work, struct gfs2_sbd, sd_control_work.work); | 577 | struct gfs2_sbd *sdp = container_of(work, struct gfs2_sbd, sd_control_work.work); |
582 | struct lm_lockstruct *ls = &sdp->sd_lockstruct; | 578 | struct lm_lockstruct *ls = &sdp->sd_lockstruct; |
583 | char lvb_bits[GDLM_LVB_SIZE]; | ||
584 | uint32_t block_gen, start_gen, lvb_gen, flags; | 579 | uint32_t block_gen, start_gen, lvb_gen, flags; |
585 | int recover_set = 0; | 580 | int recover_set = 0; |
586 | int write_lvb = 0; | 581 | int write_lvb = 0; |
@@ -634,7 +629,7 @@ static void gfs2_control_func(struct work_struct *work) | |||
634 | return; | 629 | return; |
635 | } | 630 | } |
636 | 631 | ||
637 | control_lvb_read(ls, &lvb_gen, lvb_bits); | 632 | control_lvb_read(ls, &lvb_gen, ls->ls_lvb_bits); |
638 | 633 | ||
639 | spin_lock(&ls->ls_recover_spin); | 634 | spin_lock(&ls->ls_recover_spin); |
640 | if (block_gen != ls->ls_recover_block || | 635 | if (block_gen != ls->ls_recover_block || |
@@ -664,10 +659,10 @@ static void gfs2_control_func(struct work_struct *work) | |||
664 | 659 | ||
665 | ls->ls_recover_result[i] = 0; | 660 | ls->ls_recover_result[i] = 0; |
666 | 661 | ||
667 | if (!test_bit_le(i, lvb_bits + JID_BITMAP_OFFSET)) | 662 | if (!test_bit_le(i, ls->ls_lvb_bits + JID_BITMAP_OFFSET)) |
668 | continue; | 663 | continue; |
669 | 664 | ||
670 | __clear_bit_le(i, lvb_bits + JID_BITMAP_OFFSET); | 665 | __clear_bit_le(i, ls->ls_lvb_bits + JID_BITMAP_OFFSET); |
671 | write_lvb = 1; | 666 | write_lvb = 1; |
672 | } | 667 | } |
673 | } | 668 | } |
@@ -691,7 +686,7 @@ static void gfs2_control_func(struct work_struct *work) | |||
691 | continue; | 686 | continue; |
692 | if (ls->ls_recover_submit[i] < start_gen) { | 687 | if (ls->ls_recover_submit[i] < start_gen) { |
693 | ls->ls_recover_submit[i] = 0; | 688 | ls->ls_recover_submit[i] = 0; |
694 | __set_bit_le(i, lvb_bits + JID_BITMAP_OFFSET); | 689 | __set_bit_le(i, ls->ls_lvb_bits + JID_BITMAP_OFFSET); |
695 | } | 690 | } |
696 | } | 691 | } |
697 | /* even if there are no bits to set, we need to write the | 692 | /* 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) | |||
705 | spin_unlock(&ls->ls_recover_spin); | 700 | spin_unlock(&ls->ls_recover_spin); |
706 | 701 | ||
707 | if (write_lvb) { | 702 | if (write_lvb) { |
708 | control_lvb_write(ls, start_gen, lvb_bits); | 703 | control_lvb_write(ls, start_gen, ls->ls_lvb_bits); |
709 | flags = DLM_LKF_CONVERT | DLM_LKF_VALBLK; | 704 | flags = DLM_LKF_CONVERT | DLM_LKF_VALBLK; |
710 | } else { | 705 | } else { |
711 | flags = DLM_LKF_CONVERT; | 706 | flags = DLM_LKF_CONVERT; |
@@ -725,7 +720,7 @@ static void gfs2_control_func(struct work_struct *work) | |||
725 | */ | 720 | */ |
726 | 721 | ||
727 | for (i = 0; i < recover_size; i++) { | 722 | for (i = 0; i < recover_size; i++) { |
728 | if (test_bit_le(i, lvb_bits + JID_BITMAP_OFFSET)) { | 723 | if (test_bit_le(i, ls->ls_lvb_bits + JID_BITMAP_OFFSET)) { |
729 | fs_info(sdp, "recover generation %u jid %d\n", | 724 | fs_info(sdp, "recover generation %u jid %d\n", |
730 | start_gen, i); | 725 | start_gen, i); |
731 | gfs2_recover_set(sdp, i); | 726 | gfs2_recover_set(sdp, i); |
@@ -758,7 +753,6 @@ static void gfs2_control_func(struct work_struct *work) | |||
758 | static int control_mount(struct gfs2_sbd *sdp) | 753 | static int control_mount(struct gfs2_sbd *sdp) |
759 | { | 754 | { |
760 | struct lm_lockstruct *ls = &sdp->sd_lockstruct; | 755 | struct lm_lockstruct *ls = &sdp->sd_lockstruct; |
761 | char lvb_bits[GDLM_LVB_SIZE]; | ||
762 | uint32_t start_gen, block_gen, mount_gen, lvb_gen; | 756 | uint32_t start_gen, block_gen, mount_gen, lvb_gen; |
763 | int mounted_mode; | 757 | int mounted_mode; |
764 | int retries = 0; | 758 | int retries = 0; |
@@ -857,7 +851,7 @@ locks_done: | |||
857 | * lvb_gen will be non-zero. | 851 | * lvb_gen will be non-zero. |
858 | */ | 852 | */ |
859 | 853 | ||
860 | control_lvb_read(ls, &lvb_gen, lvb_bits); | 854 | control_lvb_read(ls, &lvb_gen, ls->ls_lvb_bits); |
861 | 855 | ||
862 | if (lvb_gen == 0xFFFFFFFF) { | 856 | if (lvb_gen == 0xFFFFFFFF) { |
863 | /* special value to force mount attempts to fail */ | 857 | /* special value to force mount attempts to fail */ |
@@ -887,7 +881,7 @@ locks_done: | |||
887 | * and all lvb bits to be clear (no pending journal recoveries.) | 881 | * and all lvb bits to be clear (no pending journal recoveries.) |
888 | */ | 882 | */ |
889 | 883 | ||
890 | if (!all_jid_bits_clear(lvb_bits)) { | 884 | if (!all_jid_bits_clear(ls->ls_lvb_bits)) { |
891 | /* journals need recovery, wait until all are clear */ | 885 | /* journals need recovery, wait until all are clear */ |
892 | fs_info(sdp, "control_mount wait for journal recovery\n"); | 886 | fs_info(sdp, "control_mount wait for journal recovery\n"); |
893 | goto restart; | 887 | goto restart; |
@@ -949,7 +943,6 @@ static int dlm_recovery_wait(void *word) | |||
949 | static int control_first_done(struct gfs2_sbd *sdp) | 943 | static int control_first_done(struct gfs2_sbd *sdp) |
950 | { | 944 | { |
951 | struct lm_lockstruct *ls = &sdp->sd_lockstruct; | 945 | struct lm_lockstruct *ls = &sdp->sd_lockstruct; |
952 | char lvb_bits[GDLM_LVB_SIZE]; | ||
953 | uint32_t start_gen, block_gen; | 946 | uint32_t start_gen, block_gen; |
954 | int error; | 947 | int error; |
955 | 948 | ||
@@ -991,8 +984,8 @@ restart: | |||
991 | memset(ls->ls_recover_result, 0, ls->ls_recover_size*sizeof(uint32_t)); | 984 | memset(ls->ls_recover_result, 0, ls->ls_recover_size*sizeof(uint32_t)); |
992 | spin_unlock(&ls->ls_recover_spin); | 985 | spin_unlock(&ls->ls_recover_spin); |
993 | 986 | ||
994 | memset(lvb_bits, 0, sizeof(lvb_bits)); | 987 | memset(ls->ls_lvb_bits, 0, GDLM_LVB_SIZE); |
995 | control_lvb_write(ls, start_gen, lvb_bits); | 988 | control_lvb_write(ls, start_gen, ls->ls_lvb_bits); |
996 | 989 | ||
997 | error = mounted_lock(sdp, DLM_LOCK_PR, DLM_LKF_CONVERT); | 990 | error = mounted_lock(sdp, DLM_LOCK_PR, DLM_LKF_CONVERT); |
998 | if (error) | 991 | if (error) |
@@ -1022,6 +1015,12 @@ static int set_recover_size(struct gfs2_sbd *sdp, struct dlm_slot *slots, | |||
1022 | uint32_t old_size, new_size; | 1015 | uint32_t old_size, new_size; |
1023 | int i, max_jid; | 1016 | int i, max_jid; |
1024 | 1017 | ||
1018 | if (!ls->ls_lvb_bits) { | ||
1019 | ls->ls_lvb_bits = kzalloc(GDLM_LVB_SIZE, GFP_NOFS); | ||
1020 | if (!ls->ls_lvb_bits) | ||
1021 | return -ENOMEM; | ||
1022 | } | ||
1023 | |||
1025 | max_jid = 0; | 1024 | max_jid = 0; |
1026 | for (i = 0; i < num_slots; i++) { | 1025 | for (i = 0; i < num_slots; i++) { |
1027 | if (max_jid < slots[i].slot - 1) | 1026 | if (max_jid < slots[i].slot - 1) |
@@ -1057,6 +1056,7 @@ static int set_recover_size(struct gfs2_sbd *sdp, struct dlm_slot *slots, | |||
1057 | 1056 | ||
1058 | static void free_recover_size(struct lm_lockstruct *ls) | 1057 | static void free_recover_size(struct lm_lockstruct *ls) |
1059 | { | 1058 | { |
1059 | kfree(ls->ls_lvb_bits); | ||
1060 | kfree(ls->ls_recover_submit); | 1060 | kfree(ls->ls_recover_submit); |
1061 | kfree(ls->ls_recover_result); | 1061 | kfree(ls->ls_recover_result); |
1062 | ls->ls_recover_submit = NULL; | 1062 | ls->ls_recover_submit = NULL; |
@@ -1205,6 +1205,7 @@ static int gdlm_mount(struct gfs2_sbd *sdp, const char *table) | |||
1205 | ls->ls_recover_size = 0; | 1205 | ls->ls_recover_size = 0; |
1206 | ls->ls_recover_submit = NULL; | 1206 | ls->ls_recover_submit = NULL; |
1207 | ls->ls_recover_result = NULL; | 1207 | ls->ls_recover_result = NULL; |
1208 | ls->ls_lvb_bits = NULL; | ||
1208 | 1209 | ||
1209 | error = set_recover_size(sdp, NULL, 0); | 1210 | error = set_recover_size(sdp, NULL, 0); |
1210 | if (error) | 1211 | if (error) |
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index d1f51fd73f86..5a51265a4341 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c | |||
@@ -576,7 +576,7 @@ int gfs2_rs_alloc(struct gfs2_inode *ip) | |||
576 | RB_CLEAR_NODE(&ip->i_res->rs_node); | 576 | RB_CLEAR_NODE(&ip->i_res->rs_node); |
577 | out: | 577 | out: |
578 | up_write(&ip->i_rw_mutex); | 578 | up_write(&ip->i_rw_mutex); |
579 | return 0; | 579 | return error; |
580 | } | 580 | } |
581 | 581 | ||
582 | static void dump_rs(struct seq_file *seq, const struct gfs2_blkreserv *rs) | 582 | 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, | |||
1181 | const struct gfs2_bitmap *bi, unsigned minlen, u64 *ptrimmed) | 1181 | const struct gfs2_bitmap *bi, unsigned minlen, u64 *ptrimmed) |
1182 | { | 1182 | { |
1183 | struct super_block *sb = sdp->sd_vfs; | 1183 | struct super_block *sb = sdp->sd_vfs; |
1184 | struct block_device *bdev = sb->s_bdev; | ||
1185 | const unsigned int sects_per_blk = sdp->sd_sb.sb_bsize / | ||
1186 | bdev_logical_block_size(sb->s_bdev); | ||
1187 | u64 blk; | 1184 | u64 blk; |
1188 | sector_t start = 0; | 1185 | sector_t start = 0; |
1189 | sector_t nr_sects = 0; | 1186 | sector_t nr_blks = 0; |
1190 | int rv; | 1187 | int rv; |
1191 | unsigned int x; | 1188 | unsigned int x; |
1192 | u32 trimmed = 0; | 1189 | u32 trimmed = 0; |
@@ -1206,35 +1203,34 @@ int gfs2_rgrp_send_discards(struct gfs2_sbd *sdp, u64 offset, | |||
1206 | if (diff == 0) | 1203 | if (diff == 0) |
1207 | continue; | 1204 | continue; |
1208 | blk = offset + ((bi->bi_start + x) * GFS2_NBBY); | 1205 | blk = offset + ((bi->bi_start + x) * GFS2_NBBY); |
1209 | blk *= sects_per_blk; /* convert to sectors */ | ||
1210 | while(diff) { | 1206 | while(diff) { |
1211 | if (diff & 1) { | 1207 | if (diff & 1) { |
1212 | if (nr_sects == 0) | 1208 | if (nr_blks == 0) |
1213 | goto start_new_extent; | 1209 | goto start_new_extent; |
1214 | if ((start + nr_sects) != blk) { | 1210 | if ((start + nr_blks) != blk) { |
1215 | if (nr_sects >= minlen) { | 1211 | if (nr_blks >= minlen) { |
1216 | rv = blkdev_issue_discard(bdev, | 1212 | rv = sb_issue_discard(sb, |
1217 | start, nr_sects, | 1213 | start, nr_blks, |
1218 | GFP_NOFS, 0); | 1214 | GFP_NOFS, 0); |
1219 | if (rv) | 1215 | if (rv) |
1220 | goto fail; | 1216 | goto fail; |
1221 | trimmed += nr_sects; | 1217 | trimmed += nr_blks; |
1222 | } | 1218 | } |
1223 | nr_sects = 0; | 1219 | nr_blks = 0; |
1224 | start_new_extent: | 1220 | start_new_extent: |
1225 | start = blk; | 1221 | start = blk; |
1226 | } | 1222 | } |
1227 | nr_sects += sects_per_blk; | 1223 | nr_blks++; |
1228 | } | 1224 | } |
1229 | diff >>= 2; | 1225 | diff >>= 2; |
1230 | blk += sects_per_blk; | 1226 | blk++; |
1231 | } | 1227 | } |
1232 | } | 1228 | } |
1233 | if (nr_sects >= minlen) { | 1229 | if (nr_blks >= minlen) { |
1234 | rv = blkdev_issue_discard(bdev, start, nr_sects, GFP_NOFS, 0); | 1230 | rv = sb_issue_discard(sb, start, nr_blks, GFP_NOFS, 0); |
1235 | if (rv) | 1231 | if (rv) |
1236 | goto fail; | 1232 | goto fail; |
1237 | trimmed += nr_sects; | 1233 | trimmed += nr_blks; |
1238 | } | 1234 | } |
1239 | if (ptrimmed) | 1235 | if (ptrimmed) |
1240 | *ptrimmed = trimmed; | 1236 | *ptrimmed = trimmed; |