#ifdef AFS_OSF_ENV
#include <ufs/inode.h>
#else /* AFS_OSF_ENV */
-#if !defined(AFS_LINUX20_ENV) && !defined(AFS_XBSD_ENV) && !defined(AFS_ARM_DARWIN_ENV)
+#if !defined(AFS_LINUX20_ENV) && !defined(AFS_XBSD_ENV) && !defined(AFS_DARWIN_ENV)
#include <sys/inode.h>
#endif
#endif
if (GetInodeSummary(salvinfo, inodeFile, singleVolumeNumber) < 0) {
OS_CLOSE(inodeFile);
- if (singleVolumeNumber) {
- /* the volume group -- let alone the volume -- does not exist,
- * but we checked it out, so give it back to the fileserver */
- AskDelete(salvinfo, singleVolumeNumber);
- }
return;
}
salvinfo->inodeFd = inodeFile;
/* Salvage the group of volumes (several read-only + 1 read/write)
* starting with the current read-only volume we're looking at.
*/
- SalvageVolumeGroup(salvinfo, &salvinfo->inodeSummary[i], j - i);
+#ifdef AFS_NT40_ENV
+ nt_SalvageVolumeGroup(salvinfo, &salvinfo->inodeSummary[i], j - i);
+#else
+ DoSalvageVolumeGroup(salvinfo, &salvinfo->inodeSummary[i], j - i);
+#endif /* AFS_NT40_ENV */
+
}
/* Delete any additional volumes that were listed in the partition but which didn't have any corresponding inodes */
params = (struct SalvageScanParams *)rock;
+ memset(&summary, 0, sizeof(summary));
+
singleVolumeNumber = params->singleVolumeNumber;
salvinfo = params->salvinfo;
}
void
-SalvageVolumeGroup(struct SalvInfo *salvinfo, struct InodeSummary *isp, int nVols)
+nt_SalvageVolumeGroup(struct SalvInfo *salvinfo, struct InodeSummary *isp, int nVols)
{
pthread_t tid;
pthread_attr_t tattr;
IH_INIT(salvinfo->VGLinkH, salvinfo->fileSysDevice, isp->RWvolumeId, ino);
fdP = IH_OPEN(salvinfo->VGLinkH);
}
+ if (VALID_INO(ino) && fdP != NULL) {
+ struct versionStamp header;
+ afs_sfsize_t nBytes;
+
+ nBytes = FDH_PREAD(fdP, (char *)&header, sizeof(struct versionStamp), 0);
+ if (nBytes != sizeof(struct versionStamp)
+ || header.magic != LINKTABLEMAGIC) {
+ Log("Bad linktable header for volume %u.\n", isp->RWvolumeId);
+ FDH_REALLYCLOSE(fdP);
+ fdP = NULL;
+ }
+ }
if (!VALID_INO(ino) || fdP == NULL) {
Log("%s link table for volume %u.\n",
Testing ? "Would have recreated" : "Recreating", isp->RWvolumeId);
if (stuff[i].inodeType == VI_LINKTABLE) {
/* Gross hack: SalvageHeader does a bcmp on the volume header.
* And we may have recreated the link table earlier, so set the
- * RW header as well.
+ * RW header as well. The header magic was already checked.
*/
if (VALID_INO(salvinfo->VGLinkH->ih_ino)) {
*stuff[i].inode = salvinfo->VGLinkH->ih_ino;
return 0;
#ifndef AFS_NAMEI_ENV
if (sp->inodeType == VI_LINKTABLE)
- return 0;
+ return 0; /* header magic was already checked */
#endif
if (*(sp->inode) == 0) {
if (check) {
}
vnode.cloned = 0;
VNDISK_SET_INO(&vnode, newinode);
- length = Length(&newdir);
+ length = afs_dir_Length(&newdir);
VNDISK_SET_LEN(&vnode, length);
lcode =
IH_IWRITE(salvinfo->vnodeInfo[vLarge].handle,
}
if (!Testing) {
CopyOnWrite(salvinfo, dir);
- osi_Assert(Delete(&dir->dirHandle, name) == 0);
+ osi_Assert(afs_dir_Delete(&dir->dirHandle, name) == 0);
}
return 0;
}
if (!unique) {
if (!Testing) {
CopyOnWrite(salvinfo, dir);
- osi_Assert(Delete(&dir->dirHandle, name) == 0);
+ osi_Assert(afs_dir_Delete(&dir->dirHandle, name) == 0);
}
return 0;
}
fid.Vnode = vnodeNumber;
fid.Unique = vnodeEssence->unique;
CopyOnWrite(salvinfo, dir);
- osi_Assert(Delete(&dir->dirHandle, name) == 0);
+ osi_Assert(afs_dir_Delete(&dir->dirHandle, name) == 0);
if (!todelete)
- osi_Assert(Create(&dir->dirHandle, name, &fid) == 0);
+ osi_Assert(afs_dir_Create(&dir->dirHandle, name, &fid) == 0);
}
if (todelete)
return 0; /* no need to continue */
Log("directory vnode %u.%u: bad '.' entry (was %u.%u); fixed\n", dir->vnodeNumber, dir->unique, vnodeNumber, unique);
if (!Testing) {
CopyOnWrite(salvinfo, dir);
- osi_Assert(Delete(&dir->dirHandle, ".") == 0);
+ osi_Assert(afs_dir_Delete(&dir->dirHandle, ".") == 0);
fid.Vnode = dir->vnodeNumber;
fid.Unique = dir->unique;
- osi_Assert(Create(&dir->dirHandle, ".", &fid) == 0);
+ osi_Assert(afs_dir_Create(&dir->dirHandle, ".", &fid) == 0);
}
vnodeNumber = fid.Vnode; /* Get the new Essence */
Log("directory vnode %u.%u: bad '..' entry (was %u.%u); fixed\n", dir->vnodeNumber, dir->unique, vnodeNumber, unique);
if (!Testing) {
CopyOnWrite(salvinfo, dir);
- osi_Assert(Delete(&dir->dirHandle, "..") == 0);
- osi_Assert(Create(&dir->dirHandle, "..", &pa) == 0);
+ osi_Assert(afs_dir_Delete(&dir->dirHandle, "..") == 0);
+ osi_Assert(afs_dir_Create(&dir->dirHandle, "..", &pa) == 0);
}
vnodeNumber = pa.Vnode; /* Get the new Essence */
}
if (!Testing) {
CopyOnWrite(salvinfo, dir);
- osi_Assert(Delete(&dir->dirHandle, name) == 0);
+ osi_Assert(afs_dir_Delete(&dir->dirHandle, name) == 0);
}
vnodeEssence->claimed = 0; /* Not claimed: Orphaned */
vnodeEssence->todelete = 1; /* Will later delete vnode and decr inode */
}
if (!Testing) {
CopyOnWrite(salvinfo, dir);
- osi_Assert(Delete(&dir->dirHandle, name) == 0);
+ osi_Assert(afs_dir_Delete(&dir->dirHandle, name) == 0);
}
return 0;
}
judge_params.salvinfo = salvinfo;
judge_params.dir = &dir;
- osi_Assert(EnumerateDir(&dirHandle, JudgeEntry, &judge_params) == 0);
+ osi_Assert(afs_dir_EnumerateDir(&dirHandle, JudgeEntry,
+ &judge_params) == 0);
}
/* Delete the old directory if it was copied in order to salvage.
did.Volume = vid;
did.Vnode = 1;
did.Unique = 1;
- if (MakeDir(&rootdir->dirHandle, (afs_int32*)&did, (afs_int32*)&did)) {
+ if (afs_dir_MakeDir(&rootdir->dirHandle, (afs_int32*)&did, (afs_int32*)&did)) {
Log("CreateRootDir: MakeDir failed\n");
goto error;
}
- if (Create(&rootdir->dirHandle, "README.ROOTDIR", &readmeid)) {
+ if (afs_dir_Create(&rootdir->dirHandle, "README.ROOTDIR", &readmeid)) {
Log("CreateRootDir: Create failed\n");
goto error;
}
DFlush();
- length = Length(&rootdir->dirHandle);
- DZap((void *)&rootdir->dirHandle);
+ length = afs_dir_Length(&rootdir->dirHandle);
+ DZap(&rootdir->dirHandle);
/* create the new root dir vnode */
rootvnode = calloc(1, SIZEOF_LARGEDISKVNODE);
&salvinfo->VolumeChanged);
pa.Vnode = LFVnode;
pa.Unique = LFUnique;
- osi_Assert(Delete(&dh, "..") == 0);
- osi_Assert(Create(&dh, "..", &pa) == 0);
+ osi_Assert(afs_dir_Delete(&dh, "..") == 0);
+ osi_Assert(afs_dir_Create(&dh, "..", &pa) == 0);
/* The original parent's link count was decremented above.
* Here we increment the new parent's link count.
ThisVnode, ThisUnique);
CopyOnWrite(salvinfo, &rootdir);
- code = Create(&rootdir.dirHandle, npath, &pa);
+ code = afs_dir_Create(&rootdir.dirHandle, npath, &pa);
if (!code)
break;
afs_printable_uint32_lu(vid));
}
+ if (!Testing && salvinfo->VolumeChanged) {
#ifdef FSSYNC_BUILD_CLIENT
- if (!Testing && salvinfo->VolumeChanged && salvinfo->useFSYNC) {
- afs_int32 fsync_code;
-
- fsync_code = FSYNC_VolOp(vid, NULL, FSYNC_VOL_BREAKCBKS, FSYNC_SALVAGE, NULL);
- if (fsync_code) {
- Log("Error trying to tell the fileserver to break callbacks for "
- "changed volume %lu; error code %ld\n",
- afs_printable_uint32_lu(vid),
- afs_printable_int32_ld(fsync_code));
- } else {
- salvinfo->VolumeChanged = 0;
+ if (salvinfo->useFSYNC) {
+ afs_int32 fsync_code;
+
+ fsync_code = FSYNC_VolOp(vid, NULL, FSYNC_VOL_BREAKCBKS, FSYNC_SALVAGE, NULL);
+ if (fsync_code) {
+ Log("Error trying to tell the fileserver to break callbacks for "
+ "changed volume %lu; error code %ld\n",
+ afs_printable_uint32_lu(vid),
+ afs_printable_int32_ld(fsync_code));
+ } else {
+ salvinfo->VolumeChanged = 0;
+ }
}
- }
#endif /* FSSYNC_BUILD_CLIENT */
+#if defined(AFS_DEMAND_ATTACH_FS) || defined(AFS_DEMAND_ATTACH_UTIL)
+ if (!salvinfo->useFSYNC) {
+ /* A volume's contents have changed, but the fileserver will not
+ * break callbacks on the volume until it tries to load the vol
+ * header. So, to reduce the amount of time a client could have
+ * stale data, remove fsstate.dat, so the fileserver will init
+ * callback state with all clients. This is a very coarse hammer,
+ * and in the future we should just record which volumes have
+ * changed. */
+ code = unlink(AFSDIR_SERVER_FSSTATE_FILEPATH);
+ if (code && errno != ENOENT) {
+ Log("Error %d when trying to unlink FS state file %s\n", errno,
+ AFSDIR_SERVER_FSSTATE_FILEPATH);
+ }
+ }
+#endif
+ }
+
/* Turn off the inUse bit; the volume's been salvaged! */
volHeader.inUse = 0; /* clear flag indicating inUse@last crash */
volHeader.needsSalvaged = 0; /* clear 'damaged' flag */