aboutsummaryrefslogtreecommitdiff
path: root/sys/fs/nfsserver/nfs_nfsdserv.c
diff options
context:
space:
mode:
authorRick Macklem <rmacklem@FreeBSD.org>2020-07-31 23:35:49 +0000
committerRick Macklem <rmacklem@FreeBSD.org>2020-07-31 23:35:49 +0000
commitcb889ce631b9d37bf0fe82290616bf4e4596d47f (patch)
treeb7b4210bf7dd8b06322062c12787df5f239f0ebf /sys/fs/nfsserver/nfs_nfsdserv.c
parent0eed04c802f4a50c9409a6682a474852bebee990 (diff)
downloadsrc-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.c73
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);