aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/locks.c18
-rw-r--r--include/linux/fs.h1
2 files changed, 17 insertions, 2 deletions
diff --git a/fs/locks.c b/fs/locks.c
index 1ad29c9b6252..50cb0a2b74d9 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -725,6 +725,10 @@ next_task:
725/* Try to create a FLOCK lock on filp. We always insert new FLOCK locks 725/* Try to create a FLOCK lock on filp. We always insert new FLOCK locks
726 * at the head of the list, but that's secret knowledge known only to 726 * at the head of the list, but that's secret knowledge known only to
727 * flock_lock_file and posix_lock_file. 727 * flock_lock_file and posix_lock_file.
728 *
729 * Note that if called with an FL_EXISTS argument, the caller may determine
730 * whether or not a lock was successfully freed by testing the return
731 * value for -ENOENT.
728 */ 732 */
729static int flock_lock_file(struct file *filp, struct file_lock *request) 733static int flock_lock_file(struct file *filp, struct file_lock *request)
730{ 734{
@@ -750,8 +754,11 @@ static int flock_lock_file(struct file *filp, struct file_lock *request)
750 break; 754 break;
751 } 755 }
752 756
753 if (request->fl_type == F_UNLCK) 757 if (request->fl_type == F_UNLCK) {
758 if ((request->fl_flags & FL_EXISTS) && !found)
759 error = -ENOENT;
754 goto out; 760 goto out;
761 }
755 762
756 error = -ENOMEM; 763 error = -ENOMEM;
757 new_fl = locks_alloc_lock(); 764 new_fl = locks_alloc_lock();
@@ -948,8 +955,11 @@ static int __posix_lock_file_conf(struct inode *inode, struct file_lock *request
948 955
949 error = 0; 956 error = 0;
950 if (!added) { 957 if (!added) {
951 if (request->fl_type == F_UNLCK) 958 if (request->fl_type == F_UNLCK) {
959 if (request->fl_flags & FL_EXISTS)
960 error = -ENOENT;
952 goto out; 961 goto out;
962 }
953 963
954 if (!new_fl) { 964 if (!new_fl) {
955 error = -ENOLCK; 965 error = -ENOLCK;
@@ -996,6 +1006,10 @@ static int __posix_lock_file_conf(struct inode *inode, struct file_lock *request
996 * Add a POSIX style lock to a file. 1006 * Add a POSIX style lock to a file.
997 * We merge adjacent & overlapping locks whenever possible. 1007 * We merge adjacent & overlapping locks whenever possible.
998 * POSIX locks are sorted by owner task, then by starting address 1008 * POSIX locks are sorted by owner task, then by starting address
1009 *
1010 * Note that if called with an FL_EXISTS argument, the caller may determine
1011 * whether or not a lock was successfully freed by testing the return
1012 * value for -ENOENT.
999 */ 1013 */
1000int posix_lock_file(struct file *filp, struct file_lock *fl) 1014int posix_lock_file(struct file *filp, struct file_lock *fl)
1001{ 1015{
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 134b32068246..43aef9b230fd 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -716,6 +716,7 @@ extern spinlock_t files_lock;
716#define FL_POSIX 1 716#define FL_POSIX 1
717#define FL_FLOCK 2 717#define FL_FLOCK 2
718#define FL_ACCESS 8 /* not trying to lock, just looking */ 718#define FL_ACCESS 8 /* not trying to lock, just looking */
719#define FL_EXISTS 16 /* when unlocking, test for existence */
719#define FL_LEASE 32 /* lease held on this file */ 720#define FL_LEASE 32 /* lease held on this file */
720#define FL_CLOSE 64 /* unlock on close */ 721#define FL_CLOSE 64 /* unlock on close */
721#define FL_SLEEP 128 /* A blocking lock */ 722#define FL_SLEEP 128 /* A blocking lock */