Skip to content

Commit 9bd0f45

Browse files
Jeff LaytonJeff Layton
authored andcommitted
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>
1 parent 7448cc3 commit 9bd0f45

File tree

4 files changed

+38
-35
lines changed

4 files changed

+38
-35
lines changed

fs/ceph/locks.c

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -242,25 +242,18 @@ int ceph_flock(struct file *file, int cmd, struct file_lock *fl)
242242
/*
243243
* Fills in the passed counter variables, so you can prepare pagelist metadata
244244
* before calling ceph_encode_locks.
245-
*
246-
* FIXME: add counters to struct file_lock_context so we don't need to do this?
247245
*/
248246
void ceph_count_locks(struct inode *inode, int *fcntl_count, int *flock_count)
249247
{
250-
struct file_lock *lock;
251248
struct file_lock_context *ctx;
252249

253250
*fcntl_count = 0;
254251
*flock_count = 0;
255252

256253
ctx = inode->i_flctx;
257254
if (ctx) {
258-
spin_lock(&ctx->flc_lock);
259-
list_for_each_entry(lock, &ctx->flc_posix, fl_list)
260-
++(*fcntl_count);
261-
list_for_each_entry(lock, &ctx->flc_flock, fl_list)
262-
++(*flock_count);
263-
spin_unlock(&ctx->flc_lock);
255+
*fcntl_count = ctx->flc_posix_cnt;
256+
*flock_count = ctx->flc_flock_cnt;
264257
}
265258
dout("counted %d flock locks and %d fcntl locks",
266259
*flock_count, *fcntl_count);

fs/cifs/file.c

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1125,7 +1125,7 @@ cifs_push_posix_locks(struct cifsFileInfo *cfile)
11251125
struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
11261126
struct file_lock *flock;
11271127
struct file_lock_context *flctx = inode->i_flctx;
1128-
unsigned int count = 0, i;
1128+
unsigned int i;
11291129
int rc = 0, xid, type;
11301130
struct list_head locks_to_send, *el;
11311131
struct lock_to_push *lck, *tmp;
@@ -1136,20 +1136,14 @@ cifs_push_posix_locks(struct cifsFileInfo *cfile)
11361136
if (!flctx)
11371137
goto out;
11381138

1139-
spin_lock(&flctx->flc_lock);
1140-
list_for_each(el, &flctx->flc_posix) {
1141-
count++;
1142-
}
1143-
spin_unlock(&flctx->flc_lock);
1144-
11451139
INIT_LIST_HEAD(&locks_to_send);
11461140

11471141
/*
1148-
* Allocating count locks is enough because no FL_POSIX locks can be
1149-
* added to the list while we are holding cinode->lock_sem that
1142+
* Allocating flc_posix_cnt locks is enough because no FL_POSIX locks
1143+
* can be added to the list while we are holding cinode->lock_sem that
11501144
* protects locking operations of this inode.
11511145
*/
1152-
for (i = 0; i < count; i++) {
1146+
for (i = 0; i < flctx->flc_posix_cnt; i++) {
11531147
lck = kmalloc(sizeof(struct lock_to_push), GFP_KERNEL);
11541148
if (!lck) {
11551149
rc = -ENOMEM;

fs/locks.c

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -681,18 +681,21 @@ static void locks_wake_up_blocks(struct file_lock *blocker)
681681
}
682682

683683
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)
685686
{
686687
fl->fl_nspid = get_pid(task_tgid(current));
687688
list_add_tail(&fl->fl_list, before);
689+
++*counter;
688690
locks_insert_global_locks(fl);
689691
}
690692

691693
static void
692-
locks_unlink_lock_ctx(struct file_lock *fl)
694+
locks_unlink_lock_ctx(struct file_lock *fl, int *counter)
693695
{
694696
locks_delete_global_locks(fl);
695697
list_del_init(&fl->fl_list);
698+
--*counter;
696699
if (fl->fl_nspid) {
697700
put_pid(fl->fl_nspid);
698701
fl->fl_nspid = NULL;
@@ -701,9 +704,10 @@ locks_unlink_lock_ctx(struct file_lock *fl)
701704
}
702705

703706
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)
705709
{
706-
locks_unlink_lock_ctx(fl);
710+
locks_unlink_lock_ctx(fl, counter);
707711
if (dispose)
708712
list_add(&fl->fl_list, dispose);
709713
else
@@ -891,7 +895,7 @@ static int flock_lock_file(struct file *filp, struct file_lock *request)
891895
if (request->fl_type == fl->fl_type)
892896
goto out;
893897
found = true;
894-
locks_delete_lock_ctx(fl, &dispose);
898+
locks_delete_lock_ctx(fl, &ctx->flc_flock_cnt, &dispose);
895899
break;
896900
}
897901

@@ -925,7 +929,7 @@ static int flock_lock_file(struct file *filp, struct file_lock *request)
925929
if (request->fl_flags & FL_ACCESS)
926930
goto out;
927931
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);
929933
new_fl = NULL;
930934
error = 0;
931935

@@ -1042,7 +1046,8 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str
10421046
else
10431047
request->fl_end = fl->fl_end;
10441048
if (added) {
1045-
locks_delete_lock_ctx(fl, &dispose);
1049+
locks_delete_lock_ctx(fl, &ctx->flc_posix_cnt,
1050+
&dispose);
10461051
continue;
10471052
}
10481053
request = fl;
@@ -1071,7 +1076,8 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str
10711076
* one (This may happen several times).
10721077
*/
10731078
if (added) {
1074-
locks_delete_lock_ctx(fl, &dispose);
1079+
locks_delete_lock_ctx(fl,
1080+
&ctx->flc_posix_cnt, &dispose);
10751081
continue;
10761082
}
10771083
/*
@@ -1087,8 +1093,10 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str
10871093
locks_copy_lock(new_fl, request);
10881094
request = new_fl;
10891095
new_fl = NULL;
1090-
locks_insert_lock_ctx(request, &fl->fl_list);
1091-
locks_delete_lock_ctx(fl, &dispose);
1096+
locks_insert_lock_ctx(request,
1097+
&ctx->flc_posix_cnt, &fl->fl_list);
1098+
locks_delete_lock_ctx(fl,
1099+
&ctx->flc_posix_cnt, &dispose);
10921100
added = true;
10931101
}
10941102
}
@@ -1116,7 +1124,8 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str
11161124
goto out;
11171125
}
11181126
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);
11201129
new_fl = NULL;
11211130
}
11221131
if (right) {
@@ -1127,7 +1136,8 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str
11271136
left = new_fl2;
11281137
new_fl2 = NULL;
11291138
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);
11311141
}
11321142
right->fl_start = request->fl_end + 1;
11331143
locks_wake_up_blocks(right);
@@ -1311,6 +1321,7 @@ static void lease_clear_pending(struct file_lock *fl, int arg)
13111321
/* We already had a lease on this file; just change its type */
13121322
int lease_modify(struct file_lock *fl, int arg, struct list_head *dispose)
13131323
{
1324+
struct file_lock_context *flctx;
13141325
int error = assign_type(fl, arg);
13151326

13161327
if (error)
@@ -1320,14 +1331,15 @@ int lease_modify(struct file_lock *fl, int arg, struct list_head *dispose)
13201331
if (arg == F_UNLCK) {
13211332
struct file *filp = fl->fl_file;
13221333

1334+
flctx = file_inode(filp)->i_flctx;
13231335
f_delown(filp);
13241336
filp->f_owner.signum = 0;
13251337
fasync_helper(0, fl->fl_file, 0, &fl->fl_fasync);
13261338
if (fl->fl_fasync != NULL) {
13271339
printk(KERN_ERR "locks_delete_lock: fasync == %p\n", fl->fl_fasync);
13281340
fl->fl_fasync = NULL;
13291341
}
1330-
locks_delete_lock_ctx(fl, dispose);
1342+
locks_delete_lock_ctx(fl, &flctx->flc_lease_cnt, dispose);
13311343
}
13321344
return 0;
13331345
}
@@ -1442,7 +1454,8 @@ int __break_lease(struct inode *inode, unsigned int mode, unsigned int type)
14421454
fl->fl_downgrade_time = break_time;
14431455
}
14441456
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);
14461459
}
14471460

