namei decodevolume allow low volume ids
[openafs.git] / src / vol / namei_ops.c
index 25edb7e..b4e0649 100644 (file)
@@ -40,6 +40,8 @@
 #include "voldefs.h"
 #include "partition.h"
 #include "fssync.h"
+#include "volume_inline.h"
+#include "common.h"
 #include <afs/errors.h>
 
 /*@+fcnmacros +macrofcndecl@*/
@@ -64,8 +66,6 @@ extern off_t afs_lseek(int FD, off_t O, int F);
 #endif /* !O_LARGEFILE */
 /*@=fcnmacros =macrofcndecl@*/
 
-/*@printflike@*/ extern void Log(const char *format, ...);
-
 #ifndef LOCK_SH
 #define   LOCK_SH   1    /* shared lock */
 #define   LOCK_EX   2    /* exclusive lock */
@@ -738,7 +738,7 @@ namei_dec(IHandle_t * ih, Inode ino, int p1)
            IHandle_t *th;
            IH_INIT(th, ih->ih_dev, ih->ih_vid, ino);
            Log("Warning: Lost ref on ihandle dev %d vid %d ino %" AFS_INT64_FMT "\n",
-               th->ih_dev, th->ih_vid, (int64_t) th->ih_ino);
+               th->ih_dev, th->ih_vid, (afs_int64)th->ih_ino);
            IH_RELEASE(th);
          
            /* If we're less than 0, someone presumably unlinked;
@@ -833,7 +833,7 @@ namei_copy_on_write(IHandle_t *h)
        char path[259];
        char *buf;
        afs_size_t size;
-       afs_int32 tlen;
+       ssize_t tlen;
        
        fdP = IH_OPEN(h);
        if (!fdP)
@@ -1039,7 +1039,7 @@ GetFreeTag(IHandle_t * ih, int vno)
     int col;
     int coldata;
     short row;
-    int code;
+    ssize_t nBytes;
 
 
     fdP = IH_OPEN(ih);
@@ -1057,9 +1057,9 @@ GetFreeTag(IHandle_t * ih, int vno)
        goto badGetFreeTag;
     }
 
-    code = read(fdP->fd_fd, (char *)&row, sizeof(row));
-    if (code != sizeof(row)) {
-       if (code != 0)
+    nBytes = read(fdP->fd_fd, (char *)&row, sizeof(row));
+    if (nBytes != sizeof(row)) {
+       if (nBytes != 0)
            goto badGetFreeTag;
        row = 0;
     }
@@ -1108,7 +1108,7 @@ namei_SetLinkCount(FdHandle_t * fdP, Inode ino, int count, int locked)
     int index;
     unsigned short row;
     int junk;
-    int code = -1;
+    ssize_t nBytes = -1;
 
     namei_GetLCOffsetAndIndexFromIno(ino, &offset, &index);
 
@@ -1123,9 +1123,9 @@ namei_SetLinkCount(FdHandle_t * fdP, Inode ino, int count, int locked)
     }
 
 
-    code = read(fdP->fd_fd, (char *)&row, sizeof(row));
-    if (code != sizeof(row)) {
-       if (code != 0) {
+    nBytes = read(fdP->fd_fd, (char *)&row, sizeof(row));
+    if (nBytes != sizeof(row)) {
+       if (nBytes != 0) {
            errno = EBADF;
            goto bad_SetLinkCount;
        }
@@ -1148,13 +1148,13 @@ namei_SetLinkCount(FdHandle_t * fdP, Inode ino, int count, int locked)
     }
     FDH_SYNC(fdP);
 
-    code = 0;
+    nBytes = 0;
 
 
   bad_SetLinkCount:
     flock(fdP->fd_fd, LOCK_UN);
 
-    return code;
+    return nBytes;
 }
 
 
@@ -1218,66 +1218,51 @@ VerifyDirPerms(char *path)
  * If the resultFile is NULL, then don't call the write routine.
  */
 int
