diff options
author | Christoph Hellwig <hch@lst.de> | 2015-01-21 13:14:02 -0500 |
---|---|---|
committer | Christoph Hellwig <hch@lst.de> | 2015-02-02 12:09:38 -0500 |
commit | 2ab99ee12440e66ec1efd2a98599010471de785e (patch) | |
tree | e9d8946babd68a56c0c35bdf77d852ee74e346dc /fs | |
parent | 6cae0a4648c0db2a74efb816cd2ce84390c90480 (diff) |
fs: track fl_owner for leases
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>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/locks.c | 12 | ||||
-rw-r--r-- | fs/nfsd/nfs4state.c | 2 |
2 files changed, 8 insertions, 6 deletions
diff --git a/fs/locks.c b/fs/locks.c index 4d0d41163a50..22ac7694cc84 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
@@ -1661,7 +1661,8 @@ generic_add_lease(struct file *filp, long arg, struct file_lock **flp, void **pr | |||
1661 | */ | 1661 | */ |
1662 | error = -EAGAIN; | 1662 | error = -EAGAIN; |
1663 | list_for_each_entry(fl, &ctx->flc_lease, fl_list) { | 1663 | list_for_each_entry(fl, &ctx->flc_lease, fl_list) { |
1664 | if (fl->fl_file == filp) { | 1664 | if (fl->fl_file == filp && |
1665 | fl->fl_owner == lease->fl_owner) { | ||
1665 | my_fl = fl; | 1666 | my_fl = fl; |
1666 | continue; | 1667 | continue; |
1667 | } | 1668 | } |
@@ -1721,7 +1722,7 @@ out: | |||
1721 | return error; | 1722 | return error; |
1722 | } | 1723 | } |
1723 | 1724 | ||
1724 | static int generic_delete_lease(struct file *filp) | 1725 | static int generic_delete_lease(struct file *filp, void *owner) |
1725 | { | 1726 | { |
1726 | int error = -EAGAIN; | 1727 | int error = -EAGAIN; |
1727 | struct file_lock *fl, *victim = NULL; | 1728 | struct file_lock *fl, *victim = NULL; |
@@ -1737,7 +1738,8 @@ static int generic_delete_lease(struct file *filp) | |||
1737 | 1738 | ||
1738 | spin_lock(&ctx->flc_lock); | 1739 | spin_lock(&ctx->flc_lock); |
1739 | list_for_each_entry(fl, &ctx->flc_lease, fl_list) { | 1740 | list_for_each_entry(fl, &ctx->flc_lease, fl_list) { |
1740 | if (fl->fl_file == filp) { | 1741 | if (fl->fl_file == filp && |
1742 | fl->fl_owner == owner) { | ||
1741 | victim = fl; | 1743 | victim = fl; |
1742 | break; | 1744 | break; |
1743 | } | 1745 | } |
@@ -1778,7 +1780,7 @@ int generic_setlease(struct file *filp, long arg, struct file_lock **flp, | |||
1778 | 1780 | ||
1779 | switch (arg) { | 1781 | switch (arg) { |
1780 | case F_UNLCK: | 1782 | case F_UNLCK: |
1781 | return generic_delete_lease(filp); | 1783 | return generic_delete_lease(filp, *priv); |
1782 | case F_RDLCK: | 1784 | case F_RDLCK: |
1783 | case F_WRLCK: | 1785 | case F_WRLCK: |
1784 | if (!(*flp)->fl_lmops->lm_break) { | 1786 | if (!(*flp)->fl_lmops->lm_break) { |
@@ -1857,7 +1859,7 @@ static int do_fcntl_add_lease(unsigned int fd, struct file *filp, long arg) | |||
1857 | int fcntl_setlease(unsigned int fd, struct file *filp, long arg) | 1859 | int fcntl_setlease(unsigned int fd, struct file *filp, long arg) |
1858 | { | 1860 | { |
1859 | if (arg == F_UNLCK) | 1861 | if (arg == F_UNLCK) |
1860 | return vfs_setlease(filp, F_UNLCK, NULL, NULL); | 1862 | return vfs_setlease(filp, F_UNLCK, NULL, (void **)&filp); |
1861 | return do_fcntl_add_lease(fd, filp, arg); | 1863 | return do_fcntl_add_lease(fd, filp, arg); |
1862 | } | 1864 | } |
1863 | 1865 | ||
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 370a53a5da13..e6b354a0d89e 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -683,7 +683,7 @@ static void nfs4_put_deleg_lease(struct nfs4_file *fp) | |||
683 | spin_unlock(&fp->fi_lock); | 683 | spin_unlock(&fp->fi_lock); |
684 | 684 | ||
685 | if (filp) { | 685 | if (filp) { |
686 | vfs_setlease(filp, F_UNLCK, NULL, NULL); | 686 | vfs_setlease(filp, F_UNLCK, NULL, (void **)&fp); |
687 | fput(filp); | 687 | fput(filp); |
688 | } | 688 | } |
689 | } | 689 | } |