Commit f475ae95 authored by Trond Myklebust's avatar Trond Myklebust

VFS: Allow caller to determine if BSD or posix locks were actually freed

Change posix_lock_file_conf(), and flock_lock_file() so that if called
with an F_UNLCK argument, and the FL_EXISTS flag they will indicate
whether or not any locks were actually freed by returning 0 or -ENOENT.
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 5e66dd6d
...@@ -725,6 +725,10 @@ static int posix_locks_deadlock(struct file_lock *caller_fl, ...@@ -725,6 +725,10 @@ static int posix_locks_deadlock(struct file_lock *caller_fl,
/* Try to create a FLOCK lock on filp. We always insert new FLOCK locks /* Try to create a FLOCK lock on filp. We always insert new FLOCK locks
* at the head of the list, but that's secret knowledge known only to * at the head of the list, but that's secret knowledge known only to
* flock_lock_file and posix_lock_file. * flock_lock_file and posix_lock_file.
*
* Note that if called with an FL_EXISTS argument, the caller may determine
* whether or not a lock was successfully freed by testing the return
* value for -ENOENT.
*/ */
static int flock_lock_file(struct file *filp, struct file_lock *request) static int flock_lock_file(struct file *filp, struct file_lock *request)
{ {
...@@ -750,8 +754,11 @@ static int flock_lock_file(struct file *filp, struct file_lock *request) ...@@ -750,8 +754,11 @@ static int flock_lock_file(struct file *filp, struct file_lock *request)
break; break;
} }
if (request->fl_type == F_UNLCK) if (request->fl_type == F_UNLCK) {
if ((request->fl_flags & FL_EXISTS) && !found)
error = -ENOENT;
goto out; goto out;
}
error = -ENOMEM; error = -ENOMEM;
new_fl = locks_alloc_lock(); new_fl = locks_alloc_lock();
...@@ -948,8 +955,11 @@ static int __posix_lock_file_conf(struct inode *inode, struct file_lock *request ...@@ -948,8 +955,11 @@ static int __posix_lock_file_conf(struct inode *inode, struct file_lock *request
error = 0; error = 0;
if (!added) { if (!added) {
if (request->fl_type == F_UNLCK) if (request->fl_type == F_UNLCK) {
if (request->fl_flags & FL_EXISTS)
error = -ENOENT;
goto out; goto out;
}
if (!new_fl) { if (!new_fl) {
error = -ENOLCK; error = -ENOLCK;
...@@ -996,6 +1006,10 @@ static int __posix_lock_file_conf(struct inode *inode, struct file_lock *request ...@@ -996,6 +1006,10 @@ static int __posix_lock_file_conf(struct inode *inode, struct file_lock *request
* Add a POSIX style lock to a file. * Add a POSIX style lock to a file.
* We merge adjacent & overlapping locks whenever possible. * We merge adjacent & overlapping locks whenever possible.
* POSIX locks are sorted by owner task, then by starting address * POSIX locks are sorted by owner task, then by starting address
*
* Note that if called with an FL_EXISTS argument, the caller may determine
* whether or not a lock was successfully freed by testing the return
* value for -ENOENT.
*/ */
int posix_lock_file(struct file *filp, struct file_lock *fl) int posix_lock_file(struct file *filp, struct file_lock *fl)
{ {
......
...@@ -716,6 +716,7 @@ extern spinlock_t files_lock; ...@@ -716,6 +716,7 @@ extern spinlock_t files_lock;
#define FL_POSIX 1 #define FL_POSIX 1
#define FL_FLOCK 2 #define FL_FLOCK 2
#define FL_ACCESS 8 /* not trying to lock, just looking */ #define FL_ACCESS 8 /* not trying to lock, just looking */
#define FL_EXISTS 16 /* when unlocking, test for existence */
#define FL_LEASE 32 /* lease held on this file */ #define FL_LEASE 32 /* lease held on this file */
#define FL_CLOSE 64 /* unlock on close */ #define FL_CLOSE 64 /* unlock on close */
#define FL_SLEEP 128 /* A blocking lock */ #define FL_SLEEP 128 /* A blocking lock */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment