#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)
 
 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);
  * 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;
 
 
        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;
 
         * 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;
                        WARN_ON_ONCE(1);
                        return -ENOLCK;
                }
+
                return generic_add_lease(filp, arg, flp, priv);
        default:
                return -EINVAL;
 
 #define FL_DOWNGRADE_PENDING   256 /* Lease is being downgraded */
 #define FL_UNLOCK_PENDING      512 /* Lease is being broken */
 #define FL_OFDLCK      1024    /* lock is "owned" by struct file */
+#define FL_LAYOUT      2048    /* outstanding pNFS layout */
 
 /*
  * Special return value from posix_lock_file() and vfs_lock_file() for
        return ret;
 }
 
+static inline int break_layout(struct inode *inode, bool wait)
+{
+       smp_mb();
+       if (inode->i_flctx && !list_empty_careful(&inode->i_flctx->flc_lease))
+               return __break_lease(inode,
+                               wait ? O_WRONLY : O_WRONLY | O_NONBLOCK,
+                               FL_LAYOUT);
+       return 0;
+}
+
 #else /* !CONFIG_FILE_LOCKING */
 static inline int locks_mandatory_locked(struct file *file)
 {
        return 0;
 }
 
+static inline int break_layout(struct inode *inode, bool wait)
+{
+       return 0;
+}
+
 #endif /* CONFIG_FILE_LOCKING */
 
 /* fs/open.c */