#if defined(AFS_HPUX101_ENV)
#include <unistd.h>
#endif
+#include "lock.h"
+#include "ihandle.h"
+#include "vnode.h"
+#include "volume.h"
+#include "volinodes.h"
#include "partition.h"
+#include "fssync.h"
/*@+fcnmacros +macrofcndecl@*/
#ifdef O_LARGEFILE
return -1;
}
- inodeFile = fopen(resultFile, "w");
- if (inodeFile == NULL) {
- Log("Unable to create inode description file %s\n", resultFile);
- goto out;
+ if (resultFile) {
+ inodeFile = fopen(resultFile, "w");
+ if (inodeFile == NULL) {
+ Log("Unable to create inode description file %s\n", resultFile);
+ goto out;
+ }
}
/*
if (judgeInode && (*judgeInode) (&info, judgeParam, rock) == 0)
continue;
- if (fwrite(&info, sizeof info, 1, inodeFile) != 1) {
- Log("Error writing inode file for partition %s\n", partition);
- goto out;
+ if (inodeFile) {
+ if (fwrite(&info, sizeof info, 1, inodeFile) != 1) {
+ Log("Error writing inode file for partition %s\n", partition);
+ goto out;
+ }
}
++ninodes;
}
- if (fflush(inodeFile) == EOF) {
- Log("Unable to successfully flush inode file for %s\n", partition);
- err = -2;
- goto out1;
- }
- if (fsync(fileno(inodeFile)) == -1) {
- Log("Unable to successfully fsync inode file for %s\n", partition);
- err = -2;
- goto out1;
- }
- if (fclose(inodeFile) == EOF) {
- Log("Unable to successfully close inode file for %s\n", partition);
- err = -2;
- goto out1;
- }
+ if (inodeFile) {
+ if (fflush(inodeFile) == EOF) {
+ Log("Unable to successfully flush inode file for %s\n", partition);
+ err = -2;
+ goto out1;
+ }
+ if (fsync(fileno(inodeFile)) == -1) {
+ Log("Unable to successfully fsync inode file for %s\n", partition);
+ err = -2;
+ goto out1;
+ }
+ if (fclose(inodeFile) == EOF) {
+ Log("Unable to successfully close inode file for %s\n", partition);
+ err = -2;
+ goto out1;
+ }
- /*
- * Paranoia: check that the file is really the right size
- */
- if (stat(resultFile, &status) == -1) {
- Log("Unable to successfully stat inode file for %s\n", partition);
- err = -2;
- goto out1;
- }
- 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),
- partition);
- err = -2;
- goto out1;
+ /*
+ * Paranoia: check that the file is really the right size
+ */
+ if (stat(resultFile, &status) == -1) {
+ Log("Unable to successfully stat inode file for %s\n", partition);
+ err = -2;
+ goto out1;
+ }
+ 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),
+ partition);
+ err = -2;
+ goto out1;
+ }
}
close(pfd);
return 0;
return -1;
}
- inodeFile = fopen(resultFile, "w");
- if (inodeFile == NULL) {
- Log("Unable to create inode description file %s\n", resultFile);
- goto out;
+ if (resultFile) {
+ inodeFile = fopen(resultFile, "w");
+ if (inodeFile == NULL) {
+ Log("Unable to create inode description file %s\n", resultFile);
+ goto out;
+ }
}
/* Allocate space for one cylinder group's worth of inodes. */
if (judgeInode && (*judgeInode) (&info, judgeParam, rock) == 0)
continue;
- if (fwrite(&info, sizeof info, 1, inodeFile) != 1) {
- Log("Error writing inode file for partition %s\n", partition);
- goto out;
+ if (inodeFile) {
+ if (fwrite(&info, sizeof info, 1, inodeFile) != 1) {
+ Log("Error writing inode file for partition %s\n", partition);
+ goto out;
+ }
}
++ninodes;
}
- if (fflush(inodeFile) == EOF) {
- Log("Unable to successfully flush inode file for %s\n", partition);
- err = -2;
- goto out1;
- }
- if (fsync(fileno(inodeFile)) == -1) {
- Log("Unable to successfully fsync inode file for %s\n", partition);
- err = -2;
- goto out1;
- }
- if (fclose(inodeFile) == EOF) {
- Log("Unable to successfully close inode file for %s\n", partition);
- err = -2;
- goto out1;
- }
+ if (inodeFile) {
+ if (fflush(inodeFile) == EOF) {
+ Log("Unable to successfully flush inode file for %s\n", partition);
+ err = -2;
+ goto out1;
+ }
+ if (fsync(fileno(inodeFile)) == -1) {
+ Log("Unable to successfully fsync inode file for %s\n", partition);
+ err = -2;
+ goto out1;
+ }
+ if (fclose(inodeFile) == EOF) {
+ Log("Unable to successfully close inode file for %s\n", partition);
+ err = -2;
+ goto out1;
+ }
- /*
- * Paranoia: check that the file is really the right size
- */
- if (stat(resultFile, &status) == -1) {
- Log("Unable to successfully stat inode file for %s\n", partition);
- err = -2;
- goto out1;
- }
- 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),
- partition);
- err = -2;
- goto out1;
+ /*
+ * Paranoia: check that the file is really the right size
+ */
+ if (stat(resultFile, &status) == -1) {
+ Log("Unable to successfully stat inode file for %s\n", partition);
+ err = -2;
+ goto out1;
+ }
+ 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),
+ partition);
+ err = -2;
+ goto out1;
+ }
}
efs_umount(mp);
if (dinodeBuf) {
return -1;
}
- inodeFile = fopen(resultFile, "w");
- if (inodeFile == NULL) {
- Log("Unable to create inode description file %s\n", resultFile);
- return -1;
+ if (resultFile) {
+ inodeFile = fopen(resultFile, "w");
+ if (inodeFile == NULL) {
+ Log("Unable to create inode description file %s\n", resultFile);
+ return -1;
+ }
}
if ((top_dirp = opendir(mountedOn)) == NULL) {
n_renames++;
}
- if (fwrite
- (&info.ili_info, sizeof(vice_inode_info_t), 1, inodeFile)
- != 1) {
- Log("Error writing inode file for partition %s\n", mountedOn);
- goto err1_exit;
+ if (inodeFile) {
+ if (fwrite(&info.ili_info, sizeof(vice_inode_info_t), 1, inodeFile) != 1) {
+ Log("Error writing inode file for partition %s\n", mountedOn);
+ goto err1_exit;
+ }
}
ninodes++;
closedir(top_dirp);
if (renames)
free((char *)renames);
- if (fflush(inodeFile) == EOF) {
- ("Unable to successfully flush inode file for %s\n", mountedOn);
- fclose(inodeFile);
- return errors ? -1 : -2;
- }
- if (fsync(fileno(inodeFile)) == -1) {
- Log("Unable to successfully fsync inode file for %s\n", mountedOn);
- fclose(inodeFile);
- return errors ? -1 : -2;
- }
- if (fclose(inodeFile) == EOF) {
- Log("Unable to successfully close inode file for %s\n", mountedOn);
- return errors ? -1 : -2;
- }
- /*
- * Paranoia: check that the file is really the right size
- */
- if (stat(resultFile, &status) == -1) {
- Log("Unable to successfully stat inode file for %s\n", partition);
- return errors ? -1 : -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),
- partition);
- return errors ? -1 : -2;
+
+ if (inodeFile) {
+ if (fflush(inodeFile) == EOF) {
+ ("Unable to successfully flush inode file for %s\n", mountedOn);
+ fclose(inodeFile);
+ return errors ? -1 : -2;
+ }
+ if (fsync(fileno(inodeFile)) == -1) {
+ Log("Unable to successfully fsync inode file for %s\n", mountedOn);
+ fclose(inodeFile);
+ return errors ? -1 : -2;
+ }
+ if (fclose(inodeFile) == EOF) {
+ Log("Unable to successfully close inode file for %s\n", mountedOn);
+ return errors ? -1 : -2;
+ }
+ /*
+ * Paranoia: check that the file is really the right size
+ */
+ if (stat(resultFile, &status) == -1) {
+ Log("Unable to successfully stat inode file for %s\n", partition);
+ return errors ? -1 : -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),
+ partition);
+ return errors ? -1 : -2;
+ }
}
if (errors) {
goto out;
}
- inodeFile = fopen(resultFile, "w");
- if (inodeFile == NULL) {
- Log("Unable to create inode description file %s\n", resultFile);
- goto out;
+ if (resultFile) {
+ inodeFile = fopen(resultFile, "w");
+ if (inodeFile == NULL) {
+ Log("Unable to create inode description file %s\n", resultFile);
+ goto out;
+ }
}
#ifdef AFS_AIX_ENV
/*
info.u.param[3] = auxp->aux_param4;
if (judgeInode && (*judgeInode) (&info, judgeParam, rock) == 0)
continue;
- if (fwrite(&info, sizeof info, 1, inodeFile) != 1) {
- Log("Error writing inode file for partition %s\n", partition);
- goto out;
+ if (inodeFile) {
+ if (fwrite(&info, sizeof info, 1, inodeFile) != 1) {
+ Log("Error writing inode file for partition %s\n", partition);
+ goto out;
+ }
}
ninodes++;
}
info.linkCount = p->di_nlink;
if (judgeInode && (*judgeInode) (&info, judgeParam, rock) == 0)
continue;
- if (fwrite(&info, sizeof info, 1, inodeFile) != 1) {
- Log("Error writing inode file for partition %s\n",
- partition);
- goto out;
+ if (inodeFile) {
+ if (fwrite(&info, sizeof info, 1, inodeFile) != 1) {
+ Log("Error writing inode file for partition %s\n",
+ partition);
+ goto out;
+ }
}
ninodes++;
}
if (inodes)
free(inodes);
#endif
- if (fflush(inodeFile) == EOF) {
- Log("Unable to successfully flush inode file for %s\n", partition);
- err = -2;
- goto out1;
- }
- if (fsync(fileno(inodeFile)) == -1) {
- Log("Unable to successfully fsync inode file for %s\n", partition);
- err = -2;
- goto out1;
- }
- if (fclose(inodeFile) == EOF) {
- Log("Unable to successfully close inode file for %s\n", partition);
- err = -2;
- goto out1;
- }
-
- /*
- * Paranoia: check that the file is really the right size
- */
- if (stat(resultFile, &status) == -1) {
- Log("Unable to successfully stat inode file for %s\n", partition);
- err = -2;
- goto out1;
- }
- 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),
- partition);
- err = -2;
- goto out1;
+ if (inodeFile) {
+ if (fflush(inodeFile) == EOF) {
+ Log("Unable to successfully flush inode file for %s\n", partition);
+ err = -2;
+ goto out1;
+ }
+ if (fsync(fileno(inodeFile)) == -1) {
+ Log("Unable to successfully fsync inode file for %s\n", partition);
+ err = -2;
+ goto out1;
+ }
+ if (fclose(inodeFile) == EOF) {
+ Log("Unable to successfully close inode file for %s\n", partition);
+ err = -2;
+ goto out1;
+ }
+
+ /*
+ * Paranoia: check that the file is really the right size
+ */
+ if (stat(resultFile, &status) == -1) {
+ Log("Unable to successfully stat inode file for %s\n", partition);
+ err = -2;
+ goto out1;
+ }
+ 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),
+ partition);
+ err = -2;
+ goto out1;
+ }
}
close(pfd);
return 0;
}
#endif /* AFS_LINUX20_ENV */
+static afs_int32
+convertVolumeInfo(int fdr, int fdw, afs_uint32 vid)
+{
+ struct VolumeDiskData vd;
+ char *p;
+
+ if (read(fdr, &vd, sizeof(struct VolumeDiskData)) !=
+ sizeof(struct VolumeDiskData)) {
+ Log("1 convertiVolumeInfo: read failed for %lu with code %d\n", vid,
+ errno);
+ return -1;
+ }
+ vd.restoredFromId = vd.id; /* remember the RO volume here */
+ vd.cloneId = vd.id;
+ vd.id = vd.parentId;
+ vd.type = RWVOL;
+ vd.dontSalvage = 0;
+ vd.inUse = 0;
+ vd.uniquifier += 5000; /* just in case there are still file copies
+ from the old RW volume around */
+
+ p = strrchr(vd.name, '.');
+ if (p && !strcmp(p, ".readonly")) {
+ memset(p, 0, 9);
+ }
+
+ if (write(fdw, &vd, sizeof(struct VolumeDiskData)) !=
+ sizeof(struct VolumeDiskData)) {
+ Log("1 convertiVolumeInfo: write failed for %lu with code %d\n", vid,
+ errno);
+ return -1;
+ }
+ return 0;
+}
+
+struct specino {
+ afs_int32 inodeType;
+ Inode inodeNumber;
+ Inode ninodeNumber;
+};
+
+
+int
+UpdateThisVolume(struct ViceInodeInfo *inodeinfo, VolumeId singleVolumeNumber,
+ struct specino *specinos)
+{
+ struct dinode *p;
+ if ((inodeinfo->u.vnode.vnodeNumber == INODESPECIAL) &&
+ (inodeinfo->u.vnode.volumeId == singleVolumeNumber)) {
+ specinos[inodeinfo->u.special.type].inodeNumber =
+ inodeinfo->inodeNumber;
+ }
+ return 0; /* We aren't using a result file, we're caching */
+}
+
+static char *
+getDevName(char *pbuffer, char *wpath)
+{
+ char pbuf[128], *ptr;
+ strcpy(pbuf, pbuffer);
+ ptr = (char *)strrchr(pbuf, '/');
+ if (ptr) {
+ *ptr = '\0';
+ strcpy(wpath, pbuf);
+ } else
+ return NULL;
+ ptr = (char *)strrchr(pbuffer, '/');
+ if (ptr) {
+ strcpy(pbuffer, ptr + 1);
+ return pbuffer;
+ } else
+ return NULL;
+}
+
+int
+inode_ConvertROtoRWvolume(char *pname, afs_int32 volumeId)
+{
+ char dir_name[512], oldpath[512], newpath[512];
+ char volname[20];
+ char headername[16];
+ char *name;
+ int fd, err, forcep, len, j, code;
+ struct dirent *dp;
+ struct DiskPartition *partP;
+ struct ViceInodeInfo info;
+ struct VolumeDiskHeader h;
+ IHandle_t *ih, *ih2;
+ FdHandle_t *fdP, *fdP2;
+ char wpath[100];
+ char tmpDevName[100];
+ char buffer[128];
+ struct specino specinos[VI_LINKTABLE+1];
+ Inode nearInode = 0;
+
+ memset(&specinos, 0, sizeof(specinos));
+
+ (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 inode_ConvertROtoRWvolume: Couldn't open header for RO-volume %lu.\n", volumeId);
+ return ENOENT;
+ }
+ if (read(fd, &h, sizeof(h)) != sizeof(h)) {
+ Log("1 inode_ConvertROtoRWvolume: Couldn't read header for RO-volume %lu.\n", volumeId);
+ close(fd);
+ return EIO;
+ }
+ close(fd);
+ FSYNC_askfs(volumeId, pname, FSYNC_RESTOREVOLUME, 0);
+
+ /* now do the work */
+
+ for (partP = DiskPartitionList; partP && strcmp(partP->name, pname);
+ partP = partP->next);
+ if (!partP) {
+ Log("1 inode_ConvertROtoRWvolume: Couldn't find DiskPartition for %s\n", pname);
+ return EIO;
+ }
+
+ strcpy(tmpDevName, partP->devName);
+ name = getDevName(tmpDevName, wpath);
+
+ if ((err = ListViceInodes(name, VPartitionPath(partP),
+ NULL, UpdateThisVolume, volumeId,
+ &forcep, 0, wpath, &specinos)) < 0)
+ {
+ Log("1 inode_ConvertROtoRWvolume: Couldn't get special inodes\n");
+ return EIO;
+ }
+
+#if defined(NEARINODE_HINT)
+ nearInodeHash(volumeId, nearInode);
+ nearInode %= partP->f_files;
+#endif
+
+ for (j = VI_VOLINFO; j < VI_LINKTABLE+1; j++) {
+ if (specinos[j].inodeNumber > 0) {
+ specinos[j].ninodeNumber =
+ IH_CREATE(NULL, partP->device, VPartitionPath(partP),
+ nearInode, h.parent, INODESPECIAL, j, h.parent);
+ IH_INIT(ih, partP->device, volumeId,
+ specinos[j].inodeNumber);
+ fdP = IH_OPEN(ih);
+ if (!fdP) {
+ Log("1 inode_ConvertROtoRWvolume: Couldn't find special inode %d for %d\n", j, volumeId);
+ return -1;
+ }
+
+ IH_INIT(ih2, partP->device, h.parent, specinos[j].ninodeNumber);
+ fdP2 = IH_OPEN(ih2);
+ if (!fdP2) {
+ Log("1 inode_ConvertROtoRWvolume: Couldn't find special inode %d for %d\n", j, h.parent);
+ return -1;
+ }
+
+ if (j == VI_VOLINFO)
+ convertVolumeInfo(fdP->fd_fd, fdP2->fd_fd, ih2->ih_vid);
+ else {
+ while (1) {
+ len = read(fdP->fd_fd, buffer, sizeof(buffer));
+ if (len < 0)
+ return errno;
+ if (len == 0)
+ break;
+ code = write(fdP2->fd_fd, buffer, len);
+ if (code != len)
+ return -1;
+ }
+ }
+
+ FDH_CLOSE(fdP);
+ FDH_CLOSE(fdP2);
+ IH_RELEASE(ih);
+ IH_RELEASE(ih2);
+ }
+ }
+
+ h.id = h.parent;
+#ifdef AFS_64BIT_IOPS_ENV
+ h.volumeInfo_lo = (afs_int32)specinos[VI_VOLINFO].ninodeNumber & 0xffffffff;
+ h.volumeInfo_hi = (afs_int32)(specinos[VI_VOLINFO].ninodeNumber >> 32) && 0xffffffff;
+ h.smallVnodeIndex_lo = (afs_int32)specinos[VI_SMALLINDEX].ninodeNumber & 0xffffffff;
+ h.smallVnodeIndex_hi = (afs_int32)(specinos[VI_SMALLINDEX].ninodeNumber >> 32) & 0xffffffff;
+ h.largeVnodeIndex_lo = (afs_int32)specinos[VI_LARGEINDEX].ninodeNumber & 0xffffffff;
+ h.largeVnodeIndex_hi = (afs_int32)(specinos[VI_LARGEINDEX].ninodeNumber >> 32) & 0xffffffff;
+ if (specinos[VI_LINKTABLE].ninodeNumber) {
+ h.linkTable_lo = (afs_int32)specinos[VI_LINKTABLE].ninodeNumber & 0xffffffff;
+ h.linkTable_hi = (afs_int32)specinos[VI_LINKTABLE].ninodeNumber & 0xffffffff;
+ }
+#else
+ h.volumeInfo_lo = specinos[VI_VOLINFO].ninodeNumber;
+ h.smallVnodeIndex_lo = specinos[VI_SMALLINDEX].ninodeNumber;
+ h.largeVnodeIndex_lo = specinos[VI_LARGEINDEX].ninodeNumber;
+ if (specinos[VI_LINKTABLE].ninodeNumber) {
+ h.linkTable_lo = specinos[VI_LINKTABLE].ninodeNumber;
+ }
+#endif
+
+ (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 inode_ConvertROtoRWvolume: Couldn't create header for RW-volume %lu.\n", h.id);
+ return EIO;
+ }
+ if (write(fd, &h, sizeof(h)) != sizeof(h)) {
+ Log("1 inode_ConvertROtoRWvolume: Couldn't write header for RW-volume %lu.\n", h.id);
+ close(fd);
+ return EIO;
+ }
+ close(fd);
+ if (unlink(oldpath) < 0) {
+ Log("1 inode_ConvertROtoRWvolume: Couldn't unlink RO header, error = %d\n", errno);
+ }
+ FSYNC_askfs(volumeId, pname, FSYNC_DONE, 0);
+ FSYNC_askfs(h.id, pname, FSYNC_ON, 0);
+ return 0;
+}
#endif /* AFS_NAMEI_ENV */
#include "voldefs.h"
#include "partition.h"
#include <afs/errors.h>
+#include <afs/fssync.h>
/*@+fcnmacros +macrofcndecl@*/
#ifdef O_LARGEFILE
*/
int
-namei_ConvertROtoRWvolume(IHandle_t * h, afs_uint32 vid)
+namei_ConvertROtoRWvolume(char *pname, afs_int32 volumeId)
{
namei_t n;
char dir_name[512], oldpath[512], newpath[512];
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 DiskPartition *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_askfs(volumeId, pname, FSYNC_RESTOREVOLUME, 0);
+
+ 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, h);
+ namei_HandleToName(&n, ih);
strcpy(dir_name, n.n_path);
p = strrchr(dir_name, '/');
*p = 0;
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);
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;
*/
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);
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) {
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);
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);
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_askfs(volumeId, pname, FSYNC_DONE, 0);
+ FSYNC_askfs(h.id, pname, FSYNC_ON, 0);
return 0;
}
*error = EINVAL;
return NULL;
}
- tv = VAttachVolumeByName(error, pbuf, vbuf, amode);
+ tv = VAttachVolumeByName((Error *)error, pbuf, vbuf, amode);
return tv;
}
return error;
}
-#ifdef AFS_NAMEI_ENV
-/*
- * Inode number format (from namei_ops.c):
- * low 26 bits - vnode number - all 1's if volume special file.
- * next 3 bits - tag
- * next 3 bits spare (0's)
- * high 32 bits - uniquifier (regular) or type if spare
- */
-#define NAMEI_VNODEMASK 0x003ffffff
-#define NAMEI_TAGMASK 0x7
-#define NAMEI_TAGSHIFT 26
-#define NAMEI_UNIQMASK 0xffffffff
-#define NAMEI_UNIQSHIFT 32
-#define NAMEI_INODESPECIAL ((Inode)NAMEI_VNODEMASK)
-#define NAMEI_VNODESPECIAL NAMEI_VNODEMASK
-#endif /* AFS_NAMEI_ENV */
-
afs_int32
SAFSVolConvertROtoRWvolume(struct rx_call *acid, afs_int32 partId,
afs_int32 volumeId)
{
-#if defined(AFS_NAMEI_ENV) && !defined(AFS_NT40_ENV)
+#ifdef AFS_NT40_ENV
+ return EXDEV;
+#else
+ char caller[MAXKTCNAMELEN];
DIR *dirp;
- char pname[16];
- char volname[20];
- afs_int32 error = 0;
+ register struct volser_trans *ttc;
+ char pname[16], volname[20];
+ struct DiskPartition *partP;
+ afs_int32 ret = ENODEV;
afs_int32 volid;
- int found = 0;
- char caller[MAXKTCNAMELEN];
- char headername[16];
- char opath[256];
- char npath[256];
- struct VolumeDiskHeader h;
- int fd;
- IHandle_t *ih;
- Inode ino;
- struct DiskPartition *dp;
if (!afsconf_SuperUser(tdir, acid, caller))
return VOLSERBAD_ACCESS; /*not a super user */
if (GetPartName(partId, pname))
- return VOLSERILLEGAL_PARTITION;
- dirp = opendir(pname);
+ return VOLSERILLEGAL_PARTITION;
+ if (!(partP = VGetPartition(pname, 0)))
+ return VOLSERILLEGAL_PARTITION;
+ dirp = opendir(VPartitionPath(partP));
if (dirp == NULL)
return VOLSERILLEGAL_PARTITION;
strcpy(volname, "");
+ ttc = (struct volser_trans *)0;
- while (strcmp(volname, "EOD") && !found) { /*while there are more volumes in the partition */
- GetNextVol(dirp, volname, &volid);
- if (strcmp(volname, "")) { /* its a volume */
- if (volid == volumeId)
- found = 1;
+ while (strcmp(volname, "EOD")) {
+ if (!strcmp(volname, "")) { /* its not a volume, fetch next file */
+ GetNextVol(dirp, volname, &volid);
+ continue; /*back to while loop */
+ }
+
+ if (volid == volumeId) { /*copy other things too */
+#ifndef AFS_PTHREAD_ENV
+ IOMGR_Poll(); /*make sure that the client doesnot time out */
+#endif
+ ttc = NewTrans(volumeId, partId);
+ if (!ttc) {
+ return VBUSY;
+ }
+#ifdef AFS_NAMEI_ENV
+ ret = namei_ConvertROtoRWvolume(pname, volumeId);
+#else
+ ret = inode_ConvertROtoRWvolume(pname, volumeId);
+#endif
+ break;
}
+ GetNextVol(dirp, volname, &volid);
}
- if (!found)
- return ENOENT;
- (void)afs_snprintf(headername, sizeof headername, VFORMAT, volumeId);
- (void)afs_snprintf(opath, sizeof opath, "%s/%s", pname, headername);
- fd = open(opath, O_RDONLY);
- if (fd < 0) {
- Log("1 SAFS_VolConvertROtoRWvolume: Couldn't open header for RO-volume %lu.\n", volumeId);
- return ENOENT;
- }
- if (read(fd, &h, sizeof(h)) != sizeof(h)) {
- Log("1 SAFS_VolConvertROtoRWvolume: 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);
-
- for (dp = DiskPartitionList; dp && strcmp(dp->name, pname);
- dp = dp->next);
- if (!dp) {
- Log("1 SAFS_VolConvertROtoRWvolume: Couldn't find DiskPartition for %s\n", pname);
- return EIO;
- }
- ino = namei_MakeSpecIno(h.parent, VI_LINKTABLE);
- IH_INIT(ih, dp->device, h.parent, ino);
-
- error = namei_ConvertROtoRWvolume(ih, volumeId);
- if (error)
- return error;
- 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(npath, sizeof npath, "%s/%s", pname, headername);
- fd = open(npath, O_CREAT | O_EXCL | O_RDWR, 0644);
- if (fd < 0) {
- Log("1 SAFS_VolConvertROtoRWvolume: Couldn't create header for RW-volume %lu.\n", h.id);
- return EIO;
- }
- if (write(fd, &h, sizeof(h)) != sizeof(h)) {
- Log("1 SAFS_VolConvertROtoRWvolume: Couldn't write header for RW-volume %lu.\n", h.id);
- close(fd);
- return EIO;
- }
- close(fd);
- if (unlink(opath) < 0) {
- Log("1 SAFS_VolConvertROtoRWvolume: Couldn't unlink RO header, error = %d\n", error);
+
+ if (ttc) {
+ DeleteTrans(ttc, 1);
+ ttc = (struct volser_trans *)0;
}
- FSYNC_VolOp(volumeId, pname, FSYNC_VOL_DONE, 0, NULL);
- FSYNC_VolOp(h.id, pname, FSYNC_VOL_ON, 0, NULL);
- return 0;
-#else /* AFS_NAMEI_ENV */
- return EINVAL;
-#endif /* AFS_NAMEI_ENV */
+
+ closedir(dirp);
+ return ret;
+#endif
}
afs_int32