summaryrefslogtreecommitdiffstats
path: root/sys/fs/nfs
diff options
context:
space:
mode:
authorrmacklem <rmacklem@FreeBSD.org>2009-05-24 19:46:12 +0000
committerrmacklem <rmacklem@FreeBSD.org>2009-05-24 19:46:12 +0000
commit60701108210c5e00058fafcdae7619c72a6f01e0 (patch)
tree26bd4f3c7cc6d7160e718135947b63cb108ddc5e /sys/fs/nfs
parent65e538f91c24b2aa809442ae16fcbabef86e8f16 (diff)
downloadFreeBSD-src-60701108210c5e00058fafcdae7619c72a6f01e0.zip
FreeBSD-src-60701108210c5e00058fafcdae7619c72a6f01e0.tar.gz
Crib the realign function out of nfs_krpc.c and add a call
to it for the client side reply. Hopefully this fixes the problem with using the new krpc for arm for the experimental nfs client. Approved by: kib (mentor)
Diffstat (limited to 'sys/fs/nfs')
-rw-r--r--sys/fs/nfs/nfs_commonkrpc.c7
-rw-r--r--sys/fs/nfs/nfs_commonport.c59
2 files changed, 40 insertions, 26 deletions
diff --git a/sys/fs/nfs/nfs_commonkrpc.c b/sys/fs/nfs/nfs_commonkrpc.c
index d487703..1f0cb55 100644
--- a/sys/fs/nfs/nfs_commonkrpc.c
+++ b/sys/fs/nfs/nfs_commonkrpc.c
@@ -603,6 +603,13 @@ tryagain:
KASSERT(nd->nd_mrep != NULL, ("mrep shouldn't be NULL if no error\n"));
+ /*
+ * Search for any mbufs that are not a multiple of 4 bytes long
+ * or with m_data not longword aligned.
+ * These could cause pointer alignment problems, so copy them to
+ * well aligned mbufs.
+ */
+ newnfs_realign(&nd->nd_mrep);
nd->nd_md = nd->nd_mrep;
nd->nd_dpos = NFSMTOD(nd->nd_md, caddr_t);
nd->nd_repstat = 0;
diff --git a/sys/fs/nfs/nfs_commonport.c b/sys/fs/nfs/nfs_commonport.c
index 1c22657..4c17aee 100644
--- a/sys/fs/nfs/nfs_commonport.c
+++ b/sys/fs/nfs/nfs_commonport.c
@@ -70,8 +70,8 @@ static int nfs_realign_test;
static int nfs_realign_count;
SYSCTL_NODE(_vfs, OID_AUTO, newnfs, CTLFLAG_RW, 0, "New NFS filesystem");
-SYSCTL_INT(_vfs_newnfs, OID_AUTO, realign_test, CTLFLAG_RW, &nfs_realign_test, 0, "");
-SYSCTL_INT(_vfs_newnfs, OID_AUTO, realign_count, CTLFLAG_RW, &nfs_realign_count, 0, "");
+SYSCTL_INT(_vfs_newnfs, OID_AUTO, newnfs_realign_test, CTLFLAG_RW, &nfs_realign_test, 0, "");
+SYSCTL_INT(_vfs_newnfs, OID_AUTO, newnfs_realign_count, CTLFLAG_RW, &nfs_realign_count, 0, "");
SYSCTL_INT(_vfs_newnfs, OID_AUTO, nfs4acl_enable, CTLFLAG_RW, &nfsrv_useacl, 0, "");
SYSCTL_STRING(_vfs_newnfs, OID_AUTO, callback_addr, CTLFLAG_RW,
nfsv4_callbackaddr, sizeof(nfsv4_callbackaddr), "");
@@ -129,7 +129,7 @@ newnfs_realign(struct mbuf **pm)
}
#else
/*
- * nfs_realign:
+ * newnfs_realign:
*
* Check for badly aligned mbuf data and realign by copying the unaligned
* portion of the data into a new mbuf chain and freeing the portions
@@ -142,43 +142,50 @@ newnfs_realign(struct mbuf **pm)
* We would prefer to avoid this situation entirely. The situation does
* not occur with NFS/UDP and is supposed to only occassionally occur
* with TCP. Use vfs.nfs.realign_count and realign_test to check this.
+ *
*/
void
newnfs_realign(struct mbuf **pm)
{
- struct mbuf *m;
- struct mbuf *n = NULL;
- int off = 0;
+ struct mbuf *m, *n;
+ int off, space;
++nfs_realign_test;
while ((m = *pm) != NULL) {
if ((m->m_len & 0x3) || (mtod(m, intptr_t) & 0x3)) {
- MGET(n, M_WAIT, MT_DATA);
- if (m->m_len >= MINCLSIZE) {
- MCLGET(n, M_WAIT);
- }
+ /*
+ * NB: we can't depend on m_pkthdr.len to help us
+ * decide what to do here. May not be worth doing
+ * the m_length calculation as m_copyback will
+ * expand the mbuf chain below as needed.
+ */
+ space = m_length(m, NULL);
+ if (space >= MINCLSIZE) {
+ /* NB: m_copyback handles space > MCLBYTES */
+ n = m_getcl(M_WAITOK, MT_DATA, 0);
+ } else
+ n = m_get(M_WAITOK, MT_DATA);
+ if (n == NULL)
+ return;
+ /*
+ * Align the remainder of the mbuf chain.
+ */
n->m_len = 0;
+ off = 0;
+ while (m != NULL) {
+ m_copyback(n, off, m->m_len, mtod(m, caddr_t));
+ off += m->m_len;
+ m = m->m_next;
+ }
+ m_freem(*pm);
+ *pm = n;
+ ++nfs_realign_count;
break;
}
pm = &m->m_next;
}
-
- /*
- * If n is non-NULL, loop on m copying data, then replace the
- * portion of the chain that had to be realigned.
- */
- if (n != NULL) {
- ++nfs_realign_count;
- while (m) {
- m_copyback(n, off, m->m_len, mtod(m, caddr_t));
- off += m->m_len;
- m = m->m_next;
- }
- m_freem(*pm);
- *pm = n;
- }
}
-#endif /* newnfs_realign */
+#endif /* !__i386__ */
#ifdef notdef
static void
OpenPOWER on IntegriCloud