Skip to content

Commit a33e4b0

Browse files
westonandrosadamsonamschuma-ntap
authored andcommitted
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: Weston Andros Adamson <dros@primarydata.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
1 parent 0338533 commit a33e4b0

File tree

6 files changed

+48
-6
lines changed

6 files changed

+48
-6
lines changed

fs/nfs/client.c

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,10 +325,33 @@ static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *dat
325325
return NULL;
326326
}
327327

328-
static bool nfs_client_init_is_complete(const struct nfs_client *clp)
328+
/*
329+
* Return true if @clp is done initializing, false if still working on it.
330+
*
331+
* Use nfs_client_init_status to check if it was successful.
332+
*/
333+
bool nfs_client_init_is_complete(const struct nfs_client *clp)
329334
{
330335
return clp->cl_cons_state <= NFS_CS_READY;
331336
}
337+
EXPORT_SYMBOL_GPL(nfs_client_init_is_complete);
338+
339+
/*
340+
* Return 0 if @clp was successfully initialized, -errno otherwise.
341+
*
342+
* This must be called *after* nfs_client_init_is_complete() returns true,
343+
* otherwise it will pop WARN_ON_ONCE and return -EINVAL
344+
*/
345+
int nfs_client_init_status(const struct nfs_client *clp)
346+
{
347+
/* called without checking nfs_client_init_is_complete */
348+
if (clp->cl_cons_state > NFS_CS_READY) {
349+
WARN_ON_ONCE(1);
350+
return -EINVAL;
351+
}
352+
return clp->cl_cons_state;
353+
}
354+
EXPORT_SYMBOL_GPL(nfs_client_init_status);
332355

333356
int nfs_wait_client_init_complete(const struct nfs_client *clp)
334357
{

fs/nfs/filelayout/filelayoutdev.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,7 @@ nfs4_fl_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx)
266266
struct nfs4_deviceid_node *devid = FILELAYOUT_DEVID_NODE(lseg);
267267
struct nfs4_pnfs_ds *ret = ds;
268268
struct nfs_server *s = NFS_SERVER(lseg->pls_layout->plh_inode);
269+
int status;
269270

270271
if (ds == NULL) {
271272
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)
277278
if (ds->ds_clp)
278279
goto out_test_devid;
279280

280-
nfs4_pnfs_ds_connect(s, ds, devid, dataserver_timeo,
281+
status = nfs4_pnfs_ds_connect(s, ds, devid, dataserver_timeo,
281282
dataserver_retrans, 4,
282283
s->nfs_client->cl_minorversion);
284+
if (status) {
285+
ret = NULL;
286+
goto out;
287+
}
283288

284289
out_test_devid:
285290
if (ret->ds_clp == NULL ||

fs/nfs/flexfilelayout/flexfilelayoutdev.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,7 @@ nfs4_ff_layout_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx,
384384
struct inode *ino = lseg->pls_layout->plh_inode;
385385
struct nfs_server *s = NFS_SERVER(ino);
386386
unsigned int max_payload;
387+
int status;
387388

388389
if (!ff_layout_mirror_valid(lseg, mirror, true)) {
389390
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,
404405
/* FIXME: For now we assume the server sent only one version of NFS
405406
* to use for the DS.
406407
*/
407-
nfs4_pnfs_ds_connect(s, ds, devid, dataserver_timeo,
408+
status = nfs4_pnfs_ds_connect(s, ds, devid, dataserver_timeo,
408409
dataserver_retrans,
409410
mirror->mirror_ds->ds_versions[0].version,
410411
mirror->mirror_ds->ds_versions[0].minor_version);

fs/nfs/internal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,8 @@ extern struct nfs_server *nfs_clone_server(struct nfs_server *,
186186
struct nfs_fh *,
187187
struct nfs_fattr *,
188188
rpc_authflavor_t);
189+
extern bool nfs_client_init_is_complete(const struct nfs_client *clp);
190+
extern int nfs_client_init_status(const struct nfs_client *clp);
189191
extern int nfs_wait_client_init_complete(const struct nfs_client *clp);
190192
extern void nfs_mark_client_ready(struct nfs_client *clp, int state);
191193
extern struct nfs_client *nfs4_set_ds_client(struct nfs_server *mds_srv,

fs/nfs/pnfs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ void nfs4_pnfs_ds_put(struct nfs4_pnfs_ds *ds);
367367
struct nfs4_pnfs_ds *nfs4_pnfs_ds_add(struct list_head *dsaddrs,
368368
gfp_t gfp_flags);
369369
void nfs4_pnfs_v3_ds_connect_unload(void);
370-
void nfs4_pnfs_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds,
370+
int nfs4_pnfs_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds,
371371
struct nfs4_deviceid_node *devid, unsigned int timeo,
372372
unsigned int retrans, u32 version, u32 minor_version);
373373
struct nfs4_pnfs_ds_addr *nfs4_decode_mp_ds_addr(struct net *net,

fs/nfs/pnfs_nfs.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -745,9 +745,9 @@ static int _nfs4_pnfs_v4_ds_connect(struct nfs_server *mds_srv,
745745
/*
746746
* Create an rpc connection to the nfs4_pnfs_ds data server.
747747
* Currently only supports IPv4 and IPv6 addresses.
748-
* If connection fails, make devid unavailable.
748+
* If connection fails, make devid unavailable and return a -errno.
749749
*/
750-
void nfs4_pnfs_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds,
750+
int nfs4_pnfs_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds,
751751
struct nfs4_deviceid_node *devid, unsigned int timeo,
752752
unsigned int retrans, u32 version, u32 minor_version)
753753
{
@@ -772,6 +772,17 @@ void nfs4_pnfs_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds,
772772
} else {
773773
nfs4_wait_ds_connect(ds);
774774
}
775+
776+
/*
777+
* At this point the ds->ds_clp should be ready, but it might have
778+
* hit an error.
779+
*/
780+
if (!ds->ds_clp || !nfs_client_init_is_complete(ds->ds_clp)) {
781+
WARN_ON_ONCE(1);
782+
return -EINVAL;
783+
}
784+
785+
return nfs_client_init_status(ds->ds_clp);
775786
}
776787
EXPORT_SYMBOL_GPL(nfs4_pnfs_ds_connect);
777788

0 commit comments

Comments
 (0)