mirror of
https://github.com/torvalds/linux.git
synced 2026-09-25 17:42:03 +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);
|
get_nfs4_file(fp);
|
||||||
stp->sc_file = fp;
|
stp->sc_file = fp;
|
||||||
|
if (parent->sc_export)
|
||||||
|
stp->sc_export = exp_get(parent->sc_export);
|
||||||
|
|
||||||
ls = layoutstateid(stp);
|
ls = layoutstateid(stp);
|
||||||
INIT_LIST_HEAD(&ls->ls_perclnt);
|
INIT_LIST_HEAD(&ls->ls_perclnt);
|
||||||
|
|
|
||||||
|
|
@ -1168,6 +1168,7 @@ alloc_init_deleg(struct nfs4_client *clp, struct nfs4_file *fp,
|
||||||
void
|
void
|
||||||
nfs4_put_stid(struct nfs4_stid *s)
|
nfs4_put_stid(struct nfs4_stid *s)
|
||||||
{
|
{
|
||||||
|
struct svc_export *exp = s->sc_export;
|
||||||
struct nfs4_file *fp = s->sc_file;
|
struct nfs4_file *fp = s->sc_file;
|
||||||
struct nfs4_client *clp = s->sc_client;
|
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);
|
nfs4_free_cpntf_statelist(clp->net, s);
|
||||||
spin_unlock(&clp->cl_lock);
|
spin_unlock(&clp->cl_lock);
|
||||||
s->sc_free(s);
|
s->sc_free(s);
|
||||||
|
if (exp)
|
||||||
|
exp_put(exp);
|
||||||
if (fp)
|
if (fp)
|
||||||
put_nfs4_file(fp);
|
put_nfs4_file(fp);
|
||||||
}
|
}
|
||||||
|
|
@ -1763,6 +1766,25 @@ static struct nfs4_stid *find_one_sb_stid(struct nfs4_client *clp,
|
||||||
return stid;
|
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,
|
static void revoke_ol_stid(struct nfs4_client *clp,
|
||||||
struct nfs4_ol_stateid *stp)
|
struct nfs4_ol_stateid *stp)
|
||||||
{
|
{
|
||||||
|
|
@ -1787,6 +1809,7 @@ static void revoke_ol_stid(struct nfs4_client *clp,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
release_all_access(stp);
|
release_all_access(stp);
|
||||||
|
drop_stid_export(clp, stid);
|
||||||
} else
|
} else
|
||||||
spin_unlock(&clp->cl_lock);
|
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))
|
if (!unhash_delegation_locked(dp, SC_STATUS_ADMIN_REVOKED))
|
||||||
dp = NULL;
|
dp = NULL;
|
||||||
spin_unlock(&nn->deleg_lock);
|
spin_unlock(&nn->deleg_lock);
|
||||||
if (dp)
|
if (dp) {
|
||||||
revoke_delegation(dp);
|
revoke_delegation(dp);
|
||||||
else
|
drop_stid_export(clp, stid);
|
||||||
|
} else
|
||||||
nfs4_put_stid(stid);
|
nfs4_put_stid(stid);
|
||||||
break;
|
break;
|
||||||
case SC_TYPE_LAYOUT:
|
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);
|
spin_unlock(&clp->cl_lock);
|
||||||
nfsd4_close_layout(layoutstateid(stid));
|
nfsd4_close_layout(layoutstateid(stid));
|
||||||
|
drop_stid_export(clp, stid);
|
||||||
break;
|
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);
|
dp = alloc_init_deleg(clp, fp, odstate, dl_type);
|
||||||
if (!dp)
|
if (!dp)
|
||||||
goto out_delegees;
|
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);
|
fl = nfs4_alloc_init_lease(dp);
|
||||||
if (!fl)
|
if (!fl)
|
||||||
|
|
@ -6505,8 +6532,11 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!open->op_stp)
|
if (!open->op_stp) {
|
||||||
new_stp = true;
|
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);
|
stp->st_stateowner = nfs4_get_stateowner(&lo->lo_owner);
|
||||||
get_nfs4_file(fp);
|
get_nfs4_file(fp);
|
||||||
stp->st_stid.sc_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_access_bmap = 0;
|
||||||
stp->st_deny_bmap = open_stp->st_deny_bmap;
|
stp->st_deny_bmap = open_stp->st_deny_bmap;
|
||||||
stp->st_openstp = open_stp;
|
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);
|
dp = alloc_init_deleg(clp, fp, NULL, NFS4_OPEN_DELEGATE_READ);
|
||||||
if (!dp)
|
if (!dp)
|
||||||
goto out_delegees;
|
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);
|
fl = nfs4_alloc_init_lease(dp);
|
||||||
if (!fl)
|
if (!fl)
|
||||||
|
|
|
||||||
|
|
@ -145,6 +145,7 @@ struct nfs4_stid {
|
||||||
spinlock_t sc_lock;
|
spinlock_t sc_lock;
|
||||||
struct nfs4_client *sc_client;
|
struct nfs4_client *sc_client;
|
||||||
struct nfs4_file *sc_file;
|
struct nfs4_file *sc_file;
|
||||||
|
struct svc_export *sc_export;
|
||||||
void (*sc_free)(struct nfs4_stid *);
|
void (*sc_free)(struct nfs4_stid *);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user