fs: track fl_owner for leases
authorChristoph Hellwig <hch@lst.de>
Wed, 21 Jan 2015 18:14:02 +0000 (19:14 +0100)
committerChristoph Hellwig <hch@lst.de>
Mon, 2 Feb 2015 17:09:38 +0000 (18:09 +0100)
Just like for other lock types we should allow different owners to have
a read lease on a file.  Currently this can't happen, but with the addition
of pNFS layout leases we'll need this feature.

Signed-off-by: Christoph Hellwig <hch@lst.de>
fs/locks.c
fs/nfsd/nfs4state.c

index 4d0d41163a50fedbe7c9b7d81911c5d5f2fbec6f..22ac7694cc84022b060e36588030bbcd4edf21a5 100644 (file)
@@ -1661,7 +1661,8 @@ generic_add_lease(struct file *filp, long arg, struct file_lock **flp, void **pr
         */
        error = -EAGAIN;
        list_for_each_entry(fl, &ctx->flc_lease, fl_list) {
-               if (fl->fl_file == filp) {
+               if (fl->fl_file == filp &&
+                   fl->fl_owner == lease->fl_owner) {
                        my_fl = fl;
                        continue;
                }
@@ -1721,7 +1722,7 @@ out:
        return error;
 }
 
-static int generic_delete_lease(struct file *filp)
+static int generic_delete_lease(struct file *filp, void *owner)
 {
        int error = -EAGAIN;
        struct file_lock *fl, *victim = NULL;
@@ -1737,7 +1738,8 @@ static int generic_delete_lease(struct file *filp)
 
        spin_lock(&ctx->flc_lock);
        list_for_each_entry(fl, &ctx->flc_lease, fl_list) {
-               if (fl->fl_file == filp) {
+               if (fl->fl_file == filp &&
+                   fl->fl_owner == owner) {
                        victim = fl;
                        break;
                }
@@ -1778,7 +1780,7 @@ int generic_setlease(struct file *filp, long arg, struct file_lock **flp,
 
        switch (arg) {
        case F_UNLCK:
-               return generic_delete_lease(filp);
+               return generic_delete_lease(filp, *priv);
        case F_RDLCK:
        case F_WRLCK:
                if (!(*flp)->fl_lmops->lm_break) {
@@ -1857,7 +1859,7 @@ static int do_fcntl_add_lease(unsigned int fd, struct file *filp, long arg)
 int fcntl_setlease(unsigned int fd, struct file *filp, long arg)
 {
        if (arg == F_UNLCK)
-               return vfs_setlease(filp, F_UNLCK, NULL, NULL);
+               return vfs_setlease(filp, F_UNLCK, NULL, (void **)&filp);
        return do_fcntl_add_lease(fd, filp, arg);
 }
 
index 370a53a5da1335d598b6825e5fb60e203ae817a6..e6b354a0d89ec373e41983886d4a58c84139a21f 100644 (file)
@@ -683,7 +683,7 @@ static void nfs4_put_deleg_lease(struct nfs4_file *fp)
        spin_unlock(&fp->fi_lock);
 
        if (filp) {
-               vfs_setlease(filp, F_UNLCK, NULL, NULL);
+               vfs_setlease(filp, F_UNLCK, NULL, (void **)&fp);
                fput(filp);
        }
 }