| File: | afs/VNOPS/afs_vnop_readdir.c |
| Location: | line 674, column 5 |
| Description: | Value stored to 'len' is never read |
| 1 | /* |
| 2 | * Copyright 2000, International Business Machines Corporation and others. |
| 3 | * All Rights Reserved. |
| 4 | * |
| 5 | * This software has been released under the terms of the IBM Public |
| 6 | * License. For details, see the LICENSE file in the top-level source |
| 7 | * directory or online at http://www.openafs.org/dl/license10.html |
| 8 | */ |
| 9 | |
| 10 | /* |
| 11 | * afs_vnop_readdir.c - afs_readdir and bulk stat |
| 12 | * |
| 13 | * Implements: |
| 14 | * BlobScan |
| 15 | * afs_readdir_move |
| 16 | * afs_bulkstat_send |
| 17 | * afs_readdir/afs_readdir2(HP) |
| 18 | * afs_readdir1 - HP NFS version |
| 19 | * |
| 20 | */ |
| 21 | |
| 22 | #include <afsconfig.h> |
| 23 | #include "afs/param.h" |
| 24 | |
| 25 | |
| 26 | #include "afs/sysincludes.h" /* Standard vendor system headers */ |
| 27 | #include "afsincludes.h" /* Afs-based standard headers */ |
| 28 | #include "afs/afs_stats.h" /* statistics */ |
| 29 | #include "afs/afs_cbqueue.h" |
| 30 | #include "afs/nfsclient.h" |
| 31 | #include "afs/afs_osidnlc.h" |
| 32 | |
| 33 | #if defined(AFS_HPUX1122_ENV) |
| 34 | #define DIRPAD3 7 |
| 35 | #elif defined(AFS_NBSD40_ENV) |
| 36 | #define DIRPAD3 7 |
| 37 | #else |
| 38 | #define DIRPAD3 3 |
| 39 | #endif |
| 40 | |
| 41 | /* |
| 42 | * AFS readdir vnodeop and bulk stat support. |
| 43 | */ |
| 44 | |
| 45 | /* BlobScan is supposed to ensure that the blob reference refers to a valid |
| 46 | directory entry. It consults the allocation map in the page header |
| 47 | to determine whether a blob is actually in use or not. |
| 48 | |
| 49 | More formally, BlobScan is supposed to return a new blob number which is just like |
| 50 | the input parameter, only it is advanced over header or free blobs. |
| 51 | |
| 52 | Note that BlobScan switches pages if necessary. BlobScan may return |
| 53 | either 0 or an out-of-range blob number for end of file. |
| 54 | |
| 55 | BlobScan is used by the Linux port in a separate file, so it should not |
| 56 | become static. |
| 57 | */ |
| 58 | int |
| 59 | BlobScan(struct dcache * afile, afs_int32 ablob) |
| 60 | { |
| 61 | afs_int32 relativeBlob; |
| 62 | afs_int32 pageBlob; |
| 63 | struct PageHeader *tpe; |
| 64 | struct DirBuffer headerbuf; |
| 65 | afs_int32 i; |
| 66 | int code; |
| 67 | |
| 68 | AFS_STATCNT(BlobScan)((afs_cmstats.callInfo.C_BlobScan)++); |
| 69 | /* advance ablob over free and header blobs */ |
| 70 | while (1) { |
| 71 | pageBlob = ablob & ~(EPP64 - 1); /* base blob in same page */ |
| 72 | code = afs_dir_GetBlob(afile, pageBlob, &headerbuf); |
| 73 | if (code) |
| 74 | return 0; |
| 75 | tpe = (struct PageHeader *)headerbuf.data; |
| 76 | |
| 77 | relativeBlob = ablob - pageBlob; /* relative to page's first blob */ |
| 78 | /* first watch for headers */ |
| 79 | if (pageBlob == 0) { /* first dir page has extra-big header */ |
| 80 | /* first page */ |
| 81 | if (relativeBlob < DHE12 + 1) |
| 82 | relativeBlob = DHE12 + 1; |
| 83 | } else { /* others have one header blob */ |
| 84 | if (relativeBlob == 0) |
| 85 | relativeBlob = 1; |
| 86 | } |
| 87 | /* make sure blob is allocated */ |
| 88 | for (i = relativeBlob; i < EPP64; i++) { |
| 89 | if (tpe->freebitmap[i >> 3] & (1 << (i & 7))) |
| 90 | break; |
| 91 | } |
| 92 | /* now relativeBlob is the page-relative first allocated blob, |
| 93 | * or EPP (if there are none in this page). */ |
| 94 | DRelease(&headerbuf, 0); |
| 95 | if (i != EPP64) |
| 96 | return i + pageBlob; |
| 97 | ablob = pageBlob + EPP64; /* go around again */ |
| 98 | } |
| 99 | /* never get here */ |
| 100 | } |
| 101 | |
| 102 | |
| 103 | #if !defined(AFS_LINUX20_ENV) |
| 104 | /* Changes to afs_readdir which affect dcache or vcache handling or use of |
| 105 | * bulk stat data should also be reflected in the Linux specific verison of |
| 106 | * the readdir routine. |
| 107 | */ |
| 108 | |
| 109 | /* |
| 110 | * The kernel don't like it so much to have large stuff on the stack. |
| 111 | * Here we use a watered down version of the direct struct, since |
| 112 | * its not too bright to double copy the strings anyway. |
| 113 | */ |
| 114 | #if !defined(UKERNEL1) |
| 115 | #if defined(AFS_SGI_ENV) |
| 116 | /* Long form for 64 bit apps and kernel requests. */ |
| 117 | struct min_dirent { /* miniature dirent structure */ |
| 118 | /* If struct dirent changes, this must too */ |
| 119 | ino_tusr_ino_t d_fileno; /* This is 32 bits for 3.5, 64 for 6.2+ */ |
| 120 | off64_t d_off; |
| 121 | u_short d_reclen; |
| 122 | }; |
| 123 | /* Short form for 32 bit apps. */ |
| 124 | struct irix5_min_dirent { /* miniature dirent structure */ |
| 125 | /* If struct dirent changes, this must too */ |
| 126 | afs_uint32 d_fileno; |
| 127 | afs_int32 d_off; |
| 128 | u_short d_reclen; |
| 129 | }; |
| 130 | #ifdef AFS_SGI62_ENV |
| 131 | #define AFS_DIRENT32BASESIZE IRIX5_DIRENTBASESIZE |
| 132 | #define AFS_DIRENT64BASESIZE DIRENT64BASESIZE |
| 133 | #else |
| 134 | #define AFS_DIRENT32BASESIZE IRIX5_DIRENTBASESIZE |
| 135 | #define AFS_DIRENT64BASESIZE DIRENTBASESIZE |
| 136 | #endif /* AFS_SGI62_ENV */ |
| 137 | #else |
| 138 | struct min_direct { /* miniature direct structure */ |
| 139 | /* If struct direct changes, this must too */ |
| 140 | #if defined(AFS_DARWIN80_ENV) |
| 141 | ino_tusr_ino_t d_fileno; |
| 142 | u_short d_reclen; |
| 143 | u_char d_type; |
| 144 | u_char d_namlen; |
| 145 | #elif defined(AFS_NBSD40_ENV) |
| 146 | ino_tusr_ino_t d_fileno; /* file number of entry */ |
| 147 | uint16_t d_reclen; /* length of this record */ |
| 148 | uint16_t d_namlen; /* length of string in d_name */ |
| 149 | uint8_t d_type; /* file type, see below */ |
| 150 | #elif defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) |
| 151 | afs_uint32 d_fileno; |
| 152 | u_short d_reclen; |
| 153 | u_char d_type; |
| 154 | u_char d_namlen; |
| 155 | #elif defined(AFS_SUN5_ENV) |
| 156 | afs_uint32 d_fileno; |
| 157 | afs_int32 d_off; |
| 158 | u_short d_reclen; |
| 159 | #else |
| 160 | #if defined(AFS_AIX32_ENV) |
| 161 | afs_int32 d_off; |
| 162 | #elif defined(AFS_HPUX100_ENV) |
| 163 | unsigned long long d_off; |
| 164 | #endif |
| 165 | afs_uint32 d_fileno; |
| 166 | u_short d_reclen; |
| 167 | u_short d_namlen; |
| 168 | #endif |
| 169 | }; |
| 170 | #endif /* AFS_SGI_ENV */ |
| 171 | |
| 172 | #if defined(AFS_HPUX_ENV) |
| 173 | struct minnfs_direct { |
| 174 | afs_int32 d_off; /* XXX */ |
| 175 | afs_uint32 d_fileno; |
| 176 | u_short d_reclen; |
| 177 | u_short d_namlen; |
| 178 | }; |
| 179 | #define NDIRSIZ_LEN(len)((sizeof (struct usr_dirent)+4 - (255 +1)) + (((len)+1 + 3) & ~ 3)) ((sizeof (struct direntusr_dirent)+4 - (MAXNAMLEN255+1)) + (((len)+1 + DIRPAD3) &~ DIRPAD3)) |
| 180 | #endif |
| 181 | #endif /* !defined(UKERNEL) */ |
| 182 | |
| 183 | |
| 184 | /* |
| 185 | *------------------------------------------------------------------------------ |
| 186 | * |
| 187 | * Keep a stack of about 256 fids for the bulk stat call. |
| 188 | * Fill it during the readdir_move. Later empty it... |
| 189 | */ |
| 190 | |
| 191 | #define READDIR_STASH50 AFSCBMAX50 |
| 192 | struct AFSFid afs_readdir_stash[READDIR_STASH50]; |
| 193 | int afs_rd_stash_i = 0; |
| 194 | |
| 195 | /* |
| 196 | *------------------------------------------------------------------------------ |
| 197 | * |
| 198 | * afs_readdir_move. |
| 199 | * mainly a kind of macro... makes getting the struct direct |
| 200 | * out to the user space easy... could take more parameters, |
| 201 | * but now just takes what it needs. |
| 202 | * |
| 203 | * |
| 204 | */ |
| 205 | |
| 206 | #if defined(AFS_HPUX100_ENV) |
| 207 | #define DIRSIZ_LEN(len)((sizeof (struct usr_dirent) - (255 +1)) + (((len)+1 + 3) & ~ 3)) \ |
| 208 | ((sizeof (struct __dirent) - (_MAXNAMLEN+1)) + (((len)+1 + DIRPAD3) &~ DIRPAD3)) |
| 209 | #else |
| 210 | #if defined(AFS_SUN5_ENV) |
| 211 | #define DIRSIZ_LEN(len)((sizeof (struct usr_dirent) - (255 +1)) + (((len)+1 + 3) & ~ 3)) ((18 + (len) + 1 + 7) & ~7 ) |
| 212 | #else |
| 213 | #ifdef AFS_NBSD40_ENV |
| 214 | #define DIRSIZ_LEN(len)((sizeof (struct usr_dirent) - (255 +1)) + (((len)+1 + 3) & ~ 3)) \ |
| 215 | ((sizeof (struct direntusr_dirent) - (MAXNAMLEN255+1)) + (((len)+1 + 7) & ~7)) |
| 216 | #else |
| 217 | #ifdef AFS_DIRENT |
| 218 | #define DIRSIZ_LEN(len)((sizeof (struct usr_dirent) - (255 +1)) + (((len)+1 + 3) & ~ 3)) \ |
| 219 | ((sizeof (struct direntusr_dirent) - (MAXNAMLEN255+1)) + (((len)+1 + 3) &~ 3)) |
| 220 | #else |
| 221 | #if defined(AFS_SGI_ENV) |
| 222 | #ifndef AFS_SGI53_ENV |
| 223 | /* SGI 5.3 and later use 32/64 bit versions of directory size. */ |
| 224 | #define DIRSIZ_LEN(len)((sizeof (struct usr_dirent) - (255 +1)) + (((len)+1 + 3) & ~ 3)) DIRENTSIZE(len) |
| 225 | #endif |
| 226 | #else /* AFS_SGI_ENV */ |
| 227 | #define DIRSIZ_LEN(len)((sizeof (struct usr_dirent) - (255 +1)) + (((len)+1 + 3) & ~ 3)) \ |
| 228 | ((sizeof (struct direct) - (MAXNAMLEN255+1)) + (((len)+1 + 3) &~ 3)) |
| 229 | #endif /* AFS_SGI_ENV */ |
| 230 | #endif /* AFS_DIRENT */ |
| 231 | #endif /* AFS_NBSD40_ENV */ |
| 232 | #endif /* AFS_SUN5_ENV */ |
| 233 | #endif /* AFS_HPUX100_ENV */ |
| 234 | |
| 235 | #if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) |
| 236 | int |
| 237 | afs_readdir_type(struct vcache *avc, struct DirEntry *ade) |
| 238 | { |
| 239 | struct VenusFid tfid; |
| 240 | struct vcache *tvc; |
| 241 | int vtype; |
| 242 | tfid.Cell = avc->f.fidusr_fid.Cell; |
| 243 | tfid.Fid.Volume = avc->f.fidusr_fid.Fid.Volume; |
| 244 | tfid.Fid.Vnode = ntohl(ade->fid.vnode)(__builtin_constant_p(ade->usr_fid.usr_vnode) ? ((((__uint32_t )(ade->usr_fid.usr_vnode)) >> 24) | ((((__uint32_t)( ade->usr_fid.usr_vnode)) & (0xff << 16)) >> 8) | ((((__uint32_t)(ade->usr_fid.usr_vnode)) & (0xff << 8)) << 8) | (((__uint32_t)(ade->usr_fid.usr_vnode )) << 24)) : __bswap32_var(ade->usr_fid.usr_vnode)); |
| 245 | tfid.Fid.Unique = ntohl(ade->fid.vunique)(__builtin_constant_p(ade->usr_fid.vunique) ? ((((__uint32_t )(ade->usr_fid.vunique)) >> 24) | ((((__uint32_t)(ade ->usr_fid.vunique)) & (0xff << 16)) >> 8) | ((((__uint32_t)(ade->usr_fid.vunique)) & (0xff << 8)) << 8) | (((__uint32_t)(ade->usr_fid.vunique)) << 24)) : __bswap32_var(ade->usr_fid.vunique)); |
| 246 | if ((avc->f.states & CForeign0x00002000) == 0 && (ntohl(ade->fid.vnode)(__builtin_constant_p(ade->usr_fid.usr_vnode) ? ((((__uint32_t )(ade->usr_fid.usr_vnode)) >> 24) | ((((__uint32_t)( ade->usr_fid.usr_vnode)) & (0xff << 16)) >> 8) | ((((__uint32_t)(ade->usr_fid.usr_vnode)) & (0xff << 8)) << 8) | (((__uint32_t)(ade->usr_fid.usr_vnode )) << 24)) : __bswap32_var(ade->usr_fid.usr_vnode)) & 1)) { |
| 247 | return DT_DIR4; |
| 248 | } |
| 249 | ObtainReadLock(&afs_xvcache)do { ; if (!((&afs_xvcache)->excl_locked & 2)) ((& afs_xvcache)->readers_reading)++; else Afs_Lock_Obtain(& afs_xvcache, 1); (&afs_xvcache)->pid_last_reader = (get_user_struct ()->u_procp->p_pid ); } while (0); |
| 250 | if ((tvc = afs_FindVCache(&tfid, 0, 0))) { |
| 251 | ReleaseReadLock(&afs_xvcache)do { ; if (!(--((&afs_xvcache)->readers_reading)) && (&afs_xvcache)->wait_states) Afs_Lock_ReleaseW(&afs_xvcache ) ; if ( (&afs_xvcache)->pid_last_reader == (get_user_struct ()->u_procp->p_pid ) ) (&afs_xvcache)->pid_last_reader =0; } while (0); |
| 252 | if (tvc->mvstat) { |
| 253 | afs_PutVCache(tvc); |
| 254 | return DT_DIR4; |
| 255 | } else if (((tvc->f.states) & (CStatd0x00000001 | CTruth0x00000400))) { |
| 256 | /* CTruth will be set if the object has |
| 257 | *ever* been statd */ |
| 258 | vtype = vType(tvc)(tvc)->v.v_type; |
| 259 | afs_PutVCache(tvc); |
| 260 | if (vtype == VDIR0040000) |
| 261 | return DT_DIR4; |
| 262 | else if (vtype == VREG0100000) |
| 263 | return DT_REG8; |
| 264 | /* Don't do this until we're sure it can't be a mtpt */ |
| 265 | /* if we're CStatd and CTruth and mvstat==0, it's a link */ |
| 266 | else if (vtype == VLNK0120000) |
| 267 | return DT_LNK10; |
| 268 | /* what other types does AFS support? */ |
| 269 | } else |
| 270 | afs_PutVCache(tvc); |
| 271 | } else |
| 272 | ReleaseReadLock(&afs_xvcache)do { ; if (!(--((&afs_xvcache)->readers_reading)) && (&afs_xvcache)->wait_states) Afs_Lock_ReleaseW(&afs_xvcache ) ; if ( (&afs_xvcache)->pid_last_reader == (get_user_struct ()->u_procp->p_pid ) ) (&afs_xvcache)->pid_last_reader =0; } while (0); |
| 273 | return DT_UNKNOWN0; |
| 274 | } |
| 275 | #endif |
| 276 | |
| 277 | #ifdef AFS_AIX41_ENV |
| 278 | #define AFS_MOVE_LOCK() AFS_GLOCK()do { do{if (!(pthread_mutex_lock(&afs_global_lock) == 0)) AssertionFailed("/home/wollman/openafs/src/afs/VNOPS/afs_vnop_readdir.c" , 278);}while(0); afs_global_owner = pthread_self(); } while( 0) |
| 279 | #define AFS_MOVE_UNLOCK() AFS_GUNLOCK()do { do { if (!(pthread_self() == afs_global_owner)) { osi_Panic ("afs global lock not held"); } } while(0); memset(&afs_global_owner , 0, sizeof(pthread_t)); do{if (!(pthread_mutex_unlock(&afs_global_lock ) == 0)) AssertionFailed("/home/wollman/openafs/src/afs/VNOPS/afs_vnop_readdir.c" , 279);}while(0); } while(0) |
| 280 | #else |
| 281 | #define AFS_MOVE_LOCK() |
| 282 | #define AFS_MOVE_UNLOCK() |
| 283 | #endif |
| 284 | char bufofzeros[64]; /* gotta fill with something */ |
| 285 | |
| 286 | #ifdef AFS_SGI65_ENV |
| 287 | int |
| 288 | afs_readdir_move(struct DirEntry *de, struct vcache *vc, struct uiousr_uio *auio, |
| 289 | int slen, ssize_t rlen, afs_size_t off) |
| 290 | #else |
| 291 | int |
| 292 | afs_readdir_move(struct DirEntry *de, struct vcache *vc, struct uiousr_uio *auio, |
| 293 | int slen, int rlen, afs_size_t off) |
| 294 | #endif |
| 295 | { |
| 296 | int code = 0; |
| 297 | struct volume *tvp; |
| 298 | afs_uint32 Volume = vc->f.fidusr_fid.Fid.Volume; |
| 299 | afs_uint32 Vnode = de->fidusr_fid.vnodeusr_vnode; |
| 300 | #if defined(AFS_SUN5_ENV) |
| 301 | struct dirent64 *direntp; |
| 302 | #else |
| 303 | #if (defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL)) |
| 304 | struct direntusr_dirent *direntp; |
| 305 | #endif |
| 306 | #endif /* AFS_SUN5_ENV */ |
| 307 | #ifndef AFS_SGI53_ENV |
| 308 | struct min_direct sdirEntry; |
| 309 | #endif /* AFS_SGI53_ENV */ |
| 310 | |
| 311 | AFS_STATCNT(afs_readdir_move)((afs_cmstats.callInfo.C_afs_readdir_move)++); |
| 312 | |
| 313 | #define READDIR_CORRECT_INUMS |
| 314 | #ifdef READDIR_CORRECT_INUMS |
| 315 | if (de->name[0] == '.' && !de->name[1]) { |
| 316 | /* This is the '.' entry; if we are a volume root, we need to |
| 317 | * ignore the directory and use the inum for the mount point. |
| 318 | */ |
| 319 | if (!FidCmp(&afs_rootFid, &vc->f.fid)((&afs_rootFid)->Fid.Unique != (&vc->f.usr_fid) ->Fid.Unique || (&afs_rootFid)->Fid.Vnode != (& vc->f.usr_fid)->Fid.Vnode || (&afs_rootFid)->Fid .Volume != (&vc->f.usr_fid)->Fid.Volume || (&afs_rootFid )->Cell != (&vc->f.usr_fid)->Cell)) { |
| 320 | Volume = 0; |
| 321 | Vnode = 2; |
| 322 | } else if (vc->mvstat == 2) { |
| 323 | tvp = afs_GetVolume(&vc->f.fidusr_fid, 0, READ_LOCK1); |
| 324 | if (tvp) { |
| 325 | Volume = tvp->mtpoint.Fid.Volume; |
| 326 | Vnode = tvp->mtpoint.Fid.Vnode; |
| 327 | afs_PutVolume(tvp, READ_LOCK)((tvp)->refCount--); |
| 328 | } |
| 329 | } |
| 330 | } |
| 331 | else if (de->name[0] == '.' && de->name[1] == '.' && !de->name[2]) { |
| 332 | /* This is the '..' entry. Getting this right is very tricky, |
| 333 | * because we might be a volume root (so our parent is in a |
| 334 | * different volume), or our parent might be a volume root |
| 335 | * (so we actually want the mount point) or BOTH! */ |
| 336 | if (!FidCmp(&afs_rootFid, &vc->f.fid)((&afs_rootFid)->Fid.Unique != (&vc->f.usr_fid) ->Fid.Unique || (&afs_rootFid)->Fid.Vnode != (& vc->f.usr_fid)->Fid.Vnode || (&afs_rootFid)->Fid .Volume != (&vc->f.usr_fid)->Fid.Volume || (&afs_rootFid )->Cell != (&vc->f.usr_fid)->Cell)) { |
| 337 | /* We are the root of the AFS root, and thus our own parent */ |
| 338 | Volume = 0; |
| 339 | Vnode = 2; |
| 340 | } else if (vc->mvstat == 2) { |
| 341 | /* We are a volume root, which means our parent is in another |
| 342 | * volume. Luckily, we should have his fid cached... */ |
| 343 | if (vc->mvid) { |
| 344 | if (!FidCmp(&afs_rootFid, vc->mvid)((&afs_rootFid)->Fid.Unique != (vc->mvid)->Fid.Unique || (&afs_rootFid)->Fid.Vnode != (vc->mvid)->Fid .Vnode || (&afs_rootFid)->Fid.Volume != (vc->mvid)-> Fid.Volume || (&afs_rootFid)->Cell != (vc->mvid)-> Cell)) { |
| 345 | /* Parent directory is the root of the AFS root */ |
| 346 | Volume = 0; |
| 347 | Vnode = 2; |
| 348 | } else if (vc->mvid->Fid.Vnode == 1 |
| 349 | && vc->mvid->Fid.Unique == 1) { |
| 350 | /* XXX The above test is evil and probably breaks DFS */ |
| 351 | /* Parent directory is the target of a mount point */ |
| 352 | tvp = afs_GetVolume(vc->mvid, 0, READ_LOCK1); |
| 353 | if (tvp) { |
| 354 | Volume = tvp->mtpoint.Fid.Volume; |
| 355 | Vnode = tvp->mtpoint.Fid.Vnode; |
| 356 | afs_PutVolume(tvp, READ_LOCK)((tvp)->refCount--); |
| 357 | } |
| 358 | } else { |
| 359 | /* Parent directory is not a volume root */ |
| 360 | Volume = vc->mvid->Fid.Volume; |
| 361 | Vnode = vc->mvid->Fid.Vnode; |
| 362 | } |
| 363 | } |
| 364 | } else if (de->fidusr_fid.vnodeusr_vnode == 1 && de->fidusr_fid.vunique == 1) { |
| 365 | /* XXX The above test is evil and probably breaks DFS */ |
| 366 | /* Parent directory is a volume root; use the right inum */ |
| 367 | tvp = afs_GetVolume(&vc->f.fidusr_fid, 0, READ_LOCK1); |
| 368 | if (tvp) { |
| 369 | if (tvp->cell == afs_rootFid.Cell |
| 370 | && tvp->volume == afs_rootFid.Fid.Volume) { |
| 371 | /* Parent directory is the root of the AFS root */ |
| 372 | Volume = 0; |
| 373 | Vnode = 2; |
| 374 | } else { |
| 375 | /* Parent directory is the target of a mount point */ |
| 376 | Volume = tvp->mtpoint.Fid.Volume; |
| 377 | Vnode = tvp->mtpoint.Fid.Vnode; |
| 378 | } |
| 379 | afs_PutVolume(tvp, READ_LOCK)((tvp)->refCount--); |
| 380 | } |
| 381 | } |
| 382 | } |
| 383 | #endif |
| 384 | |
| 385 | #ifdef AFS_SGI53_ENV |
| 386 | { |
| 387 | afs_int32 use64BitDirent; |
| 388 | |
| 389 | #ifdef AFS_SGI61_ENV |
| 390 | #ifdef AFS_SGI62_ENV |
| 391 | use64BitDirent = |
| 392 | ABI_IS(ABI_IRIX5_64, GETDENTS_ABI(OSI_GET_CURRENT_ABI(), auio)); |
| 393 | #else |
| 394 | use64BitDirent = |
| 395 | (auio->uio_segflg != |
| 396 | UIO_USERSPACE0x0000) ? ABI_IRIX5_64 : (ABI_IS(ABI_IRIX5_64 | |
| 397 | ABI_IRIX5_N32, |
| 398 | u.u_procp->p_abi)); |
| 399 | #endif |
| 400 | #else /* AFS_SGI61_ENV */ |
| 401 | use64BitDirent = |
| 402 | (auio->uio_segflg != |
| 403 | UIO_USERSPACE0x0000) ? ABI_IRIX5_64 : (ABI_IS(ABI_IRIX5_64, |
| 404 | u.u_procp->p_abi)); |
| 405 | #endif /* AFS_SGI61_ENV */ |
| 406 | |
| 407 | if (use64BitDirent) { |
| 408 | struct min_dirent sdirEntry; |
| 409 | sdirEntry.d_fileno = afs_calc_inum(vc->f.fidusr_fid.Cell, |
| 410 | Volume, ntohl(Vnode)(__builtin_constant_p(Vnode) ? ((((__uint32_t)(Vnode)) >> 24) | ((((__uint32_t)(Vnode)) & (0xff << 16)) >> 8) | ((((__uint32_t)(Vnode)) & (0xff << 8)) << 8) | (((__uint32_t)(Vnode)) << 24)) : __bswap32_var(Vnode ))); |
| 411 | sdirEntry.d_reclen = rlen; |
| 412 | sdirEntry.d_off = (off_t) off; |
| 413 | AFS_UIOMOVE(&sdirEntry, AFS_DIRENT64BASESIZE, UIO_READ, auio,do { code = usr_uiomove((&sdirEntry),(AFS_DIRENT64BASESIZE ),(0x0000),(auio)); } while(0) |
| 414 | code)do { code = usr_uiomove((&sdirEntry),(AFS_DIRENT64BASESIZE ),(0x0000),(auio)); } while(0); |
| 415 | if (code == 0) |
| 416 | AFS_UIOMOVE(de->name, slen - 1, UIO_READ, auio, code)do { code = usr_uiomove((de->name),(slen - 1),(0x0000),(auio )); } while(0); |
| 417 | if (code == 0) |
| 418 | AFS_UIOMOVE(bufofzeros,do { code = usr_uiomove((bufofzeros),(DIRENTSIZE(slen) - (AFS_DIRENT64BASESIZE + slen - 1)),(0x0000),(auio)); } while(0) |
| 419 | DIRENTSIZE(slen) - (AFS_DIRENT64BASESIZE + slen -do { code = usr_uiomove((bufofzeros),(DIRENTSIZE(slen) - (AFS_DIRENT64BASESIZE + slen - 1)),(0x0000),(auio)); } while(0) |
| 420 | 1), UIO_READ, auio, code)do { code = usr_uiomove((bufofzeros),(DIRENTSIZE(slen) - (AFS_DIRENT64BASESIZE + slen - 1)),(0x0000),(auio)); } while(0); |
| 421 | if (DIRENTSIZE(slen) < rlen) { |
| 422 | while (DIRENTSIZE(slen) < rlen) { |
| 423 | int minLen = rlen - DIRENTSIZE(slen); |
| 424 | if (minLen > sizeof(bufofzeros)) |
| 425 | minLen = sizeof(bufofzeros); |
| 426 | AFS_UIOMOVE(bufofzeros, minLen, UIO_READ, auio, code)do { code = usr_uiomove((bufofzeros),(minLen),(0x0000),(auio) ); } while(0); |
| 427 | rlen -= minLen; |
| 428 | } |
| 429 | } |
| 430 | } else { |
| 431 | struct irix5_min_dirent sdirEntry; |
| 432 | sdirEntry.d_fileno = afs_calc_inum(vc->f.fidusr_fid.Cell, |
| 433 | Volume, ntohl(Vnode)(__builtin_constant_p(Vnode) ? ((((__uint32_t)(Vnode)) >> 24) | ((((__uint32_t)(Vnode)) & (0xff << 16)) >> 8) | ((((__uint32_t)(Vnode)) & (0xff << 8)) << 8) | (((__uint32_t)(Vnode)) << 24)) : __bswap32_var(Vnode ))); |
| 434 | sdirEntry.d_reclen = rlen; |
| 435 | sdirEntry.d_off = (afs_int32) off; |
| 436 | AFS_UIOMOVE(&sdirEntry, AFS_DIRENT32BASESIZE, UIO_READ, auio,do { code = usr_uiomove((&sdirEntry),(AFS_DIRENT32BASESIZE ),(0x0000),(auio)); } while(0) |
| 437 | code)do { code = usr_uiomove((&sdirEntry),(AFS_DIRENT32BASESIZE ),(0x0000),(auio)); } while(0); |
| 438 | if (code == 0) |
| 439 | AFS_UIOMOVE(de->name, slen - 1, UIO_READ, auio, code)do { code = usr_uiomove((de->name),(slen - 1),(0x0000),(auio )); } while(0); |
| 440 | if (code == 0) |
| 441 | AFS_UIOMOVE(bufofzeros,do { code = usr_uiomove((bufofzeros),(IRIX5_DIRENTSIZE(slen) - (AFS_DIRENT32BASESIZE + slen - 1)),(0x0000),(auio)); } while (0) |
| 442 | IRIX5_DIRENTSIZE(slen) - (AFS_DIRENT32BASESIZE +do { code = usr_uiomove((bufofzeros),(IRIX5_DIRENTSIZE(slen) - (AFS_DIRENT32BASESIZE + slen - 1)),(0x0000),(auio)); } while (0) |
| 443 | slen - 1), UIO_READ,do { code = usr_uiomove((bufofzeros),(IRIX5_DIRENTSIZE(slen) - (AFS_DIRENT32BASESIZE + slen - 1)),(0x0000),(auio)); } while (0) |
| 444 | auio, code)do { code = usr_uiomove((bufofzeros),(IRIX5_DIRENTSIZE(slen) - (AFS_DIRENT32BASESIZE + slen - 1)),(0x0000),(auio)); } while (0); |
| 445 | if (IRIX5_DIRENTSIZE(slen) < rlen) { |
| 446 | while (IRIX5_DIRENTSIZE(slen) < rlen) { |
| 447 | int minLen = rlen - IRIX5_DIRENTSIZE(slen); |
| 448 | if (minLen > sizeof(bufofzeros)) |
| 449 | minLen = sizeof(bufofzeros); |
| 450 | AFS_UIOMOVE(bufofzeros, minLen, UIO_READ, auio, code)do { code = usr_uiomove((bufofzeros),(minLen),(0x0000),(auio) ); } while(0); |
| 451 | rlen -= minLen; |
| 452 | } |
| 453 | } |
| 454 | } |
| 455 | } |
| 456 | #else /* AFS_SGI53_ENV */ |
| 457 | #if defined(AFS_SUN5_ENV) || (defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL)) |
| 458 | #if defined(AFS_SUN5_ENV) |
| 459 | direntp = (struct dirent64 *)osi_AllocLargeSpace(AFS_LRALLOCSIZ4096); |
| 460 | #else |
| 461 | direntp = (struct direntusr_dirent *)osi_AllocLargeSpace(AFS_LRALLOCSIZ4096); |
| 462 | #endif |
| 463 | direntp->d_inod_fileno = afs_calc_inum(vc->f.fidusr_fid.Cell, Volume, ntohl(Vnode)(__builtin_constant_p(Vnode) ? ((((__uint32_t)(Vnode)) >> 24) | ((((__uint32_t)(Vnode)) & (0xff << 16)) >> 8) | ((((__uint32_t)(Vnode)) & (0xff << 8)) << 8) | (((__uint32_t)(Vnode)) << 24)) : __bswap32_var(Vnode ))); |
| 464 | #if defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL) |
| 465 | direntp->d_offset = off; |
| 466 | direntp->d_namlen = slen; |
| 467 | #else |
| 468 | direntp->d_off = off; |
| 469 | #endif |
| 470 | direntp->d_reclen = rlen; |
| 471 | strcpy(direntp->d_name, de->name); |
| 472 | AFS_UIOMOVE((caddr_t) direntp, rlen, UIO_READ, auio, code)do { code = usr_uiomove(((caddr_t) direntp),(rlen),(0x0000),( auio)); } while(0); |
| 473 | osi_FreeLargeSpace((char *)direntp); |
| 474 | #else /* AFS_SUN5_ENV */ |
| 475 | /* Note the odd mechanism for building the inode number */ |
| 476 | sdirEntry.d_fileno = afs_calc_inum(vc->f.fidusr_fid.Cell, Volume, ntohl(Vnode)(__builtin_constant_p(Vnode) ? ((((__uint32_t)(Vnode)) >> 24) | ((((__uint32_t)(Vnode)) & (0xff << 16)) >> 8) | ((((__uint32_t)(Vnode)) & (0xff << 8)) << 8) | (((__uint32_t)(Vnode)) << 24)) : __bswap32_var(Vnode ))); |
| 477 | sdirEntry.d_reclen = rlen; |
| 478 | #if !defined(AFS_SGI_ENV) |
| 479 | sdirEntry.d_namlen = slen; |
| 480 | #endif |
| 481 | #if defined(AFS_AIX32_ENV) || defined(AFS_SGI_ENV) |
| 482 | sdirEntry.d_off = off; |
| 483 | #endif |
| 484 | #if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) |
| 485 | sdirEntry.d_type = afs_readdir_type(vc, de); |
| 486 | #endif |
| 487 | |
| 488 | #if defined(AFS_SGI_ENV) |
| 489 | AFS_UIOMOVE(&sdirEntry, DIRENTBASESIZE, UIO_READ, auio, code)do { code = usr_uiomove((&sdirEntry),(DIRENTBASESIZE),(0x0000 ),(auio)); } while(0); |
| 490 | if (code == 0) |
| 491 | AFS_UIOMOVE(de->name, slen - 1, UIO_READ, auio, code)do { code = usr_uiomove((de->name),(slen - 1),(0x0000),(auio )); } while(0); |
| 492 | if (code == 0) |
| 493 | AFS_UIOMOVE(bufofzeros,do { code = usr_uiomove((bufofzeros),(((sizeof (struct usr_dirent ) - (255 +1)) + (((slen)+1 + 3) &~ 3)) - (DIRENTBASESIZE + slen - 1)),(0x0000),(auio)); } while(0) |
| 494 | DIRSIZ_LEN(slen) - (DIRENTBASESIZE + slen - 1), UIO_READ,do { code = usr_uiomove((bufofzeros),(((sizeof (struct usr_dirent ) - (255 +1)) + (((slen)+1 + 3) &~ 3)) - (DIRENTBASESIZE + slen - 1)),(0x0000),(auio)); } while(0) |
| 495 | auio, code)do { code = usr_uiomove((bufofzeros),(((sizeof (struct usr_dirent ) - (255 +1)) + (((slen)+1 + 3) &~ 3)) - (DIRENTBASESIZE + slen - 1)),(0x0000),(auio)); } while(0); |
| 496 | #else /* AFS_SGI_ENV */ |
| 497 | AFS_MOVE_UNLOCK(); |
| 498 | #if defined(AFS_NBSD40_ENV) |
| 499 | { |
| 500 | struct direntusr_dirent *dp; |
| 501 | dp = osi_AllocLargeSpace(sizeof(struct direntusr_dirent)); |
| 502 | memset(dp, 0, sizeof(struct direntusr_dirent)); |
| 503 | dp->d_inod_fileno = afs_calc_inum(vc->f.fidusr_fid.Cell, Volume, ntohl(Vnode)(__builtin_constant_p(Vnode) ? ((((__uint32_t)(Vnode)) >> 24) | ((((__uint32_t)(Vnode)) & (0xff << 16)) >> 8) | ((((__uint32_t)(Vnode)) & (0xff << 8)) << 8) | (((__uint32_t)(Vnode)) << 24)) : __bswap32_var(Vnode ))); |
| 504 | dp->d_namlen = slen; |
| 505 | dp->d_type = afs_readdir_type(vc, de); |
| 506 | strcpy(dp->d_name, de->name); |
| 507 | dp->d_reclen = _DIRENT_SIZE(dp) /* rlen */; |
| 508 | if ((afs_debug & AFSDEB_VNLAYER8) != 0) { |
| 509 | afs_warn("%s: %s type %d slen %d rlen %d act. rlen %zu\n", __func__, |
| 510 | dp->d_name, dp->d_type, slen, rlen, _DIRENT_SIZE(dp)); |
| 511 | } |
| 512 | AFS_UIOMOVE(dp, dp->d_reclen, UIO_READ, auio, code)do { code = usr_uiomove((dp),(dp->d_reclen),(0x0000),(auio )); } while(0); |
| 513 | osi_FreeLargeSpace((char *)dp); |
| 514 | } |
| 515 | #else |
| 516 | AFS_UIOMOVE((char *) &sdirEntry, sizeof(sdirEntry), UIO_READ, auio, code)do { code = usr_uiomove(((char *) &sdirEntry),(sizeof(sdirEntry )),(0x0000),(auio)); } while(0); |
| 517 | if (code == 0) { |
| 518 | AFS_UIOMOVE(de->name, slen, UIO_READ, auio, code)do { code = usr_uiomove((de->name),(slen),(0x0000),(auio)) ; } while(0); |
| 519 | } |
| 520 | /* pad out the remaining characters with zeros */ |
| 521 | if (code == 0) { |
| 522 | AFS_UIOMOVE(bufofzeros, ((slen + 1 + DIRPAD) & ~DIRPAD) - slen,do { code = usr_uiomove((bufofzeros),(((slen + 1 + 3) & ~ 3) - slen),(0x0000),(auio)); } while(0) |
| 523 | UIO_READ, auio, code)do { code = usr_uiomove((bufofzeros),(((slen + 1 + 3) & ~ 3) - slen),(0x0000),(auio)); } while(0); |
| 524 | } |
| 525 | #endif |
| 526 | AFS_MOVE_LOCK(); |
| 527 | #endif /* AFS_SGI_ENV */ |
| 528 | #if !defined(AFS_NBSD_ENV) |
| 529 | /* pad out the difference between rlen and slen... */ |
| 530 | if (DIRSIZ_LEN(slen)((sizeof (struct usr_dirent) - (255 +1)) + (((slen)+1 + 3) & ~ 3)) < rlen) { |
| 531 | AFS_MOVE_UNLOCK(); |
| 532 | while (DIRSIZ_LEN(slen)((sizeof (struct usr_dirent) - (255 +1)) + (((slen)+1 + 3) & ~ 3)) < rlen) { |
| 533 | int minLen = rlen - DIRSIZ_LEN(slen)((sizeof (struct usr_dirent) - (255 +1)) + (((slen)+1 + 3) & ~ 3)); |
| 534 | if (minLen > sizeof(bufofzeros)) |
| 535 | minLen = sizeof(bufofzeros); |
| 536 | AFS_UIOMOVE(bufofzeros, minLen, UIO_READ, auio, code)do { code = usr_uiomove((bufofzeros),(minLen),(0x0000),(auio) ); } while(0); |
| 537 | rlen -= minLen; |
| 538 | } |
| 539 | AFS_MOVE_LOCK(); |
| 540 | } |
| 541 | #endif |
| 542 | #endif /* AFS_SUN5_ENV */ |
| 543 | #endif /* AFS_SGI53_ENV */ |
| 544 | return (code); |
| 545 | } |
| 546 | |
| 547 | |
| 548 | /* |
| 549 | *------------------------------------------------------------------------------ |
| 550 | * |
| 551 | * Read directory entries. |
| 552 | * There are some weird things to look out for here. The uio_offset |
| 553 | * field is either 0 or it is the offset returned from a previous |
| 554 | * readdir. It is an opaque value used by the server to find the |
| 555 | * correct directory block to read. The byte count must be at least |
| 556 | * vtoblksz(vp) bytes. The count field is the number of blocks to |
| 557 | * read on the server. This is advisory only, the server may return |
| 558 | * only one block's worth of entries. Entries may be compressed on |
| 559 | * the server. |
| 560 | * |
| 561 | * This routine encodes knowledge of Vice dirs. |
| 562 | */ |
| 563 | |
| 564 | void |
| 565 | afs_bulkstat_send(struct vcache *avc, struct vrequest *req) |
| 566 | { |
| 567 | afs_rd_stash_i = 0; |
| 568 | } |
| 569 | |
| 570 | /* |
| 571 | * Here is the bad, bad, really bad news. |
| 572 | * It has to do with 'offset' (seek locations). |
| 573 | */ |
| 574 | |
| 575 | int |
| 576 | #if defined(AFS_SUN5_ENV) || defined(AFS_SGI_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) |
| 577 | afs_readdir(OSI_VC_DECL(avc)struct vcache *avc, struct uiousr_uio *auio, afs_ucred_tstruct usr_ucred *acred, |
| 578 | int *eofp) |
| 579 | #else |
| 580 | #if defined(AFS_HPUX100_ENV) |
| 581 | afs_readdir2(OSI_VC_DECL(avc)struct vcache *avc, struct uiousr_uio *auio, afs_ucred_tstruct usr_ucred *acred) |
| 582 | #else |
| 583 | afs_readdir(OSI_VC_DECL(avc)struct vcache *avc, struct uiousr_uio *auio, afs_ucred_tstruct usr_ucred *acred) |
| 584 | #endif |
| 585 | #endif |
| 586 | { |
| 587 | struct vrequest treq; |
| 588 | struct dcache *tdc; |
| 589 | afs_size_t origOffset, tlen; |
| 590 | afs_int32 len; |
| 591 | int code = 0; |
| 592 | struct DirBuffer oldEntry, nextEntry; |
| 593 | struct DirEntry *ode = 0, *nde = 0; |
| 594 | int o_slen = 0, n_slen = 0; |
| 595 | afs_uint32 us; |
| 596 | struct afs_fakestat_state fakestate; |
| 597 | #if defined(AFS_SGI53_ENV) |
| 598 | afs_int32 use64BitDirent, dirsiz; |
| 599 | #endif /* defined(AFS_SGI53_ENV) */ |
| 600 | #ifndef AFS_HPUX_ENV |
| 601 | OSI_VC_CONVERT(avc); |
| 602 | #else |
| 603 | /* |
| 604 | * XXX All the hacks for alloced sdirEntry and inlining of afs_readdir_move instead of calling |
| 605 | * it is necessary for hpux due to stack problems that seem to occur when coming thru the nfs |
| 606 | * translator side XXX |
| 607 | */ |
| 608 | struct min_direct *sdirEntry = |
| 609 | (struct min_direct *)osi_AllocSmallSpace(sizeof(struct min_direct)); |
| 610 | afs_int32 rlen; |
| 611 | #endif |
| 612 | |
| 613 | /* opaque value is pointer into a vice dir; use bit map to decide |
| 614 | * if the entries are in use. Always assumed to be valid. 0 is |
| 615 | * special, means start of a new dir. Int32 inode, followed by |
| 616 | * short reclen and short namelen. Namelen does not include |
| 617 | * the null byte. Followed by null-terminated string. |
| 618 | */ |
| 619 | AFS_STATCNT(afs_readdir)((afs_cmstats.callInfo.C_afs_readdir)++); |
| 620 | |
| 621 | memset(&oldEntry, 0, sizeof(struct DirBuffer)); |
| 622 | memset(&nextEntry, 0, sizeof(struct DirBuffer)); |
| 623 | |
| 624 | #if defined(AFS_SGI53_ENV) |
| 625 | #ifdef AFS_SGI61_ENV |
| 626 | #ifdef AFS_SGI62_ENV |
| 627 | use64BitDirent = |
| 628 | ABI_IS(ABI_IRIX5_64, GETDENTS_ABI(OSI_GET_CURRENT_ABI(), auio)); |
| 629 | #else |
| 630 | use64BitDirent = |
| 631 | (auio->uio_segflg != |
| 632 | UIO_USERSPACE0x0000) ? ABI_IRIX5_64 : (ABI_IS(ABI_IRIX5_64 | ABI_IRIX5_N32, |
| 633 | u.u_procp->p_abi)); |
| 634 | #endif /* AFS_SGI62_ENV */ |
| 635 | #else /* AFS_SGI61_ENV */ |
| 636 | use64BitDirent = |
| 637 | (auio->uio_segflg != |
| 638 | UIO_USERSPACE0x0000) ? ABI_IRIX5_64 : (ABI_IS(ABI_IRIX5_64, |
| 639 | u.u_procp->p_abi)); |
| 640 | #endif /* AFS_SGI61_ENV */ |
| 641 | #endif /* defined(AFS_SGI53_ENV) */ |
| 642 | |
| 643 | #if defined(AFS_SUN5_ENV) || defined(AFS_SGI_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) |
| 644 | /* Not really used by the callee so we ignore it for now */ |
| 645 | if (eofp) |
| 646 | *eofp = 0; |
| 647 | #endif |
| 648 | #ifndef AFS_64BIT_CLIENT |
| 649 | if (AfsLargeFileUio(auio)0 /* file is large than 2 GB */ |
| 650 | ||AfsLargeFileSize(AFS_UIO_OFFSET(auio), AFS_UIO_RESID(auio))0) |
| 651 | return EFBIG27; |
| 652 | #endif |
| 653 | |
| 654 | if ((code = afs_InitReq(&treq, acred))) { |
| 655 | #ifdef AFS_HPUX_ENV |
| 656 | osi_FreeSmallSpace((char *)sdirEntry); |
| 657 | #endif |
| 658 | return code; |
| 659 | } |
| 660 | /* update the cache entry */ |
| 661 | afs_InitFakeStat(&fakestate); |
| 662 | |
| 663 | AFS_DISCON_LOCK()do { ; if (!((&afs_discon_lock)->excl_locked & 2)) ((&afs_discon_lock)->readers_reading)++; else Afs_Lock_Obtain (&afs_discon_lock, 1); (&afs_discon_lock)->pid_last_reader = (get_user_struct()->u_procp->p_pid ); } while (0); |
| 664 | |
| 665 | code = afs_EvalFakeStat(&avc, &fakestate, &treq); |
| 666 | if (code) |
| 667 | goto done; |
| 668 | tagain: |
| 669 | code = afs_VerifyVCache(avc, &treq)(((avc)->f.states & 0x00000001) ? 0 : afs_VerifyVCache2 ((avc),&treq)); |
| 670 | if (code) |
| 671 | goto done; |
| 672 | /* get a reference to the entire directory */ |
| 673 | tdc = afs_GetDCache(avc, (afs_size_t) 0, &treq, &origOffset, &tlen, 1); |
| 674 | len = tlen; |
Value stored to 'len' is never read | |
| 675 | if (!tdc) { |
| 676 | code = ENOENT2; |
| 677 | goto done; |
| 678 | } |
| 679 | ObtainReadLock(&avc->lock)do { ; if (!((&avc->lock)->excl_locked & 2)) (( &avc->lock)->readers_reading)++; else Afs_Lock_Obtain (&avc->lock, 1); (&avc->lock)->pid_last_reader = (get_user_struct()->u_procp->p_pid ); } while (0); |
| 680 | ObtainReadLock(&tdc->lock)do { ; if (!((&tdc->lock)->excl_locked & 2)) (( &tdc->lock)->readers_reading)++; else Afs_Lock_Obtain (&tdc->lock, 1); (&tdc->lock)->pid_last_reader = (get_user_struct()->u_procp->p_pid ); } while (0); |
| 681 | |
| 682 | /* |
| 683 | * Make sure that the data in the cache is current. There are two |
| 684 | * cases we need to worry about: |
| 685 | * 1. The cache data is being fetched by another process. |
| 686 | * 2. The cache data is no longer valid |
| 687 | */ |
| 688 | while ((avc->f.states & CStatd0x00000001) |
| 689 | && (tdc->dflags & DFFetching0x04) |
| 690 | && hsame(avc->f.m.DataVersion, tdc->f.versionNo)((avc->f.m.DataVersion).low == (tdc->f.versionNo).low && (avc->f.m.DataVersion).high == (tdc->f.versionNo).high )) { |
| 691 | afs_Trace4(afs_iclSetp, CM_TRACE_DCACHEWAIT, ICL_TYPE_STRING,(((afs_iclSetp) && (afs_iclSetp->states & 2)) ? afs_icl_Event4(afs_iclSetp, (701087887L), (1<<24)+((4) <<18)+((7)<<12)+((2)<<6)+(7), (long)("/home/wollman/openafs/src/afs/VNOPS/afs_vnop_readdir.c" ), (long)(692), (long)(tdc), (long)(tdc->dflags)) : 0) |
| 692 | __FILE__, ICL_TYPE_INT32, __LINE__, ICL_TYPE_POINTER, tdc,(((afs_iclSetp) && (afs_iclSetp->states & 2)) ? afs_icl_Event4(afs_iclSetp, (701087887L), (1<<24)+((4) <<18)+((7)<<12)+((2)<<6)+(7), (long)("/home/wollman/openafs/src/afs/VNOPS/afs_vnop_readdir.c" ), (long)(692), (long)(tdc), (long)(tdc->dflags)) : 0) |
| 693 | ICL_TYPE_INT32, tdc->dflags)(((afs_iclSetp) && (afs_iclSetp->states & 2)) ? afs_icl_Event4(afs_iclSetp, (701087887L), (1<<24)+((4) <<18)+((7)<<12)+((2)<<6)+(7), (long)("/home/wollman/openafs/src/afs/VNOPS/afs_vnop_readdir.c" ), (long)(692), (long)(tdc), (long)(tdc->dflags)) : 0); |
| 694 | ReleaseReadLock(&tdc->lock)do { ; if (!(--((&tdc->lock)->readers_reading)) && (&tdc->lock)->wait_states) Afs_Lock_ReleaseW(& tdc->lock) ; if ( (&tdc->lock)->pid_last_reader == (get_user_struct()->u_procp->p_pid ) ) (&tdc->lock )->pid_last_reader =0; } while (0); |
| 695 | ReleaseReadLock(&avc->lock)do { ; if (!(--((&avc->lock)->readers_reading)) && (&avc->lock)->wait_states) Afs_Lock_ReleaseW(& avc->lock) ; if ( (&avc->lock)->pid_last_reader == (get_user_struct()->u_procp->p_pid ) ) (&avc->lock )->pid_last_reader =0; } while (0); |
| 696 | afs_osi_Sleep(&tdc->validPos); |
| 697 | ObtainReadLock(&avc->lock)do { ; if (!((&avc->lock)->excl_locked & 2)) (( &avc->lock)->readers_reading)++; else Afs_Lock_Obtain (&avc->lock, 1); (&avc->lock)->pid_last_reader = (get_user_struct()->u_procp->p_pid ); } while (0); |
| 698 | ObtainReadLock(&tdc->lock)do { ; if (!((&tdc->lock)->excl_locked & 2)) (( &tdc->lock)->readers_reading)++; else Afs_Lock_Obtain (&tdc->lock, 1); (&tdc->lock)->pid_last_reader = (get_user_struct()->u_procp->p_pid ); } while (0); |
| 699 | } |
| 700 | if (!(avc->f.states & CStatd0x00000001) |
| 701 | || !hsame(avc->f.m.DataVersion, tdc->f.versionNo)((avc->f.m.DataVersion).low == (tdc->f.versionNo).low && (avc->f.m.DataVersion).high == (tdc->f.versionNo).high )) { |
| 702 | ReleaseReadLock(&tdc->lock)do { ; if (!(--((&tdc->lock)->readers_reading)) && (&tdc->lock)->wait_states) Afs_Lock_ReleaseW(& tdc->lock) ; if ( (&tdc->lock)->pid_last_reader == (get_user_struct()->u_procp->p_pid ) ) (&tdc->lock )->pid_last_reader =0; } while (0); |
| 703 | ReleaseReadLock(&avc->lock)do { ; if (!(--((&avc->lock)->readers_reading)) && (&avc->lock)->wait_states) Afs_Lock_ReleaseW(& avc->lock) ; if ( (&avc->lock)->pid_last_reader == (get_user_struct()->u_procp->p_pid ) ) (&avc->lock )->pid_last_reader =0; } while (0); |
| 704 | afs_PutDCache(tdc); |
| 705 | goto tagain; |
| 706 | } |
| 707 | |
| 708 | /* |
| 709 | * iterator for the directory reads. Takes the AFS DirEntry |
| 710 | * structure and slams them into UFS direct structures. |
| 711 | * uses afs_readdir_move to get the struct to the user space. |
| 712 | * |
| 713 | * The routine works by looking ahead one AFS directory entry. |
| 714 | * That's because the AFS entry we are currenly working with |
| 715 | * may not fit into the buffer the user has provided. If it |
| 716 | * doesn't we have to change the size of the LAST AFS directory |
| 717 | * entry, so that it will FIT perfectly into the block the |
| 718 | * user has provided. |
| 719 | * |
| 720 | * The 'forward looking' of the code makes it a bit tough to read. |
| 721 | * Remember we need to get an entry, see if it it fits, then |
| 722 | * set it up as the LAST entry, and find the next one. |
| 723 | * |
| 724 | * Tough to take: We give out an EINVAL if we don't have enough |
| 725 | * space in the buffer, and at the same time, don't have an entry |
| 726 | * to put into the buffer. This CAN happen if the first AFS entry |
| 727 | * we get can't fit into the 512 character buffer provided. Seems |
| 728 | * it ought not happen... |
| 729 | * |
| 730 | * Assumption: don't need to use anything but one dc entry: |
| 731 | * this means the directory ought not be greater than 64k. |
| 732 | */ |
| 733 | len = 0; |
| 734 | #ifdef AFS_HPUX_ENV |
| 735 | auio->uio_fpflags = 0; |
| 736 | #endif |
| 737 | while (code == 0) { |
| 738 | origOffset = AFS_UIO_OFFSET(auio)(auio)->uio_offset; |
| 739 | /* scan for the next interesting entry scan for in-use blob otherwise up point at |
| 740 | * this blob note that ode, if non-zero, also represents a held dir page */ |
| 741 | if (!(us = BlobScan(tdc, (origOffset >> 5))) |
| 742 | || (afs_dir_GetBlob(tdc, us, &nextEntry) != 0)) { |
| 743 | /* failed to setup nde, return what we've got, and release ode */ |
| 744 | if (len) { |
| 745 | /* something to hand over. */ |
| 746 | #ifdef AFS_HPUX_ENV |
| 747 | sdirEntry->d_fileno = afs_calc_inum(avc->f.fidusr_fid.Cell, |
| 748 | avc->f.fidusr_fid.Fid.Volume, |
| 749 | ntohl(ode->fid.vnode)(__builtin_constant_p(ode->usr_fid.usr_vnode) ? ((((__uint32_t )(ode->usr_fid.usr_vnode)) >> 24) | ((((__uint32_t)( ode->usr_fid.usr_vnode)) & (0xff << 16)) >> 8) | ((((__uint32_t)(ode->usr_fid.usr_vnode)) & (0xff << 8)) << 8) | (((__uint32_t)(ode->usr_fid.usr_vnode )) << 24)) : __bswap32_var(ode->usr_fid.usr_vnode))); |
| 750 | sdirEntry->d_reclen = rlen = AFS_UIO_RESID(auio)(auio)->uio_resid; |
| 751 | sdirEntry->d_namlen = o_slen; |
| 752 | #if defined(AFS_SUN5_ENV) || defined(AFS_AIX32_ENV) || defined(AFS_HPUX100_ENV) |
| 753 | sdirEntry->d_off = origOffset; |
| 754 | #endif |
| 755 | AFS_UIOMOVE((char *)sdirEntry, sizeof(*sdirEntry), UIO_READ,do { code = usr_uiomove(((char *)sdirEntry),(sizeof(*sdirEntry )),(0x0000),(auio)); } while(0) |
| 756 | auio, code)do { code = usr_uiomove(((char *)sdirEntry),(sizeof(*sdirEntry )),(0x0000),(auio)); } while(0); |
| 757 | if (code == 0) |
| 758 | AFS_UIOMOVE(ode->name, o_slen, UIO_READ, auio, code)do { code = usr_uiomove((ode->name),(o_slen),(0x0000),(auio )); } while(0); |
| 759 | /* pad out the remaining characters with zeros */ |
| 760 | if (code == 0) { |
| 761 | AFS_UIOMOVE(bufofzeros,do { code = usr_uiomove((bufofzeros),(((o_slen + 1 + 3) & ~3) - o_slen),(0x0000),(auio)); } while(0) |
| 762 | ((o_slen + 1 + DIRPAD) & ~DIRPAD) - o_slen,do { code = usr_uiomove((bufofzeros),(((o_slen + 1 + 3) & ~3) - o_slen),(0x0000),(auio)); } while(0) |
| 763 | UIO_READ, auio, code)do { code = usr_uiomove((bufofzeros),(((o_slen + 1 + 3) & ~3) - o_slen),(0x0000),(auio)); } while(0); |
| 764 | } |
| 765 | /* pad out the difference between rlen and slen... */ |
| 766 | if (DIRSIZ_LEN(o_slen)((sizeof (struct usr_dirent) - (255 +1)) + (((o_slen)+1 + 3) & ~ 3)) < rlen) { |
| 767 | while (DIRSIZ_LEN(o_slen)((sizeof (struct usr_dirent) - (255 +1)) + (((o_slen)+1 + 3) & ~ 3)) < rlen) { |
| 768 | int minLen = rlen - DIRSIZ_LEN(o_slen)((sizeof (struct usr_dirent) - (255 +1)) + (((o_slen)+1 + 3) & ~ 3)); |
| 769 | if (minLen > sizeof(bufofzeros)) |
| 770 | minLen = sizeof(bufofzeros); |
| 771 | AFS_UIOMOVE(bufofzeros, minLen, UIO_READ, auio, code)do { code = usr_uiomove((bufofzeros),(minLen),(0x0000),(auio) ); } while(0); |
| 772 | rlen -= minLen; |
| 773 | } |
| 774 | } |
| 775 | #else |
| 776 | code = afs_readdir_move(ode, avc, auio, o_slen, |
| 777 | #if defined(AFS_SUN5_ENV) || defined(AFS_NBSD_ENV) |
| 778 | len, origOffset); |
| 779 | #else |
| 780 | AFS_UIO_RESID(auio)(auio)->uio_resid, origOffset); |
| 781 | #endif |
| 782 | #endif /* AFS_HPUX_ENV */ |
| 783 | #if !defined(AFS_SUN5_ENV) && !defined(AFS_NBSD_ENV) |
| 784 | AFS_UIO_SETRESID(auio, 0)(auio)->uio_resid = 0; |
| 785 | #endif |
| 786 | } else { |
| 787 | /* nothin to hand over */ |
| 788 | } |
| 789 | #if defined(AFS_SUN5_ENV) || defined(AFS_SGI_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) |
| 790 | if (eofp) |
| 791 | *eofp = 1; /* Set it properly */ |
| 792 | #endif |
| 793 | DRelease(&oldEntry, 0); |
| 794 | goto dirend; |
| 795 | } |
| 796 | nde = (struct DirEntry *)nextEntry.data; |
| 797 | |
| 798 | /* Do we have enough user space to carry out our mission? */ |
| 799 | #if defined(AFS_SGI_ENV) |
| 800 | n_slen = strlen(nde->name) + 1; /* NULL terminate */ |
| 801 | #else |
| 802 | n_slen = strlen(nde->name); |
| 803 | #endif |
| 804 | #ifdef AFS_SGI53_ENV |
| 805 | dirsiz = |
| 806 | use64BitDirent ? DIRENTSIZE(n_slen) : IRIX5_DIRENTSIZE(n_slen); |
| 807 | if (dirsiz >= (AFS_UIO_RESID(auio)(auio)->uio_resid - len)) { |
| 808 | #else |
| 809 | if (DIRSIZ_LEN(n_slen)((sizeof (struct usr_dirent) - (255 +1)) + (((n_slen)+1 + 3) & ~ 3)) >= (AFS_UIO_RESID(auio)(auio)->uio_resid - len)) { |
| 810 | #endif /* AFS_SGI53_ENV */ |
| 811 | /* No can do no more now; ya know... at this time */ |
| 812 | DRelease(&nextEntry, 0); /* can't use this one. */ |
| 813 | if (len) { |
| 814 | #ifdef AFS_HPUX_ENV |
| 815 | sdirEntry->d_fileno = afs_calc_inum(avc->f.fidusr_fid.Cell, |
| 816 | avc->f.fidusr_fid.Fid.Volume, |
| 817 | ntohl(ode->fid.vnode)(__builtin_constant_p(ode->usr_fid.usr_vnode) ? ((((__uint32_t )(ode->usr_fid.usr_vnode)) >> 24) | ((((__uint32_t)( ode->usr_fid.usr_vnode)) & (0xff << 16)) >> 8) | ((((__uint32_t)(ode->usr_fid.usr_vnode)) & (0xff << 8)) << 8) | (((__uint32_t)(ode->usr_fid.usr_vnode )) << 24)) : __bswap32_var(ode->usr_fid.usr_vnode))); |
| 818 | sdirEntry->d_reclen = rlen = AFS_UIO_RESID(auio)(auio)->uio_resid; |
| 819 | sdirEntry->d_namlen = o_slen; |
| 820 | #if defined(AFS_SUN5_ENV) || defined(AFS_AIX32_ENV) || defined(AFS_HPUX100_ENV) |
| 821 | sdirEntry->d_off = origOffset; |
| 822 | #endif |
| 823 | AFS_UIOMOVE((char *)sdirEntry, sizeof(*sdirEntry), UIO_READ,do { code = usr_uiomove(((char *)sdirEntry),(sizeof(*sdirEntry )),(0x0000),(auio)); } while(0) |
| 824 | auio, code)do { code = usr_uiomove(((char *)sdirEntry),(sizeof(*sdirEntry )),(0x0000),(auio)); } while(0); |
| 825 | if (code == 0) |
| 826 | AFS_UIOMOVE(ode->name, o_slen, UIO_READ, auio, code)do { code = usr_uiomove((ode->name),(o_slen),(0x0000),(auio )); } while(0); |
| 827 | /* pad out the remaining characters with zeros */ |
| 828 | if (code == 0) { |
| 829 | AFS_UIOMOVE(bufofzeros,do { code = usr_uiomove((bufofzeros),(((o_slen + 1 + 3) & ~3) - o_slen),(0x0000),(auio)); } while(0) |
| 830 | ((o_slen + 1 + DIRPAD) & ~DIRPAD) - o_slen,do { code = usr_uiomove((bufofzeros),(((o_slen + 1 + 3) & ~3) - o_slen),(0x0000),(auio)); } while(0) |
| 831 | UIO_READ, auio, code)do { code = usr_uiomove((bufofzeros),(((o_slen + 1 + 3) & ~3) - o_slen),(0x0000),(auio)); } while(0); |
| 832 | } |
| 833 | /* pad out the difference between rlen and slen... */ |
| 834 | if (DIRSIZ_LEN(o_slen)((sizeof (struct usr_dirent) - (255 +1)) + (((o_slen)+1 + 3) & ~ 3)) < rlen) { |
| 835 | while (DIRSIZ_LEN(o_slen)((sizeof (struct usr_dirent) - (255 +1)) + (((o_slen)+1 + 3) & ~ 3)) < rlen) { |
| 836 | int minLen = rlen - DIRSIZ_LEN(o_slen)((sizeof (struct usr_dirent) - (255 +1)) + (((o_slen)+1 + 3) & ~ 3)); |
| 837 | if (minLen > sizeof(bufofzeros)) |
| 838 | minLen = sizeof(bufofzeros); |
| 839 | AFS_UIOMOVE(bufofzeros, minLen, UIO_READ, auio, code)do { code = usr_uiomove((bufofzeros),(minLen),(0x0000),(auio) ); } while(0); |
| 840 | rlen -= minLen; |
| 841 | } |
| 842 | } |
| 843 | #else /* AFS_HPUX_ENV */ |
| 844 | code = |
| 845 | afs_readdir_move(ode, avc, auio, o_slen, |
| 846 | AFS_UIO_RESID(auio)(auio)->uio_resid, origOffset); |
| 847 | #endif /* AFS_HPUX_ENV */ |
| 848 | /* this next line used to be AFSVFS40 or AIX 3.1, but is |
| 849 | * really generic */ |
| 850 | AFS_UIO_SETOFFSET(auio, origOffset)(auio)->uio_offset = origOffset; |
| 851 | #if !defined(AFS_NBSD_ENV) |
| 852 | AFS_UIO_SETRESID(auio, 0)(auio)->uio_resid = 0; |
| 853 | #endif |
| 854 | } else { /* trouble, can't give anything to the user! */ |
| 855 | /* even though he has given us a buffer, |
| 856 | * even though we have something to give us, |
| 857 | * Looks like we lost something somewhere. |
| 858 | */ |
| 859 | code = EINVAL22; |
| 860 | } |
| 861 | DRelease(&oldEntry, 0); |
| 862 | goto dirend; |
| 863 | } |
| 864 | |
| 865 | /* |
| 866 | * In any event, we move out the LAST de entry, getting ready |
| 867 | * to set up for the next one. |
| 868 | */ |
| 869 | if (len) { |
| 870 | #ifdef AFS_HPUX_ENV |
| 871 | sdirEntry->d_fileno = afs_calc_inum(avc->f.fidusr_fid.Cell, |
| 872 | avc->f.fidusr_fid.Fid.Volume, |
| 873 | ntohl(ode->fid.vnode)(__builtin_constant_p(ode->usr_fid.usr_vnode) ? ((((__uint32_t )(ode->usr_fid.usr_vnode)) >> 24) | ((((__uint32_t)( ode->usr_fid.usr_vnode)) & (0xff << 16)) >> 8) | ((((__uint32_t)(ode->usr_fid.usr_vnode)) & (0xff << 8)) << 8) | (((__uint32_t)(ode->usr_fid.usr_vnode )) << 24)) : __bswap32_var(ode->usr_fid.usr_vnode))); |
| 874 | sdirEntry->d_reclen = rlen = len; |
| 875 | sdirEntry->d_namlen = o_slen; |
| 876 | #if defined(AFS_SUN5_ENV) || defined(AFS_AIX32_ENV) || defined(AFS_HPUX100_ENV) |
| 877 | sdirEntry->d_off = origOffset; |
| 878 | #endif |
| 879 | AFS_UIOMOVE((char *)sdirEntry, sizeof(*sdirEntry), UIO_READ, auio,do { code = usr_uiomove(((char *)sdirEntry),(sizeof(*sdirEntry )),(0x0000),(auio)); } while(0) |
| 880 | code)do { code = usr_uiomove(((char *)sdirEntry),(sizeof(*sdirEntry )),(0x0000),(auio)); } while(0); |
| 881 | if (code == 0) |
| 882 | AFS_UIOMOVE(ode->name, o_slen, UIO_READ, auio, code)do { code = usr_uiomove((ode->name),(o_slen),(0x0000),(auio )); } while(0); |
| 883 | /* pad out the remaining characters with zeros */ |
| 884 | if (code == 0) { |
| 885 | AFS_UIOMOVE(bufofzeros,do { code = usr_uiomove((bufofzeros),(((o_slen + 1 + 3) & ~3) - o_slen),(0x0000),(auio)); } while(0) |
| 886 | ((o_slen + 1 + DIRPAD) & ~DIRPAD) - o_slen,do { code = usr_uiomove((bufofzeros),(((o_slen + 1 + 3) & ~3) - o_slen),(0x0000),(auio)); } while(0) |
| 887 | UIO_READ, auio, code)do { code = usr_uiomove((bufofzeros),(((o_slen + 1 + 3) & ~3) - o_slen),(0x0000),(auio)); } while(0); |
| 888 | } |
| 889 | /* pad out the difference between rlen and slen... */ |
| 890 | if (DIRSIZ_LEN(o_slen)((sizeof (struct usr_dirent) - (255 +1)) + (((o_slen)+1 + 3) & ~ 3)) < rlen) { |
| 891 | while (DIRSIZ_LEN(o_slen)((sizeof (struct usr_dirent) - (255 +1)) + (((o_slen)+1 + 3) & ~ 3)) < rlen) { |
| 892 | int minLen = rlen - DIRSIZ_LEN(o_slen)((sizeof (struct usr_dirent) - (255 +1)) + (((o_slen)+1 + 3) & ~ 3)); |
| 893 | if (minLen > sizeof(bufofzeros)) |
| 894 | minLen = sizeof(bufofzeros); |
| 895 | AFS_UIOMOVE(bufofzeros, minLen, UIO_READ, auio, code)do { code = usr_uiomove((bufofzeros),(minLen),(0x0000),(auio) ); } while(0); |
| 896 | rlen -= minLen; |
| 897 | } |
| 898 | } |
| 899 | #else /* AFS_HPUX_ENV */ |
| 900 | code = afs_readdir_move(ode, avc, auio, o_slen, len, origOffset); |
| 901 | #endif /* AFS_HPUX_ENV */ |
| 902 | } |
| 903 | #ifdef AFS_SGI53_ENV |
| 904 | len = use64BitDirent ? DIRENTSIZE(o_slen = |
| 905 | n_slen) : IRIX5_DIRENTSIZE(o_slen = |
| 906 | n_slen); |
| 907 | #else |
| 908 | len = DIRSIZ_LEN(o_slen = n_slen)((sizeof (struct usr_dirent) - (255 +1)) + (((o_slen = n_slen )+1 + 3) &~ 3)); |
| 909 | #endif /* AFS_SGI53_ENV */ |
| 910 | |
| 911 | DRelease(&oldEntry, 0); |
| 912 | ode = nde; |
| 913 | AFS_UIO_SETOFFSET(auio, (afs_int32) ((us + afs_dir_NameBlobs(nde->name)) << 5))(auio)->uio_offset = (afs_int32) ((us + afs_dir_NameBlobs( nde->name)) << 5); |
| 914 | } |
| 915 | |
| 916 | DRelease(&oldEntry, 0); |
| 917 | |
| 918 | dirend: |
| 919 | ReleaseReadLock(&tdc->lock)do { ; if (!(--((&tdc->lock)->readers_reading)) && (&tdc->lock)->wait_states) Afs_Lock_ReleaseW(& tdc->lock) ; if ( (&tdc->lock)->pid_last_reader == (get_user_struct()->u_procp->p_pid ) ) (&tdc->lock )->pid_last_reader =0; } while (0); |
| 920 | afs_PutDCache(tdc); |
| 921 | ReleaseReadLock(&avc->lock)do { ; if (!(--((&avc->lock)->readers_reading)) && (&avc->lock)->wait_states) Afs_Lock_ReleaseW(& avc->lock) ; if ( (&avc->lock)->pid_last_reader == (get_user_struct()->u_procp->p_pid ) ) (&avc->lock )->pid_last_reader =0; } while (0); |
| 922 | |
| 923 | done: |
| 924 | #ifdef AFS_HPUX_ENV |
| 925 | osi_FreeSmallSpace((char *)sdirEntry); |
| 926 | #endif |
| 927 | AFS_DISCON_UNLOCK()do { ; if (!(--((&afs_discon_lock)->readers_reading)) && (&afs_discon_lock)->wait_states) Afs_Lock_ReleaseW(& afs_discon_lock) ; if ( (&afs_discon_lock)->pid_last_reader == (get_user_struct()->u_procp->p_pid ) ) (&afs_discon_lock )->pid_last_reader =0; } while (0); |
| 928 | afs_PutFakeStat(&fakestate); |
| 929 | code = afs_CheckCode(code, &treq, 28); |
| 930 | return code; |
| 931 | } |
| 932 | |
| 933 | #endif /* !AFS_LINUX20_ENV */ |