mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 09:36:22 +02:00
NFSD: Track svc_export in nfs4_stid
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. Reviewed-by: Jeff Layton <jlayton@kernel.org> Tested-by: Dai Ngo <dai.ngo@oracle.com> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
This commit is contained in:
parent
8fc2748835
commit
ba0cde5dc8
|
|
@ -234,6 +234,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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -1763,6 +1766,25 @@ static struct nfs4_stid *find_one_sb_stid(struct nfs4_client *clp,
|
|||
return stid;
|
||||
}
|
||||
|
||||
/*
|
||||
* Release the export reference an admin-revoked stateid holds,
|
||||
* so the svc_export (and its vfsmount) is not pinned until the
|
||||
* client issues FREE_STATEID. sc_export is no longer consulted
|
||||
* once SC_STATUS_ADMIN_REVOKED is set.
|
||||
*/
|
||||
static void drop_stid_export(struct nfs4_client *clp,
|
||||
struct nfs4_stid *stid)
|
||||
{
|
||||
struct svc_export *exp;
|
||||
|
||||
spin_lock(&clp->cl_lock);
|
||||
exp = stid->sc_export;
|
||||
stid->sc_export = NULL;
|
||||
spin_unlock(&clp->cl_lock);
|
||||
if (exp)
|
||||
exp_put(exp);
|
||||
}
|
||||
|
||||
static void revoke_ol_stid(struct nfs4_client *clp,
|
||||
struct nfs4_ol_stateid *stp)
|
||||
{
|
||||
|
|
@ -1787,6 +1809,7 @@ static void revoke_ol_stid(struct nfs4_client *clp,
|
|||
}
|
||||
}
|
||||
release_all_access(stp);
|
||||
drop_stid_export(clp, stid);
|
||||
} else
|
||||
spin_unlock(&clp->cl_lock);
|
||||
}
|
||||
|
|
@ -1820,9 +1843,10 @@ static void revoke_one_stid(struct nfsd_net *nn, struct nfs4_client *clp,
|
|||
if (!unhash_delegation_locked(dp, SC_STATUS_ADMIN_REVOKED))
|
||||
dp = NULL;
|
||||
spin_unlock(&nn->deleg_lock);
|
||||
if (dp)
|
||||
if (dp) {
|
||||
revoke_delegation(dp);
|
||||
else
|
||||
drop_stid_export(clp, stid);
|
||||
} else
|
||||
nfs4_put_stid(stid);
|
||||
break;
|
||||
case SC_TYPE_LAYOUT:
|
||||
|
|
@ -1833,6 +1857,7 @@ static void revoke_one_stid(struct nfsd_net *nn, struct nfs4_client *clp,
|
|||
}
|
||||
spin_unlock(&clp->cl_lock);
|
||||
nfsd4_close_layout(layoutstateid(stid));
|
||||
drop_stid_export(clp, stid);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -6172,6 +6197,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)
|
||||
|
|
@ -6505,8 +6532,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);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -8202,6 +8232,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;
|
||||
|
|
@ -9532,6 +9565,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)
|
||||
|
|
|
|||
|
|
@ -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 *);
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user