From b3230e80a6d115d2eb50fe3f4794ad04d84766de Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 25 Apr 2017 10:56:19 -0400 Subject: pNFS: Ensure we check layout segment validity in the pg_init() callback If we have a layout segment cached in pgio->pg_lseg, we should check it for validity before reusing it in a new RPC request. Otherwise, if we recoalesce, we can end up looping forever. Signed-off-by: Trond Myklebust --- fs/nfs/pnfs.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'fs/nfs/pnfs.c') diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index 3917a6272789..634adb3f8524 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -2072,11 +2072,23 @@ void pnfs_error_mark_layout_for_return(struct inode *inode, } EXPORT_SYMBOL_GPL(pnfs_error_mark_layout_for_return); +void +pnfs_generic_pg_check_layout(struct nfs_pageio_descriptor *pgio) +{ + if (pgio->pg_lseg == NULL || + test_bit(NFS_LSEG_VALID, &pgio->pg_lseg->pls_flags)) + return; + pnfs_put_lseg(pgio->pg_lseg); + pgio->pg_lseg = NULL; +} +EXPORT_SYMBOL_GPL(pnfs_generic_pg_check_layout); + void pnfs_generic_pg_init_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *req) { u64 rd_size = req->wb_bytes; + pnfs_generic_pg_check_layout(pgio); if (pgio->pg_lseg == NULL) { if (pgio->pg_dreq == NULL) rd_size = i_size_read(pgio->pg_inode) - req_offset(req); @@ -2107,6 +2119,7 @@ void pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *pgio, struct nfs_page *req, u64 wb_size) { + pnfs_generic_pg_check_layout(pgio); if (pgio->pg_lseg == NULL) { pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode, req->wb_context, -- cgit v1.2.3-59-g8ed1b