aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2007-07-17 21:50:45 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2007-07-19 15:09:03 -0400
commit6f220ed5a84d87645a84ae22105dc565f3f248b5 (patch)
treef7a9cc2a178da84c656f794248e1a55c6f5e09d3 /fs
parent8cd69e1bc7970bfb032b425043cc0d4e4345c74c (diff)
NFSv4: Fix open state recovery
Ensure that opendata->state is always initialised when we do state recovery. Ensure that we set the filehandle in the case where we're doing an "OPEN_CLAIM_PREVIOUS" call due to a server reboot. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/nfs/nfs4proc.c36
1 files changed, 24 insertions, 12 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index fee2da856c95..8799b1d54a0d 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -552,6 +552,18 @@ static struct nfs_open_context *nfs4_state_find_open_context(struct nfs4_state *
552 return ERR_PTR(-ENOENT); 552 return ERR_PTR(-ENOENT);
553} 553}
554 554
555static struct nfs4_opendata *nfs4_open_recoverdata_alloc(struct nfs_open_context *ctx, struct nfs4_state *state)
556{
557 struct nfs4_opendata *opendata;
558
559 opendata = nfs4_opendata_alloc(&ctx->path, state->owner, 0, NULL);
560 if (opendata == NULL)
561 return ERR_PTR(-ENOMEM);
562 opendata->state = state;
563 atomic_inc(&state->count);
564 return opendata;
565}
566
555static int nfs4_open_recover_helper(struct nfs4_opendata *opendata, mode_t openflags, struct nfs4_state **res) 567static int nfs4_open_recover_helper(struct nfs4_opendata *opendata, mode_t openflags, struct nfs4_state **res)
556{ 568{
557 struct nfs4_state *newstate; 569 struct nfs4_state *newstate;
@@ -626,12 +638,11 @@ static int _nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state
626 int delegation_type = 0; 638 int delegation_type = 0;
627 int status; 639 int status;
628 640
629 opendata = nfs4_opendata_alloc(&ctx->path, state->owner, 0, NULL); 641 opendata = nfs4_open_recoverdata_alloc(ctx, state);
630 if (opendata == NULL) 642 if (IS_ERR(opendata))
631 return -ENOMEM; 643 return PTR_ERR(opendata);
632 opendata->o_arg.claim = NFS4_OPEN_CLAIM_PREVIOUS; 644 opendata->o_arg.claim = NFS4_OPEN_CLAIM_PREVIOUS;
633 opendata->o_arg.fh = NFS_FH(state->inode); 645 opendata->o_arg.fh = NFS_FH(state->inode);
634 nfs_copy_fh(&opendata->o_res.fh, opendata->o_arg.fh);
635 rcu_read_lock(); 646 rcu_read_lock();
636 delegation = rcu_dereference(NFS_I(state->inode)->delegation); 647 delegation = rcu_dereference(NFS_I(state->inode)->delegation);
637 if (delegation != NULL && (delegation->flags & NFS_DELEGATION_NEED_RECLAIM) != 0) 648 if (delegation != NULL && (delegation->flags & NFS_DELEGATION_NEED_RECLAIM) != 0)
@@ -672,13 +683,12 @@ static int nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *sta
672 683
673static int _nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid) 684static int _nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid)
674{ 685{
675 struct nfs4_state_owner *sp = state->owner;
676 struct nfs4_opendata *opendata; 686 struct nfs4_opendata *opendata;
677 int ret; 687 int ret;
678 688
679 opendata = nfs4_opendata_alloc(&ctx->path, sp, 0, NULL); 689 opendata = nfs4_open_recoverdata_alloc(ctx, state);
680 if (opendata == NULL) 690 if (IS_ERR(opendata))
681 return -ENOMEM; 691 return PTR_ERR(opendata);
682 opendata->o_arg.claim = NFS4_OPEN_CLAIM_DELEGATE_CUR; 692 opendata->o_arg.claim = NFS4_OPEN_CLAIM_DELEGATE_CUR;
683 memcpy(opendata->o_arg.u.delegation.data, stateid->data, 693 memcpy(opendata->o_arg.u.delegation.data, stateid->data,
684 sizeof(opendata->o_arg.u.delegation.data)); 694 sizeof(opendata->o_arg.u.delegation.data));
@@ -823,8 +833,10 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata)
823 /* Update sequence id. */ 833 /* Update sequence id. */
824 data->o_arg.id = sp->so_owner_id.id; 834 data->o_arg.id = sp->so_owner_id.id;
825 data->o_arg.clientid = sp->so_client->cl_clientid; 835 data->o_arg.clientid = sp->so_client->cl_clientid;
826 if (data->o_arg.claim == NFS4_OPEN_CLAIM_PREVIOUS) 836 if (data->o_arg.claim == NFS4_OPEN_CLAIM_PREVIOUS) {
827 msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_NOATTR]; 837 msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_NOATTR];
838 nfs_copy_fh(&data->o_res.fh, data->o_arg.fh);
839 }
828 data->timestamp = jiffies; 840 data->timestamp = jiffies;
829 rpc_call_setup(task, &msg, 0); 841 rpc_call_setup(task, &msg, 0);
830 return; 842 return;
@@ -989,9 +1001,9 @@ static int _nfs4_open_expired(struct nfs_open_context *ctx, struct nfs4_state *s
989 struct nfs4_opendata *opendata; 1001 struct nfs4_opendata *opendata;
990 int ret; 1002 int ret;
991 1003
992 opendata = nfs4_opendata_alloc(&ctx->path, state->owner, 0, NULL); 1004 opendata = nfs4_open_recoverdata_alloc(ctx, state);
993 if (opendata == NULL) 1005 if (IS_ERR(opendata))
994 return -ENOMEM; 1006 return PTR_ERR(opendata);
995 ret = nfs4_open_recover(opendata, state); 1007 ret = nfs4_open_recover(opendata, state);
996 if (ret == -ESTALE) { 1008 if (ret == -ESTALE) {
997 /* Invalidate the state owner so we don't ever use it again */ 1009 /* Invalidate the state owner so we don't ever use it again */