summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorBenjamin Coddington <bcodding@redhat.com>2019-05-23 10:45:45 -0400
committerJ. Bruce Fields <bfields@redhat.com>2019-07-03 17:52:08 -0400
commit89e0edfbea103d9b274efa10a8fc7a88bdac8f76 (patch)
treee13bb61003180e2cf10d5266af2a24052f5d4fff /fs
parent9de3ec1d57113e270638254868675d9c048b071e (diff)
lockd: Convert NLM service fl_owner to nlm_lockowner
Do as the NLM client: allocate and track a struct nlm_lockowner for use as the fl_owner for locks created by the NLM sever. This allows us to keep the svid within this structure for matching locks, and will allow us to track the pid of lockd in a future patch. It should also allow easier reference of the nlm_host in conflicting locks, and simplify lock hashing and comparison. Signed-off-by: Benjamin Coddington <bcodding@redhat.com> [bfields@redhat.com: fix type of some error returns] Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/lockd/svc4proc.c13
-rw-r--r--fs/lockd/svclock.c96
-rw-r--r--fs/lockd/svcproc.c13
-rw-r--r--fs/lockd/svcsubs.c2
-rw-r--r--fs/lockd/xdr.c1
-rw-r--r--fs/lockd/xdr4.c1
6 files changed, 121 insertions, 5 deletions
diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c
index 1bddf70d9656..a00134fd8956 100644
--- a/fs/lockd/svc4proc.c
+++ b/fs/lockd/svc4proc.c
@@ -46,8 +46,13 @@ nlm4svc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp,
46 46
47 /* Set up the missing parts of the file_lock structure */ 47 /* Set up the missing parts of the file_lock structure */
48 lock->fl.fl_file = file->f_file; 48 lock->fl.fl_file = file->f_file;
49 lock->fl.fl_owner = (fl_owner_t) host;
50 lock->fl.fl_lmops = &nlmsvc_lock_operations; 49 lock->fl.fl_lmops = &nlmsvc_lock_operations;
50 nlmsvc_locks_init_private(&lock->fl, host, (pid_t)lock->svid);
51 if (!lock->fl.fl_owner) {
52 /* lockowner allocation has failed */
53 nlmsvc_release_host(host);
54 return nlm_lck_denied_nolocks;
55 }
51 } 56 }
52 57
53 return 0; 58 return 0;
@@ -94,6 +99,7 @@ __nlm4svc_proc_test(struct svc_rqst *rqstp, struct nlm_res *resp)
94 else 99 else
95 dprintk("lockd: TEST4 status %d\n", ntohl(resp->status)); 100 dprintk("lockd: TEST4 status %d\n", ntohl(resp->status));
96 101
102 nlmsvc_release_lockowner(&argp->lock);
97 nlmsvc_release_host(host); 103 nlmsvc_release_host(host);
98 nlm_release_file(file); 104 nlm_release_file(file);
99 return rc; 105 return rc;
@@ -142,6 +148,7 @@ __nlm4svc_proc_lock(struct svc_rqst *rqstp, struct nlm_res *resp)
142 else 148 else
143 dprintk("lockd: LOCK status %d\n", ntohl(resp->status)); 149 dprintk("lockd: LOCK status %d\n", ntohl(resp->status));
144 150
151 nlmsvc_release_lockowner(&argp->lock);
145 nlmsvc_release_host(host); 152 nlmsvc_release_host(host);
146 nlm_release_file(file); 153 nlm_release_file(file);
147 return rc; 154 return rc;
@@ -178,6 +185,7 @@ __nlm4svc_proc_cancel(struct svc_rqst *rqstp, struct nlm_res *resp)
178 resp->status = nlmsvc_cancel_blocked(SVC_NET(rqstp), file, &argp->lock); 185 resp->status = nlmsvc_cancel_blocked(SVC_NET(rqstp), file, &argp->lock);
179 186
180 dprintk("lockd: CANCEL status %d\n", ntohl(resp->status)); 187 dprintk("lockd: CANCEL status %d\n", ntohl(resp->status));
188 nlmsvc_release_lockowner(&argp->lock);
181 nlmsvc_release_host(host); 189 nlmsvc_release_host(host);
182 nlm_release_file(file); 190 nlm_release_file(file);
183 return rpc_success; 191 return rpc_success;
@@ -217,6 +225,7 @@ __nlm4svc_proc_unlock(struct svc_rqst *rqstp, struct nlm_res *resp)
217 resp->status = nlmsvc_unlock(SVC_NET(rqstp), file, &argp->lock); 225 resp->status = nlmsvc_unlock(SVC_NET(rqstp), file, &argp->lock);
218 226
219 dprintk("lockd: UNLOCK status %d\n", ntohl(resp->status)); 227 dprintk("lockd: UNLOCK status %d\n", ntohl(resp->status));
228 nlmsvc_release_lockowner(&argp->lock);
220 nlmsvc_release_host(host); 229 nlmsvc_release_host(host);
221 nlm_release_file(file); 230 nlm_release_file(file);
222 return rpc_success; 231 return rpc_success;
@@ -365,6 +374,7 @@ nlm4svc_proc_share(struct svc_rqst *rqstp)
365 resp->status = nlmsvc_share_file(host, file, argp); 374 resp->status = nlmsvc_share_file(host, file, argp);
366 375
367 dprintk("lockd: SHARE status %d\n", ntohl(resp->status)); 376 dprintk("lockd: SHARE status %d\n", ntohl(resp->status));
377 nlmsvc_release_lockowner(&argp->lock);
368 nlmsvc_release_host(host); 378 nlmsvc_release_host(host);
369 nlm_release_file(file); 379 nlm_release_file(file);
370 return rpc_success; 380 return rpc_success;
@@ -399,6 +409,7 @@ nlm4svc_proc_unshare(struct svc_rqst *rqstp)
399 resp->status = nlmsvc_unshare_file(host, file, argp); 409 resp->status = nlmsvc_unshare_file(host, file, argp);
400 410
401 dprintk("lockd: UNSHARE status %d\n", ntohl(resp->status)); 411 dprintk("lockd: UNSHARE status %d\n", ntohl(resp->status));
412 nlmsvc_release_lockowner(&argp->lock);
402 nlmsvc_release_host(host); 413 nlmsvc_release_host(host);
403 nlm_release_file(file); 414 nlm_release_file(file);
404 return rpc_success; 415 return rpc_success;
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index ea719cdd6a36..34c6ee85274e 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -332,6 +332,93 @@ restart:
332 mutex_unlock(&file->f_mutex); 332 mutex_unlock(&file->f_mutex);
333} 333}
334 334
335static struct nlm_lockowner *
336nlmsvc_get_lockowner(struct nlm_lockowner *lockowner)
337{
338 refcount_inc(&lockowner->count);
339 return lockowner;
340}
341
342static void nlmsvc_put_lockowner(struct nlm_lockowner *lockowner)
343{
344 if (!refcount_dec_and_lock(&lockowner->count, &lockowner->host->h_lock))
345 return;
346 list_del(&lockowner->list);
347 spin_unlock(&lockowner->host->h_lock);
348 nlmsvc_release_host(lockowner->host);
349 kfree(lockowner);
350}
351
352static struct nlm_lockowner *__nlmsvc_find_lockowner(struct nlm_host *host, pid_t pid)
353{
354 struct nlm_lockowner *lockowner;
355 list_for_each_entry(lockowner, &host->h_lockowners, list) {
356 if (lockowner->pid != pid)
357 continue;
358 return nlmsvc_get_lockowner(lockowner);
359 }
360 return NULL;
361}
362
363static struct nlm_lockowner *nlmsvc_find_lockowner(struct nlm_host *host, pid_t pid)
364{
365 struct nlm_lockowner *res, *new = NULL;
366
367 spin_lock(&host->h_lock);
368 res = __nlmsvc_find_lockowner(host, pid);
369
370 if (res == NULL) {
371 spin_unlock(&host->h_lock);
372 new = kmalloc(sizeof(*res), GFP_KERNEL);
373 spin_lock(&host->h_lock);
374 res = __nlmsvc_find_lockowner(host, pid);
375 if (res == NULL && new != NULL) {
376 res = new;
377 /* fs/locks.c will manage the refcount through lock_ops */
378 refcount_set(&new->count, 1);
379 new->pid = pid;
380 new->host = nlm_get_host(host);
381 list_add(&new->list, &host->h_lockowners);
382 new = NULL;
383 }
384 }
385
386 spin_unlock(&host->h_lock);
387 kfree(new);
388 return res;
389}
390
391void
392nlmsvc_release_lockowner(struct nlm_lock *lock)
393{
394 if (lock->fl.fl_owner)
395 nlmsvc_put_lockowner(lock->fl.fl_owner);
396}
397
398static void nlmsvc_locks_copy_lock(struct file_lock *new, struct file_lock *fl)
399{
400 struct nlm_lockowner *nlm_lo = (struct nlm_lockowner *)fl->fl_owner;
401 new->fl_owner = nlmsvc_get_lockowner(nlm_lo);
402}
403
404static void nlmsvc_locks_release_private(struct file_lock *fl)
405{
406 nlmsvc_put_lockowner((struct nlm_lockowner *)fl->fl_owner);
407}
408
409const struct file_lock_operations nlmsvc_lock_ops = {
410 .fl_copy_lock = nlmsvc_locks_copy_lock,
411 .fl_release_private = nlmsvc_locks_release_private,
412};
413
414void nlmsvc_locks_init_private(struct file_lock *fl, struct nlm_host *host,
415 pid_t pid)
416{
417 fl->fl_owner = nlmsvc_find_lockowner(host, pid);
418 if (fl->fl_owner != NULL)
419 fl->fl_ops = &nlmsvc_lock_ops;
420}
421
335/* 422/*
336 * Initialize arguments for GRANTED call. The nlm_rqst structure 423 * Initialize arguments for GRANTED call. The nlm_rqst structure
337 * has been cleared already. 424 * has been cleared already.
@@ -509,6 +596,7 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file,
509{ 596{
510 int error; 597 int error;
511 __be32 ret; 598 __be32 ret;
599 struct nlm_lockowner *test_owner;
512 600
513 dprintk("lockd: nlmsvc_testlock(%s/%ld, ty=%d, %Ld-%Ld)\n", 601 dprintk("lockd: nlmsvc_testlock(%s/%ld, ty=%d, %Ld-%Ld)\n",
514 locks_inode(file->f_file)->i_sb->s_id, 602 locks_inode(file->f_file)->i_sb->s_id,
@@ -522,6 +610,9 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file,
522 goto out; 610 goto out;
523 } 611 }
524 612
613 /* If there's a conflicting lock, remember to clean up the test lock */
614 test_owner = (struct nlm_lockowner *)lock->fl.fl_owner;
615
525 error = vfs_test_lock(file->f_file, &lock->fl); 616 error = vfs_test_lock(file->f_file, &lock->fl);
526 if (error) { 617 if (error) {
527 /* We can't currently deal with deferred test requests */ 618 /* We can't currently deal with deferred test requests */
@@ -548,6 +639,11 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file,
548 conflock->fl.fl_start = lock->fl.fl_start; 639 conflock->fl.fl_start = lock->fl.fl_start;
549 conflock->fl.fl_end = lock->fl.fl_end; 640 conflock->fl.fl_end = lock->fl.fl_end;
550 locks_release_private(&lock->fl); 641 locks_release_private(&lock->fl);
642
643 /* Clean up the test lock */
644 lock->fl.fl_owner = NULL;
645 nlmsvc_put_lockowner(test_owner);
646
551 ret = nlm_lck_denied; 647 ret = nlm_lck_denied;
552out: 648out:
553 return ret; 649 return ret;
diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c
index ea77c66d3cc3..36245ab43ae3 100644
--- a/fs/lockd/svcproc.c
+++ b/fs/lockd/svcproc.c
@@ -76,8 +76,13 @@ nlmsvc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp,
76 76
77 /* Set up the missing parts of the file_lock structure */ 77 /* Set up the missing parts of the file_lock structure */
78 lock->fl.fl_file = file->f_file; 78 lock->fl.fl_file = file->f_file;
79 lock->fl.fl_owner = (fl_owner_t) host;
80 lock->fl.fl_lmops = &nlmsvc_lock_operations; 79 lock->fl.fl_lmops = &nlmsvc_lock_operations;
80 nlmsvc_locks_init_private(&lock->fl, host, (pid_t)lock->svid);
81 if (!lock->fl.fl_owner) {
82 /* lockowner allocation has failed */
83 nlmsvc_release_host(host);
84 return nlm_lck_denied_nolocks;
85 }
81 } 86 }
82 87
83 return 0; 88 return 0;
@@ -125,6 +130,7 @@ __nlmsvc_proc_test(struct svc_rqst *rqstp, struct nlm_res *resp)
125 dprintk("lockd: TEST status %d vers %d\n", 130 dprintk("lockd: TEST status %d vers %d\n",
126 ntohl(resp->status), rqstp->rq_vers); 131 ntohl(resp->status), rqstp->rq_vers);
127 132
133 nlmsvc_release_lockowner(&argp->lock);
128 nlmsvc_release_host(host); 134 nlmsvc_release_host(host);
129 nlm_release_file(file); 135 nlm_release_file(file);
130 return rc; 136 return rc;
@@ -173,6 +179,7 @@ __nlmsvc_proc_lock(struct svc_rqst *rqstp, struct nlm_res *resp)
173 else 179 else
174 dprintk("lockd: LOCK status %d\n", ntohl(resp->status)); 180 dprintk("lockd: LOCK status %d\n", ntohl(resp->status));
175 181
182 nlmsvc_release_lockowner(&argp->lock);
176 nlmsvc_release_host(host); 183 nlmsvc_release_host(host);
177 nlm_release_file(file); 184 nlm_release_file(file);
178 return rc; 185 return rc;
@@ -210,6 +217,7 @@ __nlmsvc_proc_cancel(struct svc_rqst *rqstp, struct nlm_res *resp)
210 resp->status = cast_status(nlmsvc_cancel_blocked(net, file, &argp->lock)); 217 resp->status = cast_status(nlmsvc_cancel_blocked(net, file, &argp->lock));
211 218
212 dprintk("lockd: CANCEL status %d\n", ntohl(resp->status)); 219 dprintk("lockd: CANCEL status %d\n", ntohl(resp->status));
220 nlmsvc_release_lockowner(&argp->lock);
213 nlmsvc_release_host(host); 221 nlmsvc_release_host(host);
214 nlm_release_file(file); 222 nlm_release_file(file);
215 return rpc_success; 223 return rpc_success;
@@ -250,6 +258,7 @@ __nlmsvc_proc_unlock(struct svc_rqst *rqstp, struct nlm_res *resp)
250 resp->status = cast_status(nlmsvc_unlock(net, file, &argp->lock)); 258 resp->status = cast_status(nlmsvc_unlock(net, file, &argp->lock));
251 259
252 dprintk("lockd: UNLOCK status %d\n", ntohl(resp->status)); 260 dprintk("lockd: UNLOCK status %d\n", ntohl(resp->status));
261 nlmsvc_release_lockowner(&argp->lock);
253 nlmsvc_release_host(host); 262 nlmsvc_release_host(host);
254 nlm_release_file(file); 263 nlm_release_file(file);
255 return rpc_success; 264 return rpc_success;
@@ -408,6 +417,7 @@ nlmsvc_proc_share(struct svc_rqst *rqstp)
408 resp->status = cast_status(nlmsvc_share_file(host, file, argp)); 417 resp->status = cast_status(nlmsvc_share_file(host, file, argp));
409 418
410 dprintk("lockd: SHARE status %d\n", ntohl(resp->status)); 419 dprintk("lockd: SHARE status %d\n", ntohl(resp->status));
420 nlmsvc_release_lockowner(&argp->lock);
411 nlmsvc_release_host(host); 421 nlmsvc_release_host(host);
412 nlm_release_file(file); 422 nlm_release_file(file);
413 return rpc_success; 423 return rpc_success;
@@ -442,6 +452,7 @@ nlmsvc_proc_unshare(struct svc_rqst *rqstp)
442 resp->status = cast_status(nlmsvc_unshare_file(host, file, argp)); 452 resp->status = cast_status(nlmsvc_unshare_file(host, file, argp));
443 453
444 dprintk("lockd: UNSHARE status %d\n", ntohl(resp->status)); 454 dprintk("lockd: UNSHARE status %d\n", ntohl(resp->status));
455 nlmsvc_release_lockowner(&argp->lock);
445 nlmsvc_release_host(host); 456 nlmsvc_release_host(host);
446 nlm_release_file(file); 457 nlm_release_file(file);
447 return rpc_success; 458 return rpc_success;
diff --git a/fs/lockd/svcsubs.c b/fs/lockd/svcsubs.c
index 0e610f422406..028fc152da22 100644
--- a/fs/lockd/svcsubs.c
+++ b/fs/lockd/svcsubs.c
@@ -180,7 +180,7 @@ again:
180 /* update current lock count */ 180 /* update current lock count */
181 file->f_locks++; 181 file->f_locks++;
182 182
183 lockhost = (struct nlm_host *) fl->fl_owner; 183 lockhost = ((struct nlm_lockowner *)fl->fl_owner)->host;
184 if (match(lockhost, host)) { 184 if (match(lockhost, host)) {
185 struct file_lock lock = *fl; 185 struct file_lock lock = *fl;
186 186
diff --git a/fs/lockd/xdr.c b/fs/lockd/xdr.c
index 7147e4aebecc..ec717ae41ee3 100644
--- a/fs/lockd/xdr.c
+++ b/fs/lockd/xdr.c
@@ -126,7 +126,6 @@ nlm_decode_lock(__be32 *p, struct nlm_lock *lock)
126 lock->svid = ntohl(*p++); 126 lock->svid = ntohl(*p++);
127 127
128 locks_init_lock(fl); 128 locks_init_lock(fl);
129 fl->fl_owner = current->files;
130 fl->fl_pid = (pid_t)lock->svid; 129 fl->fl_pid = (pid_t)lock->svid;
131 fl->fl_flags = FL_POSIX; 130 fl->fl_flags = FL_POSIX;
132 fl->fl_type = F_RDLCK; /* as good as anything else */ 131 fl->fl_type = F_RDLCK; /* as good as anything else */
diff --git a/fs/lockd/xdr4.c b/fs/lockd/xdr4.c
index 7ed9edf9aed4..45741adfe041 100644
--- a/fs/lockd/xdr4.c
+++ b/fs/lockd/xdr4.c
@@ -118,7 +118,6 @@ nlm4_decode_lock(__be32 *p, struct nlm_lock *lock)
118 lock->svid = ntohl(*p++); 118 lock->svid = ntohl(*p++);
119 119
120 locks_init_lock(fl); 120 locks_init_lock(fl);
121 fl->fl_owner = current->files;
122 fl->fl_pid = (pid_t)lock->svid; 121 fl->fl_pid = (pid_t)lock->svid;
123 fl->fl_flags = FL_POSIX; 122 fl->fl_flags = FL_POSIX;
124 fl->fl_type = F_RDLCK; /* as good as anything else */ 123 fl->fl_type = F_RDLCK; /* as good as anything else */