dir: Prototype and function name cleanup
[openafs.git] / src / dir / salvage.c
index 75f5bc3..d984c11 100644 (file)
@@ -1,56 +1,46 @@
 /*
  * Copyright 2000, International Business Machines Corporation and others.
  * All Rights Reserved.
- * 
+ *
  * This software has been released under the terms of the IBM Public
  * License.  For details, see the LICENSE file in the top-level source
  * directory or online at http://www.openafs.org/dl/license10.html
  */
 
-/* This is the directory salvager.  It consists of two routines.  The first, 
- * DirOK, checks to see if the directory looks good.  If the directory does 
- * NOT look good, the approved procedure is to then call Salvage, which 
- * copies all the good entries from the damaged dir into a new directory. 
+/* This is the directory salvager.  It consists of two routines.  The first,
+ * DirOK, checks to see if the directory looks good.  If the directory does
+ * NOT look good, the approved procedure is to then call Salvage, which
+ * copies all the good entries from the damaged dir into a new directory.
  */
 
 #include <afsconfig.h>
 #include <afs/param.h>
 
-RCSID
-    ("$Header$");
-
-#include <sys/types.h>
-#include <errno.h>
-#ifdef AFS_NT40_ENV
-#include <winsock2.h>
-#else
-#include <netinet/in.h>
-#endif
-
-#include <string.h>
+#include <roken.h>
 
 #include "dir.h"
 /* Defined in vol/vol-salvage.c */
-extern void Log(const char *format, ...);
+extern void Log(const char *format, ...)
+    AFS_ATTRIBUTE_FORMAT(__printf__, 1, 2);
 /* Defined in vol/physio.c */
 extern void Die(char *);
-    
+
 #define printf Log             /* To make it work with volume salvager */
 
-/* This routine is called with one parameter, the id (the same thing that is 
- * passed to physio or the buffer package) of a directory to check.  It 
+/* This routine is called with one parameter, the id (the same thing that is
+ * passed to physio or the buffer package) of a directory to check.  It
  * returns 1 if the directory looks good, and 0 otherwise. */
 
 #define MAXENAME 256
 
 extern afs_int32 DErrno;
 
-/* figure out how many pages in use in a directory, given ptr to its (locked) 
+/* figure out how many pages in use in a directory, given ptr to its (locked)
  * header */
 static int
-ComputeUsedPages(register struct DirHeader *dhp)
+ComputeUsedPages(struct DirHeader *dhp)
 {
-    register afs_int32 usedPages, i;
+    afs_int32 usedPages, i;
 
     if (dhp->header.pgcount != 0) {
        /* new style */
@@ -70,8 +60,14 @@ ComputeUsedPages(register struct DirHeader *dhp)
     return usedPages;
 }
 
-/* returns true if something went wrong checking, or if dir is fine.  Returns
- * false if we *know* that the dir is bad.
+/**
+ * check whether a directory object is ok.
+ *
+ * @param[in] file  opaque pointer to directory object fid
+ *
+ * @return operation status
+ *    @retval 1 dir is fine, or something went wrong checking
+ *    @retval 0 we *know* that the dir is bad
  */
 int
 DirOK(void *file)
@@ -79,6 +75,7 @@ DirOK(void *file)
     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;
@@ -86,12 +83,13 @@ DirOK(void *file)
     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.
@@ -104,11 +102,12 @@ DirOK(void *file)
        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((struct buffer *)dhp, 0);
+       DRelease(&headerbuf, 0);
        return 0;
     }
 
@@ -129,13 +128,13 @@ DirOK(void *file)
                 * two must exist for "." and ".."
                 */
                printf("The dir header alloc map for page %d is bad.\n", i);
-               DRelease((struct buffer *)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((struct buffer *)dhp, 0);
+               DRelease(&headerbuf, 0);
                return 0;
            }
        }
@@ -146,7 +145,7 @@ DirOK(void *file)
                printf
                    ("A partially-full page occurs in slot %d, after the dir end.\n",
                     i);
-               DRelease((struct buffer *)dhp, 0);
+               DRelease(&headerbuf, 0);
                return 0;
            }
        } else if (j == EPP) {  /* is this the last page */
@@ -156,7 +155,7 @@ DirOK(void *file)
        }
     }
 
-    /* Compute number of used directory pages and max entries in all 
+    /* Compute number of used directory pages and max entries in all
      ** those pages, the value of 'up' must be less than pgcount. The above
      ** loop only checks the first MAXPAGES in a directory. An alloMap does
      ** not exists for pages between MAXPAGES and BIGMAXPAGES */
