if (lrp->res.lrs_present)
                pnfs_set_layout_stateid(lo, &lrp->res.stateid, true);
        clear_bit(NFS_LAYOUT_RETURN, &lo->plh_flags);
+       clear_bit(NFS_LAYOUT_RETURN_BEFORE_CLOSE, &lo->plh_flags);
+       rpc_wake_up(&NFS_SERVER(lo->plh_inode)->roc_rpcwaitq);
        lo->plh_block_lgets--;
        spin_unlock(&lo->plh_inode->i_lock);
        pnfs_put_layout_hdr(lrp->args.layout);
 
                status = -ENOMEM;
                spin_lock(&ino->i_lock);
                lo->plh_block_lgets--;
+               rpc_wake_up(&NFS_SERVER(ino)->roc_rpcwaitq);
                spin_unlock(&ino->i_lock);
                pnfs_put_layout_hdr(lo);
                goto out;
 
        status = nfs4_proc_layoutreturn(lrp, sync);
 out:
-       if (status) {
-               spin_lock(&ino->i_lock);
-               clear_bit(NFS_LAYOUT_RETURN, &lo->plh_flags);
-               spin_unlock(&ino->i_lock);
-       }
        dprintk("<-- %s status: %d\n", __func__, status);
        return status;
 }
 {
        struct pnfs_layout_hdr *lo;
        struct pnfs_layout_segment *lseg, *tmp;
+       nfs4_stateid stateid;
        LIST_HEAD(tmp_list);
-       bool found = false;
+       bool found = false, layoutreturn = false;
 
        spin_lock(&ino->i_lock);
        lo = NFS_I(ino)->layout;
        return true;
 
 out_nolayout:
+       if (lo) {
+               stateid = lo->plh_stateid;
+               layoutreturn =
+                       test_and_clear_bit(NFS_LAYOUT_RETURN_BEFORE_CLOSE,
+                                          &lo->plh_flags);
+               if (layoutreturn) {
+                       lo->plh_block_lgets++;
+                       pnfs_get_layout_hdr(lo);
+               }
+       }
        spin_unlock(&ino->i_lock);
+       if (layoutreturn)
+               pnfs_send_layoutreturn(lo, stateid, IOMODE_ANY, 0,
+                                      NFS4_MAX_UINT64, true);
        return false;
 }
 
        struct nfs_inode *nfsi = NFS_I(ino);
        struct pnfs_layout_hdr *lo;
        struct pnfs_layout_segment *lseg;
+       nfs4_stateid stateid;
        u32 current_seqid;
-       bool found = false;
+       bool found = false, layoutreturn = false;
 
        spin_lock(&ino->i_lock);
        list_for_each_entry(lseg, &nfsi->layout->plh_segs, pls_list)
         */
        *barrier = current_seqid + atomic_read(&lo->plh_outstanding);
 out:
+       if (!found) {
+               stateid = lo->plh_stateid;
+               layoutreturn =
+                       test_and_clear_bit(NFS_LAYOUT_RETURN_BEFORE_CLOSE,
+                                          &lo->plh_flags);
+               if (layoutreturn) {
+                       lo->plh_block_lgets++;
+                       pnfs_get_layout_hdr(lo);
+               }
+       }
        spin_unlock(&ino->i_lock);
+       if (layoutreturn) {
+               rpc_sleep_on(&NFS_SERVER(ino)->roc_rpcwaitq, task, NULL);
+               pnfs_send_layoutreturn(lo, stateid, IOMODE_ANY, 0,
+                                      NFS4_MAX_UINT64, false);
+       }
        return found;
 }
 
 
        NFS_LAYOUT_BULK_RECALL,         /* bulk recall affecting layout */
        NFS_LAYOUT_ROC,                 /* some lseg had roc bit set */
        NFS_LAYOUT_RETURN,              /* Return this layout ASAP */
+       NFS_LAYOUT_RETURN_BEFORE_CLOSE, /* Return this layout before close */
        NFS_LAYOUT_INVALID_STID,        /* layout stateid id is invalid */
        NFS_LAYOUT_FIRST_LAYOUTGET,     /* Serialize first layoutget */
 };