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,10 +25,13 @@
/*
* 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,15 +775,10 @@
}
}
}
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;
@@ -792,25 +790,15 @@
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;
}
- /* 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
@@ -819,13 +807,32 @@
* 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).