diff options
author | Jeff Layton <jeff.layton@primarydata.com> | 2015-02-16 14:32:03 -0500 |
---|---|---|
committer | Jeff Layton <jeff.layton@primarydata.com> | 2015-02-16 14:32:03 -0500 |
commit | e084c1bd40926938ff8d26af3bde34396dd4d06d (patch) | |
tree | 5d4dd8e3eaf5c46430670d4858084230128f3bbd | |
parent | 1fa185ebcbcefdc5229c783450c9f0439a69f0c1 (diff) |
Revert "locks: keep a count of locks on the flctx lists"
This reverts commit 9bd0f45b7037fcfa8b575c7e27d0431d6e6dc3bb.
Linus rightly pointed out that I failed to initialize the counters
when adding them, so they don't work as expected. Just revert this
patch for now.
Reported-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Jeff Layton <jeff.layton@primarydata.com>
-rw-r--r-- | fs/ceph/locks.c | 9 | ||||
-rw-r--r-- | fs/cifs/file.c | 14 | ||||
-rw-r--r-- | fs/locks.c | 45 | ||||
-rw-r--r-- | include/linux/fs.h | 3 |
4 files changed, 33 insertions, 38 deletions
diff --git a/fs/ceph/locks.c b/fs/ceph/locks.c index 06ea5cd05cd9..4347039ecc18 100644 --- a/fs/ceph/locks.c +++ b/fs/ceph/locks.c | |||
@@ -245,6 +245,7 @@ int ceph_flock(struct file *file, int cmd, struct file_lock *fl) | |||
245 | */ | 245 | */ |
246 | void ceph_count_locks(struct inode *inode, int *fcntl_count, int *flock_count) | 246 | void ceph_count_locks(struct inode *inode, int *fcntl_count, int *flock_count) |
247 | { | 247 | { |
248 | struct file_lock *lock; | ||
248 | struct file_lock_context *ctx; | 249 | struct file_lock_context *ctx; |
249 | 250 | ||
250 | *fcntl_count = 0; | 251 | *fcntl_count = 0; |
@@ -252,8 +253,12 @@ void ceph_count_locks(struct inode *inode, int *fcntl_count, int *flock_count) | |||
252 | 253 | ||
253 | ctx = inode->i_flctx; | 254 | ctx = inode->i_flctx; |
254 | if (ctx) { | 255 | if (ctx) { |
255 | *fcntl_count = ctx->flc_posix_cnt; | 256 | spin_lock(&ctx->flc_lock); |
256 | *flock_count = ctx->flc_flock_cnt; | 257 | list_for_each_entry(lock, &ctx->flc_posix, fl_list) |
258 | ++(*fcntl_count); | ||
259 | list_for_each_entry(lock, &ctx->flc_flock, fl_list) | ||
260 | ++(*flock_count); | ||
261 | spin_unlock(&ctx->flc_lock); | ||
257 | } | 262 | } |
258 | dout("counted %d flock locks and %d fcntl locks", | 263 | dout("counted %d flock locks and %d fcntl locks", |
259 | *flock_count, *fcntl_count); | 264 | *flock_count, *fcntl_count); |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 8fe1f7a21b3e..a94b3e673182 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -1129,7 +1129,7 @@ cifs_push_posix_locks(struct cifsFileInfo *cfile) | |||
1129 | struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); | 1129 | struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); |
1130 | struct file_lock *flock; | 1130 | struct file_lock *flock; |
1131 | struct file_lock_context *flctx = inode->i_flctx; | 1131 | struct file_lock_context *flctx = inode->i_flctx; |
1132 | unsigned int i; | 1132 | unsigned int count = 0, i; |
1133 | int rc = 0, xid, type; | 1133 | int rc = 0, xid, type; |
1134 | struct list_head locks_to_send, *el; | 1134 | struct list_head locks_to_send, *el; |
1135 | struct lock_to_push *lck, *tmp; | 1135 | struct lock_to_push *lck, *tmp; |
@@ -1140,14 +1140,20 @@ cifs_push_posix_locks(struct cifsFileInfo *cfile) | |||
1140 | if (!flctx) | 1140 | if (!flctx) |
1141 | goto out; | 1141 | goto out; |
1142 | 1142 | ||
1143 | spin_lock(&flctx->flc_lock); | ||
1144 | list_for_each(el, &flctx->flc_posix) { | ||
1145 | count++; | ||
1146 | } | ||
1147 | spin_unlock(&flctx->flc_lock); | ||
1148 | |||
1143 | INIT_LIST_HEAD(&locks_to_send); | 1149 | INIT_LIST_HEAD(&locks_to_send); |
1144 | 1150 | ||
1145 | /* | 1151 | /* |
1146 | * Allocating flc_posix_cnt locks is enough because no FL_POSIX locks | 1152 | * Allocating count locks is enough because no FL_POSIX locks can be |
1147 | * can be added to the list while we are holding cinode->lock_sem that | 1153 | * added to the list while we are holding cinode->lock_sem that |
1148 | * protects locking operations of this inode. | 1154 | * protects locking operations of this inode. |
1149 | */ | 1155 | */ |
1150 | for (i = 0; i < flctx->flc_posix_cnt; i++) { | 1156 | for (i = 0; i < count; i++) { |
1151 | lck = kmalloc(sizeof(struct lock_to_push), GFP_KERNEL); | 1157 | lck = kmalloc(sizeof(struct lock_to_push), GFP_KERNEL); |
1152 | if (!lck) { | 1158 | if (!lck) { |
1153 | rc = -ENOMEM; | 1159 | rc = -ENOMEM; |
diff --git a/fs/locks.c b/fs/locks.c index 4753218f308e..7998f670812c 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
@@ -681,21 +681,18 @@ static void locks_wake_up_blocks(struct file_lock *blocker) | |||
681 | } | 681 | } |
682 | 682 | ||
683 | static void | 683 | static void |
684 | locks_insert_lock_ctx(struct file_lock *fl, int *counter, | 684 | locks_insert_lock_ctx(struct file_lock *fl, struct list_head *before) |
685 | struct list_head *before) | ||
686 | { | 685 | { |
687 | fl->fl_nspid = get_pid(task_tgid(current)); | 686 | fl->fl_nspid = get_pid(task_tgid(current)); |
688 | list_add_tail(&fl->fl_list, before); | 687 | list_add_tail(&fl->fl_list, before); |
689 | ++*counter; | ||
690 | locks_insert_global_locks(fl); | 688 | locks_insert_global_locks(fl); |
691 | } | 689 | } |
692 | 690 | ||
693 | static void | 691 | static void |
694 | locks_unlink_lock_ctx(struct file_lock *fl, int *counter) | 692 | locks_unlink_lock_ctx(struct file_lock *fl) |
695 | { | 693 | { |
696 | locks_delete_global_locks(fl); | 694 | locks_delete_global_locks(fl); |
697 | list_del_init(&fl->fl_list); | 695 | list_del_init(&fl->fl_list); |
698 | --*counter; | ||
699 | if (fl->fl_nspid) { | 696 | if (fl->fl_nspid) { |
700 | put_pid(fl->fl_nspid); | 697 | put_pid(fl->fl_nspid); |
701 | fl->fl_nspid = NULL; | 698 | fl->fl_nspid = NULL; |
@@ -704,10 +701,9 @@ locks_unlink_lock_ctx(struct file_lock *fl, int *counter) | |||
704 | } | 701 | } |
705 | 702 | ||
706 | static void | 703 | static void |
707 | locks_delete_lock_ctx(struct file_lock *fl, int *counter, | 704 | locks_delete_lock_ctx(struct file_lock *fl, struct list_head *dispose) |
708 | struct list_head *dispose) | ||
709 | { | 705 | { |
710 | locks_unlink_lock_ctx(fl, counter); | 706 | locks_unlink_lock_ctx(fl); |
711 | if (dispose) | 707 | if (dispose) |
712 | list_add(&fl->fl_list, dispose); | 708 | list_add(&fl->fl_list, dispose); |
713 | else | 709 | else |
@@ -895,7 +891,7 @@ static int flock_lock_file(struct file *filp, struct file_lock *request) | |||
895 | if (request->fl_type == fl->fl_type) | 891 | if (request->fl_type == fl->fl_type) |
896 | goto out; | 892 | goto out; |
897 | found = true; | 893 | found = true; |
898 | locks_delete_lock_ctx(fl, &ctx->flc_flock_cnt, &dispose); | 894 | locks_delete_lock_ctx(fl, &dispose); |
899 | break; | 895 | break; |
900 | } | 896 | } |
901 | 897 | ||
@@ -929,7 +925,7 @@ find_conflict: | |||
929 | if (request->fl_flags & FL_ACCESS) | 925 | if (request->fl_flags & FL_ACCESS) |
930 | goto out; | 926 | goto out; |
931 | locks_copy_lock(new_fl, request); | 927 | locks_copy_lock(new_fl, request); |
932 | locks_insert_lock_ctx(new_fl, &ctx->flc_flock_cnt, &ctx->flc_flock); | 928 | locks_insert_lock_ctx(new_fl, &ctx->flc_flock); |
933 | new_fl = NULL; | 929 | new_fl = NULL; |
934 | error = 0; | 930 | error = 0; |
935 | 931 | ||
@@ -1046,8 +1042,7 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str | |||
1046 | else | 1042 | else |
1047 | request->fl_end = fl->fl_end; | 1043 | request->fl_end = fl->fl_end; |
1048 | if (added) { | 1044 | if (added) { |
1049 | locks_delete_lock_ctx(fl, &ctx->flc_posix_cnt, | 1045 | locks_delete_lock_ctx(fl, &dispose); |
1050 | &dispose); | ||
1051 | continue; | 1046 | continue; |
1052 | } | 1047 | } |
1053 | request = fl; | 1048 | request = fl; |
@@ -1076,8 +1071,7 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str | |||
1076 | * one (This may happen several times). | 1071 | * one (This may happen several times). |
1077 | */ | 1072 | */ |
1078 | if (added) { | 1073 | if (added) { |
1079 | locks_delete_lock_ctx(fl, | 1074 | locks_delete_lock_ctx(fl, &dispose); |
1080 | &ctx->flc_posix_cnt, &dispose); | ||
1081 | continue; | 1075 | continue; |
1082 | } | 1076 | } |
1083 | /* | 1077 | /* |
@@ -1093,10 +1087,8 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str | |||
1093 | locks_copy_lock(new_fl, request); | 1087 | locks_copy_lock(new_fl, request); |
1094 | request = new_fl; | 1088 | request = new_fl; |
1095 | new_fl = NULL; | 1089 | new_fl = NULL; |
1096 | locks_insert_lock_ctx(request, | 1090 | locks_insert_lock_ctx(request, &fl->fl_list); |
1097 | &ctx->flc_posix_cnt, &fl->fl_list); | 1091 | locks_delete_lock_ctx(fl, &dispose); |
1098 | locks_delete_lock_ctx(fl, | ||
1099 | &ctx->flc_posix_cnt, &dispose); | ||
1100 | added = true; | 1092 | added = true; |
1101 | } | 1093 | } |
1102 | } | 1094 | } |
@@ -1124,8 +1116,7 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str | |||
1124 | goto out; | 1116 | goto out; |
1125 | } | 1117 | } |
1126 | locks_copy_lock(new_fl, request); | 1118 | locks_copy_lock(new_fl, request); |
1127 | locks_insert_lock_ctx(new_fl, &ctx->flc_posix_cnt, | 1119 | locks_insert_lock_ctx(new_fl, &fl->fl_list); |
1128 | &fl->fl_list); | ||
1129 | new_fl = NULL; | 1120 | new_fl = NULL; |
1130 | } | 1121 | } |
1131 | if (right) { | 1122 | if (right) { |
@@ -1136,8 +1127,7 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str | |||
1136 | left = new_fl2; | 1127 | left = new_fl2; |
1137 | new_fl2 = NULL; | 1128 | new_fl2 = NULL; |
1138 | locks_copy_lock(left, right); | 1129 | locks_copy_lock(left, right); |
1139 | locks_insert_lock_ctx(left, &ctx->flc_posix_cnt, | 1130 | locks_insert_lock_ctx(left, &fl->fl_list); |
1140 | &fl->fl_list); | ||
1141 | } | 1131 | } |
1142 | right->fl_start = request->fl_end + 1; | 1132 | right->fl_start = request->fl_end + 1; |
1143 | locks_wake_up_blocks(right); | 1133 | locks_wake_up_blocks(right); |
@@ -1321,7 +1311,6 @@ static void lease_clear_pending(struct file_lock *fl, int arg) | |||
1321 | /* We already had a lease on this file; just change its type */ | 1311 | /* We already had a lease on this file; just change its type */ |
1322 | int lease_modify(struct file_lock *fl, int arg, struct list_head *dispose) | 1312 | int lease_modify(struct file_lock *fl, int arg, struct list_head *dispose) |
1323 | { | 1313 | { |
1324 | struct file_lock_context *flctx; | ||
1325 | int error = assign_type(fl, arg); | 1314 | int error = assign_type(fl, arg); |
1326 | 1315 | ||
1327 | if (error) | 1316 | if (error) |
@@ -1331,7 +1320,6 @@ int lease_modify(struct file_lock *fl, int arg, struct list_head *dispose) | |||
1331 | if (arg == F_UNLCK) { | 1320 | if (arg == F_UNLCK) { |
1332 | struct file *filp = fl->fl_file; | 1321 | struct file *filp = fl->fl_file; |
1333 | 1322 | ||
1334 | flctx = file_inode(filp)->i_flctx; | ||
1335 | f_delown(filp); | 1323 | f_delown(filp); |
1336 | filp->f_owner.signum = 0; | 1324 | filp->f_owner.signum = 0; |
1337 | fasync_helper(0, fl->fl_file, 0, &fl->fl_fasync); | 1325 | fasync_helper(0, fl->fl_file, 0, &fl->fl_fasync); |
@@ -1339,7 +1327,7 @@ int lease_modify(struct file_lock *fl, int arg, struct list_head *dispose) | |||
1339 | printk(KERN_ERR "locks_delete_lock: fasync == %p\n", fl->fl_fasync); | 1327 | printk(KERN_ERR "locks_delete_lock: fasync == %p\n", fl->fl_fasync); |
1340 | fl->fl_fasync = NULL; | 1328 | fl->fl_fasync = NULL; |
1341 | } | 1329 | } |
1342 | locks_delete_lock_ctx(fl, &flctx->flc_lease_cnt, dispose); | 1330 | locks_delete_lock_ctx(fl, dispose); |
1343 | } | 1331 | } |
1344 | return 0; | 1332 | return 0; |
1345 | } | 1333 | } |
@@ -1456,8 +1444,7 @@ int __break_lease(struct inode *inode, unsigned int mode, unsigned int type) | |||
1456 | fl->fl_downgrade_time = break_time; | 1444 | fl->fl_downgrade_time = break_time; |
1457 | } | 1445 | } |
1458 | if (fl->fl_lmops->lm_break(fl)) | 1446 | if (fl->fl_lmops->lm_break(fl)) |
1459 | locks_delete_lock_ctx(fl, &ctx->flc_lease_cnt, | 1447 | locks_delete_lock_ctx(fl, &dispose); |
1460 | &dispose); | ||
1461 | } | 1448 | } |
1462 | 1449 | ||
1463 | if (list_empty(&ctx->flc_lease)) | 1450 | if (list_empty(&ctx->flc_lease)) |
@@ -1697,7 +1684,7 @@ generic_add_lease(struct file *filp, long arg, struct file_lock **flp, void **pr | |||
1697 | if (!leases_enable) | 1684 | if (!leases_enable) |
1698 | goto out; | 1685 | goto out; |
1699 | 1686 | ||
1700 | locks_insert_lock_ctx(lease, &ctx->flc_lease_cnt, &ctx->flc_lease); | 1687 | locks_insert_lock_ctx(lease, &ctx->flc_lease); |
1701 | /* | 1688 | /* |
1702 | * The check in break_lease() is lockless. It's possible for another | 1689 | * The check in break_lease() is lockless. It's possible for another |
1703 | * open to race in after we did the earlier check for a conflicting | 1690 | * open to race in after we did the earlier check for a conflicting |
@@ -1710,7 +1697,7 @@ generic_add_lease(struct file *filp, long arg, struct file_lock **flp, void **pr | |||
1710 | smp_mb(); | 1697 | smp_mb(); |
1711 | error = check_conflicting_open(dentry, arg, lease->fl_flags); | 1698 | error = check_conflicting_open(dentry, arg, lease->fl_flags); |
1712 | if (error) { | 1699 | if (error) { |
1713 | locks_unlink_lock_ctx(lease, &ctx->flc_lease_cnt); | 1700 | locks_unlink_lock_ctx(lease); |
1714 | goto out; | 1701 | goto out; |
1715 | } | 1702 | } |
1716 | 1703 | ||
diff --git a/include/linux/fs.h b/include/linux/fs.h index e49f10cc8a73..a5a303e8a33c 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -969,9 +969,6 @@ struct file_lock_context { | |||
969 | struct list_head flc_flock; | 969 | struct list_head flc_flock; |
970 | struct list_head flc_posix; | 970 | struct list_head flc_posix; |
971 | struct list_head flc_lease; | 971 | struct list_head flc_lease; |
972 | int flc_flock_cnt; | ||
973 | int flc_posix_cnt; | ||
974 | int flc_lease_cnt; | ||
975 | }; | 972 | }; |
976 | 973 | ||
977 | /* The following constant reflects the upper bound of the file/locking space */ | 974 | /* The following constant reflects the upper bound of the file/locking space */ |