Skip to content

Commit

Permalink
NFSv4.1: nfs4_fl_prepare_ds - fix bugs when the connect attempt fails
Browse files Browse the repository at this point in the history
- Fix an Oops when nfs4_ds_connect() returns an error.
- Always check the device status after waiting for a connect to complete.

Reported-by: Andy Adamson <andros@netapp.com>
Reported-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Cc: <stable@vger.kernel.org> # v3.10+
  • Loading branch information
Trond Myklebust authored and Trond Myklebust committed Sep 29, 2013
1 parent 5bc2afc commit 52b26a3
Showing 1 changed file with 9 additions and 9 deletions.
18 changes: 9 additions & 9 deletions fs/nfs/nfs4filelayoutdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 52b26a3

Please sign in to comment.