aboutsummaryrefslogtreecommitdiffstats
path: root/fs/locks.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2015-01-21 13:17:03 -0500
committerChristoph Hellwig <hch@lst.de>2015-02-02 12:09:38 -0500
commit11afe9f76e121e960445deee5b7f26f0787a1990 (patch)
tree512e3b9dd23b394b826a18eca3947df9487c28bc /fs/locks.c
parent2ab99ee12440e66ec1efd2a98599010471de785e (diff)
fs: add FL_LAYOUT lease type
This (ab-)uses the file locking code to allow filesystems to recall outstanding pNFS layouts on a file. This new lease type is similar but not quite the same as FL_DELEG. A FL_LAYOUT lease can always be granted, an a per-filesystem lock (XFS iolock for the initial implementation) ensures not FL_LAYOUT leases granted when we would need to recall them. Also included are changes that allow multiple outstanding read leases of different types on the same file as long as they have a differnt owner. This wasn't a problem until now as nfsd never set FL_LEASE leases, and no one else used FL_DELEG leases, but given that nfsd will also issues FL_LAYOUT leases we will have to handle it now. Signed-off-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'fs/locks.c')
-rw-r--r--fs/locks.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/fs/locks.c b/fs/locks.c
index 22ac7694cc84..4753218f308e 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -137,7 +137,7 @@
137 137
138#define IS_POSIX(fl) (fl->fl_flags & FL_POSIX) 138#define IS_POSIX(fl) (fl->fl_flags & FL_POSIX)
139#define IS_FLOCK(fl) (fl->fl_flags & FL_FLOCK) 139#define IS_FLOCK(fl) (fl->fl_flags & FL_FLOCK)
140#define IS_LEASE(fl) (fl->fl_flags & (FL_LEASE|FL_DELEG)) 140#define IS_LEASE(fl) (fl->fl_flags & (FL_LEASE|FL_DELEG|FL_LAYOUT))
141#define IS_OFDLCK(fl) (fl->fl_flags & FL_OFDLCK) 141#define IS_OFDLCK(fl) (fl->fl_flags & FL_OFDLCK)
142 142
143static bool lease_breaking(struct file_lock *fl) 143static bool lease_breaking(struct file_lock *fl)
@@ -1371,6 +1371,8 @@ static void time_out_leases(struct inode *inode, struct list_head *dispose)
1371 1371
1372static bool leases_conflict(struct file_lock *lease, struct file_lock *breaker) 1372static bool leases_conflict(struct file_lock *lease, struct file_lock *breaker)
1373{ 1373{
1374 if ((breaker->fl_flags & FL_LAYOUT) != (lease->fl_flags & FL_LAYOUT))
1375 return false;
1374 if ((breaker->fl_flags & FL_DELEG) && (lease->fl_flags & FL_LEASE)) 1376 if ((breaker->fl_flags & FL_DELEG) && (lease->fl_flags & FL_LEASE))
1375 return false; 1377 return false;
1376 return locks_conflict(breaker, lease); 1378 return locks_conflict(breaker, lease);
@@ -1594,11 +1596,14 @@ int fcntl_getlease(struct file *filp)
1594 * conflict with the lease we're trying to set. 1596 * conflict with the lease we're trying to set.
1595 */ 1597 */
1596static int 1598static int
1597check_conflicting_open(const struct dentry *dentry, const long arg) 1599check_conflicting_open(const struct dentry *dentry, const long arg, int flags)
1598{ 1600{
1599 int ret = 0; 1601 int ret = 0;
1600 struct inode *inode = dentry->d_inode; 1602 struct inode *inode = dentry->d_inode;
1601 1603
1604 if (flags & FL_LAYOUT)
1605 return 0;
1606
1602 if ((arg == F_RDLCK) && (atomic_read(&inode->i_writecount) > 0)) 1607 if ((arg == F_RDLCK) && (atomic_read(&inode->i_writecount) > 0))
1603 return -EAGAIN; 1608 return -EAGAIN;
1604 1609
@@ -1647,7 +1652,7 @@ generic_add_lease(struct file *filp, long arg, struct file_lock **flp, void **pr
1647 1652
1648 spin_lock(&ctx->flc_lock); 1653 spin_lock(&ctx->flc_lock);
1649 time_out_leases(inode, &dispose); 1654 time_out_leases(inode, &dispose);
1650 error = check_conflicting_open(dentry, arg); 1655 error = check_conflicting_open(dentry, arg, lease->fl_flags);
1651 if (error) 1656 if (error)
1652 goto out; 1657 goto out;
1653 1658
@@ -1703,7 +1708,7 @@ generic_add_lease(struct file *filp, long arg, struct file_lock **flp, void **pr
1703 * precedes these checks. 1708 * precedes these checks.
1704 */ 1709 */
1705 smp_mb(); 1710 smp_mb();
1706 error = check_conflicting_open(dentry, arg); 1711 error = check_conflicting_open(dentry, arg, lease->fl_flags);
1707 if (error) { 1712 if (error) {
1708 locks_unlink_lock_ctx(lease, &ctx->flc_lease_cnt); 1713 locks_unlink_lock_ctx(lease, &ctx->flc_lease_cnt);
1709 goto out; 1714 goto out;
@@ -1787,6 +1792,7 @@ int generic_setlease(struct file *filp, long arg, struct file_lock **flp,
1787 WARN_ON_ONCE(1); 1792 WARN_ON_ONCE(1);
1788 return -ENOLCK; 1793 return -ENOLCK;
1789 } 1794 }
1795
1790 return generic_add_lease(filp, arg, flp, priv); 1796 return generic_add_lease(filp, arg, flp, priv);
1791 default: 1797 default:
1792 return -EINVAL; 1798 return -EINVAL;