Commit f062eb6ced3b297277b94b4da3113b1d3782e539

Authored by Bryan Schumaker
Committed by Trond Myklebust
1 parent 9aeda35fd6

NFS: test and free stateids during recovery

When recovering open files and locks, the stateid should be tested
against the server and freed if it is invalid.  This patch adds new
recovery functions for NFS v4.1.

Signed-off-by: Bryan Schumaker <bjschuma@netapp.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>

Showing 1 changed file with 34 additions and 3 deletions Side-by-side Diff

... ... @@ -80,7 +80,10 @@
80 80 static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
81 81 struct nfs_fattr *fattr, struct iattr *sattr,
82 82 struct nfs4_state *state);
83   -
  83 +#ifdef CONFIG_NFS_V4_1
  84 +static int nfs41_test_stateid(struct nfs_server *, struct nfs4_state *);
  85 +static int nfs41_free_stateid(struct nfs_server *, struct nfs4_state *);
  86 +#endif
84 87 /* Prevent leaks of NFSv4 errors into userland */
85 88 static int nfs4_map_errors(int err)
86 89 {
... ... @@ -1687,6 +1690,20 @@
1687 1690 return ret;
1688 1691 }
1689 1692  
  1693 +#if defined(CONFIG_NFS_V4_1)
  1694 +static int nfs41_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *state)
  1695 +{
  1696 + int status;
  1697 + struct nfs_server *server = NFS_SERVER(state->inode);
  1698 +
  1699 + status = nfs41_test_stateid(server, state);
  1700 + if (status == NFS_OK)
  1701 + return 0;
  1702 + nfs41_free_stateid(server, state);
  1703 + return nfs4_open_expired(sp, state);
  1704 +}
  1705 +#endif
  1706 +
1690 1707 /*
1691 1708 * on an EXCLUSIVE create, the server should send back a bitmask with FATTR4-*
1692 1709 * fields corresponding to attributes that were used to store the verifier.
... ... @@ -4444,6 +4461,20 @@
4444 4461 return err;
4445 4462 }
4446 4463  
  4464 +#if defined(CONFIG_NFS_V4_1)
  4465 +static int nfs41_lock_expired(struct nfs4_state *state, struct file_lock *request)
  4466 +{
  4467 + int status;
  4468 + struct nfs_server *server = NFS_SERVER(state->inode);
  4469 +
  4470 + status = nfs41_test_stateid(server, state);
  4471 + if (status == NFS_OK)
  4472 + return 0;
  4473 + nfs41_free_stateid(server, state);
  4474 + return nfs4_lock_expired(state, request);
  4475 +}
  4476 +#endif
  4477 +
4447 4478 static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request)
4448 4479 {
4449 4480 struct nfs_inode *nfsi = NFS_I(state->inode);
... ... @@ -6109,8 +6140,8 @@
6109 6140 struct nfs4_state_recovery_ops nfs41_nograce_recovery_ops = {
6110 6141 .owner_flag_bit = NFS_OWNER_RECLAIM_NOGRACE,
6111 6142 .state_flag_bit = NFS_STATE_RECLAIM_NOGRACE,
6112   - .recover_open = nfs4_open_expired,
6113   - .recover_lock = nfs4_lock_expired,
  6143 + .recover_open = nfs41_open_expired,
  6144 + .recover_lock = nfs41_lock_expired,
6114 6145 .establish_clid = nfs41_init_clientid,
6115 6146 .get_clid_cred = nfs4_get_exchange_id_cred,
6116 6147 };