#include <afs/osi_inode.h>
#endif
#include <afs/cmd.h>
+#include <afs/dir.h>
#include <afs/afsutil.h>
#include <afs/fileutil.h>
#include <afs/procmgmt.h> /* signal(), kill(), wait(), etc. */
#include "salvage.h"
#include "volinodes.h" /* header magic number, etc. stuff */
#include "vol-salvage.h"
+#include "vol_internal.h"
+
#ifdef AFS_NT40_ENV
#include <pthread.h>
#endif
|| (vsp->header.id == singleVolumeNumber
|| vsp->header.parent == singleVolumeNumber)) {
(void)afs_snprintf(nameShouldBe, sizeof nameShouldBe,
- VFORMAT, afs_cast_uint32(vsp->header.id));
+ VFORMAT, afs_printable_uint32_lu(vsp->header.id));
if (singleVolumeNumber
&& vsp->header.id != singleVolumeNumber)
AskOffline(vsp->header.id, fileSysPartition->name);
if (isp->volSummary == NULL) {
char path[64];
char headerName[64];
- (void)afs_snprintf(headerName, sizeof headerName, VFORMAT, afs_cast_uint32(isp->volumeId));
+ (void)afs_snprintf(headerName, sizeof headerName, VFORMAT, afs_printable_uint32_lu(isp->volumeId));
(void)afs_snprintf(path, sizeof path, "%s/%s", fileSysPath, headerName);
if (check) {
Log("No header file for volume %u\n", isp->volumeId);
if (isp->volSummary->fileName) {
strcpy(headerName, isp->volSummary->fileName);
} else {
- (void)afs_snprintf(headerName, sizeof headerName, VFORMAT, afs_cast_uint32(isp->volumeId));
+ (void)afs_snprintf(headerName, sizeof headerName, VFORMAT, afs_printable_uint32_lu(isp->volumeId));
isp->volSummary->fileName = ToString(headerName);
}
(void)afs_snprintf(path, sizeof path, "%s/%s", fileSysPath, headerName);
}
int
-JudgeEntry(struct DirSummary *dir, char *name, VnodeId vnodeNumber,
- Unique unique)
+JudgeEntry(void *dirVal, char *name, afs_int32 vnodeNumber,
+ afs_int32 unique)
{
+ struct DirSummary *dir = (struct DirSummary *)dirVal;
struct VnodeEssence *vnodeEssence;
afs_int32 dirOrphaned, todelete;
Log("dir vnode %u: %s/%s (vnode %u): unique changed from %u to %u %s\n", dir->vnodeNumber, (dir->name ? dir->name : "??"), name, vnodeNumber, unique, vnodeEssence->unique, (!todelete ? "" : (Testing ? "-- would have deleted" : "-- deleted")));
}
if (!Testing) {
- ViceFid fid;
+ AFSFid fid;
fid.Vnode = vnodeNumber;
fid.Unique = vnodeEssence->unique;
CopyOnWrite(dir);
if (strcmp(name, ".") == 0) {
if (dir->vnodeNumber != vnodeNumber || (dir->unique != unique)) {
- ViceFid fid;
+ AFSFid fid;
if (!Showmode)
Log("directory vnode %u.%u: bad '.' entry (was %u.%u); fixed\n", dir->vnodeNumber, dir->unique, vnodeNumber, unique);
if (!Testing) {
}
dir->haveDot = 1;
} else if (strcmp(name, "..") == 0) {
- ViceFid pa;
+ AFSFid pa;
if (dir->parent) {
struct VnodeEssence *dotdot;
pa.Vnode = dir->parent;
vep->owner = vnode->owner;
vep->group = vnode->group;
if (vnode->type == vDirectory) {
- assert(class == vLarge);
- vip->inodes[vnodeIndex] = VNDISK_GET_INO(vnode);
+ if (class != vLarge) {
+ VnodeId vnodeNumber = bitNumberToVnodeNumber(vnodeIndex, class);
+ vip->nAllocatedVnodes--;
+ memset(vnode, 0, sizeof(vnode));
+ IH_IWRITE(vnodeInfo[vSmall].handle,
+ vnodeIndexOffset(vcp, vnodeNumber),
+ (char *)&vnode, sizeof(vnode));
+ VolumeChanged = 1;
+ } else
+ vip->inodes[vnodeIndex] = VNDISK_GET_INO(vnode);
}
}
}
afs_int32 v, pv;
IHandle_t *h;
afs_sfsize_t nBytes;
- ViceFid pa;
+ AFSFid pa;
VnodeId LFVnode, ThisVnode;
Unique LFUnique, ThisUnique;
char npath[128];
* won't be visible there.
*/
if (class == vLarge) {
- ViceFid pa;
+ AFSFid pa;
DirHandle dh;
/* Remove and recreate the ".." entry in this orphaned directory */
Log("AskOffline: request for fileserver to take volume offline failed; salvage aborting.\n");
Abort("Salvage aborted\n");
}
+
+#ifdef AFS_DEMAND_ATTACH_FS
+ /* set inUse = programType in the volume header. We do this in case
+ * the fileserver restarts/crashes while we are salvaging.
+ * Otherwise, the fileserver could attach the volume again on
+ * startup while we are salvaging, which would be very bad, or
+ * schedule another salvage while we are salvaging, which would be
+ * annoying. */
+ if (!Testing) {
+ int fd;
+ IHandle_t *h;
+ char name[VMAXPATHLEN];
+ struct VolumeHeader header;
+ struct VolumeDiskHeader diskHeader;
+ struct VolumeDiskData volHeader;
+
+ afs_snprintf(name, sizeof(name), "%s/" VFORMAT, fileSysPathName,
+ afs_printable_uint32_lu(volumeId));
+
+ fd = afs_open(name, O_RDONLY);
+ if (fd < 0) {
+ return;
+ }
+ if (read(fd, &diskHeader, sizeof(diskHeader)) != sizeof(diskHeader) ||
+ diskHeader.stamp.magic != VOLUMEHEADERMAGIC) {
+
+ close(fd);
+ return;
+ }
+ close(fd);
+
+ DiskToVolumeHeader(&header, &diskHeader);
+
+ IH_INIT(h, fileSysDevice, header.parent, header.volumeInfo);
+ if (IH_IREAD(h, 0, (char*)&volHeader, sizeof(volHeader)) != sizeof(volHeader) ||
+ volHeader.stamp.magic != VOLUMEINFOMAGIC) {
+
+ IH_RELEASE(h);
+ return;
+ }
+
+ volHeader.inUse = programType;
+
+ /* If we can't re-write the header, bail out and error. We don't
+ * assert when reading the header, since it's possible the
+ * header isn't really there (when there's no data associated
+ * with the volume; we just delete the vol header file in that
+ * case). But if it's there enough that we can read it, but
+ * somehow we cannot write to it to signify we're salvaging it,
+ * we've got a big problem and we cannot continue. */
+ assert(IH_IWRITE(h, 0, (char*)&volHeader, sizeof(volHeader)) == sizeof(volHeader));
+
+ IH_RELEASE(h);
+ }
+#endif /* AFS_DEMAND_ATTACH_FS */
}
void