Bug Summary

File:afs/VNOPS/afs_vnop_readdir.c
Location:line 674, column 5
Description:Value stored to 'len' is never read

Annotated Source Code

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*/
58int
59BlobScan(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. */
117struct 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. */
124struct 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
138struct 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)
173struct 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
192struct AFSFid afs_readdir_stash[READDIR_STASH50];
193int 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)
236int
237afs_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
284char bufofzeros[64]; /* gotta fill with something */
285
286#ifdef AFS_SGI65_ENV
287int
288afs_readdir_move(struct DirEntry *de, struct vcache *vc, struct uiousr_uio *auio,
289 int slen, ssize_t rlen, afs_size_t off)
290#else
291int
292afs_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
564void
565afs_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
575int
576#if defined(AFS_SUN5_ENV) || defined(AFS_SGI_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
577afs_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)
581afs_readdir2(OSI_VC_DECL(avc)struct vcache *avc, struct uiousr_uio *auio, afs_ucred_tstruct usr_ucred *acred)
582#else
583afs_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 */