summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
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 */