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

Commit a33e4b03 authored by Weston Andros Adamson's avatar Weston Andros Adamson Committed by Anna Schumaker
Browse files

pNFS: return status from nfs4_pnfs_ds_connect



The nfs4_pnfs_ds_connect path can call rpc_create which can fail or it
can wait on another context to reach the same failure.

This checks that the rpc_create succeeded and returns the error to the
caller.

When an error is returned, both the files and flexfiles layouts will return
NULL from _prepare_ds(). The flexfiles layout will also return the layout
with the error NFS4ERR_NXIO.

Signed-off-by: default avatarWeston Andros Adamson <dros@primarydata.com>
Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
parent 03385332
Loading
Loading
Loading
Loading
+24 −1
Original line number Diff line number Diff line
@@ -325,10 +325,33 @@ static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *dat
	return NULL;
}

static bool nfs_client_init_is_complete(const struct nfs_client *clp)
/*
 * Return true if @clp is done initializing, false if still working on it.
 *
 * Use nfs_client_init_status to check if it was successful.
 */
bool nfs_client_init_is_complete(const struct nfs_client *clp)
{
	return clp->cl_cons_state <= NFS_CS_READY;
}
EXPORT_SYMBOL_GPL(nfs_client_init_is_complete);

/*
 * Return 0 if @clp was successfully initialized, -errno otherwise.
 *
 * This must be called *after* nfs_client_init_is_complete() returns true,
 * otherwise it will pop WARN_ON_ONCE and return -EINVAL
 */
int nfs_client_init_status(const struct nfs_client *clp)
{
	/* called without checking nfs_client_init_is_complete */
	if (clp->cl_cons_state > NFS_CS_READY) {
		WARN_ON_ONCE(1);
		return -EINVAL;
	}
	return clp->cl_cons_state;
}
EXPORT_SYMBOL_GPL(nfs_client_init_status);

int nfs_wait_client_init_complete(const struct nfs_client *clp)
{
+6 −1
Original line number Diff line number Diff line
@@ -266,6 +266,7 @@ nfs4_fl_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx)
	struct nfs4_deviceid_node *devid = FILELAYOUT_DEVID_NODE(lseg);
	struct nfs4_pnfs_ds *ret = ds;
	struct nfs_server *s = NFS_SERVER(lseg->pls_layout->plh_inode);
	int status;

	if (ds == NULL) {
		printk(KERN_ERR "NFS: %s: No data server for offset index %d\n",
@@ -277,9 +278,13 @@ nfs4_fl_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx)
	if (ds->ds_clp)
		goto out_test_devid;

	nfs4_pnfs_ds_connect(s, ds, devid, dataserver_timeo,
	status = nfs4_pnfs_ds_connect(s, ds, devid, dataserver_timeo,
			     dataserver_retrans, 4,
			     s->nfs_client->cl_minorversion);
	if (status) {
		ret = NULL;
		goto out;
	}

out_test_devid:
	if (ret->ds_clp == NULL ||
+2 −1
Original line number Diff line number Diff line
@@ -384,6 +384,7 @@ nfs4_ff_layout_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx,
	struct inode *ino = lseg->pls_layout->plh_inode;
	struct nfs_server *s = NFS_SERVER(ino);
	unsigned int max_payload;
	int status;

	if (!ff_layout_mirror_valid(lseg, mirror, true)) {
		pr_err_ratelimited("NFS: %s: No data server for offset index %d\n",
@@ -404,7 +405,7 @@ nfs4_ff_layout_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx,
	/* FIXME: For now we assume the server sent only one version of NFS
	 * to use for the DS.
	 */
	nfs4_pnfs_ds_connect(s, ds, devid, dataserver_timeo,
	status = nfs4_pnfs_ds_connect(s, ds, devid, dataserver_timeo,
			     dataserver_retrans,
			     mirror->mirror_ds->ds_versions[0].version,
			     mirror->mirror_ds->ds_versions[0].minor_version);
+2 −0
Original line number Diff line number Diff line
@@ -186,6 +186,8 @@ extern struct nfs_server *nfs_clone_server(struct nfs_server *,
					   struct nfs_fh *,
					   struct nfs_fattr *,
					   rpc_authflavor_t);
extern bool nfs_client_init_is_complete(const struct nfs_client *clp);
extern int nfs_client_init_status(const struct nfs_client *clp);
extern int nfs_wait_client_init_complete(const struct nfs_client *clp);
extern void nfs_mark_client_ready(struct nfs_client *clp, int state);
extern struct nfs_client *nfs4_set_ds_client(struct nfs_server *mds_srv,
+1 −1
Original line number Diff line number Diff line
@@ -367,7 +367,7 @@ void nfs4_pnfs_ds_put(struct nfs4_pnfs_ds *ds);
struct nfs4_pnfs_ds *nfs4_pnfs_ds_add(struct list_head *dsaddrs,
				      gfp_t gfp_flags);
void nfs4_pnfs_v3_ds_connect_unload(void);
void nfs4_pnfs_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds,
int nfs4_pnfs_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds,
			  struct nfs4_deviceid_node *devid, unsigned int timeo,
			  unsigned int retrans, u32 version, u32 minor_version);
struct nfs4_pnfs_ds_addr *nfs4_decode_mp_ds_addr(struct net *net,
Loading