@@ -164,7 +163,7 @@ DirOK(void *file)
     if (usedPages < up) {
        printf
            ("Count of used directory pages does not match count in directory header\n");
-       DRelease((struct buffer *)dhp, 0);
+       DRelease(&headerbuf, 0);
        return 0;
     }
 
@@ -174,9 +173,9 @@ DirOK(void *file)
      */
     for (i = 0; i < usedPages; i++) {
        /* Read the page header */
-       pp = (struct PageHeader *)DRead(file, i);
-       if (!pp) {
-           DRelease((struct buffer *)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);
@@ -186,12 +185,13 @@ DirOK(void *file)
            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((struct buffer *)pp, 0);
-           DRelease((struct buffer *)dhp, 0);
+           DRelease(&pagebuf, 0);
+           DRelease(&headerbuf, 0);
            return 0;
        }
 
@@ -225,12 +225,12 @@ DirOK(void *file)
            printf
                ("Header alloMap count doesn't match count in freebitmap for page %d.\n",
                 i);
-           DRelease((struct buffer *)pp, 0);
-           DRelease((struct buffer *)dhp, 0);
+           DRelease(&pagebuf, 0);
+           DRelease(&headerbuf, 0);
            return 0;
        }
 
-       DRelease((struct buffer *)pp, 0);
+       DRelease(&pagebuf, 0);
     }
 
     /* Initialize the in-memory freebit map for all pages. */
@@ -258,80 +258,82 @@ DirOK(void *file)
            /* 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((struct buffer *)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((struct buffer *)dhp, 0);
+                   DRelease(&headerbuf, 0);
                    Die("dirok3");
                }
                printf("Invalid hash id %d in chain %d.\n", entry, i);
-               DRelease((struct buffer *)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((struct buffer *)ep, 0);
-               DRelease((struct buffer *)dhp, 0);
+               DRelease(&entrybuf, 0);
+               DRelease(&headerbuf, 0);
                return 0;
            }
 
            /* A null name is no good */
            if (ep->name[0] == '\000') {
-               printf("Dir entry %x in chain %d has bogus (null) name.\n",
-                      (int)ep, i);
-               DRelease((struct buffer *)ep, 0);
-               DRelease((struct buffer *)dhp, 0);
+               printf("Dir entry %"AFS_PTR_FMT
+                      " in chain %d has bogus (null) name.\n", ep, i);
+               DRelease(&entrybuf, 0);
+               DRelease(&headerbuf, 0);
                return 0;
            }
 
            /* The entry flag better be FFIRST */
            if (ep->flag != FFIRST) {
-               printf("Dir entry %x in chain %d has bogus flag field.\n", (int)ep,
-                      i);
-               DRelease((struct buffer *)ep, 0);
-               DRelease((struct buffer *)dhp, 0);
+               printf("Dir entry %"AFS_PTR_FMT
+                      " in chain %d has bogus flag field.\n", ep, i);
+               DRelease(&entrybuf, 0);
+               DRelease(&headerbuf, 0);
                return 0;
            }
 
            /* Check the size of the name */
            j = strlen(ep->name);
            if (j >= MAXENAME) {        /* MAXENAME counts the null */
-               printf("Dir entry %x in chain %d has too-long name.\n", (int)ep,
-                      i);
-               DRelease((struct buffer *)ep, 0);
-               DRelease((struct buffer *)dhp, 0);
+               printf("Dir entry %"AFS_PTR_FMT
+                      " in chain %d has too-long name.\n", ep, i);
+               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) {
-               printf
-                   ("Dir entry %x should be in hash bucket %d but IS in %d.\n",
-                    (int)ep, j, i);
-               DRelease((struct buffer *)ep, 0);
-               DRelease((struct buffer *)dhp, 0);
+           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(&entrybuf, 0);
+               DRelease(&headerbuf, 0);
                return 0;
            }
 
@@ -341,10 +343,11 @@ DirOK(void *file)
                    havedot = 1;
                } else {
                    printf
-                       ("Dir entry %x, index 13 has name '%s' should be '.'\n",
-                        (int)ep, ep->name);
-                   DRelease((struct buffer *)ep, 0);
-                   DRelease((struct buffer *)dhp, 0);
+                       ("Dir entry %"AFS_PTR_FMT
+                        ", index 13 has name '%s' should be '.'\n",
+                        ep, ep->name);
+                   DRelease(&entrybuf, 0);
+                   DRelease(&headerbuf, 0);
                    return 0;
                }
            }
