diff options
author | Jeff Layton <jlayton@primarydata.com> | 2015-01-16 15:05:57 -0500 |
---|---|---|
committer | Jeff Layton <jeff.layton@primarydata.com> | 2015-01-16 16:08:50 -0500 |
commit | 9bd0f45b7037fcfa8b575c7e27d0431d6e6dc3bb (patch) | |
tree | 205f3c2107cec0323dc25c959fefcc4fd709fa49 /fs | |
parent | 7448cc37b1a6b620d948aaee3bb30960c06d5d5d (diff) |
locks: keep a count of locks on the flctx lists
This makes things a bit more efficient in the cifs and ceph lock
pushing code.
Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Acked-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ceph/locks.c | 11 | ||||
-rw-r--r-- | fs/cifs/file.c | 14 | ||||
-rw-r--r-- | fs/locks.c | 45 |
3 files changed, 35 insertions, 35 deletions
diff --git a/fs/ceph/locks.c b/fs/ceph/locks.c index 0303da8e3233..06ea5cd05cd9 100644 --- a/fs/ceph/locks.c +++ b/fs/ceph/locks.c | |||
@@ -242,12 +242,9 @@ int ceph_flock(struct file *file, int cmd, struct file_lock *fl) | |||
242 | /* | 242 | /* |
243 | * Fills in the passed counter variables, so you can prepare pagelist metadata | 243 | * Fills in the passed counter variables, so you can prepare pagelist metadata |
244 | * before calling ceph_encode_locks. | 244 | * before calling ceph_encode_locks. |
245 | * | ||
246 | * FIXME: add counters to struct file_lock_context so we don't need to do this? | ||
247 | */ | 245 | */ |
248 | 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) |
249 | { | 247 | { |
250 | struct file_lock *lock; | ||
251 | struct file_lock_context *ctx; | 248 | struct file_lock_context *ctx; |
252 | 249 | ||
253 | *fcntl_count = 0; | 250 | *fcntl_count = 0; |
@@ -255,12 +252,8 @@ void ceph_count_locks(struct inode *inode, int *fcntl_count, int *flock_count) | |||
255 | 252 | ||
256 | ctx = inode->i_flctx; | 253 | ctx = inode->i_flctx; |
257 | if (ctx) { | 254 | if (ctx) { |
258 | spin_lock(&ctx->flc_lock); | 255 | *fcntl_count = ctx->flc_posix_cnt; |
259 | list_for_each_entry(lock, &ctx->flc_posix, fl_list) | 256 | *flock_count = ctx->flc_flock_cnt; |
260 | ++(*fcntl_count); | ||
261 | list_for_each_entry(lock, &ctx->flc_flock, fl_list) | ||
262 | ++(*flock_count); | ||
263 | spin_unlock(&ctx->flc_lock); | ||
264 | } | 257 | } |
265 | dout("counted %d flock locks and %d fcntl locks", | 258 | dout("counted %d flock locks and %d fcntl locks", |
266 | *flock_count, *fcntl_count); | 259 | *flock_count, *fcntl_count); |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index b65166eb111e..8c2ca6f62bad 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -1125,7 +1125,7 @@ cifs_push_posix_locks(struct cifsFileInfo *cfile) | |||
1125 | struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); | 1125 | struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); |
1126 | struct file_lock *flock; | 1126 | struct file_lock *flock; |
1127 | struct file_lock_context *flctx = inode->i_flctx; | 1127 | struct file_lock_context *flctx = inode->i_flctx; |
1128 | unsigned int count = 0, i; | 1128 | unsigned int i; |
1129 | int rc = 0, xid, type; | 1129 | int rc = 0, xid, type; |
1130 | struct list_head locks_to_send, *el; | 1130 | struct list_head locks_to_send, *el; |
1131 | struct lock_to_push *lck, *tmp; | 1131 | struct lock_to_push *lck, *tmp; |
@@ -1136,20 +1136,14 @@ cifs_push_posix_locks(struct cifsFileInfo *cfile) | |||
1136 | if (!flctx) | 1136 | if (!flctx) |
1137 | goto out; | 1137 | goto out; |
1138 | 1138 | ||
1139 | spin_lock(&flctx->flc_lock); | ||
1140 | list_for_each(el, &flctx->flc_posix) { | ||
1141 | count++; | ||
1142 | } | ||
1143 | spin_unlock(&flctx->flc_lock); | ||
1144 | |||
1145 | INIT_LIST_HEAD(&locks_to_send); | 1139 | INIT_LIST_HEAD(&locks_to_send); |
1146 | 1140 | ||
1147 | /* | 1141 | /* |
1148 | * Allocating count locks is enough because no FL_POSIX locks can be | 1142 | * Allocating flc_posix_cnt locks is enough because no FL_POSIX locks |
1149 | * added to the list while we are holding cinode->lock_sem that | 1143 | * can be added to the list while we are holding cinode->lock_sem that |
1150 | * protects locking operations of this inode. | 1144 | * protects locking operations of this inode. |
1151 | */ | 1145 | */ |
1152 | for (i = 0; i < count; i++) { | 1146 | for (i = 0; i < flctx->flc_posix_cnt; i++) { |
1153 | lck = kmalloc(sizeof(struct lock_to_push), GFP_KERNEL); | 1147 | lck = kmalloc(sizeof(struct lock_to_push), GFP_KERNEL); |
1154 | if (!lck) { | 1148 | if (!lck) { |
1155 | rc = -ENOMEM; | 1149 | rc = -ENOMEM; |
diff --git a/fs/locks.c b/fs/locks.c index 864f2460a0ad..bd578700342d 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
@@ -681,18 +681,21 @@ 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, struct list_head *before) | 684 | locks_insert_lock_ctx(struct file_lock *fl, int *counter, |
685 | struct list_head *before) | ||
685 | { | 686 | { |
686 | fl->fl_nspid = get_pid(task_tgid(current)); | 687 | fl->fl_nspid = get_pid(task_tgid(current)); |
687 | list_add_tail(&fl->fl_list, before); | 688 | list_add_tail(&fl->fl_list, before); |
689 | ++*counter; | ||
688 | locks_insert_global_locks(fl); | 690 | locks_insert_global_locks(fl); |
689 | } | 691 | } |
690 | 692 | ||
691 | static void | 693 | static void |
692 | locks_unlink_lock_ctx(struct file_lock *fl) | 694 | locks_unlink_lock_ctx(struct file_lock *fl, int *counter) |
693 | { | 695 | { |
694 | locks_delete_global_locks(fl); | 696 | locks_delete_global_locks(fl); |
695 | list_del_init(&fl->fl_list); | 697 | list_del_init(&fl->fl_list); |
698 | --*counter; | ||
696 | if (fl->fl_nspid) { | 699 | if (fl->fl_nspid) { |
697 | put_pid(fl->fl_nspid); | 700 | put_pid(fl->fl_nspid); |
698 | fl->fl_nspid = NULL; | 701 | fl->fl_nspid = NULL; |
@@ -701,9 +704,10 @@ locks_unlink_lock_ctx(struct file_lock *fl) | |||
701 | } | 704 | } |
702 | 705 | ||
703 | static void | 706 | static void |
704 | locks_delete_lock_ctx(struct file_lock *fl, struct list_head *dispose) | 707 | locks_delete_lock_ctx(struct file_lock *fl, int *counter, |
708 | struct list_head *dispose) | ||
705 | { | 709 | { |
706 | locks_unlink_lock_ctx(fl); | 710 | locks_unlink_lock_ctx(fl, counter); |
707 | if (dispose) | 711 | if (dispose) |
708 | list_add(&fl->fl_list, dispose); | 712 | list_add(&fl->fl_list, dispose); |
709 | else | 713 | else |
@@ -891,7 +895,7 @@ static int flock_lock_file(struct file *filp, struct file_lock *request) | |||
891 | if (request->fl_type == fl->fl_type) | 895 | if (request->fl_type == fl->fl_type) |
892 | goto out; | 896 | goto out; |
893 | found = true; | 897 | found = true; |
894 | locks_delete_lock_ctx(fl, &dispose); | 898 | locks_delete_lock_ctx(fl, &ctx->flc_flock_cnt, &dispose); |
895 | break; | 899 | break; |
896 | } | 900 | } |
897 | 901 | ||
@@ -925,7 +929,7 @@ find_conflict: | |||
925 | if (request->fl_flags & FL_ACCESS) | 929 | if (request->fl_flags & FL_ACCESS) |
926 | goto out; | 930 | goto out; |
927 | locks_copy_lock(new_fl, request); | 931 | locks_copy_lock(new_fl, request); |
928 | locks_insert_lock_ctx(new_fl, &ctx->flc_flock); | 932 | locks_insert_lock_ctx(new_fl, &ctx->flc_flock_cnt, &ctx->flc_flock); |
929 | new_fl = NULL; | 933 | new_fl = NULL; |
930 | error = 0; | 934 | error = 0; |
931 | 935 | ||
@@ -1042,7 +1046,8 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str | |||
1042 | else | 1046 | else |
1043 | request->fl_end = fl->fl_end; | 1047 | request->fl_end = fl->fl_end; |
1044 | if (added) { | 1048 | if (added) { |
1045 | locks_delete_lock_ctx(fl, &dispose); | 1049 | locks_delete_lock_ctx(fl, &ctx->flc_posix_cnt, |
1050 | &dispose); | ||
1046 | continue; | 1051 | continue; |
1047 | } | 1052 | } |
1048 | request = fl; | 1053 | request = fl; |
@@ -1071,7 +1076,8 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str | |||
1071 | * one (This may happen several times). | 1076 | * one (This may happen several times). |
1072 | */ | 1077 | */ |
1073 | if (added) { | 1078 | if (added) { |
1074 | locks_delete_lock_ctx(fl, &dispose); | 1079 | locks_delete_lock_ctx(fl, |
1080 | &ctx->flc_posix_cnt, &dispose); | ||
1075 | continue; | 1081 | continue; |
1076 | } | 1082 | } |
1077 | /* | 1083 | /* |
@@ -1087,8 +1093,10 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str | |||
1087 | locks_copy_lock(new_fl, request); | 1093 | locks_copy_lock(new_fl, request); |
1088 | request = new_fl; | 1094 | request = new_fl; |
1089 | new_fl = NULL; | 1095 | new_fl = NULL; |
1090 | locks_insert_lock_ctx(request, &fl->fl_list); | 1096 | locks_insert_lock_ctx(request, |
1091 | locks_delete_lock_ctx(fl, &dispose); | 1097 | &ctx->flc_posix_cnt, &fl->fl_list); |
1098 | locks_delete_lock_ctx(fl, | ||
1099 | &ctx->flc_posix_cnt, &dispose); | ||
1092 | added = true; | 1100 | added = true; |
1093 | } | 1101 | } |
1094 | } | 1102 | } |
@@ -1116,7 +1124,8 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str | |||
1116 | goto out; | 1124 | goto out; |
1117 | } | 1125 | } |
1118 | locks_copy_lock(new_fl, request); | 1126 | locks_copy_lock(new_fl, request); |
1119 | locks_insert_lock_ctx(new_fl, &fl->fl_list); | 1127 | locks_insert_lock_ctx(new_fl, &ctx->flc_posix_cnt, |
1128 | &fl->fl_list); | ||
1120 | new_fl = NULL; | 1129 | new_fl = NULL; |
1121 | } | 1130 | } |
1122 | if (right) { | 1131 | if (right) { |
@@ -1127,7 +1136,8 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str | |||
1127 | left = new_fl2; | 1136 | left = new_fl2; |
1128 | new_fl2 = NULL; | 1137 | new_fl2 = NULL; |
1129 | locks_copy_lock(left, right); | 1138 | locks_copy_lock(left, right); |
1130 | locks_insert_lock_ctx(left, &fl->fl_list); | 1139 | locks_insert_lock_ctx(left, &ctx->flc_posix_cnt, |
1140 | &fl->fl_list); | ||
1131 | } | 1141 | } |
1132 | right->fl_start = request->fl_end + 1; | 1142 | right->fl_start = request->fl_end + 1; |
1133 | locks_wake_up_blocks(right); | 1143 | locks_wake_up_blocks(right); |
@@ -1311,6 +1321,7 @@ static void lease_clear_pending(struct file_lock *fl, int arg) | |||
1311 | /* We already had a lease on this file; just change its type */ | 1321 | /* We already had a lease on this file; just change its type */ |
1312 | int lease_modify(struct file_lock *fl, int arg, struct list_head *dispose) | 1322 | int lease_modify(struct file_lock *fl, int arg, struct list_head *dispose) |
1313 | { | 1323 | { |
1324 | struct file_lock_context *flctx; | ||
1314 | int error = assign_type(fl, arg); | 1325 | int error = assign_type(fl, arg); |
1315 | 1326 | ||
1316 | if (error) | 1327 | if (error) |
@@ -1320,6 +1331,7 @@ int lease_modify(struct file_lock *fl, int arg, struct list_head *dispose) | |||
1320 | if (arg == F_UNLCK) { | 1331 | if (arg == F_UNLCK) { |
1321 | struct file *filp = fl->fl_file; | 1332 | struct file *filp = fl->fl_file; |
1322 | 1333 | ||
1334 | flctx = file_inode(filp)->i_flctx; | ||
1323 | f_delown(filp); | 1335 | f_delown(filp); |
1324 | filp->f_owner.signum = 0; | 1336 | filp->f_owner.signum = 0; |
1325 | fasync_helper(0, fl->fl_file, 0, &fl->fl_fasync); | 1337 | fasync_helper(0, fl->fl_file, 0, &fl->fl_fasync); |
@@ -1327,7 +1339,7 @@ int lease_modify(struct file_lock *fl, int arg, struct list_head *dispose) | |||
1327 | printk(KERN_ERR "locks_delete_lock: fasync == %p\n", fl->fl_fasync); | 1339 | printk(KERN_ERR "locks_delete_lock: fasync == %p\n", fl->fl_fasync); |
1328 | fl->fl_fasync = NULL; | 1340 | fl->fl_fasync = NULL; |
1329 | } | 1341 | } |
1330 | locks_delete_lock_ctx(fl, dispose); | 1342 | locks_delete_lock_ctx(fl, &flctx->flc_lease_cnt, dispose); |
1331 | } | 1343 | } |
1332 | return 0; | 1344 | return 0; |
1333 | } | 1345 | } |
@@ -1442,7 +1454,8 @@ int __break_lease(struct inode *inode, unsigned int mode, unsigned int type) | |||
1442 | fl->fl_downgrade_time = break_time; | 1454 | fl->fl_downgrade_time = break_time; |
1443 | } | 1455 | } |
1444 | if (fl->fl_lmops->lm_break(fl)) | 1456 | if (fl->fl_lmops->lm_break(fl)) |
1445 | locks_delete_lock_ctx(fl, &dispose); | 1457 | locks_delete_lock_ctx(fl, &ctx->flc_lease_cnt, |
1458 | &dispose); | ||
1446 | } | 1459 | } |
1447 | 1460 | ||
1448 | if (list_empty(&ctx->flc_lease)) | 1461 | if (list_empty(&ctx->flc_lease)) |
@@ -1678,7 +1691,7 @@ generic_add_lease(struct file *filp, long arg, struct file_lock **flp, void **pr | |||
1678 | if (!leases_enable) | 1691 | if (!leases_enable) |
1679 | goto out; | 1692 | goto out; |
1680 | 1693 | ||
1681 | locks_insert_lock_ctx(lease, &ctx->flc_lease); | 1694 | locks_insert_lock_ctx(lease, &ctx->flc_lease_cnt, &ctx->flc_lease); |
1682 | /* | 1695 | /* |
1683 | * The check in break_lease() is lockless. It's possible for another | 1696 | * The check in break_lease() is lockless. It's possible for another |
1684 | * open to race in after we did the earlier check for a conflicting | 1697 | * open to race in after we did the earlier check for a conflicting |
@@ -1691,7 +1704,7 @@ generic_add_lease(struct file *filp, long arg, struct file_lock **flp, void **pr | |||
1691 | smp_mb(); | 1704 | smp_mb(); |
1692 | error = check_conflicting_open(dentry, arg); | 1705 | error = check_conflicting_open(dentry, arg); |
1693 | if (error) { | 1706 | if (error) { |
1694 | locks_unlink_lock_ctx(lease); | 1707 | locks_unlink_lock_ctx(lease, &ctx->flc_lease_cnt); |
1695 | goto out; | 1708 | goto out; |
1696 | } | 1709 | } |
1697 | 1710 | ||