Commit 108bb4af authored by Trond Myklebust's avatar Trond Myklebust
Browse files

NFSv4/flexfiles: Fix invalid deref in FF_LAYOUT_DEVID_NODE()



If the attempt to instantiate the mirror's layout DS pointer failed,
then that pointer may hold a value of type ERR_PTR(), so we need
to check that before we dereference it.

Fixes: 65990d1a ("pNFS/flexfiles: Fix a deadlock on LAYOUTGET")
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
parent 1a3466ae
Loading
Loading
Loading
Loading
+19 −13
Original line number Diff line number Diff line
@@ -132,16 +132,6 @@ FF_LAYOUT_LSEG(struct pnfs_layout_segment *lseg)
			    generic_hdr);
}

static inline struct nfs4_deviceid_node *
FF_LAYOUT_DEVID_NODE(struct pnfs_layout_segment *lseg, u32 idx)
{
	if (idx >= FF_LAYOUT_LSEG(lseg)->mirror_array_cnt ||
	    FF_LAYOUT_LSEG(lseg)->mirror_array[idx] == NULL ||
	    FF_LAYOUT_LSEG(lseg)->mirror_array[idx]->mirror_ds == NULL)
		return NULL;
	return &FF_LAYOUT_LSEG(lseg)->mirror_array[idx]->mirror_ds->id_node;
}

static inline struct nfs4_ff_layout_ds *
FF_LAYOUT_MIRROR_DS(struct nfs4_deviceid_node *node)
{
@@ -151,9 +141,25 @@ FF_LAYOUT_MIRROR_DS(struct nfs4_deviceid_node *node)
static inline struct nfs4_ff_layout_mirror *
FF_LAYOUT_COMP(struct pnfs_layout_segment *lseg, u32 idx)
{
	if (idx >= FF_LAYOUT_LSEG(lseg)->mirror_array_cnt)
	struct nfs4_ff_layout_segment *fls = FF_LAYOUT_LSEG(lseg);

	if (idx < fls->mirror_array_cnt)
		return fls->mirror_array[idx];
	return NULL;
}

static inline struct nfs4_deviceid_node *
FF_LAYOUT_DEVID_NODE(struct pnfs_layout_segment *lseg, u32 idx)
{
	struct nfs4_ff_layout_mirror *mirror = FF_LAYOUT_COMP(lseg, idx);

	if (mirror != NULL) {
		struct nfs4_ff_layout_ds *mirror_ds = mirror->mirror_ds;

		if (!IS_ERR_OR_NULL(mirror_ds))
			return &mirror_ds->id_node;
	}
	return NULL;
	return FF_LAYOUT_LSEG(lseg)->mirror_array[idx];
}

static inline u32