Print this page
OS-20 share_nfs(1m) charset handling is unreliable
OS-22 Page fault at nfscmd_dropped_entrysize+0x1e()
OS-23 NFSv2/3/4: READDIR responses are inconsistent when charset conversion fails
OS-24 rfs3_readdir(): Issues related to nfscmd_convdirent()
Reviewed by: Jan Kryl <jan.kryl@nexenta.com>
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>

*** 25,34 **** --- 25,37 ---- /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ + /* + * Copyright 2013 Nexenta Systems, Inc. All rights reserved. + */ #include <sys/param.h> #include <sys/types.h> #include <sys/systm.h> #include <sys/cred.h>
*** 772,786 **** } } } reencode_attrs: - /* encode the BOOLEAN for the existence of the next entry */ - IXDR_PUT_U_INT32(ptr, true); - /* encode the COOKIE for the entry */ - IXDR_PUT_U_HYPER(ptr, dp->d_off); - name = nfscmd_convname(ca, cs->exi, dp->d_name, NFSCMD_CONV_OUTBOUND, MAXPATHLEN + 1); if (name == NULL) { rddir_next_offset = dp->d_off; --- 775,784 ----
*** 792,816 **** rndup = RNDUP(namelen) / BYTES_PER_XDR_UNIT; /* room for LENGTH + string ? */ if ((ptr + (1 + rndup)) > ptr_redzone) { no_space = TRUE; continue; } - /* encode the LENGTH of the name */ - IXDR_PUT_U_INT32(ptr, namelen); - /* encode the RNDUP FILL first */ - ptr[rndup - 1] = 0; - /* encode the NAME of the entry */ - bcopy(name, (char *)ptr, namelen); - /* now bump the ptr after... */ - ptr += rndup; - - if (name != dp->d_name) - kmem_free(name, MAXPATHLEN + 1); - /* * Keep checking on the dircount to see if we have * reached the limit; from the RFC, dircount is to be * the XDR encoded limit of the cookie plus name. * So the count is the name, XDR_UNIT of length for --- 790,804 ---- rndup = RNDUP(namelen) / BYTES_PER_XDR_UNIT; /* room for LENGTH + string ? */ if ((ptr + (1 + rndup)) > ptr_redzone) { no_space = TRUE; + if (name != dp->d_name) + kmem_free(name, MAXPATHLEN + 1); continue; } /* * Keep checking on the dircount to see if we have * reached the limit; from the RFC, dircount is to be * the XDR encoded limit of the cookie plus name. * So the count is the name, XDR_UNIT of length for
*** 819,831 **** --- 807,838 ---- * client's APIs. */ dircount -= DIRENT64_RECLEN(namelen); if (nents != 0 && dircount < 0) { no_space = TRUE; + if (name != dp->d_name) + kmem_free(name, MAXPATHLEN + 1); continue; } + /* encode the BOOLEAN for the existence of the next entry */ + IXDR_PUT_U_INT32(ptr, true); + /* encode the COOKIE for the entry */ + IXDR_PUT_U_HYPER(ptr, dp->d_off); + + /* encode the LENGTH of the name */ + IXDR_PUT_U_INT32(ptr, namelen); + /* encode the RNDUP FILL first */ + ptr[rndup - 1] = 0; + /* encode the NAME of the entry */ + bcopy(name, (char *)ptr, namelen); + /* now bump the ptr after... */ + ptr += rndup; + + if (name != dp->d_name) + kmem_free(name, MAXPATHLEN + 1); + /* * Attributes requested? * Gather up the attribute info and the previous VOP_LOOKUP() * succeeded; if an error occurs on the VOP_GETATTR() then * return just the error (again if it is requested).