summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJeff Layton <jlayton@primarydata.com>2015-01-16 15:05:57 -0500
committerJeff Layton <jeff.layton@primarydata.com>2015-01-16 16:08:50 -0500
commit9bd0f45b7037fcfa8b575c7e27d0431d6e6dc3bb (patch)
tree205f3c2107cec0323dc25c959fefcc4fd709fa49 /fs
parent7448cc37b1a6b620d948aaee3bb30960c06d5d5d (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.c11
-rw-r--r--fs/cifs/file.c14
-rw-r--r--fs/locks.c45
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 */
248void ceph_count_locks(struct inode *inode, int *fcntl_count, int *flock_count) 246void 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
683static void 683static void
684locks_insert_lock_ctx(struct file_lock *fl, struct list_head *before) 684locks_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
691static void 693static void
692locks_unlink_lock_ctx(struct file_lock *fl) 694locks_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
703static void 706static void
704locks_delete_lock_ctx(struct file_lock *fl, struct list_head *dispose) 707locks_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 */
1312int lease_modify(struct file_lock *fl, int arg, struct list_head *dispose) 1322int 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