Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 54e4a0df authored by Trond Myklebust's avatar Trond Myklebust
Browse files

pNFS: Fix a deadlock between read resends and layoutreturn



We must not call nfs_pageio_init_read() on a new nfs_pageio_descriptor
while holding a reference to a layout segment, as that can deadlock
pnfs_update_layout().

Fixes: d67ae825 ("pnfs/flexfiles: Add the FlexFile Layout Driver")
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@primarydata.com>
Cc: stable@vger.kernel.org # v4.0+
parent 9a837856
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -28,6 +28,9 @@

static struct group_info	*ff_zero_group;

static void ff_layout_read_record_layoutstats_done(struct rpc_task *task,
		struct nfs_pgio_header *hdr);

static struct pnfs_layout_hdr *
ff_layout_alloc_layout_hdr(struct inode *inode, gfp_t gfp_flags)
{
@@ -1293,6 +1296,7 @@ static int ff_layout_read_done_cb(struct rpc_task *task,
					hdr->pgio_mirror_idx + 1,
					&hdr->pgio_mirror_idx))
			goto out_eagain;
		ff_layout_read_record_layoutstats_done(task, hdr);
		pnfs_read_resend_pnfs(hdr);
		return task->tk_status;
	case -NFS4ERR_RESET_TO_MDS:
+4 −0
Original line number Diff line number Diff line
@@ -2286,6 +2286,10 @@ void pnfs_read_resend_pnfs(struct nfs_pgio_header *hdr)
	struct nfs_pageio_descriptor pgio;

	if (!test_and_set_bit(NFS_IOHDR_REDO, &hdr->flags)) {
		/* Prevent deadlocks with layoutreturn! */
		pnfs_put_lseg(hdr->lseg);
		hdr->lseg = NULL;

		nfs_pageio_init_read(&pgio, hdr->inode, false,
					hdr->completion_ops);
		hdr->task.tk_status = nfs_pageio_resend(&pgio, hdr);