fs: add FL_LAYOUT lease type
[linux-2.6-block.git] / fs / locks.c
index 22ac7694cc84022b060e36588030bbcd4edf21a5..4753218f308ed32ee8b09123b11bc9cba42a6af4 100644 (file)
 
 #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;