#ifdef AFS_NAMEI_ENV
#include <stdio.h>
#include <stdlib.h>
+#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include "viceinode.h"
#include "voldefs.h"
#include "partition.h"
+#include "fssync.h"
#include <afs/errors.h>
/*@+fcnmacros +macrofcndecl@*/
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);
}
} 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);
if ((row & coldata) == 0)
break;
}
- if (col >= NAMEI_MAXVOLS)
+ if (col >= NAMEI_MAXVOLS) {
+ errno = ENOSPC;
goto badGetFreeTag;
+ }
coldata = 1 << (col * 3);
row |= coldata;
int ninodes;
struct afs_stat status;
+ *forcep = 0; /* no need to salvage until further notice */
+
if (resultFile) {
fp = afs_fopen(resultFile, "w");
if (!fp) {
char fpath[512];
struct afs_stat status;
int parm, tag;
+ lb64_string_t check;
(void)strcpy(fpath, dpath);
(void)strcat(fpath, "/");
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 */
*/
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;
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_VolOp(volumeId, pname, FSYNC_VOL_DONE, 0, NULL);
+ FSYNC_VolOp(h.id, pname, FSYNC_VOL_ON, 0, NULL);
+#endif
return 0;
}