DEVEL15-windows-64bit-printf-sanity-20090218
[openafs.git] / src / vol / namei_ops.c
index 32f628a..ec54258 100644 (file)
@@ -18,6 +18,7 @@ RCSID
 #ifdef AFS_NAMEI_ENV
 #include <stdio.h>
 #include <stdlib.h>
+#include <unistd.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <sys/stat.h>
@@ -40,6 +41,7 @@ RCSID
 #include "viceinode.h"
 #include "voldefs.h"
 #include "partition.h"
+#include "fssync.h"
 #include <afs/errors.h>
 
 /*@+fcnmacros +macrofcndecl@*/
@@ -604,6 +606,8 @@ namei_icreate(IHandle_t * lh, char *part, int p1, int p2, int p3, int p4)
 
     if (p2 == -1 && p3 == VI_LINKTABLE) {
        /* hack at tmp to setup for set link count call. */
+       memset((void *)&tfd, 0, sizeof(FdHandle_t));    /* minimalistic still, but a little cleaner */
+       tfd.fd_ih = &tmp;
        tfd.fd_fd = fd;
        code = namei_SetLinkCount(&tfd, (Inode) 0, 1, 0);
     }
@@ -728,7 +732,7 @@ namei_dec(IHandle_t * ih, Inode ino, int p1)
        } else {
            IHandle_t *th;
            IH_INIT(th, ih->ih_dev, ih->ih_vid, ino);
-           Log("Warning: Lost ref on ihandle dev %d vid %d ino %lld\n",
+           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);
            IH_RELEASE(th);
          
@@ -989,8 +993,10 @@ GetFreeTag(IHandle_t * ih, int vno)
        if ((row & coldata) == 0)
            break;
     }
-    if (col >= NAMEI_MAXVOLS)
+    if (col >= NAMEI_MAXVOLS) {
+       errno = ENOSPC;
        goto badGetFreeTag;
+    }
 
     coldata = 1 << (col * 3);
     row |= coldata;
