}
#endif
-extern int BlobScan(struct dcache * afile, afs_int32 ablob);
+extern int BlobScan(struct dcache * afile, afs_int32 ablob, afs_int32 *ablobOut);
/* This is a complete rewrite of afs_readdir, since we can make use of
* filldir instead of afs_readdir_move. Note that changes to vcache/dcache
struct dcache *tdc;
int code;
int offset;
- int dirpos;
+ afs_int32 dirpos;
struct DirEntry *de;
struct DirBuffer entry;
ino_t ino;
offset = (int) fp->f_pos;
#endif
while (1) {
- dirpos = BlobScan(tdc, offset);
- if (!dirpos)
+ code = BlobScan(tdc, offset, &dirpos);
+ if (code || !dirpos)
break;
code = afs_dir_GetVerifiedBlob(tdc, dirpos, &entry);
return 0;
}
-extern int BlobScan(struct dcache * afile, afs_int32 ablob);
+extern int BlobScan(struct dcache * afile, afs_int32 ablob, afs_int32 *ablobOut);
/* called with an unlocked directory and directory cookie. Areqp
* describes who is making the call.
int ftype[4] = {VNON, VREG, VDIR, VLNK}; /* verify type is as expected */
afs_size_t statSeqNo = 0; /* Valued of file size to detect races */
int code; /* error code */
- long newIndex; /* new index in the dir */
+ afs_int32 newIndex; /* new index in the dir */
struct DirBuffer entry; /* Buffer for dir manipulation */
struct DirEntry *dirEntryp; /* dir entry we are examining */
int i;
/* look for first safe entry to examine in the directory. BlobScan
* looks for a the 1st allocated dir after the dirCookie slot.
*/
- newIndex = BlobScan(dcp, (dirCookie >> 5));
- if (newIndex == 0)
+ code = BlobScan(dcp, (dirCookie >> 5), &newIndex);
+ if (code || newIndex == 0)
break;
/* remember the updated directory cookie */
* AFS readdir vnodeop and bulk stat support.
*/
-/* BlobScan is supposed to ensure that the blob reference refers to a valid
- directory entry. It consults the allocation map in the page header
- to determine whether a blob is actually in use or not.
-
- More formally, BlobScan is supposed to return a new blob number which is just like
- the input parameter, only it is advanced over header or free blobs.
-
- Note that BlobScan switches pages if necessary. BlobScan may return
- either 0 or an out-of-range blob number for end of file.
-
- BlobScan is used by the Linux port in a separate file, so it should not
- become static.
-*/
+/**
+ * Ensure that the blob reference refers to a valid directory entry.
+ * It consults the allocation map in the page header to determine
+ * whether a blob is actually in use or not.
+ *
+ * More formally, BlobScan is supposed to return a new blob number
+ * which is just like the input parameter, only it is advanced over
+ * header or free blobs.
+ *
+ * Note that BlobScan switches pages if necessary. BlobScan may
+ * return either 0 for success or an error code. Upon successful
+ * return, the new blob value is assigned to *ablobOut.
+ *
+ * BlobScan is used by the Linux port in a separate file, so it should not
+ * become static.
+ */
int
-BlobScan(struct dcache * afile, afs_int32 ablob)
+BlobScan(struct dcache * afile, afs_int32 ablob, int *ablobOut)
{
afs_int32 relativeBlob;
afs_int32 pageBlob;
pageBlob = ablob & ~(EPP - 1); /* base blob in same page */
code = afs_dir_GetBlob(afile, pageBlob, &headerbuf);
if (code)
- return 0;
+ return code;
tpe = (struct PageHeader *)headerbuf.data;
relativeBlob = ablob - pageBlob; /* relative to page's first blob */
/* now relativeBlob is the page-relative first allocated blob,
* or EPP (if there are none in this page). */
DRelease(&headerbuf, 0);
- if (i != EPP)
- return i + pageBlob;
+ if (i != EPP) {
+ *ablobOut = i + pageBlob;
+ return 0;
+ }
ablob = pageBlob + EPP; /* go around again */
}
/* never get here */
struct DirBuffer oldEntry, nextEntry;
struct DirEntry *ode = 0, *nde = 0;
int o_slen = 0, n_slen = 0;
- afs_uint32 us;
+ afs_int32 us;
struct afs_fakestat_state fakestate;
#if defined(AFS_SGI53_ENV)
afs_int32 use64BitDirent, dirsiz;
origOffset = AFS_UIO_OFFSET(auio);
/* scan for the next interesting entry scan for in-use blob otherwise up point at
* this blob note that ode, if non-zero, also represents a held dir page */
- us = BlobScan(tdc, (origOffset >> 5));
+ code = BlobScan(tdc, (origOffset >> 5), &us);
- if (us)
+ if (code == 0 && us)
code = afs_dir_GetVerifiedBlob(tdc, us, &nextEntry);
if (us == 0 || code != 0) {
DRelease(&oldEntry, 0);
oldEntry = nextEntry;
ode = nde;
- AFS_UIO_SETOFFSET(auio, (afs_int32) ((us + afs_dir_NameBlobs(nde->name)) << 5));
+ AFS_UIO_SETOFFSET(auio, (us + afs_dir_NameBlobs(nde->name)) << 5);
}
DRelease(&oldEntry, 0);