-ListViceInodes(char *devname, char *mountedOn, char *resultFile,
+ListViceInodes(char *devname, char *mountedOn, FILE *inodeFile,
               int (*judgeInode) (struct ViceInodeInfo * info, afs_uint32 vid, void *rock),
               afs_uint32 singleVolumeNumber, int *forcep, int forceR, char *wpath, 
               void *rock)
 {
-    FILE *fp = (FILE *) - 1;
     int ninodes;
     struct afs_stat status;
 
     *forcep = 0; /* no need to salvage until further notice */
 
-    if (resultFile) {
-       fp = afs_fopen(resultFile, "w");
-       if (!fp) {
-           Log("Unable to create inode description file %s\n", resultFile);
-           return -1;
-       }
-    }
-
     /* Verify protections on directories. */
     mode_errors = 0;
     VerifyDirPerms(mountedOn);
 
     ninodes =
-       namei_ListAFSFiles(mountedOn, WriteInodeInfo, fp, judgeInode,
+       namei_ListAFSFiles(mountedOn, WriteInodeInfo, inodeFile, judgeInode,
                           singleVolumeNumber, rock);
 
-    if (!resultFile)
+    if (!inodeFile)
        return ninodes;
 
     if (ninodes < 0) {
-       fclose(fp);
        return ninodes;
     }
 
-    if (fflush(fp) == EOF) {
+    if (fflush(inodeFile) == EOF) {
        Log("Unable to successfully flush inode file for %s\n", mountedOn);
-       fclose(fp);
        return -2;
     }
-    if (fsync(fileno(fp)) == -1) {
+    if (fsync(fileno(inodeFile)) == -1) {
        Log("Unable to successfully fsync inode file for %s\n", mountedOn);
-       fclose(fp);
-       return -2;
-    }
-    if (fclose(fp) == EOF) {
-       Log("Unable to successfully close inode file for %s\n", mountedOn);
        return -2;
     }
 
     /*
      * Paranoia:  check that the file is really the right size
      */
-    if (afs_stat(resultFile, &status) == -1) {
+    if (afs_fstat(fileno(inodeFile), &status) == -1) {
        Log("Unable to successfully stat inode file for %s\n", mountedOn);
        return -2;
     }
     if (status.st_size != ninodes * sizeof(struct ViceInodeInfo)) {
-       Log("Wrong size (%d instead of %d) in inode file for %s\n",
-           status.st_size, ninodes * sizeof(struct ViceInodeInfo),
+       Log("Wrong size (%d instead of %lu) in inode file for %s\n",
+           (int) status.st_size,
+           (long unsigned int) ninodes * sizeof(struct ViceInodeInfo),
            mountedOn);
        return -2;
     }
@@ -1506,7 +1491,7 @@ namei_ListAFSSubDirs(IHandle_t * dirIH,
 static int
 DecodeVolumeName(char *name, unsigned int *vid)
 {
-    if (strlen(name) <= 2)
+    if (strlen(name) < 1)
        return -1;
     *vid = (unsigned int)flipbase64_to_int64(name);
     return 0;
@@ -1572,7 +1557,8 @@ convertVolumeInfo(int fdr, int fdw, afs_uint32 vid)
 
     if (read(fdr, &vd, sizeof(struct VolumeDiskData)) !=
        sizeof(struct VolumeDiskData)) {
-       Log("1 convertVolumeInfo: read failed for %lu with code %d\n", vid,
+       Log("1 convertVolumeInfo: read failed for %lu with code %d\n",
+           afs_printable_uint32_lu(vid),
            errno);
        return -1;
     }
@@ -1590,7 +1576,8 @@ convertVolumeInfo(int fdr, int fdw, afs_uint32 vid)
     }
     if (write(fdw, &vd, sizeof(struct VolumeDiskData)) !=
        sizeof(struct VolumeDiskData)) {
-       Log("1 convertVolumeInfo: write failed for %lu with code %d\n", vid,
+       Log("1 convertVolumeInfo: write failed for %lu with code %d\n",
+           afs_printable_uint32_lu(vid),
            errno);
        return -1;
     }
@@ -1621,6 +1608,7 @@ convertVolumeInfo(int fdr, int fdw, afs_uint32 vid)
 int
 namei_ConvertROtoRWvolume(char *pname, afs_uint32 volumeId)
 {
+    int code = 0;
 #ifdef FSSYNC_BUILD_CLIENT
     namei_t n;
     char dir_name[512], oldpath[512], newpath[512];
@@ -1633,7 +1621,7 @@ namei_ConvertROtoRWvolume(char *pname, afs_uint32 volumeId)
     char smallSeen = 0;
     char largeSeen = 0;
     char linkSeen = 0;
-    int code, fd, fd2;
+    int fd, fd2;
     char *p;
     DIR *dirp;
     Inode ino;
@@ -1641,18 +1629,33 @@ namei_ConvertROtoRWvolume(char *pname, afs_uint32 volumeId)
     struct DiskPartition64 *partP;
     struct ViceInodeInfo info;
     struct VolumeDiskHeader h;
+# ifdef AFS_DEMAND_ATTACH_FS
+    int locktype = 0;
+# endif /* AFS_DEMAND_ATTACH_FS */
 
     for (partP = DiskPartitionList; partP && strcmp(partP->name, pname);
          partP = partP->next);
     if (!partP) {
         Log("1 namei_ConvertROtoRWvolume: Couldn't find DiskPartition for %s\n", pname);
-        return EIO;
+       code = EIO;
+       goto done;
     }
 
+# ifdef AFS_DEMAND_ATTACH_FS
+    locktype = VVolLockType(V_VOLUPD, 1);
+    code = VLockVolumeByIdNB(volumeId, partP, locktype);
+    if (code) {
+       locktype = 0;
+       code = EIO;
+       goto done;
+    }
+# endif /* AFS_DEMAND_ATTACH_FS */
+
     if (VReadVolumeDiskHeader(volumeId, partP, &h)) {
        Log("1 namei_ConvertROtoRWvolume: Couldn't read header for RO-volume %lu.\n",
            afs_printable_uint32_lu(volumeId));
-       return EIO;
+       code = EIO;
+       goto done;
     }
 
     FSYNC_VolOp(volumeId, pname, FSYNC_VOL_BREAKCBKS, 0, NULL);
@@ -1667,7 +1670,8 @@ namei_ConvertROtoRWvolume(char *pname, afs_uint32 volumeId)
     dirp = opendir(dir_name);
     if (!dirp) {
        Log("1 namei_ConvertROtoRWvolume: Could not opendir(%s)\n", dir_name);
-       return EIO;
+       code = EIO;
+       goto done;
     }
 
     while ((dp = readdir(dirp))) {
@@ -1679,12 +1683,14 @@ namei_ConvertROtoRWvolume(char *pname, afs_uint32 volumeId)
            Log("1 namei_ConvertROtoRWvolume: DecodeInode failed for %s/%s\n",
                dir_name, dp->d_name);
            closedir(dirp);
-           return -1;
+           code = -1;
+           goto done;
        }
        if (info.u.param[1] != -1) {
            Log("1 namei_ConvertROtoRWvolume: found other than volume special file %s/%s\n", dir_name, dp->d_name);
            closedir(dirp);
-           return -1;
+           code = -1;
+           goto done;
        }
        if (info.u.param[0] != volumeId) {
            if (info.u.param[0] == ih->ih_vid) {
@@ -1693,9 +1699,12 @@ namei_ConvertROtoRWvolume(char *pname, afs_uint32 volumeId)
                    continue;
                }
            }
-           Log("1 namei_ConvertROtoRWvolume: found special file %s/%s for volume %lu\n", dir_name, dp->d_name, info.u.param[0]);
+           Log("1 namei_ConvertROtoRWvolume: found special file %s/%s"
+               " for volume %lu\n", dir_name, dp->d_name,
+               afs_printable_uint32_lu(info.u.param[0]));
            closedir(dirp);
-           return VVOLEXISTS;
+           code = VVOLEXISTS;
+           goto done;
        }
        if (info.u.param[2] == VI_VOLINFO) {    /* volume info file */
            strlcpy(infoName, dp->d_name, sizeof(infoName));
@@ -1709,14 +1718,16 @@ namei_ConvertROtoRWvolume(char *pname, afs_uint32 volumeId)
        } else {
            closedir(dirp);
            Log("1 namei_ConvertROtoRWvolume: unknown type %d of special file found : %s/%s\n", info.u.param[2], dir_name, dp->d_name);
-           return -1;
+           code = -1;
+           goto done;
        }
     }
     closedir(dirp);
 
     if (!infoSeen || !smallSeen || !largeSeen || !linkSeen) {
        Log("1 namei_ConvertROtoRWvolume: not all special files found in %s\n", dir_name);
-       return -1;
+       code = -1;
+       goto done;
     }
 
     /*
@@ -1733,7 +1744,8 @@ namei_ConvertROtoRWvolume(char *pname, afs_uint32 volumeId)
     if (fd < 0) {
        Log("1 namei_ConvertROtoRWvolume: could not open RO info file: %s\n",
            oldpath);
-       return -1;
+       code = -1;
+       goto done;
     }
     t_ih.ih_ino = namei_MakeSpecIno(ih->ih_vid, VI_VOLINFO);
     namei_HandleToName(&n, &t_ih);
@@ -1741,14 +1753,16 @@ namei_ConvertROtoRWvolume(char *pname, afs_uint32 volumeId)
     if (fd2 < 0) {
        Log("1 namei_ConvertROtoRWvolume: could not create RW info file: %s\n", n.n_path);
        close(fd);
-       return -1;
+       code = -1;
+       goto done;
     }
     code = convertVolumeInfo(fd, fd2, ih->ih_vid);
     close(fd);
     if (code) {
        close(fd2);
        unlink(n.n_path);
-       return -1;
+       code = -1;
+       goto done;
     }
     SetOGM(fd2, ih->ih_vid, 1);
     close(fd2);
@@ -1759,7 +1773,8 @@ namei_ConvertROtoRWvolume(char *pname, afs_uint32 volumeId)
     fd = afs_open(newpath, O_RDWR, 0);
     if (fd < 0) {
        Log("1 namei_ConvertROtoRWvolume: could not open SmallIndex file: %s\n", newpath);
-       return -1;
+       code = -1;
+       goto done;
     }
     SetOGM(fd, ih->ih_vid, 2);
     close(fd);
@@ -1772,7 +1787,8 @@ namei_ConvertROtoRWvolume(char *pname, afs_uint32 volumeId)
     fd = afs_open(newpath, O_RDWR, 0);
     if (fd < 0) {
        Log("1 namei_ConvertROtoRWvolume: could not open LargeIndex file: %s\n", newpath);
-       return -1;
+       code = -1;
+       goto done;
     }
     SetOGM(fd, ih->ih_vid, 3);
     close(fd);
@@ -1790,7 +1806,8 @@ namei_ConvertROtoRWvolume(char *pname, afs_uint32 volumeId)
     if (VCreateVolumeDiskHeader(&h, partP)) {
         Log("1 namei_ConvertROtoRWvolume: Couldn't write header for RW-volume %lu\n",
            afs_printable_uint32_lu(h.id));
-        return EIO;
+       code = EIO;
+       goto done;
     }
 
     if (VDestroyVolumeDiskHeader(partP, volumeId, h.parent)) {
@@ -1800,8 +1817,16 @@ namei_ConvertROtoRWvolume(char *pname, afs_uint32 volumeId)
 
     FSYNC_VolOp(volumeId, pname, FSYNC_VOL_DONE, 0, NULL);
     FSYNC_VolOp(h.id, pname, FSYNC_VOL_ON, 0, NULL);
+
+ done:
+# ifdef AFS_DEMAND_ATTACH_FS
+    if (locktype) {
+       VUnlockVolumeById(volumeId, partP);
+    }
+# endif /* AFS_DEMAND_ATTACH_FS */
 #endif
-    return 0;
+
+    return code;
 }
 
 /* PrintInode