@@ -355,17 +358,18 @@ DirOK(void *file)
                    havedotdot = 1;
                } else {
                    printf
-                       ("Dir entry %x, index 14 has name '%s' should be '..'\n",
-                        (int)ep, ep->name);
-                   DRelease((struct buffer *)ep, 0);
-                   DRelease((struct buffer *)dhp, 0);
+                       ("Dir entry %"AFS_PTR_FMT
+                        ", index 14 has name '%s' should be '..'\n",
+                        ep, ep->name);
+                   DRelease(&entrybuf, 0);
+                   DRelease(&headerbuf, 0);
                    return 0;
                }
            }
 
            /* CHECK FOR DUPLICATE NAMES? */
 
-           DRelease((struct buffer *)ep, 0);
+           DRelease(&entrybuf, 0);
        }
     }
 
@@ -373,7 +377,7 @@ DirOK(void *file)
     if (!havedot || !havedotdot) {
        printf
            ("Directory entry '.' or '..' does not exist or is in the wrong index.\n");
-       DRelease((struct buffer *)dhp, 0);
+       DRelease(&headerbuf, 0);
        return 0;
     }
 
@@ -382,12 +386,12 @@ DirOK(void *file)
      * 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((struct buffer *)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.
@@ -397,6 +401,7 @@ DirOK(void *file)
            else
                return 0;       /* dir is really shorter */
        }
+       pp = (struct PageHeader *)pagebuf.data;
 
        count = i * (EPP / 8);
        for (j = 0; j < EPP / 8; j++) {
@@ -404,37 +409,43 @@ DirOK(void *file)
                printf
                    ("Entry freebitmap error, page %d, map offset %d, %x should be %x.\n",
                     i, j, pp->freebitmap[j], eaMap[count + j]);
-               DRelease((struct buffer *)pp, 0);
-               DRelease((struct buffer *)dhp, 0);
+               DRelease(&pagebuf, 0);
+               DRelease(&headerbuf, 0);
                return 0;
            }
        }
 
-       DRelease((struct buffer *)pp, 0);
+       DRelease(&pagebuf, 0);
     }
 
     /* Finally cleanup and return. */
-    DRelease((struct buffer *)dhp, 0);
+    DRelease(&headerbuf, 0);
     return 1;
 }
 
-/* This routine is called with six parameters.  The first is the id of 
- * the original, currently suspect, directory.  The second is the file 
- * id of the place the salvager should place the new, fixed, directory. 
- * The third and the fourth parameters are the vnode number and the
- * uniquifier of the currently suspect directory. The fifth and the
- * sixth parameters are the vnode number and the uniquifier of the
- * parent directory.
+/**
+ * Salvage a directory object.
+ *
+ * @param[in] fromFile  fid of original, currently suspect directory object
+ * @param[in] toFile    fid where salvager will place new, fixed directory
+ * @param[in] vn        vnode of currently suspect directory
+ * @param[in] vu        uniquifier of currently suspect directory
+ * @param[in] pvn       vnode of parent directory
+ * @param[in] pvu       uniquifier of parent directory
+ *
+ * @return operation status
+ *    @retval 0 success
  */
 int
-DirSalvage(char *fromFile, char *toFile, afs_int32 vn, afs_int32 vu, 
+DirSalvage(void *fromFile, void *toFile, afs_int32 vn, afs_int32 vu,
           afs_int32 pvn, afs_int32 pvu)
 {
     /* First do a MakeDir on the target. */
     afs_int32 dot[3], dotdot[3], lfid[3], code, usedPages;
     char tname[256];
-    register int i;
-    register char *tp;
+    int i;
+    char *tp;
+    struct DirBuffer headerbuf, entrybuf;
     struct DirHeader *dhp;
     struct DirEntry *ep;
     int entry;
@@ -446,13 +457,13 @@ DirSalvage(char *fromFile, char *toFile, afs_int32 vn, afs_int32 vu,
     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,
@@ -460,6 +471,7 @@ DirSalvage(char *fromFile, char *toFile, afs_int32 vn, afs_int32 vu,
         */
        return DErrno;
     }
+    dhp = (struct DirHeader *)headerbuf.data;
 
     usedPages = ComputeUsedPages(dhp);
 
@@ -474,20 +486,23 @@ DirSalvage(char *fromFile, char *toFile, afs_int32 vn, afs_int32 vu,
                    ("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((struct buffer *)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;
@@ -497,20 +512,20 @@ DirSalvage(char *fromFile, char *toFile, afs_int32 vn, afs_int32 vu,
            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((struct buffer *)ep, 0);
+                   DRelease(&entrybuf, 0);
                    break;
                }
            }
-           DRelease((struct buffer *)ep, 0);
+           DRelease(&entrybuf, 0);
        }
     }
 
     /* Clean up things. */
-    DRelease((struct buffer *)dhp, 0);
+    DRelease(&headerbuf, 0);
     return 0;
 }