From: Chuck Lever Add an sc_export field to struct nfs4_stid so that each stateid records the export under which it was acquired. The export reference is taken via exp_get() at stateid creation and released via exp_put() in nfs4_put_stid(). Open stateids record the export from current_fh->fh_export. Lock stateids and delegations inherit the export from their parent open stateid. Layout stateids inherit from their parent stateid. Directory delegations record the export from cstate->current_fh. A subsequent commit uses sc_export to scope state revocation to a specific export, avoiding the need to walk inode dentry aliases at revocation time. Signed-off-by: Chuck Lever --- fs/nfsd/nfs4layouts.c | 2 ++ fs/nfsd/nfs4state.c | 16 +++++++++++++++- fs/nfsd/state.h | 1 + 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/fs/nfsd/nfs4layouts.c b/fs/nfsd/nfs4layouts.c index 69e41105efdd..83d8fda53efd 100644 --- a/fs/nfsd/nfs4layouts.c +++ b/fs/nfsd/nfs4layouts.c @@ -247,6 +247,8 @@ nfsd4_alloc_layout_stateid(struct nfsd4_compound_state *cstate, get_nfs4_file(fp); stp->sc_file = fp; + if (parent->sc_export) + stp->sc_export = exp_get(parent->sc_export); ls = layoutstateid(stp); INIT_LIST_HEAD(&ls->ls_perclnt); diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 62ebc7243c4f..ebbc83d7877e 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -1168,6 +1168,7 @@ alloc_init_deleg(struct nfs4_client *clp, struct nfs4_file *fp, void nfs4_put_stid(struct nfs4_stid *s) { + struct svc_export *exp = s->sc_export; struct nfs4_file *fp = s->sc_file; struct nfs4_client *clp = s->sc_client; @@ -1183,6 +1184,8 @@ nfs4_put_stid(struct nfs4_stid *s) nfs4_free_cpntf_statelist(clp->net, s); spin_unlock(&clp->cl_lock); s->sc_free(s); + if (exp) + exp_put(exp); if (fp) put_nfs4_file(fp); } @@ -6172,6 +6175,8 @@ nfs4_set_delegation(struct nfsd4_open *open, struct nfs4_ol_stateid *stp, dp = alloc_init_deleg(clp, fp, odstate, dl_type); if (!dp) goto out_delegees; + if (stp->st_stid.sc_export) + dp->dl_stid.sc_export = exp_get(stp->st_stid.sc_export); fl = nfs4_alloc_init_lease(dp); if (!fl) @@ -6506,8 +6511,11 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf goto out; } - if (!open->op_stp) + if (!open->op_stp) { new_stp = true; + stp->st_stid.sc_export = + exp_get(current_fh->fh_export); + } } /* @@ -8203,6 +8211,9 @@ init_lock_stateid(struct nfs4_ol_stateid *stp, struct nfs4_lockowner *lo, stp->st_stateowner = nfs4_get_stateowner(&lo->lo_owner); get_nfs4_file(fp); stp->st_stid.sc_file = fp; + if (open_stp->st_stid.sc_export) + stp->st_stid.sc_export = + exp_get(open_stp->st_stid.sc_export); stp->st_access_bmap = 0; stp->st_deny_bmap = open_stp->st_deny_bmap; stp->st_openstp = open_stp; @@ -9529,6 +9540,9 @@ nfsd_get_dir_deleg(struct nfsd4_compound_state *cstate, dp = alloc_init_deleg(clp, fp, NULL, NFS4_OPEN_DELEGATE_READ); if (!dp) goto out_delegees; + if (cstate->current_fh.fh_export) + dp->dl_stid.sc_export = + exp_get(cstate->current_fh.fh_export); fl = nfs4_alloc_init_lease(dp); if (!fl) diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 953675eba5c3..7d7e99eeffa5 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -145,6 +145,7 @@ struct nfs4_stid { spinlock_t sc_lock; struct nfs4_client *sc_client; struct nfs4_file *sc_file; + struct svc_export *sc_export; void (*sc_free)(struct nfs4_stid *); }; -- 2.53.0