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

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

NFS: Don't accept more reads/writes if the open context recovery failed



If the state recovery failed, we want to ensure that the application
doesn't try to use the same file descriptor for more reads or writes.

Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 5d422301
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -305,6 +305,10 @@ static void filelayout_read_prepare(struct rpc_task *task, void *data)
{
	struct nfs_read_data *rdata = data;

	if (unlikely(test_bit(NFS_CONTEXT_BAD, &rdata->args.context->flags))) {
		rpc_exit(task, -EIO);
		return;
	}
	if (filelayout_reset_to_mds(rdata->header->lseg)) {
		dprintk("%s task %u reset io to MDS\n", __func__, task->tk_pid);
		filelayout_reset_read(rdata);
@@ -407,6 +411,10 @@ static void filelayout_write_prepare(struct rpc_task *task, void *data)
{
	struct nfs_write_data *wdata = data;

	if (unlikely(test_bit(NFS_CONTEXT_BAD, &wdata->args.context->flags))) {
		rpc_exit(task, -EIO);
		return;
	}
	if (filelayout_reset_to_mds(wdata->header->lseg)) {
		dprintk("%s task %u reset io to MDS\n", __func__, task->tk_pid);
		filelayout_reset_write(wdata);
+16 −0
Original line number Diff line number Diff line
@@ -1328,9 +1328,25 @@ void nfs_inode_find_state_and_recover(struct inode *inode,
		nfs4_schedule_state_manager(clp);
}

static void nfs4_state_mark_open_context_bad(struct nfs4_state *state)
{
	struct inode *inode = state->inode;
	struct nfs_inode *nfsi = NFS_I(inode);
	struct nfs_open_context *ctx;

	spin_lock(&inode->i_lock);
	list_for_each_entry(ctx, &nfsi->open_files, list) {
		if (ctx->state != state)
			continue;
		set_bit(NFS_CONTEXT_BAD, &ctx->flags);
	}
	spin_unlock(&inode->i_lock);
}

static void nfs4_state_mark_recovery_failed(struct nfs4_state *state, int error)
{
	set_bit(NFS_STATE_RECOVERY_FAILED, &state->flags);
	nfs4_state_mark_open_context_bad(state);
}


+2 −0
Original line number Diff line number Diff line
@@ -104,6 +104,8 @@ nfs_create_request(struct nfs_open_context *ctx, struct inode *inode,
	struct nfs_page		*req;
	struct nfs_lock_context *l_ctx;

	if (test_bit(NFS_CONTEXT_BAD, &ctx->flags))
		return ERR_PTR(-EBADF);
	/* try to allocate the request struct */
	req = nfs_page_alloc();
	if (req == NULL)
+2 −0
Original line number Diff line number Diff line
@@ -514,6 +514,8 @@ void nfs_read_prepare(struct rpc_task *task, void *calldata)
{
	struct nfs_read_data *data = calldata;
	NFS_PROTO(data->header->inode)->read_rpc_prepare(task, data);
	if (unlikely(test_bit(NFS_CONTEXT_BAD, &data->args.context->flags)))
		rpc_exit(task, -EIO);
}

static const struct rpc_call_ops nfs_read_common_ops = {
+2 −0
Original line number Diff line number Diff line
@@ -1251,6 +1251,8 @@ void nfs_write_prepare(struct rpc_task *task, void *calldata)
{
	struct nfs_write_data *data = calldata;
	NFS_PROTO(data->header->inode)->write_rpc_prepare(task, data);
	if (unlikely(test_bit(NFS_CONTEXT_BAD, &data->args.context->flags)))
		rpc_exit(task, -EIO);
}

void nfs_commit_prepare(struct rpc_task *task, void *calldata)
Loading