Skip to content

Commit 1a8322b

Browse files
Marc EshelJ. Bruce Fields
Marc Eshel
authored and
J. Bruce Fields
committed
lockd: add code to handle deferred lock requests
Rewrite nlmsvc_lock() to use the asynchronous interface. As with testlock, we answer nlm requests in nlmsvc_lock by first looking up the block and then using the results we find in the block if B_QUEUED is set, and calling vfs_lock_file() otherwise. If this a new lock request and we get -EINPROGRESS return on a non-blocking request then we defer the request. Also modify nlmsvc_unlock() to call the filesystem method if appropriate. Signed-off-by: Marc Eshel <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
1 parent f812048 commit 1a8322b

File tree

4 files changed

+40
-7
lines changed

4 files changed

+40
-7
lines changed

fs/lockd/svc4proc.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,8 @@ nlm4svc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp,
145145
/* Now try to lock the file */
146146
resp->status = nlmsvc_lock(rqstp, file, &argp->lock,
147147
argp->block, &argp->cookie);
148+
if (resp->status == nlm_drop_reply)
149+
return rpc_drop_reply;
148150

149151
dprintk("lockd: LOCK status %d\n", ntohl(resp->status));
150152
nlm_release_host(host);

fs/lockd/svclock.c

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -393,17 +393,43 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
393393
} else
394394
lock->fl.fl_flags &= ~FL_SLEEP;
395395

396-
error = posix_lock_file(file->f_file, &lock->fl, NULL);
397-
lock->fl.fl_flags &= ~FL_SLEEP;
396+
if (block->b_flags & B_QUEUED) {
397+
dprintk("lockd: nlmsvc_lock deferred block %p flags %d\n",
398+
block, block->b_flags);
399+
if (block->b_granted) {
400+
nlmsvc_unlink_block(block);
401+
ret = nlm_granted;
402+
goto out;
403+
}
404+
if (block->b_flags & B_TIMED_OUT) {
405+
nlmsvc_unlink_block(block);
406+
ret = nlm_lck_denied;
407+
goto out;
408+
}
409+
ret = nlm_drop_reply;
410+
goto out;
411+
}
398412

399-
dprintk("lockd: posix_lock_file returned %d\n", error);
413+
if (!wait)
414+
lock->fl.fl_flags &= ~FL_SLEEP;
415+
error = vfs_lock_file(file->f_file, F_SETLK, &lock->fl, NULL);
416+
lock->fl.fl_flags &= ~FL_SLEEP;
400417

418+
dprintk("lockd: vfs_lock_file returned %d\n", error);
401419
switch(error) {
402420
case 0:
403421
ret = nlm_granted;
404422
goto out;
405423
case -EAGAIN:
424+
ret = nlm_lck_denied;
406425
break;
426+
case -EINPROGRESS:
427+
if (wait)
428+
break;
429+
/* Filesystem lock operation is in progress
430+
Add it to the queue waiting for callback */
431+
ret = nlmsvc_defer_lock_rqst(rqstp, block);
432+
goto out;
407433
case -EDEADLK:
408434
ret = nlm_deadlock;
409435
goto out;
@@ -535,7 +561,7 @@ nlmsvc_unlock(struct nlm_file *file, struct nlm_lock *lock)
535561
nlmsvc_cancel_blocked(file, lock);
536562

537563
lock->fl.fl_type = F_UNLCK;
538-
error = posix_lock_file(file->f_file, &lock->fl, NULL);
564+
error = vfs_lock_file(file->f_file, F_SETLK, &lock->fl, NULL);
539565

540566
return (error < 0)? nlm_lck_denied_nolocks : nlm_granted;
541567
}
@@ -564,6 +590,8 @@ nlmsvc_cancel_blocked(struct nlm_file *file, struct nlm_lock *lock)
564590
block = nlmsvc_lookup_block(file, lock);
565591
mutex_unlock(&file->f_mutex);
566592
if (block != NULL) {
593+
vfs_cancel_lock(block->b_file->f_file,
594+
&block->b_call->a_args.lock.fl);
567595
status = nlmsvc_unlink_block(block);
568596
nlmsvc_release_block(block);
569597
}
@@ -697,14 +725,15 @@ nlmsvc_grant_blocked(struct nlm_block *block)
697725

698726
/* Try the lock operation again */
699727
lock->fl.fl_flags |= FL_SLEEP;
700-
error = posix_lock_file(file->f_file, &lock->fl, NULL);
728+
error = vfs_lock_file(file->f_file, F_SETLK, &lock->fl, NULL);
701729
lock->fl.fl_flags &= ~FL_SLEEP;
702730

703731
switch (error) {
704732
case 0:
705733
break;
706734
case -EAGAIN:
707-
dprintk("lockd: lock still blocked\n");
735+
case -EINPROGRESS:
736+
dprintk("lockd: lock still blocked error %d\n", error);
708737
nlmsvc_insert_block(block, NLM_NEVER);
709738
nlmsvc_release_block(block);
710739
return;

fs/lockd/svcproc.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,8 @@ nlmsvc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp,
175175
/* Now try to lock the file */
176176
resp->status = cast_status(nlmsvc_lock(rqstp, file, &argp->lock,
177177
argp->block, &argp->cookie));
178+
if (resp->status == nlm_drop_reply)
179+
return rpc_drop_reply;
178180

179181
dprintk("lockd: LOCK status %d\n", ntohl(resp->status));
180182
nlm_release_host(host);

fs/lockd/svcsubs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ nlm_traverse_locks(struct nlm_host *host, struct nlm_file *file,
182182
lock.fl_type = F_UNLCK;
183183
lock.fl_start = 0;
184184
lock.fl_end = OFFSET_MAX;
185-
if (posix_lock_file(file->f_file, &lock, NULL) < 0) {
185+
if (vfs_lock_file(file->f_file, F_SETLK, &lock, NULL) < 0) {
186186
printk("lockd: unlock failure in %s:%d\n",
187187
__FILE__, __LINE__);
188188
return 1;

0 commit comments

Comments
 (0)