|
@@ -137,7 +137,7 @@
|
|
|
|
|
|
#define IS_POSIX(fl) (fl->fl_flags & FL_POSIX)
|
|
|
#define IS_FLOCK(fl) (fl->fl_flags & FL_FLOCK)
|
|
|
-#define IS_LEASE(fl) (fl->fl_flags & (FL_LEASE|FL_DELEG))
|
|
|
+#define IS_LEASE(fl) (fl->fl_flags & (FL_LEASE|FL_DELEG|FL_LAYOUT))
|
|
|
#define IS_OFDLCK(fl) (fl->fl_flags & FL_OFDLCK)
|
|
|
|
|
|
static bool lease_breaking(struct file_lock *fl)
|
|
@@ -1371,6 +1371,8 @@ static void time_out_leases(struct inode *inode, struct list_head *dispose)
|
|
|
|
|
|
static bool leases_conflict(struct file_lock *lease, struct file_lock *breaker)
|
|
|
{
|
|
|
+ if ((breaker->fl_flags & FL_LAYOUT) != (lease->fl_flags & FL_LAYOUT))
|
|
|
+ return false;
|
|
|
if ((breaker->fl_flags & FL_DELEG) && (lease->fl_flags & FL_LEASE))
|
|
|
return false;
|
|
|
return locks_conflict(breaker, lease);
|
|
@@ -1594,11 +1596,14 @@ int fcntl_getlease(struct file *filp)
|
|
|
* conflict with the lease we're trying to set.
|
|
|
*/
|
|
|
static int
|
|
|
-check_conflicting_open(const struct dentry *dentry, const long arg)
|
|
|
+check_conflicting_open(const struct dentry *dentry, const long arg, int flags)
|
|
|
{
|
|
|
int ret = 0;
|
|
|
struct inode *inode = dentry->d_inode;
|
|
|
|
|
|
+ if (flags & FL_LAYOUT)
|
|
|
+ return 0;
|
|
|
+
|
|
|
if ((arg == F_RDLCK) && (atomic_read(&inode->i_writecount) > 0))
|
|
|
return -EAGAIN;
|
|
|
|
|
@@ -1647,7 +1652,7 @@ generic_add_lease(struct file *filp, long arg, struct file_lock **flp, void **pr
|
|
|
|
|
|
spin_lock(&ctx->flc_lock);
|
|
|
time_out_leases(inode, &dispose);
|
|
|
- error = check_conflicting_open(dentry, arg);
|
|
|
+ error = check_conflicting_open(dentry, arg, lease->fl_flags);
|
|
|
if (error)
|
|
|
goto out;
|
|
|
|
|
@@ -1703,7 +1708,7 @@ generic_add_lease(struct file *filp, long arg, struct file_lock **flp, void **pr
|
|
|
* precedes these checks.
|
|
|
*/
|
|
|
smp_mb();
|
|
|
- error = check_conflicting_open(dentry, arg);
|
|
|
+ error = check_conflicting_open(dentry, arg, lease->fl_flags);
|
|
|
if (error) {
|
|
|
locks_unlink_lock_ctx(lease, &ctx->flc_lease_cnt);
|
|
|
goto out;
|
|
@@ -1787,6 +1792,7 @@ int generic_setlease(struct file *filp, long arg, struct file_lock **flp,
|
|
|
WARN_ON_ONCE(1);
|
|
|
return -ENOLCK;
|
|
|
}
|
|
|
+
|
|
|
return generic_add_lease(filp, arg, flp, priv);
|
|
|
default:
|
|
|
return -EINVAL;
|