@@ -1144,6 +1150,8 @@ ListViceInodes(char *devname, char *mountedOn, char *resultFile,
     int ninodes;
     struct afs_stat status;
 
+    *forcep = 0; /* no need to salvage until further notice */
+
     if (resultFile) {
        fp = afs_fopen(resultFile, "w");
        if (!fp) {
@@ -1443,6 +1451,7 @@ DecodeInode(char *dpath, char *name, struct ViceInodeInfo *info, int volid)
     char fpath[512];
     struct afs_stat status;
     int parm, tag;
+    lb64_string_t check;
 
     (void)strcpy(fpath, dpath);
     (void)strcat(fpath, "/");
@@ -1455,6 +1464,10 @@ DecodeInode(char *dpath, char *name, struct ViceInodeInfo *info, int volid)
     info->byteCount = status.st_size;
     info->inodeNumber = (Inode) flipbase64_to_int64(name);
 
+    int64_to_flipbase64(check, info->inodeNumber);
+    if (strcmp(name, check))
+       return -1;
+    
     GetOGMFromStat(&status, &parm, &tag);
     if ((info->inodeNumber & NAMEI_INODESPECIAL) == NAMEI_INODESPECIAL) {
        /* p1 - vid, p2 - -1, p3 - type, p4 - rwvid */
@@ -1534,25 +1547,57 @@ convertVolumeInfo(fdr, fdw, vid)
  */
 
 int
-namei_ConvertROtoRWvolume(IHandle_t * h, afs_uint32 vid)
+namei_ConvertROtoRWvolume(char *pname, afs_int32 volumeId)
 {
+#ifdef FSSYNC_BUILD_CLIENT
     namei_t n;
     char dir_name[512], oldpath[512], newpath[512];
     char smallName[64];
     char largeName[64];
     char infoName[64];
     IHandle_t t_ih;
+    IHandle_t *ih;
     char infoSeen = 0;
     char smallSeen = 0;
     char largeSeen = 0;
     char linkSeen = 0;
-    int code, fd, fd2;
+    int code, fd, fd2, found;
     char *p;
     DIR *dirp;
+    Inode ino;
     struct dirent *dp;
+    struct DiskPartition64 *partP;
     struct ViceInodeInfo info;
+    struct VolumeDiskHeader h;
+    char volname[20];
+    char headername[16];
+    afs_int32 error = 0;
+
+    (void)afs_snprintf(headername, sizeof headername, VFORMAT, volumeId);
+    (void)afs_snprintf(oldpath, sizeof oldpath, "%s/%s", pname, headername);
+    fd = open(oldpath, O_RDONLY);
+    if (fd < 0) {
+        Log("1 namei_ConvertROtoRWvolume: Couldn't open header for RO-volume %lu.\n", volumeId);
+        return ENOENT;
+    }
+    if (read(fd, &h, sizeof(h)) != sizeof(h)) {
+        Log("1 namei_ConvertROtoRWvolume: Couldn't read header for RO-volume %lu.\n", volumeId);
+        close(fd);
+        return EIO;
+    }
+    close(fd);
+    FSYNC_VolOp(volumeId, pname, FSYNC_VOL_BREAKCBKS, 0, NULL);
 
-    namei_HandleToName(&n, h);
+    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;
+    }
+    ino = namei_MakeSpecIno(h.parent, VI_LINKTABLE);
+    IH_INIT(ih, partP->device, h.parent, ino);
+
+    namei_HandleToName(&n, ih);
     strcpy(dir_name, n.n_path);
     p = strrchr(dir_name, '/');
     *p = 0;
@@ -1567,7 +1612,7 @@ namei_ConvertROtoRWvolume(IHandle_t * h, afs_uint32 vid)
 
        if (*dp->d_name == '.')
            continue;
-       if (DecodeInode(dir_name, dp->d_name, &info, h->ih_vid) < 0) {
+       if (DecodeInode(dir_name, dp->d_name, &info, ih->ih_vid) < 0) {
            Log("1 namei_ConvertROtoRWvolume: DecodeInode failed for %s/%s\n",
                dir_name, dp->d_name);
            closedir(dirp);
@@ -1578,8 +1623,8 @@ namei_ConvertROtoRWvolume(IHandle_t * h, afs_uint32 vid)
            closedir(dirp);
            return -1;
        }
-       if (info.u.param[0] != vid) {
-           if (info.u.param[0] == h->ih_vid) {
+       if (info.u.param[0] != volumeId) {
+           if (info.u.param[0] == ih->ih_vid) {
                if (info.u.param[2] == VI_LINKTABLE) {  /* link table */
                    linkSeen = 1;
                    continue;
@@ -1617,8 +1662,8 @@ namei_ConvertROtoRWvolume(IHandle_t * h, afs_uint32 vid)
      */
 
     memset(&t_ih, 0, sizeof(t_ih));
-    t_ih.ih_dev = h->ih_dev;
-    t_ih.ih_vid = h->ih_vid;
+    t_ih.ih_dev = ih->ih_dev;
+    t_ih.ih_vid = ih->ih_vid;
 
     (void)afs_snprintf(oldpath, sizeof oldpath, "%s/%s", dir_name, infoName);
     fd = afs_open(oldpath, O_RDWR, 0);
@@ -1627,7 +1672,7 @@ namei_ConvertROtoRWvolume(IHandle_t * h, afs_uint32 vid)
            oldpath);
        return -1;
     }
-    t_ih.ih_ino = namei_MakeSpecIno(h->ih_vid, VI_VOLINFO);
+    t_ih.ih_ino = namei_MakeSpecIno(ih->ih_vid, VI_VOLINFO);
     namei_HandleToName(&n, &t_ih);
     fd2 = afs_open(n.n_path, O_CREAT | O_EXCL | O_TRUNC | O_RDWR, 0);
     if (fd2 < 0) {
@@ -1635,17 +1680,17 @@ namei_ConvertROtoRWvolume(IHandle_t * h, afs_uint32 vid)
        close(fd);
        return -1;
     }
-    code = convertVolumeInfo(fd, fd2, h->ih_vid);
+    code = convertVolumeInfo(fd, fd2, ih->ih_vid);
     close(fd);
     if (code) {
        close(fd2);
        unlink(n.n_path);
        return -1;
     }
-    SetOGM(fd2, h->ih_vid, 1);
+    SetOGM(fd2, ih->ih_vid, 1);
     close(fd2);
 
-    t_ih.ih_ino = namei_MakeSpecIno(h->ih_vid, VI_SMALLINDEX);
+    t_ih.ih_ino = namei_MakeSpecIno(ih->ih_vid, VI_SMALLINDEX);
     namei_HandleToName(&n, &t_ih);
     (void)afs_snprintf(newpath, sizeof newpath, "%s/%s", dir_name, smallName);
     fd = afs_open(newpath, O_RDWR, 0);
@@ -1653,12 +1698,12 @@ namei_ConvertROtoRWvolume(IHandle_t * h, afs_uint32 vid)
        Log("1 namei_ConvertROtoRWvolume: could not open SmallIndex file: %s\n", newpath);
        return -1;
     }
-    SetOGM(fd, h->ih_vid, 2);
+    SetOGM(fd, ih->ih_vid, 2);
     close(fd);
     link(newpath, n.n_path);
     unlink(newpath);
 
-    t_ih.ih_ino = namei_MakeSpecIno(h->ih_vid, VI_LARGEINDEX);
+    t_ih.ih_ino = namei_MakeSpecIno(ih->ih_vid, VI_LARGEINDEX);
     namei_HandleToName(&n, &t_ih);
     (void)afs_snprintf(newpath, sizeof newpath, "%s/%s", dir_name, largeName);
     fd = afs_open(newpath, O_RDWR, 0);
@@ -1666,12 +1711,38 @@ namei_ConvertROtoRWvolume(IHandle_t * h, afs_uint32 vid)
        Log("1 namei_ConvertROtoRWvolume: could not open LargeIndex file: %s\n", newpath);
        return -1;
     }
-    SetOGM(fd, h->ih_vid, 3);
+    SetOGM(fd, ih->ih_vid, 3);
     close(fd);
     link(newpath, n.n_path);
     unlink(newpath);
 
     unlink(oldpath);
+
+    h.id = h.parent;
+    h.volumeInfo_hi = h.id;
+    h.smallVnodeIndex_hi = h.id;
+    h.largeVnodeIndex_hi = h.id;
+    h.linkTable_hi = h.id;
+    (void)afs_snprintf(headername, sizeof headername, VFORMAT, h.id);
+    (void)afs_snprintf(newpath, sizeof newpath, "%s/%s", pname, headername);
+    fd = open(newpath, O_CREAT | O_EXCL | O_RDWR, 0644);
+    if (fd < 0) {
+        Log("1 namei_ConvertROtoRWvolume: Couldn't create header for RW-volume %lu.\n", h.id);
+        return EIO;
+    }
+    if (write(fd, &h, sizeof(h)) != sizeof(h)) {
+        Log("1 namei_ConvertROtoRWvolume: Couldn't write header for RW-volume\
+ %lu.\n", h.id);
+        close(fd);
+        return EIO;
+    }
+    close(fd);
+    if (unlink(oldpath) < 0) {
+        Log("1 namei_ConvertROtoRWvolume: Couldn't unlink RO header, error = %d\n", error);
+    }
+    FSYNC_VolOp(volumeId, pname, FSYNC_VOL_DONE, 0, NULL);
+    FSYNC_VolOp(h.id, pname, FSYNC_VOL_ON, 0, NULL);
+#endif
     return 0;
 }