From: Derrick Brashear Date: Tue, 13 Nov 2007 22:15:03 +0000 (+0000) Subject: inode-convert-ro-to-rw-20071113 X-Git-Tag: BP-openafs-windows-kdfs-ifs~352 X-Git-Url: https://git.openafs.org/?p=openafs.git;a=commitdiff_plain;h=b98b51185dbd46ef6d9ef0249b032bbc49d13bfb inode-convert-ro-to-rw-20071113 so this functionality works with inode fileserver, also. corrected abstraction from previous versions so vol and volser have correct bits. --- diff --git a/src/vol/listinodes.c b/src/vol/listinodes.c index 1e10982..d268837 100644 --- a/src/vol/listinodes.c +++ b/src/vol/listinodes.c @@ -109,7 +109,13 @@ ListViceInodes(char *devname, char *mountedOn, char *resultFile, #if defined(AFS_HPUX101_ENV) #include #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 @@ -278,10 +284,12 @@ ListViceInodes(char *devname, char *mountedOn, char *resultFile, 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; + } } /* @@ -325,43 +333,47 @@ ListViceInodes(char *devname, char *mountedOn, char *resultFile, 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; @@ -683,10 +695,12 @@ xfs_ListViceInodes(char *devname, char *mountedOn, char *resultFile, 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) { @@ -790,11 +804,13 @@ xfs_ListViceInodes(char *devname, char *mountedOn, char *resultFile, 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++; @@ -813,32 +829,34 @@ xfs_ListViceInodes(char *devname, char *mountedOn, char *resultFile, 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) { @@ -984,10 +1002,12 @@ ListViceInodes(char *devname, char *mountedOn, char *resultFile, 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 /* @@ -1031,9 +1051,11 @@ ListViceInodes(char *devname, char *mountedOn, char *resultFile, 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++; } @@ -1240,10 +1262,12 @@ ListViceInodes(char *devname, char *mountedOn, char *resultFile, 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++; } @@ -1253,36 +1277,38 @@ ListViceInodes(char *devname, char *mountedOn, char *resultFile, 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; @@ -1333,4 +1359,223 @@ bread(int fd, char *buf, daddr_t blk, afs_int32 size) } #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 */ diff --git a/src/vol/namei_ops.c b/src/vol/namei_ops.c index 240e4be..509a7a3 100644 --- a/src/vol/namei_ops.c +++ b/src/vol/namei_ops.c @@ -41,6 +41,7 @@ RCSID #include "voldefs.h" #include "partition.h" #include +#include /*@+fcnmacros +macrofcndecl@*/ #ifdef O_LARGEFILE @@ -1543,7 +1544,7 @@ convertVolumeInfo(fdr, fdw, vid) */ 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]; @@ -1551,17 +1552,48 @@ namei_ConvertROtoRWvolume(IHandle_t * h, afs_uint32 vid) 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; @@ -1576,7 +1608,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); @@ -1587,8 +1619,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; @@ -1626,8 +1658,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); @@ -1636,7 +1668,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) { @@ -1644,17 +1676,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); @@ -1662,12 +1694,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); @@ -1675,12 +1707,37 @@ 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_askfs(volumeId, pname, FSYNC_DONE, 0); + FSYNC_askfs(h.id, pname, FSYNC_ON, 0); return 0; } diff --git a/src/volser/volprocs.c b/src/volser/volprocs.c index 321bf38..a63b0f6 100644 --- a/src/volser/volprocs.c +++ b/src/volser/volprocs.c @@ -191,7 +191,7 @@ XAttachVolume(afs_int32 *error, afs_int32 avolid, afs_int32 apartid, int amode) *error = EINVAL; return NULL; } - tv = VAttachVolumeByName(error, pbuf, vbuf, amode); + tv = VAttachVolumeByName((Error *)error, pbuf, vbuf, amode); return tv; } @@ -2758,116 +2758,65 @@ VolSetDate(struct rx_call *acid, afs_int32 atid, afs_int32 cdate) 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