14481461
if (list_empty(&ctx->flc_lease))
@@ -1678,7 +1691,7 @@ generic_add_lease(struct file *filp, long arg, struct file_lock **flp, void **pr
16781691
if (!leases_enable)
16791692
goto out;
16801693

1681-
locks_insert_lock_ctx(lease, &ctx->flc_lease);
1694+
locks_insert_lock_ctx(lease, &ctx->flc_lease_cnt, &ctx->flc_lease);
16821695
/*
16831696
* The check in break_lease() is lockless. It's possible for another
16841697
* 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
16911704
smp_mb();
16921705
error = check_conflicting_open(dentry, arg);
16931706
if (error) {
1694-
locks_unlink_lock_ctx(lease);
1707+
locks_unlink_lock_ctx(lease, &ctx->flc_lease_cnt);
16951708
goto out;
16961709
}
16971710

include/linux/fs.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -972,6 +972,9 @@ struct file_lock_context {
972972
struct list_head flc_flock;
973973
struct list_head flc_posix;
974974
struct list_head flc_lease;
975+
int flc_flock_cnt;
976+
int flc_posix_cnt;
977+
int flc_lease_cnt;
975978
};
976979

977980
/* The following constant reflects the upper bound of the file/locking space */

0 commit comments

Comments
 (0)