mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-30 16:51:41 +00:00
Add support to the NFSv4.1/pNFS client for commits through the DS.
A NFSv4.1/pNFS server using File Layout can specify that Commit operations are to be done against the DS instead of MDS. Since no extant pNFS server did this, the code was untested and "#ifdef notyet". The FreeBSD pNFS server I am developing does specify that Commits be done through the DS, so the code has been enabled/tested. This patch should only affect the case of a pNFS server that specfies Commits through the DS. PR: 219551 MFC after: 2 weeks
This commit is contained in:
parent
8a89ca9425
commit
81b07aac10
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=320345
@ -490,7 +490,7 @@ int nfsrpc_layoutreturn(struct nfsmount *, uint8_t *, int, int, int, uint32_t,
|
||||
int, uint64_t, uint64_t, nfsv4stateid_t *, int, uint32_t *, struct ucred *,
|
||||
NFSPROC_T *, void *);
|
||||
int nfsrpc_reclaimcomplete(struct nfsmount *, struct ucred *, NFSPROC_T *);
|
||||
int nfscl_doiods(vnode_t, struct uio *, int *, int *, uint32_t,
|
||||
int nfscl_doiods(vnode_t, struct uio *, int *, int *, uint32_t, int,
|
||||
struct ucred *, NFSPROC_T *);
|
||||
int nfscl_findlayoutforio(struct nfscllayout *, uint64_t, uint32_t,
|
||||
struct nfsclflayout **);
|
||||
|
@ -259,10 +259,12 @@ ncl_inactive(struct vop_inactive_args *ap)
|
||||
|
||||
/*
|
||||
* NMODIFIED means that there might be dirty/stale buffers
|
||||
* associated with the NFS vnode. None of the other flags are
|
||||
* meaningful after the vnode is unused.
|
||||
* associated with the NFS vnode.
|
||||
* NDSCOMMIT means that the file is on a pNFS server and commits
|
||||
* should be done to the DS.
|
||||
* None of the other flags are meaningful after the vnode is unused.
|
||||
*/
|
||||
np->n_flag &= NMODIFIED;
|
||||
np->n_flag &= (NMODIFIED | NDSCOMMIT);
|
||||
mtx_unlock(&np->n_mtx);
|
||||
return (0);
|
||||
}
|
||||
|
@ -114,7 +114,8 @@ static int nfsrpc_fillsa(struct nfsmount *, struct sockaddr_storage *,
|
||||
static void nfscl_initsessionslots(struct nfsclsession *);
|
||||
static int nfscl_doflayoutio(vnode_t, struct uio *, int *, int *, int *,
|
||||
nfsv4stateid_t *, int, struct nfscldevinfo *, struct nfscllayout *,
|
||||
struct nfsclflayout *, uint64_t, uint64_t, struct ucred *, NFSPROC_T *);
|
||||
struct nfsclflayout *, uint64_t, uint64_t, int, struct ucred *,
|
||||
NFSPROC_T *);
|
||||
static int nfsrpc_readds(vnode_t, struct uio *, nfsv4stateid_t *, int *,
|
||||
struct nfsclds *, uint64_t, int, struct nfsfh *, struct ucred *,
|
||||
NFSPROC_T *);
|
||||
@ -123,10 +124,8 @@ static int nfsrpc_writeds(vnode_t, struct uio *, int *, int *,
|
||||
struct nfsfh *, int, struct ucred *, NFSPROC_T *);
|
||||
static enum nfsclds_state nfscl_getsameserver(struct nfsmount *,
|
||||
struct nfsclds *, struct nfsclds **);
|
||||
#ifdef notyet
|
||||
static int nfsrpc_commitds(vnode_t, uint64_t, int, struct nfsclds *,
|
||||
struct nfsfh *, struct ucred *, NFSPROC_T *, void *);
|
||||
#endif
|
||||
struct nfsfh *, struct ucred *, NFSPROC_T *);
|
||||
static void nfsrv_setuplayoutget(struct nfsrv_descript *, int, uint64_t,
|
||||
uint64_t, uint64_t, nfsv4stateid_t *, int, int);
|
||||
static int nfsrv_parselayoutget(struct nfsrv_descript *, nfsv4stateid_t *,
|
||||
@ -5439,7 +5438,7 @@ nfscl_initsessionslots(struct nfsclsession *sep)
|
||||
*/
|
||||
int
|
||||
nfscl_doiods(vnode_t vp, struct uio *uiop, int *iomode, int *must_commit,
|
||||
uint32_t rwaccess, struct ucred *cred, NFSPROC_T *p)
|
||||
uint32_t rwaccess, int docommit, struct ucred *cred, NFSPROC_T *p)
|
||||
{
|
||||
struct nfsnode *np = VTONFS(vp);
|
||||
struct nfsmount *nmp = VFSTONFS(vnode_mount(vp));
|
||||
@ -5523,7 +5522,8 @@ nfscl_doiods(vnode_t vp, struct uio *uiop, int *iomode, int *must_commit,
|
||||
if (dip != NULL) {
|
||||
error = nfscl_doflayoutio(vp, uiop, iomode,
|
||||
must_commit, &eof, &stateid, rwaccess, dip,
|
||||
layp, rflp, off, xfer, newcred, p);
|
||||
layp, rflp, off, xfer, docommit, newcred,
|
||||
p);
|
||||
nfscl_reldevinfo(dip);
|
||||
lastbyte = off + xfer - 1;
|
||||
if (error == 0) {
|
||||
@ -5599,10 +5599,10 @@ static int
|
||||
nfscl_doflayoutio(vnode_t vp, struct uio *uiop, int *iomode, int *must_commit,
|
||||
int *eofp, nfsv4stateid_t *stateidp, int rwflag, struct nfscldevinfo *dp,
|
||||
struct nfscllayout *lyp, struct nfsclflayout *flp, uint64_t off,
|
||||
uint64_t len, struct ucred *cred, NFSPROC_T *p)
|
||||
uint64_t len, int docommit, struct ucred *cred, NFSPROC_T *p)
|
||||
{
|
||||
uint64_t io_off, rel_off, stripe_unit_size, transfer, xfer;
|
||||
int commit_thru_mds, error = 0, stripe_index, stripe_pos;
|
||||
int commit_thru_mds, error, stripe_index, stripe_pos;
|
||||
struct nfsnode *np;
|
||||
struct nfsfh *fhp;
|
||||
struct nfsclds **dspp;
|
||||
@ -5613,12 +5613,13 @@ nfscl_doflayoutio(vnode_t vp, struct uio *uiop, int *iomode, int *must_commit,
|
||||
stripe_pos = (rel_off / stripe_unit_size + flp->nfsfl_stripe1) %
|
||||
dp->nfsdi_stripecnt;
|
||||
transfer = stripe_unit_size - (rel_off % stripe_unit_size);
|
||||
error = 0;
|
||||
|
||||
/* Loop around, doing I/O for each stripe unit. */
|
||||
while (len > 0 && error == 0) {
|
||||
stripe_index = nfsfldi_stripeindex(dp, stripe_pos);
|
||||
dspp = nfsfldi_addr(dp, stripe_index);
|
||||
if (len > transfer)
|
||||
if (len > transfer && docommit == 0)
|
||||
xfer = transfer;
|
||||
else
|
||||
xfer = len;
|
||||
@ -5642,11 +5643,33 @@ nfscl_doflayoutio(vnode_t vp, struct uio *uiop, int *iomode, int *must_commit,
|
||||
fhp = np->n_fhp;
|
||||
io_off = off;
|
||||
}
|
||||
if ((flp->nfsfl_util & NFSFLAYUTIL_COMMIT_THRU_MDS) != 0)
|
||||
if ((flp->nfsfl_util & NFSFLAYUTIL_COMMIT_THRU_MDS) != 0) {
|
||||
commit_thru_mds = 1;
|
||||
else
|
||||
if (docommit != 0)
|
||||
error = EIO;
|
||||
} else {
|
||||
commit_thru_mds = 0;
|
||||
if (rwflag == FREAD)
|
||||
mtx_lock(&np->n_mtx);
|
||||
np->n_flag |= NDSCOMMIT;
|
||||
mtx_unlock(&np->n_mtx);
|
||||
}
|
||||
if (docommit != 0) {
|
||||
if (error == 0)
|
||||
error = nfsrpc_commitds(vp, io_off, xfer,
|
||||
*dspp, fhp, cred, p);
|
||||
if (error == 0) {
|
||||
/*
|
||||
* Set both eof and uio_resid = 0 to end any
|
||||
* loops.
|
||||
*/
|
||||
*eofp = 1;
|
||||
uiop->uio_resid = 0;
|
||||
} else {
|
||||
mtx_lock(&np->n_mtx);
|
||||
np->n_flag &= ~NDSCOMMIT;
|
||||
mtx_unlock(&np->n_mtx);
|
||||
}
|
||||
} else if (rwflag == FREAD)
|
||||
error = nfsrpc_readds(vp, uiop, stateidp, eofp, *dspp,
|
||||
io_off, xfer, fhp, cred, p);
|
||||
else {
|
||||
@ -5882,13 +5905,12 @@ nfscl_getsameserver(struct nfsmount *nmp, struct nfsclds *newdsp,
|
||||
return (NFSDSP_NOTFOUND);
|
||||
}
|
||||
|
||||
#ifdef notyet
|
||||
/*
|
||||
* NFS commit rpc to a DS.
|
||||
* NFS commit rpc to a NFSv4.1 DS.
|
||||
*/
|
||||
static int
|
||||
nfsrpc_commitds(vnode_t vp, uint64_t offset, int cnt, struct nfsclds *dsp,
|
||||
struct nfsfh *fhp, struct ucred *cred, NFSPROC_T *p, void *stuff)
|
||||
struct nfsfh *fhp, struct ucred *cred, NFSPROC_T *p)
|
||||
{
|
||||
uint32_t *tl;
|
||||
struct nfsrv_descript nfsd, *nd = &nfsd;
|
||||
@ -5896,6 +5918,7 @@ nfsrpc_commitds(vnode_t vp, uint64_t offset, int cnt, struct nfsclds *dsp,
|
||||
struct nfssockreq *nrp;
|
||||
int error;
|
||||
|
||||
nd->nd_mrep = NULL;
|
||||
nfscl_reqstart(nd, NFSPROC_COMMITDS, nmp, fhp->nfh_fh, fhp->nfh_len,
|
||||
NULL, &dsp->nfsclds_sess);
|
||||
NFSM_BUILD(tl, uint32_t *, NFSX_HYPER + NFSX_UNSIGNED);
|
||||
@ -5908,7 +5931,7 @@ nfsrpc_commitds(vnode_t vp, uint64_t offset, int cnt, struct nfsclds *dsp,
|
||||
nrp = &nmp->nm_sockreq;
|
||||
error = newnfs_request(nd, nmp, NULL, nrp, vp, p, cred,
|
||||
NFS_PROG, NFS_VER4, NULL, 1, NULL, &dsp->nfsclds_sess);
|
||||
if (error)
|
||||
if (error != 0)
|
||||
return (error);
|
||||
if (nd->nd_repstat == 0) {
|
||||
NFSM_DISSECT(tl, u_int32_t *, NFSX_VERF);
|
||||
@ -5925,7 +5948,6 @@ nfsrpc_commitds(vnode_t vp, uint64_t offset, int cnt, struct nfsclds *dsp,
|
||||
mbuf_freem(nd->nd_mrep);
|
||||
return (error);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set up the XDR arguments for the LayoutGet operation.
|
||||
|
@ -1367,7 +1367,7 @@ ncl_readrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred)
|
||||
attrflag = 0;
|
||||
if (NFSHASPNFS(nmp))
|
||||
error = nfscl_doiods(vp, uiop, NULL, NULL,
|
||||
NFSV4OPEN_ACCESSREAD, cred, uiop->uio_td);
|
||||
NFSV4OPEN_ACCESSREAD, 0, cred, uiop->uio_td);
|
||||
NFSCL_DEBUG(4, "readrpc: aft doiods=%d\n", error);
|
||||
if (error != 0)
|
||||
error = nfsrpc_read(vp, uiop, cred, uiop->uio_td, &nfsva,
|
||||
@ -1398,7 +1398,7 @@ ncl_writerpc(struct vnode *vp, struct uio *uiop, struct ucred *cred,
|
||||
attrflag = 0;
|
||||
if (NFSHASPNFS(nmp))
|
||||
error = nfscl_doiods(vp, uiop, iomode, must_commit,
|
||||
NFSV4OPEN_ACCESSWRITE, cred, uiop->uio_td);
|
||||
NFSV4OPEN_ACCESSWRITE, 0, cred, uiop->uio_td);
|
||||
NFSCL_DEBUG(4, "writerpc: aft doiods=%d\n", error);
|
||||
if (error != 0)
|
||||
error = nfsrpc_write(vp, uiop, iomode, must_commit, cred,
|
||||
@ -2555,16 +2555,34 @@ ncl_commit(struct vnode *vp, u_quad_t offset, int cnt, struct ucred *cred,
|
||||
{
|
||||
struct nfsvattr nfsva;
|
||||
struct nfsmount *nmp = VFSTONFS(vp->v_mount);
|
||||
struct nfsnode *np;
|
||||
struct uio uio;
|
||||
int error, attrflag;
|
||||
|
||||
mtx_lock(&nmp->nm_mtx);
|
||||
if ((nmp->nm_state & NFSSTA_HASWRITEVERF) == 0) {
|
||||
mtx_unlock(&nmp->nm_mtx);
|
||||
return (0);
|
||||
np = VTONFS(vp);
|
||||
error = EIO;
|
||||
attrflag = 0;
|
||||
if (NFSHASPNFS(nmp) && (np->n_flag & NDSCOMMIT) != 0) {
|
||||
uio.uio_offset = offset;
|
||||
uio.uio_resid = cnt;
|
||||
error = nfscl_doiods(vp, &uio, NULL, NULL,
|
||||
NFSV4OPEN_ACCESSWRITE, 1, cred, td);
|
||||
if (error != 0) {
|
||||
mtx_lock(&np->n_mtx);
|
||||
np->n_flag &= ~NDSCOMMIT;
|
||||
mtx_unlock(&np->n_mtx);
|
||||
}
|
||||
}
|
||||
if (error != 0) {
|
||||
mtx_lock(&nmp->nm_mtx);
|
||||
if ((nmp->nm_state & NFSSTA_HASWRITEVERF) == 0) {
|
||||
mtx_unlock(&nmp->nm_mtx);
|
||||
return (0);
|
||||
}
|
||||
mtx_unlock(&nmp->nm_mtx);
|
||||
error = nfsrpc_commit(vp, offset, cnt, cred, td, &nfsva,
|
||||
&attrflag, NULL);
|
||||
}
|
||||
mtx_unlock(&nmp->nm_mtx);
|
||||
error = nfsrpc_commit(vp, offset, cnt, cred, td, &nfsva,
|
||||
&attrflag, NULL);
|
||||
if (attrflag != 0)
|
||||
(void) nfscl_loadattrcache(&vp, &nfsva, NULL, NULL,
|
||||
0, 1);
|
||||
|
@ -158,6 +158,7 @@ struct nfsnode {
|
||||
#define NNOLAYOUT 0x00020000 /* Can't get a layout for this file */
|
||||
#define NWRITEOPENED 0x00040000 /* Has been opened for writing */
|
||||
#define NHASBEENLOCKED 0x00080000 /* Has been file locked. */
|
||||
#define NDSCOMMIT 0x00100000 /* Commit is done via the DS. */
|
||||
|
||||
/*
|
||||
* Convert between nfsnode pointers and vnode pointers
|
||||
|
Loading…
Reference in New Issue
Block a user