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;
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);
}
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)
{
}
}
release_all_access(stp);
+ drop_stid_export(clp, stid);
} else
spin_unlock(&clp->cl_lock);
}
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:
}
spin_unlock(&clp->cl_lock);
nfsd4_close_layout(layoutstateid(stid));
+ drop_stid_export(clp, stid);
break;
}
}
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)
goto out;
}
- if (!open->op_stp)
+ if (!open->op_stp) {
new_stp = true;
+ stp->st_stid.sc_export =
+ exp_get(current_fh->fh_export);
+ }
}
/*
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;
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)