diff options
author | Rick Macklem <rmacklem@FreeBSD.org> | 2020-07-31 23:35:49 +0000 |
---|---|---|
committer | Rick Macklem <rmacklem@FreeBSD.org> | 2020-07-31 23:35:49 +0000 |
commit | cb889ce631b9d37bf0fe82290616bf4e4596d47f (patch) | |
tree | b7b4210bf7dd8b06322062c12787df5f239f0ebf /sys/fs/nfsserver/nfs_nfsdserv.c | |
parent | 0eed04c802f4a50c9409a6682a474852bebee990 (diff) | |
download | src-cb889ce631b9d37bf0fe82290616bf4e4596d47f.tar.gz src-cb889ce631b9d37bf0fe82290616bf4e4596d47f.zip |
Add optional support for ext_pgs mbufs to the NFS server's read, readlink
and getxattr operations.
This patch optionally enables generation of read, readlink and getxattr replies
in ext_pgs mbufs. Since neither of ND_EXTPG or ND_TLS are currently ever set,
there is no change in semantics at this time.
It also corrects the message in a couple of panic()s that should never occur.
This is another in the series of commits that add support to the NFS client
and server for building RPC messages in ext_pgs mbufs with anonymous pages.
This is useful so that the entire mbuf list does not need to be
copied before calling sosend() when NFS over TLS is enabled.
Use of ext_pgs mbufs will not be enabled until the kernel RPC is updated
to handle TLS.
Notes
Notes:
svn path=/head/; revision=363748
Diffstat (limited to 'sys/fs/nfsserver/nfs_nfsdserv.c')
-rw-r--r-- | sys/fs/nfsserver/nfs_nfsdserv.c | 73 |
1 files changed, 63 insertions, 10 deletions
diff --git a/sys/fs/nfsserver/nfs_nfsdserv.c b/sys/fs/nfsserver/nfs_nfsdserv.c index 1b34cb27dd01..d2fe9e60a0ea 100644 --- a/sys/fs/nfsserver/nfs_nfsdserv.c +++ b/sys/fs/nfsserver/nfs_nfsdserv.c @@ -667,6 +667,7 @@ nfsrvd_readlink(struct nfsrv_descript *nd, __unused int isdgram, int getret = 1, len; struct nfsvattr nva; struct thread *p = curthread; + uint16_t off; if (nd->nd_repstat) { nfsrv_postopattr(nd, getret, &nva); @@ -678,9 +679,14 @@ nfsrvd_readlink(struct nfsrv_descript *nd, __unused int isdgram, else nd->nd_repstat = EINVAL; } - if (!nd->nd_repstat) - nd->nd_repstat = nfsvno_readlink(vp, nd->nd_cred, p, - &mp, &mpend, &len); + if (nd->nd_repstat == 0) { + if ((nd->nd_flag & ND_EXTPG) != 0) + nd->nd_repstat = nfsvno_readlink(vp, nd->nd_cred, + nd->nd_maxextsiz, p, &mp, &mpend, &len); + else + nd->nd_repstat = nfsvno_readlink(vp, nd->nd_cred, + 0, p, &mp, &mpend, &len); + } if (nd->nd_flag & ND_NFSV3) getret = nfsvno_getattr(vp, &nva, nd, p, 1, NULL); vput(vp); @@ -693,7 +699,16 @@ nfsrvd_readlink(struct nfsrv_descript *nd, __unused int isdgram, if (mp != NULL) { nd->nd_mb->m_next = mp; nd->nd_mb = mpend; - nd->nd_bpos = mtod(mpend, caddr_t) + mpend->m_len; + if ((mpend->m_flags & M_EXTPG) != 0) { + nd->nd_bextpg = mpend->m_epg_npgs - 1; + nd->nd_bpos = (char *)(void *) + PHYS_TO_DMAP(mpend->m_epg_pa[nd->nd_bextpg]); + off = (nd->nd_bextpg == 0) ? mpend->m_epg_1st_off : 0; + nd->nd_bpos += off + mpend->m_epg_last_len; + nd->nd_bextpgsiz = PAGE_SIZE - mpend->m_epg_last_len - + off; + } else + nd->nd_bpos = mtod(mpend, char *) + mpend->m_len; } out: @@ -718,6 +733,7 @@ nfsrvd_read(struct nfsrv_descript *nd, __unused int isdgram, nfsv4stateid_t stateid; nfsquad_t clientid; struct thread *p = curthread; + uint16_t poff; if (nd->nd_repstat) { nfsrv_postopattr(nd, getret, &nva); @@ -839,8 +855,21 @@ nfsrvd_read(struct nfsrv_descript *nd, __unused int isdgram, cnt = reqlen; m3 = NULL; if (cnt > 0) { - nd->nd_repstat = nfsvno_read(vp, off, cnt, nd->nd_cred, p, - &m3, &m2); + /* + * If cnt > MCLBYTES and the reply will not be saved, use + * ext_pgs mbufs for TLS. + * For NFSv4.0, we do not know for sure if the reply will + * be saved, so do not use ext_pgs mbufs for NFSv4.0. + * Always use ext_pgs mbufs if ND_EXTPG is set. + */ + if ((nd->nd_flag & ND_EXTPG) != 0 || (cnt > MCLBYTES && + (nd->nd_flag & (ND_TLS | ND_SAVEREPLY)) == ND_TLS && + (nd->nd_flag & (ND_NFSV4 | ND_NFSV41)) != ND_NFSV4)) + nd->nd_repstat = nfsvno_read(vp, off, cnt, nd->nd_cred, + nd->nd_maxextsiz, p, &m3, &m2); + else + nd->nd_repstat = nfsvno_read(vp, off, cnt, nd->nd_cred, + 0, p, &m3, &m2); if (!(nd->nd_flag & ND_NFSV4)) { getret = nfsvno_getattr(vp, &nva, nd, p, 1, NULL); if (!nd->nd_repstat) @@ -875,7 +904,17 @@ nfsrvd_read(struct nfsrv_descript *nd, __unused int isdgram, if (m3) { nd->nd_mb->m_next = m3; nd->nd_mb = m2; - nd->nd_bpos = mtod(m2, caddr_t) + m2->m_len; + if ((m2->m_flags & M_EXTPG) != 0) { + nd->nd_flag |= ND_EXTPG; + nd->nd_bextpg = m2->m_epg_npgs - 1; + nd->nd_bpos = (char *)(void *) + PHYS_TO_DMAP(m2->m_epg_pa[nd->nd_bextpg]); + poff = (nd->nd_bextpg == 0) ? m2->m_epg_1st_off : 0; + nd->nd_bpos += poff + m2->m_epg_last_len; + nd->nd_bextpgsiz = PAGE_SIZE - m2->m_epg_last_len - + poff; + } else + nd->nd_bpos = mtod(m2, char *) + m2->m_len; } out: @@ -5536,6 +5575,7 @@ nfsrvd_getxattr(struct nfsrv_descript *nd, __unused int isdgram, int error, len; char *name; struct thread *p = curthread; + uint16_t off; error = 0; if (nfs_rootfhset == 0 || nfsd_checkrootexp(nd) != 0) { @@ -5555,8 +5595,9 @@ nfsrvd_getxattr(struct nfsrv_descript *nd, __unused int isdgram, name = malloc(len + 1, M_TEMP, M_WAITOK); nd->nd_repstat = nfsrv_mtostr(nd, name, len); if (nd->nd_repstat == 0) - nd->nd_repstat = nfsvno_getxattr(vp, name, nd->nd_maxresp, - nd->nd_cred, p, &mp, &mpend, &len); + nd->nd_repstat = nfsvno_getxattr(vp, name, + nd->nd_maxresp, nd->nd_cred, nd->nd_flag, + nd->nd_maxextsiz, p, &mp, &mpend, &len); if (nd->nd_repstat == ENOATTR) nd->nd_repstat = NFSERR_NOXATTR; else if (nd->nd_repstat == EOPNOTSUPP) @@ -5567,7 +5608,19 @@ nfsrvd_getxattr(struct nfsrv_descript *nd, __unused int isdgram, if (len > 0) { nd->nd_mb->m_next = mp; nd->nd_mb = mpend; - nd->nd_bpos = mtod(mpend, caddr_t) + mpend->m_len; + if ((mpend->m_flags & M_EXTPG) != 0) { + nd->nd_flag |= ND_EXTPG; + nd->nd_bextpg = mpend->m_epg_npgs - 1; + nd->nd_bpos = (char *)(void *) + PHYS_TO_DMAP(mpend->m_epg_pa[nd->nd_bextpg]); + off = (nd->nd_bextpg == 0) ? + mpend->m_epg_1st_off : 0; + nd->nd_bpos += off + mpend->m_epg_last_len; + nd->nd_bextpgsiz = PAGE_SIZE - + mpend->m_epg_last_len - off; + } else + nd->nd_bpos = mtod(mpend, char *) + + mpend->m_len; } } free(name, M_TEMP); |