X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/blobdiff_plain/6f83ced90ea75526068ff4fbb95caabc32a7a3d8..3bf6fec386b09ee8846e7093b18975148d9da2cc:/sys/vfs/nfs/nfs_socket.c diff --git a/sys/vfs/nfs/nfs_socket.c b/sys/vfs/nfs/nfs_socket.c index 294f627419..c241c3cead 100644 --- a/sys/vfs/nfs/nfs_socket.c +++ b/sys/vfs/nfs/nfs_socket.c @@ -1240,7 +1240,7 @@ nfs_request_try(struct nfsreq *rep) * action possible is for r_mrep to be set (once we enqueue it). */ if (rep->r_flags == 0xdeadc0de) { - print_backtrace(); + print_backtrace(-1); panic("flags nbad\n"); } KKASSERT((rep->r_flags & (R_LOCKED | R_ONREQQ)) == 0); @@ -2153,49 +2153,48 @@ nfs_rcvunlock(struct nfsmount *nmp) } /* - * nfs_realign: + * nfs_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 - * of the old chain that were replaced. + * 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 + * of the old chain that were replaced. * - * We cannot simply realign the data within the existing mbuf chain - * because the underlying buffers may contain other rpc commands and - * we cannot afford to overwrite them. + * We cannot simply realign the data within the existing mbuf chain + * because the underlying buffers may contain other rpc commands and + * we cannot afford to overwrite them. * - * 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. + * 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. + * + * NOTE! MB_DONTWAIT cannot be used here. The mbufs must be acquired + * because the rpc request OR reply cannot be thrown away. TCP NFS + * mounts do not retry their RPCs unless the TCP connection itself + * is dropped so throwing away a RPC will basically cause the NFS + * operation to lockup indefinitely. */ static void nfs_realign(struct mbuf **pm, int hsiz) { struct mbuf *m; struct mbuf *n = NULL; - int off = 0; + /* + * Check for misalignemnt + */ ++nfs_realign_test; - while ((m = *pm) != NULL) { - if ((m->m_len & 0x3) || (mtod(m, intptr_t) & 0x3)) { - n = m_getl(m->m_len, MB_WAIT, MT_DATA, 0, NULL); - n->m_len = 0; + if ((m->m_len & 0x3) || (mtod(m, intptr_t) & 0x3)) 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 misalignment found make a completely new copy. */ - if (n != NULL) { + if (m) { ++nfs_realign_count; - while (m) { - m_copyback(n, off, m->m_len, mtod(m, caddr_t)); - off += m->m_len; - m = m->m_next; - } + n = m_dup_data(m, MB_WAIT); m_freem(*pm); *pm = n; }