• S
    nfs/pnfs: fix nfs_direct_req ref leak when i/o falls back to the mds · ba4a76f7
    Scott Mayhew 提交于
    Currently when falling back to doing I/O through the MDS (via
    pnfs_{read|write}_through_mds), the client frees the nfs_pgio_header
    without releasing the reference taken on the dreq
    via pnfs_generic_pg_{read|write}pages -> nfs_pgheader_init ->
    nfs_direct_pgio_init.  It then takes another reference on the dreq via
    nfs_generic_pg_pgios -> nfs_pgheader_init -> nfs_direct_pgio_init and
    as a result the requester will become stuck in inode_dio_wait.  Once
    that happens, other processes accessing the inode will become stuck as
    well.
    
    Ensure that pnfs_read_through_mds() and pnfs_write_through_mds() clean
    up correctly by calling hdr->completion_ops->completion() instead of
    calling hdr->release() directly.
    
    This can be reproduced (sometimes) by performing "storage failover
    takeover" commands on NetApp filer while doing direct I/O from a client.
    
    This can also be reproduced using SystemTap to simulate a failure while
    doing direct I/O from a client (from Dave Wysochanski
    <dwysocha@redhat.com>):
    
    stap -v -g -e 'probe module("nfs_layout_nfsv41_files").function("nfs4_fl_prepare_ds").return { $return=NULL; exit(); }'
    Suggested-by: NTrond Myklebust <trond.myklebust@primarydata.com>
    Signed-off-by: NScott Mayhew <smayhew@redhat.com>
    Fixes: 1ca018d2 ("pNFS: Fix a memory leak when attempted pnfs fails")
    Cc: stable@vger.kernel.org
    Signed-off-by: NTrond Myklebust <trond.myklebust@primarydata.com>
    ba4a76f7
pnfs.c 72.7 KB