Commit 6f220ed5a84d87645a84ae22105dc565f3f248b5

Authored by Trond Myklebust
1 parent 8cd69e1bc7

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>

Showing 1 changed file with 24 additions and 12 deletions Side-by-side Diff

... ... @@ -552,6 +552,18 @@
552 552 return ERR_PTR(-ENOENT);
553 553 }
554 554  
  555 +static 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 +
555 567 static int nfs4_open_recover_helper(struct nfs4_opendata *opendata, mode_t openflags, struct nfs4_state **res)
556 568 {
557 569 struct nfs4_state *newstate;
558 570  
... ... @@ -626,12 +638,11 @@
626 638 int delegation_type = 0;
627 639 int status;
628 640  
629   - opendata = nfs4_opendata_alloc(&ctx->path, state->owner, 0, NULL);
630   - if (opendata == NULL)
631   - return -ENOMEM;
  641 + opendata = nfs4_open_recoverdata_alloc(ctx, state);
  642 + if (IS_ERR(opendata))
  643 + return PTR_ERR(opendata);
632 644 opendata->o_arg.claim = NFS4_OPEN_CLAIM_PREVIOUS;
633 645 opendata->o_arg.fh = NFS_FH(state->inode);
634   - nfs_copy_fh(&opendata->o_res.fh, opendata->o_arg.fh);
635 646 rcu_read_lock();
636 647 delegation = rcu_dereference(NFS_I(state->inode)->delegation);
637 648 if (delegation != NULL && (delegation->flags & NFS_DELEGATION_NEED_RECLAIM) != 0)
638 649  
... ... @@ -672,13 +683,12 @@
672 683  
673 684 static 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 686 struct nfs4_opendata *opendata;
677 687 int ret;
678 688  
679   - opendata = nfs4_opendata_alloc(&ctx->path, sp, 0, NULL);
680   - if (opendata == NULL)
681   - return -ENOMEM;
  689 + opendata = nfs4_open_recoverdata_alloc(ctx, state);
  690 + if (IS_ERR(opendata))
  691 + return PTR_ERR(opendata);
682 692 opendata->o_arg.claim = NFS4_OPEN_CLAIM_DELEGATE_CUR;
683 693 memcpy(opendata->o_arg.u.delegation.data, stateid->data,
684 694 sizeof(opendata->o_arg.u.delegation.data));
685 695  
... ... @@ -823,8 +833,10 @@
823 833 /* Update sequence id. */
824 834 data->o_arg.id = sp->so_owner_id.id;
825 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 837 msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_NOATTR];
  838 + nfs_copy_fh(&data->o_res.fh, data->o_arg.fh);
  839 + }
828 840 data->timestamp = jiffies;
829 841 rpc_call_setup(task, &msg, 0);
830 842 return;
... ... @@ -989,9 +1001,9 @@
989 1001 struct nfs4_opendata *opendata;
990 1002 int ret;
991 1003  
992   - opendata = nfs4_opendata_alloc(&ctx->path, state->owner, 0, NULL);
993   - if (opendata == NULL)
994   - return -ENOMEM;
  1004 + opendata = nfs4_open_recoverdata_alloc(ctx, state);
  1005 + if (IS_ERR(opendata))
  1006 + return PTR_ERR(opendata);
995 1007 ret = nfs4_open_recover(opendata, state);
996 1008 if (ret == -ESTALE) {
997 1009 /* Invalidate the state owner so we don't ever use it again */