#include <afsconfig.h>
#include <afs/param.h>
-RCSID
- ("$Header$");
#ifdef AFS_NAMEI_ENV
#include <stdio.h>
#include <stdlib.h>
+#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <sys/param.h>
#include <lock.h>
-#ifdef AFS_AIX_ENV
-#include <sys/lockf.h>
-#endif
#if defined(AFS_SUN5_ENV) || defined(AFS_HPUX_ENV)
#include <unistd.h>
#endif
#include "viceinode.h"
#include "voldefs.h"
#include "partition.h"
+#include "fssync.h"
#include <afs/errors.h>
/*@+fcnmacros +macrofcndecl@*/
/*@printflike@*/ extern void Log(const char *format, ...);
-extern char *volutil_PartitionName_r(int volid, char *buf, int buflen);
+#ifndef LOCK_SH
+#define LOCK_SH 1 /* shared lock */
+#define LOCK_EX 2 /* exclusive lock */
+#define LOCK_NB 4 /* don't block when locking */
+#define LOCK_UN 8 /* unlock */
+#endif
+
+#ifndef HAVE_FLOCK
+#include <fcntl.h>
+
+/*
+ * This function emulates a subset of flock()
+ */
+int
+emul_flock(int fd, int cmd)
+{ struct flock f;
+
+ memset(&f, 0, sizeof (f));
+
+ if (cmd & LOCK_UN)
+ f.l_type = F_UNLCK;
+ if (cmd & LOCK_SH)
+ f.l_type = F_RDLCK;
+ if (cmd & LOCK_EX)
+ f.l_type = F_WRLCK;
+
+ return fcntl(fd, (cmd & LOCK_NB) ? F_SETLK : F_SETLKW, &f);
+}
+
+#define flock(f,c) emul_flock(f,c)
+#endif
+
+int Testing=0;
+
afs_sfsize_t
namei_iread(IHandle_t * h, afs_foff_t offset, char *buf, afs_fsize_t size)
int ogm_mode;
} namei_ogm_t;
-int namei_SetLinkCount(FdHandle_t * h, Inode ino, int count, int locked);
+static int namei_GetLinkCount2(FdHandle_t * h, Inode ino, int lockit, int fixup, int nowrite);
+
static int GetFreeTag(IHandle_t * ih, int vno);
/* namei_HandleToInodeDir
static void
namei_HandleToInodeDir(namei_t * name, IHandle_t * ih)
{
- char *tmp = name->n_base;
+ size_t offset;
memset(name, '\0', sizeof(*name));
- (void)volutil_PartitionName_r(ih->ih_dev, tmp, NAMEI_LCOMP_LEN);
- tmp += VICE_PREFIX_SIZE;
- tmp += ih->ih_dev > 25 ? 2 : 1;
- *tmp = '/';
- tmp++;
- (void)strcpy(tmp, INODEDIR);
- (void)strcpy(name->n_path, name->n_base);
+ /*
+ * Add the /vicepXX string to the start of name->n_base and then calculate
+ * offset as the number of bytes we know we added.
+ *
+ * FIXME: This embeds knowledge of the vice partition naming scheme and
+ * mapping from device numbers. There needs to be an API that tells us
+ * this offset.
+ */
+ volutil_PartitionName_r(ih->ih_dev, name->n_base, sizeof(name->n_base));
+ offset = VICE_PREFIX_SIZE + (ih->ih_dev > 25 ? 2 : 1);
+ name->n_base[offset] = '/';
+ offset++;
+ strlcpy(name->n_base + offset, INODEDIR, sizeof(name->n_base) - offset);
+ strlcpy(name->n_path, name->n_base, sizeof(name->n_path));
}
-#define addtoname(N, C) \
-do { \
- strcat((N)->n_path, "/"); strcat((N)->n_path, C); \
+#define addtoname(N, C) \
+do { \
+ strlcat((N)->n_path, "/", sizeof((N)->n_path)); \
+ strlcat((N)->n_path, (C), sizeof((N)->n_path)); \
} while(0)
namei_HandleToInodeDir(name, ih);
(void)int32_to_flipbase64(tmp, (int64_t) (ih->ih_vid & 0xff));
- (void)strcpy(name->n_voldir1, tmp);
+ strlcpy(name->n_voldir1, tmp, sizeof(name->n_voldir1));
addtoname(name, name->n_voldir1);
(void)int32_to_flipbase64(tmp, (int64_t) ih->ih_vid);
- (void)strcpy(name->n_voldir2, tmp);
+ strlcpy(name->n_voldir2, tmp, sizeof(name->n_voldir2));
addtoname(name, name->n_voldir2);
}
namei_HandleToVolDir(name, ih);
if (vno == NAMEI_VNODESPECIAL) {
- (void)strcpy(name->n_dir1, NAMEI_SPECDIR);
+ strlcpy(name->n_dir1, NAMEI_SPECDIR, sizeof(name->n_dir1));
addtoname(name, name->n_dir1);
name->n_dir2[0] = '\0';
} else {
(void)int32_to_flipbase64(str, VNO_DIR1(vno));
- (void)strcpy(name->n_dir1, str);
+ strlcpy(name->n_dir1, str, sizeof(name->n_dir1));
addtoname(name, name->n_dir1);
(void)int32_to_flipbase64(str, VNO_DIR2(vno));
- (void)strcpy(name->n_dir2, str);
+ strlcpy(name->n_dir2, str, sizeof(name->n_dir2));
addtoname(name, name->n_dir2);
}
(void)int64_to_flipbase64(str, (int64_t) ih->ih_ino);
- (void)strcpy(name->n_inode, str);
+ strlcpy(name->n_inode, str, sizeof(name->n_inode));
addtoname(name, name->n_inode);
}
*created = 0;
- (void)strcpy(tmp, name->n_base);
+ strlcpy(tmp, name->n_base, sizeof(tmp));
create_dir();
create_nextdir(name->n_voldir1);
char pbuf[MAXPATHLEN], *path = pbuf;
int prefixlen = strlen(name->n_base), err = 0;
- strcpy(path, name->n_path);
+ strlcpy(path, name->n_path, sizeof(pbuf));
/* move past the prefix */
path = path + prefixlen + 1; /* skip over the trailing / */
} 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);
return code;
}
+int
+namei_replace_file_by_hardlink(IHandle_t *hLink, IHandle_t *hTarget)
+{
+ afs_int32 code;
+ namei_t nameLink;
+ namei_t nameTarget;
+
+ /* Convert handle to file name. */
+ namei_HandleToName(&nameLink, hLink);
+ namei_HandleToName(&nameTarget, hTarget);
+
+ unlink(nameLink.n_path);
+ code = link(nameTarget.n_path, nameLink.n_path);
+ return code;
+}
+
+int
+namei_copy_on_write(IHandle_t *h)
+{
+ afs_int32 fd, code = 0;
+ namei_t name;
+ FdHandle_t *fdP;
+ struct afs_stat tstat;
+
+ namei_HandleToName(&name, h);
+ if (afs_stat(name.n_path, &tstat) < 0)
+ return EIO;
+ if (tstat.st_nlink > 1) { /* do a copy on write */
+ char path[259];
+ char *buf;
+ afs_size_t size;
+ afs_int32 tlen;
+
+ fdP = IH_OPEN(h);
+ if (!fdP)
+ return EIO;
+ afs_snprintf(path, sizeof(path), "%s-tmp", name.n_path);
+ fd = afs_open(path, O_CREAT | O_EXCL | O_TRUNC | O_RDWR, 0);
+ if (fd < 0) {
+ FDH_CLOSE(fdP);
+ return EIO;
+ }
+ buf = malloc(8192);
+ if (!buf) {
+ close(fd);
+ unlink(path);
+ FDH_CLOSE(fdP);
+ return ENOMEM;
+ }
+ size = tstat.st_size;
+ FDH_SEEK(fdP, 0, 0);
+ while (size) {
+ tlen = size > 8192 ? 8192 : size;
+ if (FDH_READ(fdP, buf, tlen) != tlen)
+ break;
+ if (write(fd, buf, tlen) != tlen)
+ break;
+ size -= tlen;
+ }
+ close(fd);
+ FDH_REALLYCLOSE(fdP);
+ free(buf);
+ if (size)
+ code = EIO;
+ else {
+ unlink(name.n_path);
+ code = rename(path, name.n_path);
+ }
+ }
+ return code;
+}
+
/************************************************************************
* File Name Structure
************************************************************************
* If lockit is set, lock the file and leave it locked upon a successful
* return.
*/
-int
-namei_GetLinkCount(FdHandle_t * h, Inode ino, int lockit)
+static int
+namei_GetLinkCount2(FdHandle_t * h, Inode ino, int lockit, int fixup, int nowrite)
{
unsigned short row = 0;
afs_foff_t offset;
+ ssize_t rc;
int index;
+ /* there's no linktable yet. the salvager will create one later */
+ if (h->fd_fd == -1 && fixup)
+ return 1;
namei_GetLCOffsetAndIndexFromIno(ino, &offset, &index);
if (lockit) {
-#if defined(AFS_AIX_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_HPUX_ENV)
- if (lockf(h->fd_fd, F_LOCK, 0) < 0)
-#else
if (flock(h->fd_fd, LOCK_EX) < 0)
-#endif
return -1;
}
if (afs_lseek(h->fd_fd, offset, SEEK_SET) == -1)
goto bad_getLinkByte;
- if (read(h->fd_fd, (char *)&row, sizeof(row)) != sizeof(row)) {
+ rc = read(h->fd_fd, (char *)&row, sizeof(row));
+ if ((rc == 0 || !((row >> index) & NAMEI_TAGMASK)) && fixup && nowrite)
+ return 1;
+ if (rc == 0 && fixup) {
+ struct stat st;
+ if (fstat(h->fd_fd, &st) || st.st_size >= offset+sizeof(row))
+ goto bad_getLinkByte;
+ FDH_TRUNC(h, offset+sizeof(row));
+ row = 1 << index;
+ rc = write(h->fd_fd, (char *)&row, sizeof(row));
+ }
+ if (rc != sizeof(row)) {
goto bad_getLinkByte;
}
+ if (fixup && !((row >> index) & NAMEI_TAGMASK)) {
+ row |= 1<<index;
+ if (afs_lseek(h->fd_fd, offset, SEEK_SET) == -1)
+ goto bad_getLinkByte;
+ rc = write(h->fd_fd, (char *)&row, sizeof(row));
+ if (rc != sizeof(row))
+ goto bad_getLinkByte;
+ }
+
return (int)((row >> index) & NAMEI_TAGMASK);
bad_getLinkByte:
if (lockit)
-#if defined(AFS_AIX_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_HPUX_ENV)
- lockf(h->fd_fd, F_ULOCK, 0);
-#else
flock(h->fd_fd, LOCK_UN);
-#endif
return -1;
}
+int
+namei_GetLinkCount(FdHandle_t * h, Inode ino, int lockit)
+{
+ return namei_GetLinkCount2(h, ino, lockit, 0, 1);
+}
+
/* Return a free column index for this vnode. */
static int
GetFreeTag(IHandle_t * ih, int vno)
return -1;
/* Only one manipulates at a time. */
-#if defined(AFS_AIX_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_HPUX_ENV)
- if (lockf(fdP->fd_fd, F_LOCK, 0) < 0) {
-#else
if (flock(fdP->fd_fd, LOCK_EX) < 0) {
-#endif
FDH_REALLYCLOSE(fdP);
return -1;
}
if ((row & coldata) == 0)
break;
}
- if (col >= NAMEI_MAXVOLS)
+ if (col >= NAMEI_MAXVOLS) {
+ errno = ENOSPC;
goto badGetFreeTag;
+ }
coldata = 1 << (col * 3);
row |= coldata;
goto badGetFreeTag;
}
FDH_SYNC(fdP);
-#if defined(AFS_AIX_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_HPUX_ENV)
- lockf(fdP->fd_fd, F_ULOCK, 0);
-#else
flock(fdP->fd_fd, LOCK_UN);
-#endif
FDH_REALLYCLOSE(fdP);
return col;;
badGetFreeTag:
-#if defined(AFS_AIX_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_HPUX_ENV)
- lockf(fdP->fd_fd, F_ULOCK, 0);
-#else
flock(fdP->fd_fd, LOCK_UN);
-#endif
FDH_REALLYCLOSE(fdP);
return -1;
}
namei_GetLCOffsetAndIndexFromIno(ino, &offset, &index);
if (!locked) {
-#if defined(AFS_AIX_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_HPUX_ENV)
- if (lockf(fdP->fd_fd, F_LOCK, 0) < 0) {
-#else
if (flock(fdP->fd_fd, LOCK_EX) < 0) {
-#endif
return -1;
}
}
bad_SetLinkCount:
-#if defined(AFS_AIX_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_HPUX_ENV)
- lockf(fdP->fd_fd, F_ULOCK, 0);
-#else
flock(fdP->fd_fd, LOCK_UN);
-#endif
return code;
}
struct ViceInodeInfo *,
char *, char *), FILE * fp,
int (*judgeFun) (struct ViceInodeInfo *,
- int vid, void *),
- int singleVolumeNumber, void *rock);
+ afs_uint32 vid, void *),
+ afs_uint32 singleVolumeNumber, void *rock);
/* WriteInodeInfo
*/
int
ListViceInodes(char *devname, char *mountedOn, char *resultFile,
- int (*judgeInode) (struct ViceInodeInfo * info, int vid, void *rock),
- int singleVolumeNumber, int *forcep, int forceR, char *wpath,
+ 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) {
namei_ListAFSFiles(char *dev,
int (*writeFun) (FILE *, struct ViceInodeInfo *, char *,
char *), FILE * fp,
- int (*judgeFun) (struct ViceInodeInfo *, int, void *),
- int singleVolumeNumber, void *rock)
+ int (*judgeFun) (struct ViceInodeInfo *, afs_uint32, void *),
+ afs_uint32 singleVolumeNumber, void *rock)
{
IHandle_t ih;
namei_t name;
while ((dp1 = readdir(dirp1))) {
if (*dp1->d_name == '.')
continue;
- (void)strcpy(path2, name.n_path);
- (void)strcat(path2, "/");
- (void)strcat(path2, dp1->d_name);
+ afs_snprintf(path2, sizeof(path2), "%s/%s", name.n_path,
+ dp1->d_name);
dirp2 = opendir(path2);
if (dirp2) {
while ((dp2 = readdir(dirp2))) {
namei_ListAFSSubDirs(IHandle_t * dirIH,
int (*writeFun) (FILE *, struct ViceInodeInfo *, char *,
char *), FILE * fp,
- int (*judgeFun) (struct ViceInodeInfo *, int, void *),
- int singleVolumeNumber, void *rock)
+ int (*judgeFun) (struct ViceInodeInfo *, afs_uint32, void *),
+ afs_uint32 singleVolumeNumber, void *rock)
{
IHandle_t myIH = *dirIH;
namei_t name;
#endif
namei_HandleToVolDir(&name, &myIH);
- (void)strcpy(path1, name.n_path);
+ strlcpy(path1, name.n_path, sizeof(path1));
/* Do the directory containing the special files first to pick up link
* counts.
/* Open this handle */
(void)afs_snprintf(path2, sizeof path2, "%s/%s", path1,
dp1->d_name);
- linkHandle.fd_fd = afs_open(path2, O_RDONLY, 0666);
+ linkHandle.fd_fd = afs_open(path2, Testing ? O_RDONLY : O_RDWR, 0666);
info.linkCount =
- namei_GetLinkCount(&linkHandle, (Inode) 0, 0);
+ namei_GetLinkCount2(&linkHandle, (Inode) 0, 1, 1, Testing);
}
if (judgeFun && !(*judgeFun) (&info, singleVolumeNumber, rock))
continue;
/* Now run through all the other subdirs */
namei_HandleToVolDir(&name, &myIH);
- (void)strcpy(path1, name.n_path);
+ strlcpy(path1, name.n_path, sizeof(path1));
dirp1 = opendir(path1);
if (dirp1) {
continue;
/* Now we've got a next level subdir. */
- (void)strcpy(path2, path1);
- (void)strcat(path2, "/");
- (void)strcat(path2, dp1->d_name);
+ afs_snprintf(path2, sizeof(path2), "%s/%s", path1, dp1->d_name);
dirp2 = opendir(path2);
if (dirp2) {
while ((dp2 = readdir(dirp2))) {
continue;
/* Now we've got to the actual data */
- (void)strcpy(path3, path2);
- (void)strcat(path3, "/");
- (void)strcat(path3, dp2->d_name);
+ afs_snprintf(path3, sizeof(path3), "%s/%s", path2,
+ dp2->d_name);
dirp3 = opendir(path3);
if (dirp3) {
while ((dp3 = readdir(dirp3))) {
(path3, dp3->d_name, &info, myIH.ih_vid) < 0)
continue;
info.linkCount =
- namei_GetLinkCount(&linkHandle,
- info.inodeNumber, 0);
+ namei_GetLinkCount2(&linkHandle,
+ info.inodeNumber, 1, 1, Testing);
if (info.linkCount == 0) {
#ifdef DELETE_ZLC
Log("Found 0 link count file %s/%s, deleting it.\n", path3, dp3->d_name);
char fpath[512];
struct afs_stat status;
int parm, tag;
+ lb64_string_t check;
- (void)strcpy(fpath, dpath);
- (void)strcat(fpath, "/");
- (void)strcat(fpath, name);
+ afs_snprintf(fpath, sizeof(fpath), "%s/%s", dpath, name);
if (afs_stat(fpath, &status) < 0) {
return -1;
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 */
*/
static afs_int32
-convertVolumeInfo(fdr, fdw, vid)
- int fdr;
- int fdw;
- afs_uint32 vid;
+convertVolumeInfo(int fdr, int fdw, afs_uint32 vid)
{
struct VolumeDiskData vd;
char *p;
*/
int
-namei_ConvertROtoRWvolume(IHandle_t * h, afs_uint32 vid)
+namei_ConvertROtoRWvolume(char *pname, afs_uint32 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;
int code, fd, fd2;
char *p;
DIR *dirp;
+ Inode ino;
struct dirent *dp;
+ struct DiskPartition64 *partP;
struct ViceInodeInfo info;
+ struct VolumeDiskHeader h;
+ char headername[16];
+ afs_int32 error = 0;
+
+ (void)afs_snprintf(headername, sizeof headername, VFORMAT, afs_cast_uint32(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);
+
+ 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);
- strcpy(dir_name, n.n_path);
+ namei_HandleToName(&n, ih);
+ strlcpy(dir_name, n.n_path, sizeof(dir_name));
p = strrchr(dir_name, '/');
*p = 0;
dirp = opendir(dir_name);
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;
return VVOLEXISTS;
}
if (info.u.param[2] == VI_VOLINFO) { /* volume info file */
- strcpy(infoName, dp->d_name);
+ strlcpy(infoName, dp->d_name, sizeof(infoName));
infoSeen = 1;
} else if (info.u.param[2] == VI_SMALLINDEX) { /* small vnodes file */
- strcpy(smallName, dp->d_name);
+ strlcpy(smallName, dp->d_name, sizeof(smallName));
smallSeen = 1;
} else if (info.u.param[2] == VI_LARGEINDEX) { /* large vnodes file */
- strcpy(largeName, dp->d_name);
+ strlcpy(largeName, dp->d_name, sizeof(largeName));
largeSeen = 1;
} else {
closedir(dirp);
*/
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, afs_cast_uint32(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;
}