1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 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 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 #ifndef _NFS4_SRV_READDIR_H 26 #define _NFS4_SRV_READDIR_H 27 28 #ifdef __cplusplus 29 extern "C" { 30 #endif 31 32 /* 33 * RFS4_MINLEN_ENTRY4: XDR-encoded size of smallest possible dirent. 34 * This is used to return NFS4ERR_TOOSMALL when clients specify 35 * maxcount that isn't large enough to hold the smallest possible 36 * XDR encoded dirent. 37 * 38 * sizeof cookie (8 bytes) + 39 * sizeof name_len (4 bytes) + 40 * sizeof smallest (padded) name (4 bytes) + 41 * sizeof bitmap4_len (12 bytes) + NOTE: we always encode len=2 bm4 42 * sizeof attrlist4_len (4 bytes) + 43 * sizeof next boolean (4 bytes) 44 * 45 * RFS4_MINLEN_RDDIR4: XDR-encoded size of READDIR op reply containing 46 * the smallest possible entry4 (assumes no attrs requested). 47 * sizeof nfsstat4 (4 bytes) + 48 * sizeof verifier4 (8 bytes) + 49 * sizeof entsecond_to_ry4list bool (4 bytes) + 50 * sizeof entry4 (36 bytes) + 51 * sizeof eof bool (4 bytes) 52 * 53 * RFS4_MINLEN_RDDIR_BUF: minimum length of buffer server will provide to 54 * VOP_READDIR. Its value is the size of the maximum possible dirent 55 * for solaris. The DIRENT64_RECLEN macro returns the size of dirent 56 * required for a given name length. MAXNAMELEN is the maximum 57 * filename length allowed in Solaris. The first two DIRENT64_RECLEN() 58 * macros are to allow for . and .. entries -- just a minor tweak to try 59 * and guarantee that buffer we give to VOP_READDIR will be large enough 60 * to hold ., .., and the largest possible solaris dirent64. 61 */ 62 #define RFS4_MINLEN_ENTRY4 36 63 #define RFS4_MINLEN_RDDIR4 (4 + NFS4_VERIFIER_SIZE + 4 + RFS4_MINLEN_ENTRY4 + 4) 64 #define RFS4_MINLEN_RDDIR_BUF \ 65 (DIRENT64_RECLEN(1) + DIRENT64_RECLEN(2) + DIRENT64_RECLEN(MAXNAMELEN)) 66 67 68 #ifdef nextdp 69 #undef nextdp 70 #endif 71 #define nextdp(dp) ((struct dirent64 *)((char *)(dp) + (dp)->d_reclen)) 72 73 extern verifier4 Readdir4verf; 74 75 extern nfs_ftype4 vt_to_nf4[]; 76 77 /* This is the set of pathconf data for vfs */ 78 typedef struct { 79 uint64_t maxfilesize; 80 uint32_t maxlink; 81 uint32_t maxname; 82 } rfs4_pc_encode_t; 83 84 /* This is the set of statvfs data that is ready for encoding */ 85 typedef struct { 86 uint64_t space_avail; 87 uint64_t space_free; 88 uint64_t space_total; 89 u_longlong_t fa; 90 u_longlong_t ff; 91 u_longlong_t ft; 92 } rfs4_sb_encode_t; 93 94 /* 95 * Macros to handle if we have don't have enough space for the requested 96 * attributes and this is the first entry and the 97 * requested attributes are more than the minimal useful 98 * set, reset the attributes to the minimal set and 99 * retry the encoding. If the client has asked for both 100 * mounted_on_fileid and fileid, prefer mounted_on_fileid. 101 */ 102 #define RFS4_MINIMAL_RD_MASK \ 103 (FATTR4_MOUNTED_ON_FILEID_MASK | \ 104 FATTR4_FILEID_MASK | \ 105 FATTR4_RDATTR_ERROR_MASK) 106 107 extern attrmap4 rfs4_minimal_rd_attrmap; 108 extern attrmap4 rfs4_minimal_rd_fileid_attrmap; 109 extern attrmap4 rfs4_minimal_rd_mntfileid_attrmap; 110 111 #define RFS4_MINRDDIR_ATTRMAP(vers) rfs4_minimal_rd_attrmap 112 #define RFS4_MINRDDIR_FILEID(vers) rfs4_minimal_rd_fileid_attrmap 113 #define RFS4_MINRDDIR_MNTFILEID(vers) rfs4_minimal_rd_mntfileid_attrmap 114 115 #define IXDR_PUT_FATTR4_BITMAP(p, m, aptr, len, v) { \ 116 \ 117 /* save length and start of encoded bitmap bits */ \ 118 (len) = (m).w.w2 ? 3 : 2; \ 119 IXDR_PUT_U_INT32((p), (len)); \ 120 \ 121 (aptr) = (p); \ 122 IXDR_PUT_HYPER((p), (m).d.d0); \ 123 if (len == 3) \ 124 IXDR_PUT_U_INT32((p), (m).w.w2); \ 125 } 126 127 #define IXDR_PUT_BITMAP4(p, m) { \ 128 IXDR_PUT_U_INT32((p), ((m).w.w2 ? 3 : 2)); \ 129 IXDR_PUT_HYPER((p), (m).d.d0); \ 130 if ((m).w.w2) { \ 131 IXDR_PUT_U_INT32((p), (m).w.w2); \ 132 } \ 133 } 134 135 #define IXDR_REWRITE_FATTR4_BITMAP(p, m, len, v) { \ 136 \ 137 /* save length and start of encoded bitmap bits */ \ 138 IXDR_PUT_HYPER((p), (m).d.d0); \ 139 if ((len) == 3) \ 140 IXDR_PUT_U_INT32((p), (m).w.w2); \ 141 } 142 143 /* 144 * minmap is either: rdattr_error | mounted_on_fileid 145 * or: rdattr_error | fileid 146 */ 147 #define MINIMIZE_ATTRMAP(m, minmap) ATTRMAP_MASK(m, minmap) 148 #define IS_MIN_ATTRMAP(m) (! ATTRMAP_TST_CMPL(m, rfs4_minimal_rd_attrmap)) 149 150 extern int rfs4_get_sb_encode(vfs_t *, rfs4_sb_encode_t *); 151 extern int rfs4_get_pc_encode(vnode_t *, rfs4_pc_encode_t *, attrmap4 *, 152 cred_t *); 153 extern int nfs4_readdir_getvp(vnode_t *, char *, vnode_t **, 154 struct exportinfo **, struct svc_req *, struct compound_state *, int); 155 156 #ifdef __cplusplus 157 } 158 #endif 159 160 #endif /* _NFS4_SRV_READDIR_H */ 161