11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
27 /* All Rights Reserved */
28
29 /*
30 * Copyright (c) 2013 by Delphix. All rights reserved.
31 */
32
33 #include <sys/param.h>
34 #include <sys/types.h>
35 #include <sys/systm.h>
36 #include <sys/user.h>
37 #include <sys/vnode.h>
38 #include <sys/file.h>
39 #include <sys/dirent.h>
40 #include <sys/vfs.h>
41 #include <sys/stream.h>
42 #include <sys/strsubr.h>
43 #include <sys/debug.h>
44 #include <sys/t_lock.h>
45 #include <sys/cmn_err.h>
46 #include <sys/dnlc.h>
47 #include <sys/cred.h>
48 #include <sys/time.h>
49 #include <sys/sdt.h>
50
1993 if ((xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) &&
1994 xdrs->x_op == XDR_ENCODE) {
1995 rci.rci_type = RCI_REPLY_CHUNK;
1996 rci.rci_len = objp->count;
1997 XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
1998 }
1999
2000 if (!xdr_u_longlong_t(xdrs, &objp->cookie))
2001 return (FALSE);
2002 /*
2003 * cookieverf is really an opaque 8 byte
2004 * quantity, but we will treat it as a
2005 * hyper for efficiency, the cost of
2006 * a byteswap here saves bcopys elsewhere
2007 */
2008 if (!xdr_u_longlong_t(xdrs, &objp->cookieverf))
2009 return (FALSE);
2010 return (xdr_u_int(xdrs, &objp->count));
2011 }
2012
2013 #ifdef nextdp
2014 #undef nextdp
2015 #endif
2016 #define nextdp(dp) ((struct dirent64 *)((char *)(dp) + (dp)->d_reclen))
2017 #ifdef roundup
2018 #undef roundup
2019 #endif
2020 #define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
2021
2022 /*
2023 * ENCODE ONLY
2024 */
2025 static bool_t
2026 xdr_putdirlist(XDR *xdrs, READDIR3resok *objp)
2027 {
2028 struct dirent64 *dp;
2029 char *name;
2030 int size;
2031 int bufsize;
2032 uint_t namlen;
2033 bool_t true = TRUE;
2034 bool_t false = FALSE;
2035 int entrysz;
2036 int tofit;
2037 fileid3 fileid;
2038 cookie3 cookie;
2039
2040 if (xdrs->x_op != XDR_ENCODE)
2041 return (FALSE);
2042
2043 /*
2044 * bufsize is used to keep track of the size of the response.
2045 * It is primed with:
2046 * 1 for the status +
2047 * 1 for the dir_attributes.attributes boolean +
2048 * 2 for the cookie verifier
2049 * all times BYTES_PER_XDR_UNIT to convert from XDR units
2050 * to bytes. If there are directory attributes to be
2051 * returned, then:
2052 * NFS3_SIZEOF_FATTR3 for the dir_attributes.attr fattr3
2053 * time BYTES_PER_XDR_UNIT is added to account for them.
2054 */
2055 bufsize = (1 + 1 + 2) * BYTES_PER_XDR_UNIT;
2056 if (objp->dir_attributes.attributes)
2057 bufsize += NFS3_SIZEOF_FATTR3 * BYTES_PER_XDR_UNIT;
2058 for (size = objp->size, dp = (struct dirent64 *)objp->reply.entries;
2059 size > 0;
2060 size -= dp->d_reclen, dp = nextdp(dp)) {
2061 if (dp->d_reclen == 0)
2062 return (FALSE);
2063 if (dp->d_ino == 0)
2064 continue;
2065 name = dp->d_name;
2066 namlen = (uint_t)strlen(dp->d_name);
2067 /*
2068 * An entry is composed of:
2069 * 1 for the true/false list indicator +
2070 * 2 for the fileid +
2071 * 1 for the length of the name +
2072 * 2 for the cookie +
2073 * all times BYTES_PER_XDR_UNIT to convert from
2074 * XDR units to bytes, plus the length of the name
2075 * rounded up to the nearest BYTES_PER_XDR_UNIT.
2076 */
2077 entrysz = (1 + 2 + 1 + 2) * BYTES_PER_XDR_UNIT +
2078 roundup(namlen, BYTES_PER_XDR_UNIT);
2079 /*
2080 * We need to check to see if the number of bytes left
2081 * to go into the buffer will actually fit into the
2082 * buffer. This is calculated as the size of this
2083 * entry plus:
2084 * 1 for the true/false list indicator +
2085 * 1 for the eof indicator
2086 * times BYTES_PER_XDR_UNIT to convert from from
2087 * XDR units to bytes.
2088 */
2089 tofit = entrysz + (1 + 1) * BYTES_PER_XDR_UNIT;
2090 if (bufsize + tofit > objp->count) {
2091 objp->reply.eof = FALSE;
2092 break;
2093 }
2094 fileid = (fileid3)(dp->d_ino);
2095 cookie = (cookie3)(dp->d_off);
2096 if (!xdr_bool(xdrs, &true) ||
2097 !xdr_u_longlong_t(xdrs, &fileid) ||
2098 !xdr_bytes(xdrs, &name, &namlen, ~0) ||
2099 !xdr_u_longlong_t(xdrs, &cookie)) {
2100 return (FALSE);
2101 }
2102 bufsize += entrysz;
2103 }
2104 if (!xdr_bool(xdrs, &false))
2105 return (FALSE);
2106 if (!xdr_bool(xdrs, &objp->reply.eof))
2107 return (FALSE);
2108 return (TRUE);
2109 }
2110
2111 bool_t
2112 xdr_READDIR3res(XDR *xdrs, READDIR3res *objp)
2113 {
2114 READDIR3resok *resokp;
2115
2116 /*
2117 * ENCODE or FREE only
2118 */
2119 if (xdrs->x_op == XDR_DECODE)
2120 return (FALSE);
2121
2122 if (!xdr_enum(xdrs, (enum_t *)&objp->status))
2123 return (FALSE);
2270 return (FALSE);
2271 /*
2272 * cookieverf is really an opaque 8 byte
2273 * quantity, but we will treat it as a
2274 * hyper for efficiency, the cost of
2275 * a byteswap here saves bcopys elsewhere
2276 */
2277 if (!xdr_u_longlong_t(xdrs, &objp->cookieverf))
2278 return (FALSE);
2279 if (!xdr_u_int(xdrs, &objp->dircount))
2280 return (FALSE);
2281 return (xdr_u_int(xdrs, &objp->maxcount));
2282 }
2283
2284 /*
2285 * ENCODE ONLY
2286 */
2287 static bool_t
2288 xdr_putdirpluslist(XDR *xdrs, READDIRPLUS3resok *objp)
2289 {
2290 struct dirent64 *dp;
2291 char *name;
2292 int nents;
2293 bool_t true = TRUE;
2294 bool_t false = FALSE;
2295 fileid3 fileid;
2296 cookie3 cookie;
2297 entryplus3_info *infop;
2298
2299 if (xdrs->x_op != XDR_ENCODE)
2300 return (FALSE);
2301
2302 dp = (struct dirent64 *)objp->reply.entries;
2303 nents = objp->size;
2304 infop = objp->infop;
2305
2306 while (nents > 0) {
2307 if (dp->d_reclen == 0)
2308 return (FALSE);
2309 if (dp->d_ino != 0) {
2310 name = dp->d_name;
2311 fileid = (fileid3)(dp->d_ino);
2312 cookie = (cookie3)(dp->d_off);
2313 if (!xdr_bool(xdrs, &true) ||
2314 !xdr_u_longlong_t(xdrs, &fileid) ||
2315 !xdr_bytes(xdrs, &name, &infop->namelen, ~0) ||
2316 !xdr_u_longlong_t(xdrs, &cookie) ||
2317 !xdr_post_op_attr(xdrs, &infop->attr) ||
2318 !xdr_post_op_fh3(xdrs, &infop->fh)) {
2319 return (FALSE);
2320 }
2321 }
2322 dp = nextdp(dp);
2323 infop++;
2324 nents--;
2325 }
2326
2327 if (!xdr_bool(xdrs, &false))
2328 return (FALSE);
2329 if (!xdr_bool(xdrs, &objp->reply.eof))
2330 return (FALSE);
2331 return (TRUE);
2332 }
2333
2334 bool_t
2335 xdr_READDIRPLUS3res(XDR *xdrs, READDIRPLUS3res *objp)
2336 {
2337 READDIRPLUS3resok *resokp;
2338
2339 /*
2340 * ENCODE or FREE only
2341 */
2342 if (xdrs->x_op == XDR_DECODE)
2343 return (FALSE);
2344
2345 if (!xdr_enum(xdrs, (enum_t *)&objp->status))
|
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
27 /* All Rights Reserved */
28
29 /*
30 * Copyright (c) 2013 by Delphix. All rights reserved.
31 * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
32 */
33
34 #include <sys/param.h>
35 #include <sys/types.h>
36 #include <sys/systm.h>
37 #include <sys/user.h>
38 #include <sys/vnode.h>
39 #include <sys/file.h>
40 #include <sys/dirent.h>
41 #include <sys/vfs.h>
42 #include <sys/stream.h>
43 #include <sys/strsubr.h>
44 #include <sys/debug.h>
45 #include <sys/t_lock.h>
46 #include <sys/cmn_err.h>
47 #include <sys/dnlc.h>
48 #include <sys/cred.h>
49 #include <sys/time.h>
50 #include <sys/sdt.h>
51
1994 if ((xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) &&
1995 xdrs->x_op == XDR_ENCODE) {
1996 rci.rci_type = RCI_REPLY_CHUNK;
1997 rci.rci_len = objp->count;
1998 XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
1999 }
2000
2001 if (!xdr_u_longlong_t(xdrs, &objp->cookie))
2002 return (FALSE);
2003 /*
2004 * cookieverf is really an opaque 8 byte
2005 * quantity, but we will treat it as a
2006 * hyper for efficiency, the cost of
2007 * a byteswap here saves bcopys elsewhere
2008 */
2009 if (!xdr_u_longlong_t(xdrs, &objp->cookieverf))
2010 return (FALSE);
2011 return (xdr_u_int(xdrs, &objp->count));
2012 }
2013
2014 /*
2015 * ENCODE ONLY
2016 */
2017 static bool_t
2018 xdr_putdirlist(XDR *xdrs, READDIR3resok *objp)
2019 {
2020 bool_t true = TRUE;
2021 bool_t false = FALSE;
2022 entry3 *entry;
2023
2024 if (xdrs->x_op != XDR_ENCODE)
2025 return (FALSE);
2026
2027 for (entry = objp->reply.entries; entry != NULL;
2028 entry = entry->nextentry) {
2029 if (!xdr_bool(xdrs, &true) ||
2030 !xdr_u_longlong_t(xdrs, &entry->fileid) ||
2031 !xdr_string(xdrs, &entry->name, MAXPATHLEN) ||
2032 !xdr_u_longlong_t(xdrs, &entry->cookie)) {
2033 return (FALSE);
2034 }
2035 }
2036
2037 if (!xdr_bool(xdrs, &false))
2038 return (FALSE);
2039 if (!xdr_bool(xdrs, &objp->reply.eof))
2040 return (FALSE);
2041 return (TRUE);
2042 }
2043
2044 bool_t
2045 xdr_READDIR3res(XDR *xdrs, READDIR3res *objp)
2046 {
2047 READDIR3resok *resokp;
2048
2049 /*
2050 * ENCODE or FREE only
2051 */
2052 if (xdrs->x_op == XDR_DECODE)
2053 return (FALSE);
2054
2055 if (!xdr_enum(xdrs, (enum_t *)&objp->status))
2056 return (FALSE);
2203 return (FALSE);
2204 /*
2205 * cookieverf is really an opaque 8 byte
2206 * quantity, but we will treat it as a
2207 * hyper for efficiency, the cost of
2208 * a byteswap here saves bcopys elsewhere
2209 */
2210 if (!xdr_u_longlong_t(xdrs, &objp->cookieverf))
2211 return (FALSE);
2212 if (!xdr_u_int(xdrs, &objp->dircount))
2213 return (FALSE);
2214 return (xdr_u_int(xdrs, &objp->maxcount));
2215 }
2216
2217 /*
2218 * ENCODE ONLY
2219 */
2220 static bool_t
2221 xdr_putdirpluslist(XDR *xdrs, READDIRPLUS3resok *objp)
2222 {
2223 bool_t true = TRUE;
2224 bool_t false = FALSE;
2225 entryplus3 *entry;
2226
2227 if (xdrs->x_op != XDR_ENCODE)
2228 return (FALSE);
2229
2230 for (entry = objp->reply.entries; entry != NULL;
2231 entry = entry->nextentry) {
2232 if (!xdr_bool(xdrs, &true) ||
2233 !xdr_u_longlong_t(xdrs, &entry->fileid) ||
2234 !xdr_string(xdrs, &entry->name, MAXPATHLEN) ||
2235 !xdr_u_longlong_t(xdrs, &entry->cookie) ||
2236 !xdr_post_op_attr(xdrs, &entry->name_attributes) ||
2237 !xdr_post_op_fh3(xdrs, &entry->name_handle)) {
2238 return (FALSE);
2239 }
2240 }
2241
2242 if (!xdr_bool(xdrs, &false))
2243 return (FALSE);
2244 if (!xdr_bool(xdrs, &objp->reply.eof))
2245 return (FALSE);
2246 return (TRUE);
2247 }
2248
2249 bool_t
2250 xdr_READDIRPLUS3res(XDR *xdrs, READDIRPLUS3res *objp)
2251 {
2252 READDIRPLUS3resok *resokp;
2253
2254 /*
2255 * ENCODE or FREE only
2256 */
2257 if (xdrs->x_op == XDR_DECODE)
2258 return (FALSE);
2259
2260 if (!xdr_enum(xdrs, (enum_t *)&objp->status))
|