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

Commit dd52128a authored by Trond Myklebust's avatar Trond Myklebust
Browse files

NFSv4.1/pnfs Ensure flexfiles reports all connection related errors



Make sure that we also handle RPC level connection and protocol
negotiation errors.

Reported-by: default avatarTom Haynes <loghyr@primarydata.com>
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@primarydata.com>
parent e76d28dd
Loading
Loading
Loading
Loading
+35 −13
Original line number Original line Diff line number Diff line
@@ -967,11 +967,36 @@ static int ff_layout_async_handle_error(struct rpc_task *task,


static void ff_layout_io_track_ds_error(struct pnfs_layout_segment *lseg,
static void ff_layout_io_track_ds_error(struct pnfs_layout_segment *lseg,
					int idx, u64 offset, u64 length,
					int idx, u64 offset, u64 length,
					u32 status, int opnum)
					u32 status, int opnum, int error)
{
{
	struct nfs4_ff_layout_mirror *mirror;
	struct nfs4_ff_layout_mirror *mirror;
	int err;
	int err;


	if (status == 0) {
		switch (error) {
		case -ETIMEDOUT:
		case -EPFNOSUPPORT:
		case -EPROTONOSUPPORT:
		case -EOPNOTSUPP:
		case -ECONNREFUSED:
		case -ECONNRESET:
		case -EHOSTDOWN:
		case -EHOSTUNREACH:
		case -ENETUNREACH:
		case -EADDRINUSE:
		case -ENOBUFS:
		case -EPIPE:
		case -EPERM:
			status = NFS4ERR_NXIO;
			break;
		case -EACCES:
			status = NFS4ERR_ACCESS;
			break;
		default:
			return;
		}
	}

	mirror = FF_LAYOUT_COMP(lseg, idx);
	mirror = FF_LAYOUT_COMP(lseg, idx);
	err = ff_layout_track_ds_error(FF_LAYOUT_FROM_HDR(lseg->pls_layout),
	err = ff_layout_track_ds_error(FF_LAYOUT_FROM_HDR(lseg->pls_layout),
				       mirror, offset, length, status, opnum,
				       mirror, offset, length, status, opnum,
@@ -988,12 +1013,11 @@ static int ff_layout_read_done_cb(struct rpc_task *task,
	int err;
	int err;


	trace_nfs4_pnfs_read(hdr, task->tk_status);
	trace_nfs4_pnfs_read(hdr, task->tk_status);
	if (task->tk_status == -ETIMEDOUT && !hdr->res.op_status)
	if (task->tk_status < 0)
		hdr->res.op_status = NFS4ERR_NXIO;
	if (task->tk_status < 0 && hdr->res.op_status)
		ff_layout_io_track_ds_error(hdr->lseg, hdr->pgio_mirror_idx,
		ff_layout_io_track_ds_error(hdr->lseg, hdr->pgio_mirror_idx,
					    hdr->args.offset, hdr->args.count,
					    hdr->args.offset, hdr->args.count,
					    hdr->res.op_status, OP_READ);
					    hdr->res.op_status, OP_READ,
					    task->tk_status);
	err = ff_layout_async_handle_error(task, hdr->args.context->state,
	err = ff_layout_async_handle_error(task, hdr->args.context->state,
					   hdr->ds_clp, hdr->lseg,
					   hdr->ds_clp, hdr->lseg,
					   hdr->pgio_mirror_idx);
					   hdr->pgio_mirror_idx);
@@ -1163,12 +1187,11 @@ static int ff_layout_write_done_cb(struct rpc_task *task,
	int err;
	int err;


	trace_nfs4_pnfs_write(hdr, task->tk_status);
	trace_nfs4_pnfs_write(hdr, task->tk_status);
	if (task->tk_status == -ETIMEDOUT && !hdr->res.op_status)
	if (task->tk_status < 0)
		hdr->res.op_status = NFS4ERR_NXIO;
	if (task->tk_status < 0 && hdr->res.op_status)
		ff_layout_io_track_ds_error(hdr->lseg, hdr->pgio_mirror_idx,
		ff_layout_io_track_ds_error(hdr->lseg, hdr->pgio_mirror_idx,
					    hdr->args.offset, hdr->args.count,
					    hdr->args.offset, hdr->args.count,
					    hdr->res.op_status, OP_WRITE);
					    hdr->res.op_status, OP_WRITE,
					    task->tk_status);
	err = ff_layout_async_handle_error(task, hdr->args.context->state,
	err = ff_layout_async_handle_error(task, hdr->args.context->state,
					   hdr->ds_clp, hdr->lseg,
					   hdr->ds_clp, hdr->lseg,
					   hdr->pgio_mirror_idx);
					   hdr->pgio_mirror_idx);
@@ -1208,12 +1231,11 @@ static int ff_layout_commit_done_cb(struct rpc_task *task,
	int err;
	int err;


	trace_nfs4_pnfs_commit_ds(data, task->tk_status);
	trace_nfs4_pnfs_commit_ds(data, task->tk_status);
	if (task->tk_status == -ETIMEDOUT && !data->res.op_status)
	if (task->tk_status < 0)
		data->res.op_status = NFS4ERR_NXIO;
	if (task->tk_status < 0 && data->res.op_status)
		ff_layout_io_track_ds_error(data->lseg, data->ds_commit_index,
		ff_layout_io_track_ds_error(data->lseg, data->ds_commit_index,
					    data->args.offset, data->args.count,
					    data->args.offset, data->args.count,
					    data->res.op_status, OP_COMMIT);
					    data->res.op_status, OP_COMMIT,
					    task->tk_status);
	err = ff_layout_async_handle_error(task, NULL, data->ds_clp,
	err = ff_layout_async_handle_error(task, NULL, data->ds_clp,
					   data->lseg, data->ds_commit_index);
					   data->lseg, data->ds_commit_index);