]> git.karo-electronics.de Git - linux-beck.git/commitdiff
pNFS: On error, do not send LAYOUTGET until the LAYOUTRETURN has completed
authorTrond Myklebust <trond.myklebust@primarydata.com>
Mon, 17 Oct 2016 21:54:32 +0000 (17:54 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 9 Jan 2017 07:32:24 +0000 (08:32 +0100)
commit 6604b203fb6394ed1f24c21bfa3c207e5ae8e461 upstream.

If there is an I/O error, we should not call LAYOUTGET until the
LAYOUTRETURN that reports the error is complete.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
fs/nfs/pnfs.c
fs/nfs/pnfs.h

index 259ef85f435aa7f9e0b0e4d06d3ce24a9e7a3ad3..d3eb4d7f0cbc4e08854d0f15c28fa4419af590c9 100644 (file)
@@ -944,6 +944,7 @@ static void pnfs_clear_layoutcommit(struct inode *inode,
 void pnfs_clear_layoutreturn_waitbit(struct pnfs_layout_hdr *lo)
 {
        clear_bit_unlock(NFS_LAYOUT_RETURN, &lo->plh_flags);
+       clear_bit(NFS_LAYOUT_RETURN_LOCK, &lo->plh_flags);
        smp_mb__after_atomic();
        wake_up_bit(&lo->plh_flags, NFS_LAYOUT_RETURN);
        rpc_wake_up(&NFS_SERVER(lo->plh_inode)->roc_rpcwaitq);
@@ -957,8 +958,9 @@ pnfs_prepare_layoutreturn(struct pnfs_layout_hdr *lo,
        /* Serialise LAYOUTGET/LAYOUTRETURN */
        if (atomic_read(&lo->plh_outstanding) != 0)
                return false;
-       if (test_and_set_bit(NFS_LAYOUT_RETURN, &lo->plh_flags))
+       if (test_and_set_bit(NFS_LAYOUT_RETURN_LOCK, &lo->plh_flags))
                return false;
+       set_bit(NFS_LAYOUT_RETURN, &lo->plh_flags);
        pnfs_get_layout_hdr(lo);
        if (test_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags)) {
                if (stateid != NULL) {
@@ -1950,6 +1952,8 @@ void pnfs_error_mark_layout_for_return(struct inode *inode,
 
        spin_lock(&inode->i_lock);
        pnfs_set_plh_return_info(lo, range.iomode, 0);
+       /* Block LAYOUTGET */
+       set_bit(NFS_LAYOUT_RETURN, &lo->plh_flags);
        /*
         * mark all matching lsegs so that we are sure to have no live
         * segments at hand when sending layoutreturn. See pnfs_put_lseg()
index 5c295512c9671e4996136264ec8a848077d835ef..44cad8afda0e4e3b95f64a57d16ec2036a4b0c90 100644 (file)
@@ -96,6 +96,7 @@ enum {
        NFS_LAYOUT_RW_FAILED,           /* get rw layout failed stop trying */
        NFS_LAYOUT_BULK_RECALL,         /* bulk recall affecting layout */
        NFS_LAYOUT_RETURN,              /* layoutreturn in progress */
+       NFS_LAYOUT_RETURN_LOCK,         /* Serialise layoutreturn */
        NFS_LAYOUT_RETURN_REQUESTED,    /* Return this layout ASAP */
        NFS_LAYOUT_INVALID_STID,        /* layout stateid id is invalid */
        NFS_LAYOUT_FIRST_LAYOUTGET,     /* Serialize first layoutget */