Date: Sun, 24 May 2009 19:46:12 +0000 (UTC) From: Rick Macklem <rmacklem@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r192695 - head/sys/fs/nfs Message-ID: <200905241946.n4OJkCnR099413@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: rmacklem Date: Sun May 24 19:46:12 2009 New Revision: 192695 URL: http://svn.freebsd.org/changeset/base/192695 Log: 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) Modified: head/sys/fs/nfs/nfs_commonkrpc.c head/sys/fs/nfs/nfs_commonport.c Modified: head/sys/fs/nfs/nfs_commonkrpc.c ============================================================================== --- head/sys/fs/nfs/nfs_commonkrpc.c Sun May 24 19:21:49 2009 (r192694) +++ head/sys/fs/nfs/nfs_commonkrpc.c Sun May 24 19:46:12 2009 (r192695) @@ -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; Modified: head/sys/fs/nfs/nfs_commonport.c ============================================================================== --- head/sys/fs/nfs/nfs_commonport.c Sun May 24 19:21:49 2009 (r192694) +++ head/sys/fs/nfs/nfs_commonport.c Sun May 24 19:46:12 2009 (r192695) @@ -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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200905241946.n4OJkCnR099413>