diff options
-rw-r--r-- | fs/dlm/plock.c | 2 | ||||
-rw-r--r-- | fs/lockd/svclock.c | 13 | ||||
-rw-r--r-- | fs/locks.c | 28 | ||||
-rw-r--r-- | include/linux/fs.h | 6 |
4 files changed, 25 insertions, 24 deletions
diff --git a/fs/dlm/plock.c b/fs/dlm/plock.c index 78878c5781ca..eba87ff3177b 100644 --- a/fs/dlm/plock.c +++ b/fs/dlm/plock.c | |||
@@ -116,7 +116,7 @@ int dlm_posix_lock(dlm_lockspace_t *lockspace, u64 number, struct file *file, | |||
116 | if (xop->callback == NULL) | 116 | if (xop->callback == NULL) |
117 | wait_event(recv_wq, (op->done != 0)); | 117 | wait_event(recv_wq, (op->done != 0)); |
118 | else { | 118 | else { |
119 | rv = -EINPROGRESS; | 119 | rv = FILE_LOCK_DEFERRED; |
120 | goto out; | 120 | goto out; |
121 | } | 121 | } |
122 | 122 | ||
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c index 821b9acdfb66..cf0d5c2c318d 100644 --- a/fs/lockd/svclock.c +++ b/fs/lockd/svclock.c | |||
@@ -418,8 +418,8 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file, | |||
418 | goto out; | 418 | goto out; |
419 | case -EAGAIN: | 419 | case -EAGAIN: |
420 | ret = nlm_lck_denied; | 420 | ret = nlm_lck_denied; |
421 | break; | 421 | goto out; |
422 | case -EINPROGRESS: | 422 | case FILE_LOCK_DEFERRED: |
423 | if (wait) | 423 | if (wait) |
424 | break; | 424 | break; |
425 | /* Filesystem lock operation is in progress | 425 | /* Filesystem lock operation is in progress |
@@ -434,10 +434,6 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file, | |||
434 | goto out; | 434 | goto out; |
435 | } | 435 | } |
436 | 436 | ||
437 | ret = nlm_lck_denied; | ||
438 | if (!wait) | ||
439 | goto out; | ||
440 | |||
441 | ret = nlm_lck_blocked; | 437 | ret = nlm_lck_blocked; |
442 | 438 | ||
443 | /* Append to list of blocked */ | 439 | /* Append to list of blocked */ |
@@ -507,7 +503,7 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file, | |||
507 | } | 503 | } |
508 | 504 | ||
509 | error = vfs_test_lock(file->f_file, &lock->fl); | 505 | error = vfs_test_lock(file->f_file, &lock->fl); |
510 | if (error == -EINPROGRESS) { | 506 | if (error == FILE_LOCK_DEFERRED) { |
511 | ret = nlmsvc_defer_lock_rqst(rqstp, block); | 507 | ret = nlmsvc_defer_lock_rqst(rqstp, block); |
512 | goto out; | 508 | goto out; |
513 | } | 509 | } |
@@ -731,8 +727,7 @@ nlmsvc_grant_blocked(struct nlm_block *block) | |||
731 | switch (error) { | 727 | switch (error) { |
732 | case 0: | 728 | case 0: |
733 | break; | 729 | break; |
734 | case -EAGAIN: | 730 | case FILE_LOCK_DEFERRED: |
735 | case -EINPROGRESS: | ||
736 | dprintk("lockd: lock still blocked error %d\n", error); | 731 | dprintk("lockd: lock still blocked error %d\n", error); |
737 | nlmsvc_insert_block(block, NLM_NEVER); | 732 | nlmsvc_insert_block(block, NLM_NEVER); |
738 | nlmsvc_release_block(block); | 733 | nlmsvc_release_block(block); |
diff --git a/fs/locks.c b/fs/locks.c index dce8c747371c..1ce57b4b362c 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
@@ -779,8 +779,10 @@ find_conflict: | |||
779 | if (!flock_locks_conflict(request, fl)) | 779 | if (!flock_locks_conflict(request, fl)) |
780 | continue; | 780 | continue; |
781 | error = -EAGAIN; | 781 | error = -EAGAIN; |
782 | if (request->fl_flags & FL_SLEEP) | 782 | if (!(request->fl_flags & FL_SLEEP)) |
783 | locks_insert_block(fl, request); | 783 | goto out; |
784 | error = FILE_LOCK_DEFERRED; | ||
785 | locks_insert_block(fl, request); | ||
784 | goto out; | 786 | goto out; |
785 | } | 787 | } |
786 | if (request->fl_flags & FL_ACCESS) | 788 | if (request->fl_flags & FL_ACCESS) |
@@ -836,7 +838,7 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str | |||
836 | error = -EDEADLK; | 838 | error = -EDEADLK; |
837 | if (posix_locks_deadlock(request, fl)) | 839 | if (posix_locks_deadlock(request, fl)) |
838 | goto out; | 840 | goto out; |
839 | error = -EAGAIN; | 841 | error = FILE_LOCK_DEFERRED; |
840 | locks_insert_block(fl, request); | 842 | locks_insert_block(fl, request); |
841 | goto out; | 843 | goto out; |
842 | } | 844 | } |
@@ -1035,7 +1037,7 @@ int posix_lock_file_wait(struct file *filp, struct file_lock *fl) | |||
1035 | might_sleep (); | 1037 | might_sleep (); |
1036 | for (;;) { | 1038 | for (;;) { |
1037 | error = posix_lock_file(filp, fl, NULL); | 1039 | error = posix_lock_file(filp, fl, NULL); |
1038 | if ((error != -EAGAIN) || !(fl->fl_flags & FL_SLEEP)) | 1040 | if (error != FILE_LOCK_DEFERRED) |
1039 | break; | 1041 | break; |
1040 | error = wait_event_interruptible(fl->fl_wait, !fl->fl_next); | 1042 | error = wait_event_interruptible(fl->fl_wait, !fl->fl_next); |
1041 | if (!error) | 1043 | if (!error) |
@@ -1107,9 +1109,7 @@ int locks_mandatory_area(int read_write, struct inode *inode, | |||
1107 | 1109 | ||
1108 | for (;;) { | 1110 | for (;;) { |
1109 | error = __posix_lock_file(inode, &fl, NULL); | 1111 | error = __posix_lock_file(inode, &fl, NULL); |
1110 | if (error != -EAGAIN) | 1112 | if (error != FILE_LOCK_DEFERRED) |
1111 | break; | ||
1112 | if (!(fl.fl_flags & FL_SLEEP)) | ||
1113 | break; | 1113 | break; |
1114 | error = wait_event_interruptible(fl.fl_wait, !fl.fl_next); | 1114 | error = wait_event_interruptible(fl.fl_wait, !fl.fl_next); |
1115 | if (!error) { | 1115 | if (!error) { |
@@ -1531,7 +1531,7 @@ int flock_lock_file_wait(struct file *filp, struct file_lock *fl) | |||
1531 | might_sleep(); | 1531 | might_sleep(); |
1532 | for (;;) { | 1532 | for (;;) { |
1533 | error = flock_lock_file(filp, fl); | 1533 | error = flock_lock_file(filp, fl); |
1534 | if ((error != -EAGAIN) || !(fl->fl_flags & FL_SLEEP)) | 1534 | if (error != FILE_LOCK_DEFERRED) |
1535 | break; | 1535 | break; |
1536 | error = wait_event_interruptible(fl->fl_wait, !fl->fl_next); | 1536 | error = wait_event_interruptible(fl->fl_wait, !fl->fl_next); |
1537 | if (!error) | 1537 | if (!error) |
@@ -1716,17 +1716,17 @@ out: | |||
1716 | * fl_grant is set. Callers expecting ->lock() to return asynchronously | 1716 | * fl_grant is set. Callers expecting ->lock() to return asynchronously |
1717 | * will only use F_SETLK, not F_SETLKW; they will set FL_SLEEP if (and only if) | 1717 | * will only use F_SETLK, not F_SETLKW; they will set FL_SLEEP if (and only if) |
1718 | * the request is for a blocking lock. When ->lock() does return asynchronously, | 1718 | * the request is for a blocking lock. When ->lock() does return asynchronously, |
1719 | * it must return -EINPROGRESS, and call ->fl_grant() when the lock | 1719 | * it must return FILE_LOCK_DEFERRED, and call ->fl_grant() when the lock |
1720 | * request completes. | 1720 | * request completes. |
1721 | * If the request is for non-blocking lock the file system should return | 1721 | * If the request is for non-blocking lock the file system should return |
1722 | * -EINPROGRESS then try to get the lock and call the callback routine with | 1722 | * FILE_LOCK_DEFERRED then try to get the lock and call the callback routine |
1723 | * the result. If the request timed out the callback routine will return a | 1723 | * with the result. If the request timed out the callback routine will return a |
1724 | * nonzero return code and the file system should release the lock. The file | 1724 | * nonzero return code and the file system should release the lock. The file |
1725 | * system is also responsible to keep a corresponding posix lock when it | 1725 | * system is also responsible to keep a corresponding posix lock when it |
1726 | * grants a lock so the VFS can find out which locks are locally held and do | 1726 | * grants a lock so the VFS can find out which locks are locally held and do |
1727 | * the correct lock cleanup when required. | 1727 | * the correct lock cleanup when required. |
1728 | * The underlying filesystem must not drop the kernel lock or call | 1728 | * The underlying filesystem must not drop the kernel lock or call |
1729 | * ->fl_grant() before returning to the caller with a -EINPROGRESS | 1729 | * ->fl_grant() before returning to the caller with a FILE_LOCK_DEFERRED |
1730 | * return code. | 1730 | * return code. |
1731 | */ | 1731 | */ |
1732 | int vfs_lock_file(struct file *filp, unsigned int cmd, struct file_lock *fl, struct file_lock *conf) | 1732 | int vfs_lock_file(struct file *filp, unsigned int cmd, struct file_lock *fl, struct file_lock *conf) |
@@ -1804,7 +1804,7 @@ again: | |||
1804 | else { | 1804 | else { |
1805 | for (;;) { | 1805 | for (;;) { |
1806 | error = posix_lock_file(filp, file_lock, NULL); | 1806 | error = posix_lock_file(filp, file_lock, NULL); |
1807 | if (error != -EAGAIN || cmd == F_SETLK) | 1807 | if (error != FILE_LOCK_DEFERRED) |
1808 | break; | 1808 | break; |
1809 | error = wait_event_interruptible(file_lock->fl_wait, | 1809 | error = wait_event_interruptible(file_lock->fl_wait, |
1810 | !file_lock->fl_next); | 1810 | !file_lock->fl_next); |
@@ -1941,7 +1941,7 @@ again: | |||
1941 | else { | 1941 | else { |
1942 | for (;;) { | 1942 | for (;;) { |
1943 | error = posix_lock_file(filp, file_lock, NULL); | 1943 | error = posix_lock_file(filp, file_lock, NULL); |
1944 | if (error != -EAGAIN || cmd == F_SETLK64) | 1944 | if (error != FILE_LOCK_DEFERRED) |
1945 | break; | 1945 | break; |
1946 | error = wait_event_interruptible(file_lock->fl_wait, | 1946 | error = wait_event_interruptible(file_lock->fl_wait, |
1947 | !file_lock->fl_next); | 1947 | !file_lock->fl_next); |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 4b86f806014c..49d8eb7a71be 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -886,6 +886,12 @@ static inline int file_check_writeable(struct file *filp) | |||
886 | #define FL_SLEEP 128 /* A blocking lock */ | 886 | #define FL_SLEEP 128 /* A blocking lock */ |
887 | 887 | ||
888 | /* | 888 | /* |
889 | * Special return value from posix_lock_file() and vfs_lock_file() for | ||
890 | * asynchronous locking. | ||
891 | */ | ||
892 | #define FILE_LOCK_DEFERRED 1 | ||
893 | |||
894 | /* | ||
889 | * The POSIX file lock owner is determined by | 895 | * The POSIX file lock owner is determined by |
890 | * the "struct files_struct" in the thread group | 896 | * the "struct files_struct" in the thread group |
891 | * (or NULL for no owner - BSD locks). | 897 | * (or NULL for no owner - BSD locks). |