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>
@@ -20,10 +20,13 @@
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+/*
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
+ */
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
#include <sys/param.h>
@@ -769,56 +772,28 @@
* ENCODE ONLY
*/
bool_t
xdr_putrddirres(XDR *xdrs, struct nfsrddirres *rd)
{
- struct dirent64 *dp;
- char *name;
- int size;
- uint_t namlen;
bool_t true = TRUE;
bool_t false = FALSE;
- int entrysz;
- int tofit;
- int bufsize;
- uint32_t ino, off;
+ struct nfsentry *entry;
if (xdrs->x_op != XDR_ENCODE)
return (FALSE);
if (!xdr_enum(xdrs, (enum_t *)&rd->rd_status))
return (FALSE);
if (rd->rd_status != NFS_OK)
return (TRUE);
- bufsize = 1 * BYTES_PER_XDR_UNIT;
- for (size = rd->rd_size, dp = rd->rd_entries;
- size > 0;
- size -= dp->d_reclen, dp = nextdp(dp)) {
- if (dp->d_reclen == 0 /* || DIRSIZ(dp) > dp->d_reclen */)
- return (FALSE);
- if (dp->d_ino == 0)
- continue;
- ino = (uint32_t)dp->d_ino; /* for LP64 we clip the bits */
- if (dp->d_ino != (ino64_t)ino) /* and they better be zeros */
- return (FALSE);
- off = (uint32_t)dp->d_off;
- name = dp->d_name;
- namlen = (uint_t)strlen(name);
- entrysz = (1 + 1 + 1 + 1) * BYTES_PER_XDR_UNIT +
- roundup(namlen, BYTES_PER_XDR_UNIT);
- tofit = entrysz + 2 * BYTES_PER_XDR_UNIT;
- if (bufsize + tofit > rd->rd_bufsize) {
- rd->rd_eof = FALSE;
- break;
- }
+ for (entry = rd->rd_entries; entry != NULL; entry = entry->nextentry) {
if (!xdr_bool(xdrs, &true) ||
- !xdr_u_int(xdrs, &ino) ||
- !xdr_bytes(xdrs, &name, &namlen, NFS_MAXNAMLEN) ||
- !xdr_u_int(xdrs, &off)) {
+ !xdr_u_int(xdrs, &entry->fileid) ||
+ !xdr_string(xdrs, &entry->name, NFS_MAXNAMLEN) ||
+ !xdr_u_int(xdrs, &entry->cookie)) {
return (FALSE);
}
- bufsize += entrysz;
}
if (!xdr_bool(xdrs, &false))
return (FALSE);
if (!xdr_bool(xdrs, &rd->rd_eof))
return (FALSE);
@@ -845,11 +820,11 @@
return (FALSE);
if (rd->rd_status != NFS_OK)
return (TRUE);
size = rd->rd_size;
- dp = rd->rd_entries;
+ dp = rd->rd_dirents;
offset = rd->rd_offset;
for (;;) {
if (!xdr_bool(xdrs, &valid))
return (FALSE);
if (!valid)
@@ -875,11 +850,11 @@
dp = nextdp(dp);
}
if (!xdr_bool(xdrs, &rd->rd_eof))
return (FALSE);
bufovflw:
- rd->rd_size = (uint32_t)((char *)dp - (char *)(rd->rd_entries));
+ rd->rd_size = (uint32_t)((char *)dp - (char *)(rd->rd_dirents));
rd->rd_offset = offset;
return (TRUE);
}
/*