#include <afsconfig.h>
#include <afs/param.h>
-
-#include <sys/types.h>
-#include <errno.h>
-#ifdef AFS_NT40_ENV
-#include <winsock2.h>
-#else
-#include <netinet/in.h>
-#endif
-
-#include <string.h>
-
-#ifdef HAVE_STDINT_H
-# include <stdint.h>
-#endif
+#include <roken.h>
#include "dir.h"
/* Defined in vol/vol-salvage.c */
struct DirHeader *dhp;
struct PageHeader *pp;
struct DirEntry *ep;
+ struct DirBuffer headerbuf, pagebuf, entrybuf;
int i, j, k, up;
int havedot = 0, havedotdot = 0;
int usedPages, count, entry;
int eaSize;
afs_int32 entcount, maxents;
unsigned short ne;
+ int code;
eaSize = BIGMAXPAGES * EPP / 8;
/* Read the directory header */
- dhp = (struct DirHeader *)DRead(file, 0);
- if (!dhp) {
+ code = DRead(file,0, &headerbuf);
+ if (code) {
/* if DErrno is 0, then we know that the read worked, but was short,
* and the damage is permanent. Otherwise, we got an I/O or programming
* error. Claim the dir is OK, but log something.
printf("First page in directory does not exist.\n");
return 0;
}
+ dhp = (struct DirHeader *)headerbuf.data;
/* Check magic number for first page */
if (dhp->header.tag != htons(1234)) {
printf("Bad first pageheader magic number.\n");
- DRelease(dhp, 0);
+ DRelease(&headerbuf, 0);
return 0;
}
* two must exist for "." and ".."
*/
printf("The dir header alloc map for page %d is bad.\n", i);
- DRelease(dhp, 0);
+ DRelease(&headerbuf, 0);
return 0;
}
} else {
if ((j < 0) || (j > EPP)) {
printf("The dir header alloc map for page %d is bad.\n", i);
- DRelease(dhp, 0);
+ DRelease(&headerbuf, 0);
return 0;
}
}
printf
("A partially-full page occurs in slot %d, after the dir end.\n",
i);
- DRelease(dhp, 0);
+ DRelease(&headerbuf, 0);
return 0;
}
} else if (j == EPP) { /* is this the last page */
if (usedPages < up) {
printf
("Count of used directory pages does not match count in directory header\n");
- DRelease(dhp, 0);
+ DRelease(&headerbuf, 0);
return 0;
}
*/
for (i = 0; i < usedPages; i++) {
/* Read the page header */
- pp = (struct PageHeader *)DRead(file, i);
- if (!pp) {
- DRelease(dhp, 0);
+ code = DRead(file, i, &pagebuf);
+ if (code) {
+ DRelease(&headerbuf, 0);
if (DErrno != 0) {
/* couldn't read page, but not because it wasn't there permanently */
printf("Failed to read dir page %d (errno %d)\n", i, DErrno);
printf("Directory shorter than alloMap indicates (page %d)\n", i);
return 0;
}
+ pp = (struct PageHeader *)pagebuf.data;
/* check the tag field */
if (pp->tag != htons(1234)) {
printf("Directory page %d has a bad magic number.\n", i);
- DRelease(pp, 0);
- DRelease(dhp, 0);
+ DRelease(&pagebuf, 0);
+ DRelease(&headerbuf, 0);
return 0;
}
printf
("Header alloMap count doesn't match count in freebitmap for page %d.\n",
i);
- DRelease(pp, 0);
- DRelease(dhp, 0);
+ DRelease(&pagebuf, 0);
+ DRelease(&headerbuf, 0);
return 0;
}
- DRelease(pp, 0);
+ DRelease(&pagebuf, 0);
}
/* Initialize the in-memory freebit map for all pages. */
/* Verify that the entry is within range */
if (entry < 0 || entry >= maxents) {
printf("Out-of-range hash id %d in chain %d.\n", entry, i);
- DRelease(dhp, 0);
+ DRelease(&headerbuf, 0);
return 0;
}
/* Read the directory entry */
DErrno = 0;
- ep = GetBlob(file, entry);
- if (!ep) {
+ code = afs_dir_GetBlob(file, entry, &entrybuf);
+ if (code) {
if (DErrno != 0) {
/* something went wrong reading the page, but it wasn't
* really something wrong with the dir that we can fix.
*/
printf("Could not get dir blob %d (errno %d)\n", entry,
DErrno);
- DRelease(dhp, 0);
+ DRelease(&headerbuf, 0);
Die("dirok3");
}
printf("Invalid hash id %d in chain %d.\n", entry, i);
- DRelease(dhp, 0);
+ DRelease(&headerbuf, 0);
return 0;
}
+ ep = (struct DirEntry *)entrybuf.data;
+
ne = ntohs(ep->next);
/* There can't be more than maxents entries */
if (++entcount >= maxents) {
printf("Directory's hash chain %d is circular.\n", i);
- DRelease(ep, 0);
- DRelease(dhp, 0);
+ DRelease(&entrybuf, 0);
+ DRelease(&headerbuf, 0);
return 0;
}
if (ep->name[0] == '\000') {
printf("Dir entry %"AFS_PTR_FMT
" in chain %d has bogus (null) name.\n", ep, i);
- DRelease(ep, 0);
- DRelease(dhp, 0);
+ DRelease(&entrybuf, 0);
+ DRelease(&headerbuf, 0);
return 0;
}
if (ep->flag != FFIRST) {
printf("Dir entry %"AFS_PTR_FMT
" in chain %d has bogus flag field.\n", ep, i);
- DRelease(ep, 0);
- DRelease(dhp, 0);
+ DRelease(&entrybuf, 0);
+ DRelease(&headerbuf, 0);
return 0;
}
if (j >= MAXENAME) { /* MAXENAME counts the null */
printf("Dir entry %"AFS_PTR_FMT
" in chain %d has too-long name.\n", ep, i);
- DRelease(ep, 0);
- DRelease(dhp, 0);
+ DRelease(&entrybuf, 0);
+ DRelease(&headerbuf, 0);
return 0;
}
/* The name used up k directory entries, set the bit in our in-memory
* freebitmap for each entry used by the name.
*/
- k = NameBlobs(ep->name);
+ k = afs_dir_NameBlobs(ep->name);
for (j = 0; j < k; j++) {
eaMap[(entry + j) >> 3] |= (1 << ((entry + j) & 7));
}
/* Hash the name and make sure it is in the correct name hash */
- if ((j = DirHash(ep->name)) != i) {
+ if ((j = afs_dir_DirHash(ep->name)) != i) {
printf("Dir entry %"AFS_PTR_FMT
" should be in hash bucket %d but IS in %d.\n",
ep, j, i);
- DRelease(ep, 0);
- DRelease(dhp, 0);
+ DRelease(&entrybuf, 0);
+ DRelease(&headerbuf, 0);
return 0;
}
("Dir entry %"AFS_PTR_FMT
", index 13 has name '%s' should be '.'\n",
ep, ep->name);
- DRelease(ep, 0);
- DRelease(dhp, 0);
+ DRelease(&entrybuf, 0);
+ DRelease(&headerbuf, 0);
return 0;
}
}
("Dir entry %"AFS_PTR_FMT
", index 14 has name '%s' should be '..'\n",
ep, ep->name);
- DRelease(ep, 0);
- DRelease(dhp, 0);
+ DRelease(&entrybuf, 0);
+ DRelease(&headerbuf, 0);
return 0;
}
}
/* CHECK FOR DUPLICATE NAMES? */
- DRelease(ep, 0);
+ DRelease(&entrybuf, 0);
}
}
if (!havedot || !havedotdot) {
printf
("Directory entry '.' or '..' does not exist or is in the wrong index.\n");
- DRelease(dhp, 0);
+ DRelease(&headerbuf, 0);
return 0;
}
* Note that if this matches, alloMap has already been checked against it.
*/
for (i = 0; i < usedPages; i++) {
- pp = DRead(file, i);
- if (!pp) {
+ code = DRead(file, i, &pagebuf);
+ if (code) {
printf
("Failed on second attempt to read dir page %d (errno %d)\n",
i, DErrno);
- DRelease(dhp, 0);
+ DRelease(&headerbuf, 0);
/* if DErrno is 0, then the dir is really bad, and we return dir *not* OK.
* otherwise, we want to return true (1), meaning the dir isn't known
* to be bad (we can't tell, since I/Os are failing.
else
return 0; /* dir is really shorter */
}
+ pp = (struct PageHeader *)pagebuf.data;
count = i * (EPP / 8);
for (j = 0; j < EPP / 8; j++) {
printf
("Entry freebitmap error, page %d, map offset %d, %x should be %x.\n",
i, j, pp->freebitmap[j], eaMap[count + j]);
- DRelease(pp, 0);
- DRelease(dhp, 0);
+ DRelease(&pagebuf, 0);
+ DRelease(&headerbuf, 0);
return 0;
}
}
- DRelease(pp, 0);
+ DRelease(&pagebuf, 0);
}
/* Finally cleanup and return. */
- DRelease(dhp, 0);
+ DRelease(&headerbuf, 0);
return 1;
}
char tname[256];
int i;
char *tp;
+ struct DirBuffer headerbuf, entrybuf;
struct DirHeader *dhp;
struct DirEntry *ep;
int entry;
dotdot[1] = pvn;
dotdot[2] = pvu;
- MakeDir(toFile, dot, dotdot); /* Returns no error code. */
+ afs_dir_MakeDir(toFile, dot, dotdot); /* Returns no error code. */
/* Find out how many pages are valid, using stupid heuristic since DRead
* never returns null.
*/
- dhp = (struct DirHeader *)DRead(fromFile, 0);
- if (!dhp) {
+ code = DRead(fromFile, 0, &headerbuf);
+ if (code) {
printf("Failed to read first page of fromDir!\n");
/* if DErrno != 0, then our call failed and we should let our
* caller know that there's something wrong with the new dir. If not,
*/
return DErrno;
}
+ dhp = (struct DirHeader *)headerbuf.data;
usedPages = ComputeUsedPages(dhp);
("Warning: bogus hash table entry encountered, ignoring.\n");
break;
}
+
DErrno = 0;
- ep = GetBlob(fromFile, entry);
- if (!ep) {
+ code = afs_dir_GetBlob(fromFile, entry, &entrybuf);
+ if (code) {
if (DErrno) {
printf
("can't continue down hash chain (entry %d, errno %d)\n",
entry, DErrno);
- DRelease(dhp, 0);
+ DRelease(&headerbuf, 0);
return DErrno;
}
printf
("Warning: bogus hash chain encountered, switching to next.\n");
break;
}
+ ep = (struct DirEntry *)entrybuf.data;
+
strncpy(tname, ep->name, MAXENAME);
tname[MAXENAME - 1] = '\000'; /* just in case */
tp = tname;
if ((strcmp(tp, ".") != 0) && (strcmp(tp, "..") != 0)) {
lfid[1] = ntohl(ep->fid.vnode);
lfid[2] = ntohl(ep->fid.vunique);
- code = Create(toFile, tname, lfid);
+ code = afs_dir_Create(toFile, tname, lfid);
if (code) {
printf
("Create of %s returned code %d, skipping to next hash chain.\n",
tname, code);
- DRelease(ep, 0);
+ DRelease(&entrybuf, 0);
break;
}
}
- DRelease(ep, 0);
+ DRelease(&entrybuf, 0);
}
}
/* Clean up things. */
- DRelease(dhp, 0);
+ DRelease(&headerbuf, 0);
return 0;
}