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

Commit 52b26a3e authored by Trond Myklebust's avatar Trond Myklebust
Browse files

NFSv4.1: nfs4_fl_prepare_ds - fix bugs when the connect attempt fails



- Fix an Oops when nfs4_ds_connect() returns an error.
- Always check the device status after waiting for a connect to complete.

Reported-by: default avatarAndy Adamson <andros@netapp.com>
Reported-by: default avatarJeff Layton <jlayton@redhat.com>
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
Cc: <stable@vger.kernel.org> # v3.10+
parent 5bc2afc2
Loading
Loading
Loading
Loading
+9 −9
Original line number Diff line number Diff line
@@ -801,34 +801,34 @@ nfs4_fl_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx)
	struct nfs4_file_layout_dsaddr *dsaddr = FILELAYOUT_LSEG(lseg)->dsaddr;
	struct nfs4_pnfs_ds *ds = dsaddr->ds_list[ds_idx];
	struct nfs4_deviceid_node *devid = FILELAYOUT_DEVID_NODE(lseg);

	if (filelayout_test_devid_unavailable(devid))
		return NULL;
	struct nfs4_pnfs_ds *ret = ds;

	if (ds == NULL) {
		printk(KERN_ERR "NFS: %s: No data server for offset index %d\n",
			__func__, ds_idx);
		filelayout_mark_devid_invalid(devid);
		return NULL;
		goto out;
	}
	if (ds->ds_clp)
		return ds;
		goto out_test_devid;

	if (test_and_set_bit(NFS4DS_CONNECTING, &ds->ds_state) == 0) {
		struct nfs_server *s = NFS_SERVER(lseg->pls_layout->plh_inode);
		int err;

		err = nfs4_ds_connect(s, ds);
		if (err) {
		if (err)
			nfs4_mark_deviceid_unavailable(devid);
			ds = NULL;
		}
		nfs4_clear_ds_conn_bit(ds);
	} else {
		/* Either ds is connected, or ds is NULL */
		nfs4_wait_ds_connect(ds);
	}
	return ds;
out_test_devid:
	if (filelayout_test_devid_unavailable(devid))
		ret = NULL;
out:
	return ret;
}

module_param(dataserver_retrans, uint, 0644);