diff --git a/src/vol/physio.c b/src/vol/physio.c index 1ede75672e..9b06ff85ec 100644 --- a/src/vol/physio.c +++ b/src/vol/physio.c @@ -78,7 +78,6 @@ int ReallyWrite(DirHandle * file, int block, char *data) { FdHandle_t *fdP; - extern int VolumeChanged; int code; ssize_t nBytes; @@ -104,7 +103,7 @@ ReallyWrite(DirHandle * file, int block, char *data) return code; } FDH_CLOSE(fdP); - VolumeChanged = 1; + *(file->volumeChanged) = 1; return 0; } @@ -114,7 +113,7 @@ ReallyWrite(DirHandle * file, int block, char *data) */ void SetSalvageDirHandle(DirHandle * dir, afs_int32 volume, Device device, - Inode inode) + Inode inode, int *volumeChanged) { static int SalvageCacheCheck = 1; memset(dir, 0, sizeof(DirHandle)); @@ -125,6 +124,7 @@ SetSalvageDirHandle(DirHandle * dir, afs_int32 volume, Device device, IH_INIT(dir->dirh_handle, device, volume, inode); /* Always re-read for a new dirhandle */ dir->dirh_cacheCheck = SalvageCacheCheck++; + dir->volumeChanged = volumeChanged; } void diff --git a/src/vol/salvage.h b/src/vol/salvage.h index 1991658554..edf90924ea 100644 --- a/src/vol/salvage.h +++ b/src/vol/salvage.h @@ -26,6 +26,7 @@ typedef struct DirHandle { Inode dirh_inode; IHandle_t *dirh_handle; afs_int32 dirh_cacheCheck; + int *volumeChanged; } DirHandle; #endif /* __salvage_h_ */ diff --git a/src/vol/vol-salvage.c b/src/vol/vol-salvage.c index 1e84484951..e07c90ce5b 100644 --- a/src/vol/vol-salvage.c +++ b/src/vol/vol-salvage.c @@ -266,51 +266,59 @@ FILE *logFile = 0; /* one of {/usr/afs/logs,/vice/file}/SalvageLog */ #define ROOTINODE 2 /* Root inode of a 4.2 Unix file system * partition */ -Device fileSysDevice; /* The device number of the current - * partition being salvaged */ -#ifdef AFS_NT40_ENV -char fileSysPath[8]; -#else -char *fileSysPath; /* The path of the mounted partition currently - * being salvaged, i.e. the directory - * containing the volume headers */ -#endif -char *fileSysPathName; /* NT needs this to make name pretty in log. */ -IHandle_t *VGLinkH; /* Link handle for current volume group. */ -int VGLinkH_cnt; /* # of references to lnk handle. */ -struct DiskPartition64 *fileSysPartition; /* Partition being salvaged */ +/** + * information that is 'global' to a particular salvage job. + */ +struct SalvInfo { + Device fileSysDevice; /**< The device number of the current partition + * being salvaged */ + char fileSysPath[8]; /**< The path of the mounted partition currently + * being salvaged, i.e. the directory containing + * the volume headers */ + char *fileSysPathName; /**< NT needs this to make name pretty log. */ + IHandle_t *VGLinkH; /**< Link handle for current volume group. */ + int VGLinkH_cnt; /**< # of references to lnk handle. */ + struct DiskPartition64 *fileSysPartition; /**< Partition being salvaged */ + #ifndef AFS_NT40_ENV -char *fileSysDeviceName; /* The block device where the file system - * being salvaged was mounted */ -char *filesysfulldev; + char *fileSysDeviceName; /**< The block device where the file system being + * salvaged was mounted */ + char *filesysfulldev; #endif -int VolumeChanged; /* Set by any routine which would change the volume in - * a way which would require callback is to be broken if the - * volume was put back on line by an active file server */ + int VolumeChanged; /**< Set by any routine which would change the + * volume in a way which would require callbacks + * to be broken if the volume was put back on + * on line by an active file server */ -VolumeDiskData VolInfo; /* A copy of the last good or salvaged volume header dealt with */ + VolumeDiskData VolInfo; /**< A copy of the last good or salvaged volume + * header dealt with */ -int nVolumesInInodeFile; /* Number of read-write volumes summarized */ -int inodeFd; /* File descriptor for inode file */ + int nVolumesInInodeFile; /**< Number of read-write volumes summarized */ + int inodeFd; /**< File descriptor for inode file */ + struct VolumeSummary *volumeSummaryp; /**< Holds all the volumes in a part */ + int nVolumes; /**< Number of volumes (read-write and read-only) + * in volume summary */ + struct InodeSummary *inodeSummary; /**< contains info on all the relevant + * inodes */ -struct VnodeInfo vnodeInfo[nVNODECLASSES]; - - -struct VolumeSummary *volumeSummaryp = NULL; /* Holds all the volumes in a part */ -int nVolumes; /* Number of volumes (read-write and read-only) - * in volume summary */ + struct VnodeInfo vnodeInfo[nVNODECLASSES]; /**< contains info on all of the + * vnodes in the volume that + * we are currently looking + * at */ +}; char *tmpdir = NULL; /* Forward declarations */ -static int IsVnodeOrphaned(VnodeId vnode); -static int AskVolumeSummary(VolumeId singleVolumeNumber); +static int IsVnodeOrphaned(struct SalvInfo *salvinfo, VnodeId vnode); +static int AskVolumeSummary(struct SalvInfo *salvinfo, + VolumeId singleVolumeNumber); #ifdef AFS_DEMAND_ATTACH_FS -static int LockVolume(VolumeId volumeId); +static int LockVolume(struct SalvInfo *salvinfo, VolumeId volumeId); #endif /* AFS_DEMAND_ATTACH_FS */ /* Uniquifier stored in the Inode */ @@ -729,8 +737,12 @@ SalvageFileSys1(struct DiskPartition64 *partP, VolumeId singleVolumeNumber) int i, j; int code; int tries = 0; + struct SalvInfo l_salvinfo; + struct SalvInfo *salvinfo = &l_salvinfo; retry: + memset(salvinfo, 0, sizeof(*salvinfo)); + tries++; if (inodeFile) { fclose(inodeFile); @@ -748,20 +760,20 @@ SalvageFileSys1(struct DiskPartition64 *partP, VolumeId singleVolumeNumber) } #endif /* AFS_DEMAND_ATTACH_FS */ - fileSysPartition = partP; - fileSysDevice = fileSysPartition->device; - fileSysPathName = VPartitionPath(fileSysPartition); + salvinfo->fileSysPartition = partP; + salvinfo->fileSysDevice = salvinfo->fileSysPartition->device; + salvinfo->fileSysPathName = VPartitionPath(salvinfo->fileSysPartition); #ifdef AFS_NT40_ENV /* Opendir can fail on "C:" but not on "C:\" if C is empty! */ - (void)sprintf(fileSysPath, "%s\\", fileSysPathName); + (void)sprintf(salvinfo->fileSysPath, "%s\\", salvinfo->fileSysPathName); name = partP->devName; #else - fileSysPath = fileSysPathName; + strlcpy(salvinfo->fileSysPath, salvinfo->fileSysPathName, sizeof(salvinfo->fileSysPath)); strcpy(tmpDevName, partP->devName); name = get_DevName(tmpDevName, wpath); - fileSysDeviceName = name; - filesysfulldev = wpath; + salvinfo->fileSysDeviceName = name; + salvinfo->filesysfulldev = wpath; #endif if (singleVolumeNumber) { @@ -778,9 +790,9 @@ SalvageFileSys1(struct DiskPartition64 *partP, VolumeId singleVolumeNumber) Abort("Couldn't connect to file server\n"); } - AskOffline(singleVolumeNumber, partP->name); + AskOffline(salvinfo, singleVolumeNumber); #ifdef AFS_DEMAND_ATTACH_FS - if (LockVolume(singleVolumeNumber)) { + if (LockVolume(salvinfo, singleVolumeNumber)) { goto retry; } #endif /* AFS_DEMAND_ATTACH_FS */ @@ -790,7 +802,7 @@ SalvageFileSys1(struct DiskPartition64 *partP, VolumeId singleVolumeNumber) if (ForceSalvage) { ForceSalvage = 1; } else { - ForceSalvage = UseTheForceLuke(fileSysPath); + ForceSalvage = UseTheForceLuke(salvinfo->fileSysPath); } if (!Showmode) Log("SALVAGING FILE SYSTEM PARTITION %s (device=%s%s)\n", @@ -808,13 +820,13 @@ SalvageFileSys1(struct DiskPartition64 *partP, VolumeId singleVolumeNumber) DIR *dirp; struct dirent *dp; - assert((dirp = opendir(fileSysPath)) != NULL); + assert((dirp = opendir(salvinfo->fileSysPath)) != NULL); while ((dp = readdir(dirp))) { if (!strncmp(dp->d_name, "salvage.inodes.", 15) || !strncmp(dp->d_name, "salvage.temp.", 13)) { char npath[1024]; Log("Removing old salvager temp files %s\n", dp->d_name); - strcpy(npath, fileSysPath); + strcpy(npath, salvinfo->fileSysPath); strcat(npath, "/"); strcat(npath, dp->d_name); unlink(npath); @@ -822,7 +834,7 @@ SalvageFileSys1(struct DiskPartition64 *partP, VolumeId singleVolumeNumber) } closedir(dirp); } - tdir = (tmpdir ? tmpdir : fileSysPath); + tdir = (tmpdir ? tmpdir : salvinfo->fileSysPath); #ifdef AFS_NT40_ENV (void)_putenv("TMP="); /* If "TMP" is set, then that overrides tdir. */ (void)strncpy(inodeListPath, _tempnam(tdir, "salvage.inodes."), 255); @@ -849,16 +861,16 @@ SalvageFileSys1(struct DiskPartition64 *partP, VolumeId singleVolumeNumber) Log("Error %d when trying to unlink %s\n", errno, inodeListPath); } - if (GetInodeSummary(inodeFile, singleVolumeNumber) < 0) { + if (GetInodeSummary(salvinfo, inodeFile, singleVolumeNumber) < 0) { fclose(inodeFile); return; } - inodeFd = fileno(inodeFile); - if (inodeFd == -1) + salvinfo->inodeFd = fileno(inodeFile); + if (salvinfo->inodeFd == -1) Abort("Temporary file %s is missing...\n", inodeListPath); - afs_lseek(inodeFd, 0L, SEEK_SET); + afs_lseek(salvinfo->inodeFd, 0L, SEEK_SET); if (ListInodeOption) { - PrintInodeList(); + PrintInodeList(salvinfo); return; } /* enumerate volumes in the partition. @@ -867,17 +879,17 @@ SalvageFileSys1(struct DiskPartition64 *partP, VolumeId singleVolumeNumber) * Fix up inodes on last volume in set (whether it is read-write * or read-only). */ - if (GetVolumeSummary(singleVolumeNumber)) { + if (GetVolumeSummary(salvinfo, singleVolumeNumber)) { goto retry; } - for (i = j = 0, vsp = volumeSummaryp, esp = vsp + nVolumes; - i < nVolumesInInodeFile; i = j) { - VolumeId rwvid = inodeSummary[i].RWvolumeId; + for (i = j = 0, vsp = salvinfo->volumeSummaryp, esp = vsp + salvinfo->nVolumes; + i < salvinfo->nVolumesInInodeFile; i = j) { + VolumeId rwvid = salvinfo->inodeSummary[i].RWvolumeId; for (j = i; - j < nVolumesInInodeFile && inodeSummary[j].RWvolumeId == rwvid; + j < salvinfo->nVolumesInInodeFile && salvinfo->inodeSummary[j].RWvolumeId == rwvid; j++) { - VolumeId vid = inodeSummary[j].volumeId; + VolumeId vid = salvinfo->inodeSummary[j].volumeId; struct VolumeSummary *tsp; /* Scan volume list (from partition root directory) looking for the * current rw volume number in the volume list from the inode scan. @@ -885,14 +897,14 @@ SalvageFileSys1(struct DiskPartition64 *partP, VolumeId singleVolumeNumber) * delete it now. */ for (; vsp < esp && (vsp->header.parent < rwvid); vsp++) { if (vsp->fileName) - DeleteExtraVolumeHeaderFile(vsp); + DeleteExtraVolumeHeaderFile(salvinfo, vsp); } /* Now match up the volume summary info from the root directory with the * entry in the volume list obtained from scanning inodes */ - inodeSummary[j].volSummary = NULL; + salvinfo->inodeSummary[j].volSummary = NULL; for (tsp = vsp; tsp < esp && (tsp->header.parent == rwvid); tsp++) { if (tsp->header.id == vid) { - inodeSummary[j].volSummary = tsp; + salvinfo->inodeSummary[j].volSummary = tsp; tsp->fileName = 0; break; } @@ -901,52 +913,52 @@ SalvageFileSys1(struct DiskPartition64 *partP, VolumeId singleVolumeNumber) /* Salvage the group of volumes (several read-only + 1 read/write) * starting with the current read-only volume we're looking at. */ - SalvageVolumeGroup(&inodeSummary[i], j - i); + SalvageVolumeGroup(salvinfo, &salvinfo->inodeSummary[i], j - i); } /* Delete any additional volumes that were listed in the partition but which didn't have any corresponding inodes */ for (; vsp < esp; vsp++) { if (vsp->fileName) - DeleteExtraVolumeHeaderFile(vsp); + DeleteExtraVolumeHeaderFile(salvinfo, vsp); } if (!singleVolumeNumber) /* Remove the FORCESALVAGE file */ - RemoveTheForce(fileSysPath); + RemoveTheForce(salvinfo->fileSysPath); if (!Testing && singleVolumeNumber) { #ifdef AFS_DEMAND_ATTACH_FS /* unlock vol headers so the fs can attach them when we AskOnline */ - VLockFileReinit(&fileSysPartition->volLockFile); + VLockFileReinit(&salvinfo->fileSysPartition->volLockFile); #endif /* AFS_DEMAND_ATTACH_FS */ - AskOnline(singleVolumeNumber, fileSysPartition->name); + AskOnline(salvinfo, singleVolumeNumber); /* Step through the volumeSummary list and set all volumes on-line. * The volumes were taken off-line in GetVolumeSummary. */ - for (j = 0; j < nVolumes; j++) { - AskOnline(volumeSummaryp[j].header.id, fileSysPartition->name); + for (j = 0; j < salvinfo->nVolumes; j++) { + AskOnline(salvinfo, salvinfo->volumeSummaryp[j].header.id); } } else { if (!Showmode) Log("SALVAGING OF PARTITION %s%s COMPLETED\n", - fileSysPartition->name, (Testing ? " (READONLY mode)" : "")); + salvinfo->fileSysPartition->name, (Testing ? " (READONLY mode)" : "")); } fclose(inodeFile); /* SalvageVolumeGroup was the last which needed it. */ } void -DeleteExtraVolumeHeaderFile(struct VolumeSummary *vsp) +DeleteExtraVolumeHeaderFile(struct SalvInfo *salvinfo, struct VolumeSummary *vsp) { char path[64]; - sprintf(path, "%s/%s", fileSysPath, vsp->fileName); + sprintf(path, "%s/%s", salvinfo->fileSysPath, vsp->fileName); if (!Showmode) Log("The volume header file %s is not associated with any actual data (%sdeleted)\n", path, (Testing ? "would have been " : "")); if (!Testing) { afs_int32 code; - code = VDestroyVolumeDiskHeader(fileSysPartition, vsp->header.id, vsp->header.parent); + code = VDestroyVolumeDiskHeader(salvinfo->fileSysPartition, vsp->header.id, vsp->header.parent); if (code) { Log("Error %ld destroying volume disk header for volume %lu\n", afs_printable_int32_ld(code), @@ -1105,7 +1117,7 @@ OnlyOneVolume(struct ViceInodeInfo *inodeinfo, afs_uint32 singleVolumeNumber, vo * be unlinked by the caller. */ int -GetInodeSummary(FILE *inodeFile, VolumeId singleVolumeNumber) +GetInodeSummary(struct SalvInfo *salvinfo, FILE *inodeFile, VolumeId singleVolumeNumber) { struct afs_stat status; int forceSal, err; @@ -1115,18 +1127,19 @@ GetInodeSummary(FILE *inodeFile, VolumeId singleVolumeNumber) char summaryFileName[50]; FILE *summaryFile; #ifdef AFS_NT40_ENV - char *dev = fileSysPath; - char *wpath = fileSysPath; + char *dev = salvinfo->fileSysPath; + char *wpath = salvinfo->fileSysPath; #else - char *dev = fileSysDeviceName; - char *wpath = filesysfulldev; + char *dev = salvinfo->fileSysDeviceName; + char *wpath = salvinfo->filesysfulldev; #endif - char *part = fileSysPath; + char *part = salvinfo->fileSysPath; char *tdir; + int i; /* This file used to come from vfsck; cobble it up ourselves now... */ if ((err = - ListViceInodes(dev, fileSysPath, inodeFile, + ListViceInodes(dev, salvinfo->fileSysPath, inodeFile, singleVolumeNumber ? OnlyOneVolume : 0, singleVolumeNumber, &forceSal, forceR, wpath, NULL)) < 0) { if (err == -2) { @@ -1140,8 +1153,8 @@ GetInodeSummary(FILE *inodeFile, VolumeId singleVolumeNumber) ForceSalvage = 1; } fseek(inodeFile, 0L, SEEK_SET); - inodeFd = fileno(inodeFile); - if (inodeFd == -1 || afs_fstat(inodeFd, &status) == -1) { + salvinfo->inodeFd = fileno(inodeFile); + if (salvinfo->inodeFd == -1 || afs_fstat(salvinfo->inodeFd, &status) == -1) { Abort("No inode description file for \"%s\"; not salvaged\n", dev); } tdir = (tmpdir ? tmpdir : part); @@ -1178,16 +1191,16 @@ GetInodeSummary(FILE *inodeFile, VolumeId singleVolumeNumber) if (nInodes == 0) { fclose(summaryFile); if (!singleVolumeNumber) /* Remove the FORCESALVAGE file */ - RemoveTheForce(fileSysPath); + RemoveTheForce(salvinfo->fileSysPath); else { struct VolumeSummary *vsp; int i; - GetVolumeSummary(singleVolumeNumber); + GetVolumeSummary(salvinfo, singleVolumeNumber); - for (i = 0, vsp = volumeSummaryp; i < nVolumes; i++) { + for (i = 0, vsp = salvinfo->volumeSummaryp; i < salvinfo->nVolumes; i++) { if (vsp->fileName) - DeleteExtraVolumeHeaderFile(vsp); + DeleteExtraVolumeHeaderFile(salvinfo, vsp); } } Log("%s vice inodes on %s; not salvaged\n", @@ -1201,13 +1214,13 @@ GetInodeSummary(FILE *inodeFile, VolumeId singleVolumeNumber) ("Unable to allocate enough space to read inode table; %s not salvaged\n", dev); } - if (read(inodeFd, ip, st_size) != st_size) { + if (read(salvinfo->inodeFd, ip, st_size) != st_size) { fclose(summaryFile); Abort("Unable to read inode table; %s not salvaged\n", dev); } qsort(ip, nInodes, sizeof(struct ViceInodeInfo), CompareInodes); - if (afs_lseek(inodeFd, 0, SEEK_SET) == -1 - || write(inodeFd, ip, st_size) != st_size) { + if (afs_lseek(salvinfo->inodeFd, 0, SEEK_SET) == -1 + || write(salvinfo->inodeFd, ip, st_size) != st_size) { fclose(summaryFile); Abort("Unable to rewrite inode table; %s not salvaged\n", dev); } @@ -1246,15 +1259,18 @@ GetInodeSummary(FILE *inodeFile, VolumeId singleVolumeNumber) if (status.st_size != 0) { int ret; unsigned long st_status=(unsigned long)status.st_size; - inodeSummary = (struct InodeSummary *)malloc(st_status); - assert(inodeSummary != NULL); + salvinfo->inodeSummary = (struct InodeSummary *)malloc(st_status); + assert(salvinfo->inodeSummary != NULL); /* For GNU we need to do lseek to get the file pointer moved. */ assert(afs_lseek(fileno(summaryFile), 0, SEEK_SET) == 0); - ret = read(fileno(summaryFile), inodeSummary, st_status); + ret = read(fileno(summaryFile), salvinfo->inodeSummary, st_status); assert(ret == st_status); } - nVolumesInInodeFile =(unsigned long)(status.st_size) / sizeof(struct InodeSummary); - Log("%d nVolumesInInodeFile %lu \n",nVolumesInInodeFile,(unsigned long)(status.st_size)); + salvinfo->nVolumesInInodeFile =(unsigned long)(status.st_size) / sizeof(struct InodeSummary); + for (i = 0; i < salvinfo->nVolumesInInodeFile; i++) { + salvinfo->inodeSummary[i].volSummary = NULL; + } + Log("%d nVolumesInInodeFile %lu \n",salvinfo->nVolumesInInodeFile,(unsigned long)(status.st_size)); fclose(summaryFile); return 0; } @@ -1294,7 +1310,7 @@ CompareVolumes(const void *_p1, const void *_p2) * @note for non-DAFS, always returns 1 */ static int -AskVolumeSummary(VolumeId singleVolumeNumber) +AskVolumeSummary(struct SalvInfo *salvinfo, VolumeId singleVolumeNumber) { afs_int32 code = 1; #if defined(FSSYNC_BUILD_CLIENT) && defined(AFS_DEMAND_ATTACH_FS) @@ -1308,7 +1324,7 @@ AskVolumeSummary(VolumeId singleVolumeNumber) memset(&res, 0, sizeof(res)); - code = FSYNC_VGCQuery(fileSysPartition->name, singleVolumeNumber, &q_res, &res); + code = FSYNC_VGCQuery(salvinfo->fileSysPartition->name, singleVolumeNumber, &q_res, &res); /* * We must wait for the partition to finish scanning before @@ -1323,7 +1339,7 @@ AskVolumeSummary(VolumeId singleVolumeNumber) */ if (code == SYNC_FAILED && res.hdr.reason == FSYNC_PART_SCANNING) { Log("waiting for fileserver to finish scanning partition %s...\n", - fileSysPartition->name); + salvinfo->fileSysPartition->name); for (i = 1; code == SYNC_FAILED && res.hdr.reason == FSYNC_PART_SCANNING; i++) { /* linearly ramp up from 1 to 10 seconds; nothing fancy, @@ -1332,7 +1348,7 @@ AskVolumeSummary(VolumeId singleVolumeNumber) * polled only once every ten seconds. */ sleep((i > 10) ? (i = 10) : i); - code = FSYNC_VGCQuery(fileSysPartition->name, singleVolumeNumber, &q_res, &res); + code = FSYNC_VGCQuery(salvinfo->fileSysPartition->name, singleVolumeNumber, &q_res, &res); } } @@ -1351,7 +1367,7 @@ AskVolumeSummary(VolumeId singleVolumeNumber) Log("fileserver refused VGCQuery request for volume %lu on " "partition %s, code %ld reason %ld\n", afs_printable_uint32_lu(singleVolumeNumber), - fileSysPartition->name, + salvinfo->fileSysPartition->name, afs_printable_int32_ld(code), afs_printable_int32_ld(res.hdr.reason)); goto done; @@ -1364,7 +1380,7 @@ AskVolumeSummary(VolumeId singleVolumeNumber) #ifdef SALVSYNC_BUILD_CLIENT if (SALVSYNC_LinkVolume(q_res.rw, singleVolumeNumber, - fileSysPartition->name, + salvinfo->fileSysPartition->name, NULL) != SYNC_OK) { Log("schedule request failed\n"); } @@ -1372,11 +1388,11 @@ AskVolumeSummary(VolumeId singleVolumeNumber) Exit(SALSRV_EXIT_VOLGROUP_LINK); } - volumeSummaryp = malloc(VOL_VG_MAX_VOLS * sizeof(struct VolumeSummary)); - assert(volumeSummaryp != NULL); + salvinfo->volumeSummaryp = malloc(VOL_VG_MAX_VOLS * sizeof(struct VolumeSummary)); + assert(salvinfo->volumeSummaryp != NULL); - nVolumes = 0; - vsp = volumeSummaryp; + salvinfo->nVolumes = 0; + vsp = salvinfo->volumeSummaryp; for (i = 0; i < VOL_VG_MAX_VOLS; i++) { char name[VMAXPATHLEN]; @@ -1387,14 +1403,14 @@ AskVolumeSummary(VolumeId singleVolumeNumber) /* AskOffline for singleVolumeNumber was called much earlier */ if (q_res.children[i] != singleVolumeNumber) { - AskOffline(q_res.children[i], fileSysPartition->name); - if (LockVolume(q_res.children[i])) { + AskOffline(salvinfo, q_res.children[i]); + if (LockVolume(salvinfo, q_res.children[i])) { /* need to retry */ return -1; } } - code = VReadVolumeDiskHeader(q_res.children[i], fileSysPartition, &diskHdr); + code = VReadVolumeDiskHeader(q_res.children[i], salvinfo->fileSysPartition, &diskHdr); if (code) { Log("Cannot read header for %lu; trying to salvage group anyway\n", afs_printable_uint32_lu(q_res.children[i])); @@ -1405,11 +1421,11 @@ AskVolumeSummary(VolumeId singleVolumeNumber) DiskToVolumeHeader(&vsp->header, &diskHdr); VolumeExternalName_r(q_res.children[i], name, sizeof(name)); vsp->fileName = ToString(name); - nVolumes++; + salvinfo->nVolumes++; vsp++; } - qsort(volumeSummaryp, nVolumes, sizeof(struct VolumeSummary), + qsort(salvinfo->volumeSummaryp, salvinfo->nVolumes, sizeof(struct VolumeSummary), CompareVolumes); } done: @@ -1456,6 +1472,7 @@ struct SalvageScanParams { afs_int32 totalVolumes; /**< max # of vols we should encounter (the * # of vols we've alloc'd memory for) */ int retry; /**< do we need to retry vol lock/checkout? */ + struct SalvInfo *salvinfo; /**< salvage job info */ }; /** @@ -1485,10 +1502,12 @@ RecordHeader(struct DiskPartition64 *dp, const char *name, struct SalvageScanParams *params; struct VolumeSummary summary; VolumeId singleVolumeNumber; + struct SalvInfo *salvinfo; params = (struct SalvageScanParams *)rock; singleVolumeNumber = params->singleVolumeNumber; + salvinfo = params->salvinfo; DiskToVolumeHeader(&summary.header, hdr); @@ -1546,13 +1565,13 @@ RecordHeader(struct DiskPartition64 *dp, const char *name, /* don't offline singleVolumeNumber; we already did that * earlier */ - AskOffline(summary.header.id, fileSysPartition->name); + AskOffline(salvinfo, summary.header.id); #ifdef AFS_DEMAND_ATTACH_FS if (!badname) { /* don't lock the volume if the header is bad, since we're * about to delete it anyway. */ - if (LockVolume(summary.header.id)) { + if (LockVolume(salvinfo, summary.header.id)) { params->retry = 1; return -1; } @@ -1642,7 +1661,7 @@ UnlinkHeader(struct DiskPartition64 *dp, const char *name, } /** - * Populates volumeSummaryp with volume summary information, either by asking + * Populates salvinfo->volumeSummaryp with volume summary information, either by asking * the fileserver for VG information, or by scanning the /vicepX partition. * * @param[in] singleVolumeNumber the volume ID of the single volume group we @@ -1655,13 +1674,13 @@ UnlinkHeader(struct DiskPartition64 *dp, const char *name, * volumes must be retried */ int -GetVolumeSummary(VolumeId singleVolumeNumber) +GetVolumeSummary(struct SalvInfo *salvinfo, VolumeId singleVolumeNumber) { afs_int32 nvols = 0; struct SalvageScanParams params; int code; - code = AskVolumeSummary(singleVolumeNumber); + code = AskVolumeSummary(salvinfo, singleVolumeNumber); if (code == 0) { /* we successfully got the vol information from the fileserver; no * need to scan the partition */ @@ -1674,10 +1693,10 @@ GetVolumeSummary(VolumeId singleVolumeNumber) if (!singleVolumeNumber) { /* Count how many volumes we have in /vicepX */ - code = VWalkVolumeHeaders(fileSysPartition, fileSysPath, CountHeader, + code = VWalkVolumeHeaders(salvinfo->fileSysPartition, salvinfo->fileSysPath, CountHeader, NULL, &nvols); if (code < 0) { - Abort("Can't read directory %s; not salvaged\n", fileSysPath); + Abort("Can't read directory %s; not salvaged\n", salvinfo->fileSysPath); } if (!nvols) nvols = 1; @@ -1685,18 +1704,19 @@ GetVolumeSummary(VolumeId singleVolumeNumber) nvols = VOL_VG_MAX_VOLS; } - volumeSummaryp = malloc(nvols * sizeof(struct VolumeSummary)); - assert(volumeSummaryp != NULL); + salvinfo->volumeSummaryp = malloc(nvols * sizeof(struct VolumeSummary)); + assert(salvinfo->volumeSummaryp != NULL); params.singleVolumeNumber = singleVolumeNumber; - params.vsp = volumeSummaryp; + params.vsp = salvinfo->volumeSummaryp; params.nVolumes = 0; params.totalVolumes = nvols; params.retry = 0; + params.salvinfo = salvinfo; /* walk the partition directory of volume headers and record the info * about them; unlinking invalid headers */ - code = VWalkVolumeHeaders(fileSysPartition, fileSysPath, RecordHeader, + code = VWalkVolumeHeaders(salvinfo->fileSysPartition, salvinfo->fileSysPath, RecordHeader, UnlinkHeader, ¶ms); if (params.retry) { /* we apparently need to retry checking-out/locking volumes */ @@ -1705,9 +1725,9 @@ GetVolumeSummary(VolumeId singleVolumeNumber) if (code < 0) { Abort("Failed to get volume header summary\n"); } - nVolumes = params.nVolumes; + salvinfo->nVolumes = params.nVolumes; - qsort(volumeSummaryp, nVolumes, sizeof(struct VolumeSummary), + qsort(salvinfo->volumeSummaryp, salvinfo->nVolumes, sizeof(struct VolumeSummary), CompareVolumes); return 0; @@ -1734,21 +1754,21 @@ FindLinkHandle(struct InodeSummary *isp, int nVols, } int -CreateLinkTable(struct InodeSummary *isp, Inode ino) +CreateLinkTable(struct SalvInfo *salvinfo, struct InodeSummary *isp, Inode ino) { struct versionStamp version; FdHandle_t *fdP; if (!VALID_INO(ino)) ino = - IH_CREATE(NULL, fileSysDevice, fileSysPath, 0, isp->volumeId, + IH_CREATE(NULL, salvinfo->fileSysDevice, salvinfo->fileSysPath, 0, isp->volumeId, INODESPECIAL, VI_LINKTABLE, isp->RWvolumeId); if (!VALID_INO(ino)) Abort ("Unable to allocate link table inode for volume %u (error = %d)\n", isp->RWvolumeId, errno); - IH_INIT(VGLinkH, fileSysDevice, isp->RWvolumeId, ino); - fdP = IH_OPEN(VGLinkH); + IH_INIT(salvinfo->VGLinkH, salvinfo->fileSysDevice, isp->RWvolumeId, ino); + fdP = IH_OPEN(salvinfo->VGLinkH); if (fdP == NULL) Abort("Can't open link table for volume %u (error = %d)\n", isp->RWvolumeId, errno); @@ -1781,12 +1801,12 @@ void * nt_SVG(void *arg) { SVGParms_t *parms = (SVGParms_t *) arg; - DoSalvageVolumeGroup(parms->svgp_inodeSummaryp, parms->svgp_count); + DoSalvageVolumeGroup(parms->salvinfo, parms->svgp_inodeSummaryp, parms->svgp_count); return NULL; } void -SalvageVolumeGroup(struct InodeSummary *isp, int nVols) +SalvageVolumeGroup(struct SalvInfo *salvinfo, struct InodeSummary *isp, int nVols) { pthread_t tid; pthread_attr_t tattr; @@ -1794,13 +1814,14 @@ SalvageVolumeGroup(struct InodeSummary *isp, int nVols) SVGParms_t parms; /* Initialize per volume global variables, even if later code does so */ - VolumeChanged = 0; - VGLinkH = NULL; - VGLinkH_cnt = 0; - memset(&VolInfo, 0, sizeof(VolInfo)); + salvinfo->VolumeChanged = 0; + salvinfo->VGLinkH = NULL; + salvinfo->VGLinkH_cnt = 0; + memset(&salvinfo->VolInfo, 0, sizeof(salvinfo->VolInfo)); parms.svgp_inodeSummaryp = isp; parms.svgp_count = nVols; + parms.svgp_salvinfo = salvinfo; code = pthread_attr_init(&tattr); if (code) { Log("Failed to salvage volume group %u: pthread_attr_init()\n", @@ -1823,7 +1844,7 @@ SalvageVolumeGroup(struct InodeSummary *isp, int nVols) #endif /* AFS_NT40_ENV */ void -DoSalvageVolumeGroup(struct InodeSummary *isp, int nVols) +DoSalvageVolumeGroup(struct SalvInfo *salvinfo, struct InodeSummary *isp, int nVols) { struct ViceInodeInfo *inodes, *allInodes, *ip; int i, totalInodes, size, salvageTo; @@ -1834,11 +1855,11 @@ DoSalvageVolumeGroup(struct InodeSummary *isp, int nVols) int VGLinkH_p1 =0; FdHandle_t *fdP = NULL; - VGLinkH_cnt = 0; + salvinfo->VGLinkH_cnt = 0; haveRWvolume = (isp->volumeId == isp->RWvolumeId && isp->nSpecialInodes > 0); if ((!ShowMounts) || (ShowMounts && !haveRWvolume)) { - if (!ForceSalvage && QuickCheck(isp, nVols)) + if (!ForceSalvage && QuickCheck(salvinfo, isp, nVols)) return; } if (ShowMounts && !haveRWvolume) @@ -1855,9 +1876,9 @@ DoSalvageVolumeGroup(struct InodeSummary *isp, int nVols) * for the partition, if all the inodes * had been read into memory */ assert(afs_lseek - (inodeFd, isp->index * sizeof(struct ViceInodeInfo), + (salvinfo->inodeFd, isp->index * sizeof(struct ViceInodeInfo), SEEK_SET) != -1); - assert(read(inodeFd, inodes, size) == size); + assert(read(salvinfo->inodeFd, inodes, size) == size); /* Don't try to salvage a read write volume if there isn't one on this * partition */ @@ -1866,19 +1887,19 @@ DoSalvageVolumeGroup(struct InodeSummary *isp, int nVols) #ifdef AFS_NAMEI_ENV ino = FindLinkHandle(isp, nVols, allInodes); if (VALID_INO(ino)) { - IH_INIT(VGLinkH, fileSysDevice, isp->RWvolumeId, ino); - fdP = IH_OPEN(VGLinkH); + IH_INIT(salvinfo->VGLinkH, salvinfo->fileSysDevice, isp->RWvolumeId, ino); + fdP = IH_OPEN(salvinfo->VGLinkH); } if (!VALID_INO(ino) || fdP == NULL) { Log("%s link table for volume %u.\n", Testing ? "Would have recreated" : "Recreating", isp->RWvolumeId); if (Testing) { - IH_INIT(VGLinkH, fileSysDevice, -1, -1); + IH_INIT(salvinfo->VGLinkH, salvinfo->fileSysDevice, -1, -1); } else { int i, j; struct ViceInodeInfo *ip; - CreateLinkTable(isp, ino); - fdP = IH_OPEN(VGLinkH); + CreateLinkTable(salvinfo, isp, ino); + fdP = IH_OPEN(salvinfo->VGLinkH); /* Sync fake 1 link counts to the link table, now that it exists */ if (fdP) { for (i = 0; i < nVols; i++) { @@ -1897,7 +1918,7 @@ DoSalvageVolumeGroup(struct InodeSummary *isp, int nVols) if (fdP) FDH_REALLYCLOSE(fdP); #else - IH_INIT(VGLinkH, fileSysDevice, -1, -1); + IH_INIT(salvinfo->VGLinkH, salvinfo->fileSysDevice, -1, -1); #endif /* Salvage in reverse order--read/write volume last; this way any @@ -1927,9 +1948,9 @@ DoSalvageVolumeGroup(struct InodeSummary *isp, int nVols) * way the whole RO volume can be deleted, below, if anything goes wrong */ for (check = 1; check >= 0; check--) { int deleteMe; - if (SalvageVolumeHeaderFile(lisp, allInodes, rw, check, &deleteMe) + if (SalvageVolumeHeaderFile(salvinfo, lisp, allInodes, rw, check, &deleteMe) == -1) { - MaybeZapVolume(lisp, "Volume header", deleteMe, check); + MaybeZapVolume(salvinfo, lisp, "Volume header", deleteMe, check); if (rw && deleteMe) { haveRWvolume = 0; /* This will cause its inodes to be deleted--since salvage * volume won't be called */ @@ -1940,8 +1961,8 @@ DoSalvageVolumeGroup(struct InodeSummary *isp, int nVols) } if (rw && check == 1) continue; - if (SalvageVnodes(isp, lisp, allInodes, check) == -1) { - MaybeZapVolume(lisp, "Vnode index", 0, check); + if (SalvageVnodes(salvinfo, isp, lisp, allInodes, check) == -1) { + MaybeZapVolume(salvinfo, lisp, "Vnode index", 0, check); break; } } @@ -1953,8 +1974,8 @@ DoSalvageVolumeGroup(struct InodeSummary *isp, int nVols) for (ip = inodes; totalInodes; ip++, totalInodes--) { static int TraceBadLinkCounts = 0; #ifdef AFS_NAMEI_ENV - if (VGLinkH->ih_ino == ip->inodeNumber) { - dec_VGLinkH = ip->linkCount - VGLinkH_cnt; + if (salvinfo->VGLinkH->ih_ino == ip->inodeNumber) { + dec_VGLinkH = ip->linkCount - salvinfo->VGLinkH_cnt; VGLinkH_p1 = ip->u.param[0]; continue; /* Deal with this last. */ } @@ -1966,7 +1987,7 @@ DoSalvageVolumeGroup(struct InodeSummary *isp, int nVols) while (ip->linkCount > 0) { /* below used to assert, not break */ if (!Testing) { - if (IH_DEC(VGLinkH, ip->inodeNumber, ip->u.param[0])) { + if (IH_DEC(salvinfo->VGLinkH, ip->inodeNumber, ip->u.param[0])) { Log("idec failed. inode %s errno %d\n", PrintInode(NULL, ip->inodeNumber), errno); break; @@ -1977,7 +1998,7 @@ DoSalvageVolumeGroup(struct InodeSummary *isp, int nVols) while (ip->linkCount < 0) { /* these used to be asserts */ if (!Testing) { - if (IH_INC(VGLinkH, ip->inodeNumber, ip->u.param[0])) { + if (IH_INC(salvinfo->VGLinkH, ip->inodeNumber, ip->u.param[0])) { Log("iinc failed. inode %s errno %d\n", PrintInode(NULL, ip->inodeNumber), errno); break; @@ -1988,13 +2009,13 @@ DoSalvageVolumeGroup(struct InodeSummary *isp, int nVols) } #ifdef AFS_NAMEI_ENV while (dec_VGLinkH > 0) { - if (IH_DEC(VGLinkH, VGLinkH->ih_ino, VGLinkH_p1) < 0) { + if (IH_DEC(salvinfo->VGLinkH, salvinfo->VGLinkH->ih_ino, VGLinkH_p1) < 0) { Log("idec failed on link table, errno = %d\n", errno); } dec_VGLinkH--; } while (dec_VGLinkH < 0) { - if (IH_INC(VGLinkH, VGLinkH->ih_ino, VGLinkH_p1) < 0) { + if (IH_INC(salvinfo->VGLinkH, salvinfo->VGLinkH->ih_ino, VGLinkH_p1) < 0) { Log("iinc failed on link table, errno = %d\n", errno); } dec_VGLinkH++; @@ -2004,8 +2025,8 @@ DoSalvageVolumeGroup(struct InodeSummary *isp, int nVols) free(inodes); /* Directory consistency checks on the rw volume */ if (haveRWvolume) - SalvageVolume(isp, VGLinkH); - IH_RELEASE(VGLinkH); + SalvageVolume(salvinfo, isp, salvinfo->VGLinkH); + IH_RELEASE(salvinfo->VGLinkH); if (canfork && !debug) { ShowLog = 0; @@ -2014,7 +2035,7 @@ DoSalvageVolumeGroup(struct InodeSummary *isp, int nVols) } int -QuickCheck(struct InodeSummary *isp, int nVols) +QuickCheck(struct SalvInfo *salvinfo, struct InodeSummary *isp, int nVols) { /* Check headers BEFORE forking */ int i; @@ -2030,7 +2051,7 @@ QuickCheck(struct InodeSummary *isp, int nVols) continue; return 0; } - IH_INIT(h, fileSysDevice, vs->header.parent, vs->header.volumeInfo); + IH_INIT(h, salvinfo->fileSysDevice, vs->header.parent, vs->header.volumeInfo); if (IH_IREAD(h, 0, (char *)&volHeader, sizeof(volHeader)) == sizeof(volHeader) && volHeader.stamp.magic == VOLUMEINFOMAGIC @@ -2066,7 +2087,7 @@ QuickCheck(struct InodeSummary *isp, int nVols) */ int -SalvageVolumeHeaderFile(struct InodeSummary *isp, +SalvageVolumeHeaderFile(struct SalvInfo *salvinfo, struct InodeSummary *isp, struct ViceInodeInfo *inodes, int RW, int check, int *deleteMe) { @@ -2220,7 +2241,7 @@ SalvageVolumeHeaderFile(struct InodeSummary *isp, } if (!check) - VGLinkH_cnt++; /* one for every header. */ + salvinfo->VGLinkH_cnt++; /* one for every header. */ if (!RW && !check && isp->volSummary) { ClearROInUseBit(isp->volSummary); @@ -2233,12 +2254,12 @@ SalvageVolumeHeaderFile(struct InodeSummary *isp, * And we may have recreated the link table earlier, so set the * RW header as well. */ - if (VALID_INO(VGLinkH->ih_ino)) { - *stuff[i].inode = VGLinkH->ih_ino; + if (VALID_INO(salvinfo->VGLinkH->ih_ino)) { + *stuff[i].inode = salvinfo->VGLinkH->ih_ino; } continue; } - if (SalvageHeader(&stuff[i], isp, check, deleteMe) == -1 && check) + if (SalvageHeader(salvinfo, &stuff[i], isp, check, deleteMe) == -1 && check) return -1; } @@ -2246,7 +2267,7 @@ SalvageVolumeHeaderFile(struct InodeSummary *isp, char path[64]; char headerName[64]; (void)afs_snprintf(headerName, sizeof headerName, VFORMAT, afs_printable_uint32_lu(isp->volumeId)); - (void)afs_snprintf(path, sizeof path, "%s/%s", fileSysPath, headerName); + (void)afs_snprintf(path, sizeof path, "%s/%s", salvinfo->fileSysPath, headerName); if (check) { Log("No header file for volume %u\n", isp->volumeId); return -1; @@ -2277,7 +2298,7 @@ SalvageVolumeHeaderFile(struct InodeSummary *isp, (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); + (void)afs_snprintf(path, sizeof path, "%s/%s", salvinfo->fileSysPath, headerName); Log("Header file %s is damaged or no longer valid%s\n", path, (check ? "" : "; repairing")); @@ -2297,7 +2318,7 @@ SalvageVolumeHeaderFile(struct InodeSummary *isp, } else { afs_int32 code; VolumeHeaderToDisk(&diskHeader, &tempHeader); - code = (*writefunc)(&diskHeader, fileSysPartition); + code = (*writefunc)(&diskHeader, salvinfo->fileSysPartition); if (code) { Log("Error %ld writing volume header file for volume %lu\n", afs_printable_int32_ld(code), @@ -2306,14 +2327,14 @@ SalvageVolumeHeaderFile(struct InodeSummary *isp, } } } - IH_INIT(isp->volSummary->volumeInfoHandle, fileSysDevice, isp->RWvolumeId, + IH_INIT(isp->volSummary->volumeInfoHandle, salvinfo->fileSysDevice, isp->RWvolumeId, isp->volSummary->header.volumeInfo); return 0; } int -SalvageHeader(struct stuff *sp, struct InodeSummary *isp, int check, - int *deleteMe) +SalvageHeader(struct SalvInfo *salvinfo, struct stuff *sp, + struct InodeSummary *isp, int check, int *deleteMe) { union { VolumeDiskData volumeInfo; @@ -2340,7 +2361,7 @@ SalvageHeader(struct stuff *sp, struct InodeSummary *isp, int check, (Testing ? "it would have recreated it" : "recreating")); if (!Testing) { *(sp->inode) = - IH_CREATE(NULL, fileSysDevice, fileSysPath, 0, isp->volumeId, + IH_CREATE(NULL, salvinfo->fileSysDevice, salvinfo->fileSysPath, 0, isp->volumeId, INODESPECIAL, sp->inodeType, isp->RWvolumeId); if (!VALID_INO(*(sp->inode))) Abort @@ -2350,7 +2371,7 @@ SalvageHeader(struct stuff *sp, struct InodeSummary *isp, int check, recreate = 1; } - IH_INIT(specH, fileSysDevice, isp->RWvolumeId, *(sp->inode)); + IH_INIT(specH, salvinfo->fileSysDevice, isp->RWvolumeId, *(sp->inode)); fdP = IH_OPEN(specH); if (OKToZap && (fdP == NULL) && BadError(errno)) { /* bail out early and destroy the volume */ @@ -2454,19 +2475,21 @@ SalvageHeader(struct stuff *sp, struct InodeSummary *isp, int check, FDH_REALLYCLOSE(fdP); IH_RELEASE(specH); if (sp->inodeType == VI_VOLINFO) { - VolInfo = header.volumeInfo; + salvinfo->VolInfo = header.volumeInfo; if (check) { char update[25]; - if (VolInfo.updateDate) { - strcpy(update, TimeStamp(VolInfo.updateDate, 0)); + + if (salvinfo->VolInfo.updateDate) { + strcpy(update, TimeStamp(salvinfo->VolInfo.updateDate, 0)); if (!Showmode) - Log("%s (%u) %supdated %s\n", VolInfo.name, VolInfo.id, + Log("%s (%u) %supdated %s\n", salvinfo->VolInfo.name, + salvinfo->VolInfo.id, (Testing ? "it would have been " : ""), update); } else { - strcpy(update, TimeStamp(VolInfo.creationDate, 0)); + strcpy(update, TimeStamp(salvinfo->VolInfo.creationDate, 0)); if (!Showmode) - Log("%s (%u) not updated (created %s)\n", VolInfo.name, - VolInfo.id, update); + Log("%s (%u) not updated (created %s)\n", + salvinfo->VolInfo.name, salvinfo->VolInfo.id, update); } } @@ -2476,7 +2499,8 @@ SalvageHeader(struct stuff *sp, struct InodeSummary *isp, int check, } int -SalvageVnodes(struct InodeSummary *rwIsp, +SalvageVnodes(struct SalvInfo *salvinfo, + struct InodeSummary *rwIsp, struct InodeSummary *thisIsp, struct ViceInodeInfo *inodes, int check) { @@ -2487,20 +2511,20 @@ SalvageVnodes(struct InodeSummary *rwIsp, RW = (rwIsp == thisIsp); nInodes = (rwIsp->nInodes - rwIsp->nSpecialInodes); ismall = - SalvageIndex(thisIsp->volSummary->header.smallVnodeIndex, vSmall, RW, + SalvageIndex(salvinfo, thisIsp->volSummary->header.smallVnodeIndex, vSmall, RW, &inodes[ioffset], nInodes, thisIsp->volSummary, check); if (check && ismall == -1) return -1; ilarge = - SalvageIndex(thisIsp->volSummary->header.largeVnodeIndex, vLarge, RW, + SalvageIndex(salvinfo, thisIsp->volSummary->header.largeVnodeIndex, vLarge, RW, &inodes[ioffset], nInodes, thisIsp->volSummary, check); return (ilarge == 0 && ismall == 0 ? 0 : -1); } int -SalvageIndex(Inode ino, VnodeClass class, int RW, +SalvageIndex(struct SalvInfo *salvinfo, Inode ino, VnodeClass class, int RW, struct ViceInodeInfo *ip, int nInodes, - struct VolumeSummary *volSummary, int check) + struct VolumeSummary *volSummary, int check) { VolumeId volumeNumber; char buf[SIZEOF_LARGEDISKVNODE]; @@ -2517,7 +2541,7 @@ SalvageIndex(Inode ino, VnodeClass class, int RW, FdHandle_t *fdP; volumeNumber = volSummary->header.id; - IH_INIT(handle, fileSysDevice, volSummary->header.parent, ino); + IH_INIT(handle, salvinfo->fileSysDevice, volSummary->header.parent, ino); fdP = IH_OPEN(handle); assert(fdP != NULL); file = FDH_FDOPEN(fdP, "r+"); @@ -2542,7 +2566,7 @@ SalvageIndex(Inode ino, VnodeClass class, int RW, * don't bother for read-only or backup volumes */ #ifdef notdef /* This is done elsewhere */ if (ShowRootFiles && RW && vnode->owner == 0 && vnodeNumber != 1) - Log("OWNER IS ROOT %s %u dir %u vnode %u author %u owner %u mode %o\n", VolInfo.name, volumeNumber, vnode->parent, vnodeNumber, vnode->author, vnode->owner, vnode->modeBits); + Log("OWNER IS ROOT %s %u dir %u vnode %u author %u owner %u mode %o\n", salvinfo->VolInfo.name, volumeNumber, vnode->parent, vnodeNumber, vnode->author, vnode->owner, vnode->modeBits); #endif if (VNDISK_GET_INO(vnode) == 0) { if (RW) { @@ -2747,7 +2771,7 @@ SalvageIndex(Inode ino, VnodeClass class, int RW, (handle, vnodeIndexOffset(vcp, vnodeNumber), (char *)vnode, vcp->diskSize) == vcp->diskSize); - VolumeChanged = 1; /* For break call back */ + salvinfo->VolumeChanged = 1; /* For break call back */ } } } @@ -2759,20 +2783,20 @@ SalvageIndex(Inode ino, VnodeClass class, int RW, } struct VnodeEssence * -CheckVnodeNumber(VnodeId vnodeNumber) +CheckVnodeNumber(struct SalvInfo *salvinfo, VnodeId vnodeNumber) { VnodeClass class; struct VnodeInfo *vip; int offset; class = vnodeIdToClass(vnodeNumber); - vip = &vnodeInfo[class]; + vip = &salvinfo->vnodeInfo[class]; offset = vnodeIdToBitNumber(vnodeNumber); return (offset >= vip->nVnodes ? NULL : &vip->vnodes[offset]); } void -CopyOnWrite(struct DirSummary *dir) +CopyOnWrite(struct SalvInfo *salvinfo, struct DirSummary *dir) { /* Copy the directory unconditionally if we are going to change it: * not just if was cloned. @@ -2787,7 +2811,7 @@ CopyOnWrite(struct DirSummary *dir) DFlush(); /* Well justified paranoia... */ code = - IH_IREAD(vnodeInfo[vLarge].handle, + IH_IREAD(salvinfo->vnodeInfo[vLarge].handle, vnodeIndexOffset(vcp, dir->vnodeNumber), (char *)&vnode, sizeof(vnode)); assert(code == sizeof(vnode)); @@ -2797,21 +2821,22 @@ CopyOnWrite(struct DirSummary *dir) * crashed before the versions were written to disk. */ newinode = - IH_CREATE(dir->ds_linkH, fileSysDevice, fileSysPath, 0, dir->rwVid, + IH_CREATE(dir->ds_linkH, salvinfo->fileSysDevice, salvinfo->fileSysPath, 0, dir->rwVid, dir->vnodeNumber, vnode.uniquifier, vnode.dataVersion += 200); assert(VALID_INO(newinode)); - assert(CopyInode(fileSysDevice, oldinode, newinode, dir->rwVid) == 0); + assert(CopyInode(salvinfo->fileSysDevice, oldinode, newinode, dir->rwVid) == 0); vnode.cloned = 0; VNDISK_SET_INO(&vnode, newinode); code = - IH_IWRITE(vnodeInfo[vLarge].handle, + IH_IWRITE(salvinfo->vnodeInfo[vLarge].handle, vnodeIndexOffset(vcp, dir->vnodeNumber), (char *)&vnode, sizeof(vnode)); assert(code == sizeof(vnode)); SetSalvageDirHandle(&dir->dirHandle, dir->dirHandle.dirh_handle->ih_vid, - fileSysDevice, newinode); + salvinfo->fileSysDevice, newinode, + &salvinfo->VolumeChanged); /* Don't delete the original inode right away, because the directory is * still being scanned. */ @@ -2825,7 +2850,7 @@ CopyOnWrite(struct DirSummary *dir) * old dir. */ void -CopyAndSalvage(struct DirSummary *dir) +CopyAndSalvage(struct SalvInfo *salvinfo, struct DirSummary *dir) { struct VnodeDiskObject vnode; struct VnodeClassInfo *vcp = &VnodeClassInfo[vLarge]; @@ -2842,7 +2867,7 @@ CopyAndSalvage(struct DirSummary *dir) return; Log("Salvaging directory %u...\n", dir->vnodeNumber); lcode = - IH_IREAD(vnodeInfo[vLarge].handle, + IH_IREAD(salvinfo->vnodeInfo[vLarge].handle, vnodeIndexOffset(vcp, dir->vnodeNumber), (char *)&vnode, sizeof(vnode)); assert(lcode == sizeof(vnode)); @@ -2852,18 +2877,19 @@ CopyAndSalvage(struct DirSummary *dir) * crashed before the versions were written to disk. */ newinode = - IH_CREATE(dir->ds_linkH, fileSysDevice, fileSysPath, 0, dir->rwVid, + IH_CREATE(dir->ds_linkH, salvinfo->fileSysDevice, salvinfo->fileSysPath, 0, dir->rwVid, dir->vnodeNumber, vnode.uniquifier, vnode.dataVersion += 200); assert(VALID_INO(newinode)); - SetSalvageDirHandle(&newdir, dir->rwVid, fileSysDevice, newinode); + SetSalvageDirHandle(&newdir, dir->rwVid, salvinfo->fileSysDevice, newinode, + &salvinfo->VolumeChanged); /* Assign . and .. vnode numbers from dir and vnode.parent. * The uniquifier for . is in the vnode. * The uniquifier for .. might be set to a bogus value of 1 and * the salvager will later clean it up. */ - if (vnode.parent && (vnodeEssence = CheckVnodeNumber(vnode.parent))) { + if (vnode.parent && (vnodeEssence = CheckVnodeNumber(salvinfo, vnode.parent))) { parentUnique = (vnodeEssence->unique ? vnodeEssence->unique : 1); } code = @@ -2894,20 +2920,20 @@ CopyAndSalvage(struct DirSummary *dir) length = Length(&newdir); VNDISK_SET_LEN(&vnode, length); lcode = - IH_IWRITE(vnodeInfo[vLarge].handle, + IH_IWRITE(salvinfo->vnodeInfo[vLarge].handle, vnodeIndexOffset(vcp, dir->vnodeNumber), (char *)&vnode, sizeof(vnode)); assert(lcode == sizeof(vnode)); #if 0 #ifdef AFS_NT40_ENV - nt_sync(fileSysDevice); + nt_sync(salvinfo->fileSysDevice); #else sync(); /* this is slow, but hopefully rarely called. We don't have * an open FD on the file itself to fsync. */ #endif #else - vnodeInfo[vLarge].handle->ih_synced = 1; + salvinfo->vnodeInfo[vLarge].handle->ih_synced = 1; #endif /* make sure old directory file is really closed */ fdP = IH_OPEN(dir->dirHandle.dirh_handle); @@ -2918,23 +2944,33 @@ CopyAndSalvage(struct DirSummary *dir) dir->dirHandle = newdir; } +/** + * arguments for JudgeEntry. + */ +struct judgeEntry_params { + struct DirSummary *dir; /**< directory we're examining entries in */ + struct SalvInfo *salvinfo; /**< SalvInfo for the current salvage job */ +}; + int -JudgeEntry(void *dirVal, char *name, afs_int32 vnodeNumber, +JudgeEntry(void *arock, char *name, afs_int32 vnodeNumber, afs_int32 unique) { - struct DirSummary *dir = (struct DirSummary *)dirVal; + struct judgeEntry_params *params = arock; + struct DirSummary *dir = params->dir; + struct SalvInfo *salvinfo = params->salvinfo; struct VnodeEssence *vnodeEssence; afs_int32 dirOrphaned, todelete; - dirOrphaned = IsVnodeOrphaned(dir->vnodeNumber); + dirOrphaned = IsVnodeOrphaned(salvinfo, dir->vnodeNumber); - vnodeEssence = CheckVnodeNumber(vnodeNumber); + vnodeEssence = CheckVnodeNumber(salvinfo, vnodeNumber); if (vnodeEssence == NULL) { if (!Showmode) { Log("dir vnode %u: invalid entry deleted: %s/%s (vnode %u, unique %u)\n", dir->vnodeNumber, dir->name ? dir->name : "??", name, vnodeNumber, unique); } if (!Testing) { - CopyOnWrite(dir); + CopyOnWrite(salvinfo, dir); assert(Delete(&dir->dirHandle, name) == 0); } return 0; @@ -2948,7 +2984,7 @@ JudgeEntry(void *dirVal, char *name, afs_int32 vnodeNumber, if (vnodeEssence->InodeNumber == 0) { Log("dir vnode %d: invalid entry: %s/%s has no inode (vnode %d, unique %d)%s\n", dir->vnodeNumber, (dir->name ? dir->name : "??"), name, vnodeNumber, unique, (Testing ? "-- would have deleted" : " -- deleted")); if (!Testing) { - CopyOnWrite(dir); + CopyOnWrite(salvinfo, dir); assert(Delete(&dir->dirHandle, name) == 0); } return 0; @@ -2966,7 +3002,7 @@ JudgeEntry(void *dirVal, char *name, afs_int32 vnodeNumber, "")); if (!unique) { if (!Testing) { - CopyOnWrite(dir); + CopyOnWrite(salvinfo, dir); assert(Delete(&dir->dirHandle, name) == 0); } return 0; @@ -2996,7 +3032,7 @@ JudgeEntry(void *dirVal, char *name, afs_int32 vnodeNumber, AFSFid fid; fid.Vnode = vnodeNumber; fid.Unique = vnodeEssence->unique; - CopyOnWrite(dir); + CopyOnWrite(salvinfo, dir); assert(Delete(&dir->dirHandle, name) == 0); if (!todelete) assert(Create(&dir->dirHandle, name, &fid) == 0); @@ -3011,7 +3047,7 @@ JudgeEntry(void *dirVal, char *name, afs_int32 vnodeNumber, if (!Showmode) Log("directory vnode %u.%u: bad '.' entry (was %u.%u); fixed\n", dir->vnodeNumber, dir->unique, vnodeNumber, unique); if (!Testing) { - CopyOnWrite(dir); + CopyOnWrite(salvinfo, dir); assert(Delete(&dir->dirHandle, ".") == 0); fid.Vnode = dir->vnodeNumber; fid.Unique = dir->unique; @@ -3020,7 +3056,7 @@ JudgeEntry(void *dirVal, char *name, afs_int32 vnodeNumber, vnodeNumber = fid.Vnode; /* Get the new Essence */ unique = fid.Unique; - vnodeEssence = CheckVnodeNumber(vnodeNumber); + vnodeEssence = CheckVnodeNumber(salvinfo, vnodeNumber); } dir->haveDot = 1; } else if (strcmp(name, "..") == 0) { @@ -3028,7 +3064,7 @@ JudgeEntry(void *dirVal, char *name, afs_int32 vnodeNumber, if (dir->parent) { struct VnodeEssence *dotdot; pa.Vnode = dir->parent; - dotdot = CheckVnodeNumber(pa.Vnode); + dotdot = CheckVnodeNumber(salvinfo, pa.Vnode); assert(dotdot != NULL); /* XXX Should not be assert */ pa.Unique = dotdot->unique; } else { @@ -3039,14 +3075,14 @@ JudgeEntry(void *dirVal, char *name, afs_int32 vnodeNumber, if (!Showmode) Log("directory vnode %u.%u: bad '..' entry (was %u.%u); fixed\n", dir->vnodeNumber, dir->unique, vnodeNumber, unique); if (!Testing) { - CopyOnWrite(dir); + CopyOnWrite(salvinfo, dir); assert(Delete(&dir->dirHandle, "..") == 0); assert(Create(&dir->dirHandle, "..", &pa) == 0); } vnodeNumber = pa.Vnode; /* Get the new Essence */ unique = pa.Unique; - vnodeEssence = CheckVnodeNumber(vnodeNumber); + vnodeEssence = CheckVnodeNumber(salvinfo, vnodeNumber); } dir->haveDotDot = 1; } else if (strncmp(name, ".__afs", 6) == 0) { @@ -3054,7 +3090,7 @@ JudgeEntry(void *dirVal, char *name, afs_int32 vnodeNumber, Log("dir vnode %u: special old unlink-while-referenced file %s %s deleted (vnode %u)\n", dir->vnodeNumber, name, (Testing ? "would have been" : "is"), vnodeNumber); } if (!Testing) { - CopyOnWrite(dir); + CopyOnWrite(salvinfo, dir); assert(Delete(&dir->dirHandle, name) == 0); } vnodeEssence->claimed = 0; /* Not claimed: Orphaned */ @@ -3071,7 +3107,7 @@ JudgeEntry(void *dirVal, char *name, afs_int32 vnodeNumber, IHandle_t *ihP; FdHandle_t *fdP; - IH_INIT(ihP, fileSysDevice, dir->dirHandle.dirh_handle->ih_vid, + IH_INIT(ihP, salvinfo->fileSysDevice, dir->dirHandle.dirh_handle->ih_vid, vnodeEssence->InodeNumber); fdP = IH_OPEN(ihP); if (fdP == NULL) { @@ -3148,7 +3184,7 @@ JudgeEntry(void *dirVal, char *name, afs_int32 vnodeNumber, } } if (!Testing) { - CopyOnWrite(dir); + CopyOnWrite(salvinfo, dir); assert(Delete(&dir->dirHandle, name) == 0); } return 0; @@ -3162,9 +3198,10 @@ JudgeEntry(void *dirVal, char *name, afs_int32 vnodeNumber, } void -DistilVnodeEssence(VolumeId rwVId, VnodeClass class, Inode ino, Unique * maxu) +DistilVnodeEssence(struct SalvInfo *salvinfo, VolumeId rwVId, + VnodeClass class, Inode ino, Unique * maxu) { - struct VnodeInfo *vip = &vnodeInfo[class]; + struct VnodeInfo *vip = &salvinfo->vnodeInfo[class]; struct VnodeClassInfo *vcp = &VnodeClassInfo[class]; char buf[SIZEOF_LARGEDISKVNODE]; struct VnodeDiskObject *vnode = (struct VnodeDiskObject *)buf; @@ -3174,7 +3211,7 @@ DistilVnodeEssence(VolumeId rwVId, VnodeClass class, Inode ino, Unique * maxu) int nVnodes; FdHandle_t *fdP; - IH_INIT(vip->handle, fileSysDevice, rwVId, ino); + IH_INIT(vip->handle, salvinfo->fileSysDevice, rwVId, ino); fdP = IH_OPEN(vip->handle); assert(fdP != NULL); file = FDH_FDOPEN(fdP, "r+"); @@ -3225,10 +3262,10 @@ DistilVnodeEssence(VolumeId rwVId, VnodeClass class, Inode ino, Unique * maxu) VnodeId vnodeNumber = bitNumberToVnodeNumber(vnodeIndex, class); vip->nAllocatedVnodes--; memset(vnode, 0, sizeof(vnode)); - IH_IWRITE(vnodeInfo[vSmall].handle, + IH_IWRITE(salvinfo->vnodeInfo[vSmall].handle, vnodeIndexOffset(vcp, vnodeNumber), (char *)&vnode, sizeof(vnode)); - VolumeChanged = 1; + salvinfo->VolumeChanged = 1; } else vip->inodes[vnodeIndex] = VNDISK_GET_INO(vnode); } @@ -3239,7 +3276,8 @@ DistilVnodeEssence(VolumeId rwVId, VnodeClass class, Inode ino, Unique * maxu) } static char * -GetDirName(VnodeId vnode, struct VnodeEssence *vp, char *path) +GetDirName(struct SalvInfo *salvinfo, VnodeId vnode, struct VnodeEssence *vp, + char *path) { struct VnodeEssence *parentvp; @@ -3247,8 +3285,8 @@ GetDirName(VnodeId vnode, struct VnodeEssence *vp, char *path) strcpy(path, "."); return path; } - if (vp->parent && vp->name && (parentvp = CheckVnodeNumber(vp->parent)) - && GetDirName(vp->parent, parentvp, path)) { + if (vp->parent && vp->name && (parentvp = CheckVnodeNumber(salvinfo, vp->parent)) + && GetDirName(salvinfo, vp->parent, parentvp, path)) { strcat(path, "/"); strcat(path, vp->name); return path; @@ -3260,7 +3298,7 @@ GetDirName(VnodeId vnode, struct VnodeEssence *vp, char *path) * vnodes must be "claimed". The vep->claimed flag is set in JudgeEntry(). */ static int -IsVnodeOrphaned(VnodeId vnode) +IsVnodeOrphaned(struct SalvInfo *salvinfo, VnodeId vnode) { struct VnodeEssence *vep; @@ -3268,17 +3306,17 @@ IsVnodeOrphaned(VnodeId vnode) return (1); /* Vnode zero does not exist */ if (vnode == 1) return (0); /* The root dir vnode is always claimed */ - vep = CheckVnodeNumber(vnode); /* Get the vnode essence */ + vep = CheckVnodeNumber(salvinfo, vnode); /* Get the vnode essence */ if (!vep || !vep->claimed) return (1); /* Vnode is not claimed - it is orphaned */ - return (IsVnodeOrphaned(vep->parent)); + return (IsVnodeOrphaned(salvinfo, vep->parent)); } void -SalvageDir(char *name, VolumeId rwVid, struct VnodeInfo *dirVnodeInfo, - IHandle_t * alinkH, int i, struct DirSummary *rootdir, - int *rootdirfound) +SalvageDir(struct SalvInfo *salvinfo, char *name, VolumeId rwVid, + struct VnodeInfo *dirVnodeInfo, IHandle_t * alinkH, int i, + struct DirSummary *rootdir, int *rootdirfound) { static struct DirSummary dir; static struct DirHandle dirHandle; @@ -3303,9 +3341,9 @@ SalvageDir(char *name, VolumeId rwVid, struct VnodeInfo *dirVnodeInfo, dirVnodeInfo->vnodes[i].changed = 1; } } else { - parent = CheckVnodeNumber(dirVnodeInfo->vnodes[i].parent); + parent = CheckVnodeNumber(salvinfo, dirVnodeInfo->vnodes[i].parent); if (parent && parent->salvaged == 0) - SalvageDir(name, rwVid, dirVnodeInfo, alinkH, + SalvageDir(salvinfo, name, rwVid, dirVnodeInfo, alinkH, vnodeIdToBitNumber(dirVnodeInfo->vnodes[i].parent), rootdir, rootdirfound); } @@ -3317,8 +3355,8 @@ SalvageDir(char *name, VolumeId rwVid, struct VnodeInfo *dirVnodeInfo, dir.parent = dirVnodeInfo->vnodes[i].parent; dir.haveDot = dir.haveDotDot = 0; dir.ds_linkH = alinkH; - SetSalvageDirHandle(&dir.dirHandle, dir.rwVid, fileSysDevice, - dirVnodeInfo->inodes[i]); + SetSalvageDirHandle(&dir.dirHandle, dir.rwVid, salvinfo->fileSysDevice, + dirVnodeInfo->inodes[i], &salvinfo->VolumeChanged); dirok = ((RebuildDirs && !Testing) ? 0 : DirOK(&dir.dirHandle)); if (!dirok) { @@ -3327,7 +3365,7 @@ SalvageDir(char *name, VolumeId rwVid, struct VnodeInfo *dirVnodeInfo, (Testing ? "skipping" : "salvaging")); } if (!Testing) { - CopyAndSalvage(&dir); + CopyAndSalvage(salvinfo, &dir); dirok = 1; dirVnodeInfo->inodes[i] = dir.dirHandle.dirh_inode; } @@ -3335,14 +3373,18 @@ SalvageDir(char *name, VolumeId rwVid, struct VnodeInfo *dirVnodeInfo, dirHandle = dir.dirHandle; dir.name = - GetDirName(bitNumberToVnodeNumber(i, vLarge), + GetDirName(salvinfo, bitNumberToVnodeNumber(i, vLarge), &dirVnodeInfo->vnodes[i], path); if (dirok) { /* If enumeration failed for random reasons, we will probably delete * too much stuff, so we guard against this instead. */ - assert(EnumerateDir(&dirHandle, JudgeEntry, &dir) == 0); + struct judgeEntry_params judge_params; + judge_params.salvinfo = salvinfo; + judge_params.dir = &dir; + + assert(EnumerateDir(&dirHandle, JudgeEntry, &judge_params) == 0); } /* Delete the old directory if it was copied in order to salvage. @@ -3377,21 +3419,23 @@ SalvageDir(char *name, VolumeId rwVid, struct VnodeInfo *dirVnodeInfo, * vnode */ static void -GetNewFID(VolumeDiskData *volHeader, VnodeClass class, AFSFid *afid, - Unique *maxunique) +GetNewFID(struct SalvInfo *salvinfo, VolumeDiskData *volHeader, + VnodeClass class, AFSFid *afid, Unique *maxunique) { int i; - for (i = 0; i < vnodeInfo[class].nVnodes; i++) { - if (vnodeInfo[class].vnodes[i].type == vNull) { + for (i = 0; i < salvinfo->vnodeInfo[class].nVnodes; i++) { + if (salvinfo->vnodeInfo[class].vnodes[i].type == vNull) { break; } } - if (i == vnodeInfo[class].nVnodes) { + if (i == salvinfo->vnodeInfo[class].nVnodes) { /* no free vnodes; make a new one */ - vnodeInfo[class].nVnodes++; - vnodeInfo[class].vnodes = realloc(vnodeInfo[class].vnodes, - sizeof(struct VnodeEssence) * (i+1)); - vnodeInfo[class].vnodes[i].type = vNull; + salvinfo->vnodeInfo[class].nVnodes++; + salvinfo->vnodeInfo[class].vnodes = + realloc(salvinfo->vnodeInfo[class].vnodes, + sizeof(struct VnodeEssence) * (i+1)); + + salvinfo->vnodeInfo[class].vnodes[i].type = vNull; } afid->Vnode = bitNumberToVnodeNumber(i, class); @@ -3423,8 +3467,9 @@ GetNewFID(VolumeDiskData *volHeader, VnodeClass class, AFSFid *afid, * @retval -1 error */ static int -CreateReadme(VolumeDiskData *volHeader, IHandle_t *alinkH, - VolumeId vid, Unique *maxunique, AFSFid *afid, Inode *ainode) +CreateReadme(struct SalvInfo *salvinfo, VolumeDiskData *volHeader, + IHandle_t *alinkH, VolumeId vid, Unique *maxunique, AFSFid *afid, + Inode *ainode) { Inode readmeinode; struct VnodeDiskObject *rvnode = NULL; @@ -3453,19 +3498,20 @@ CreateReadme(VolumeDiskData *volHeader, IHandle_t *alinkH, /* -1 for the trailing NUL */ length = sizeof(readme) - 1; - GetNewFID(volHeader, vSmall, afid, maxunique); + GetNewFID(salvinfo, volHeader, vSmall, afid, maxunique); - vep = &vnodeInfo[vSmall].vnodes[vnodeIdToBitNumber(afid->Vnode)]; + vep = &salvinfo->vnodeInfo[vSmall].vnodes[vnodeIdToBitNumber(afid->Vnode)]; /* create the inode and write the contents */ - readmeinode = IH_CREATE(alinkH, fileSysDevice, fileSysPath, 0, vid, + readmeinode = IH_CREATE(alinkH, salvinfo->fileSysDevice, + salvinfo->fileSysPath, 0, vid, afid->Vnode, afid->Unique, 1); if (!VALID_INO(readmeinode)) { Log("CreateReadme: readme IH_CREATE failed\n"); goto error; } - IH_INIT(readmeH, fileSysDevice, vid, readmeinode); + IH_INIT(readmeH, salvinfo->fileSysDevice, vid, readmeinode); bytes = IH_IWRITE(readmeH, 0, readme, length); IH_RELEASE(readmeH); @@ -3497,7 +3543,7 @@ CreateReadme(VolumeDiskData *volHeader, IHandle_t *alinkH, rvnode->group = 0; rvnode->vnodeMagic = VnodeClassInfo[vSmall].magic; - bytes = IH_IWRITE(vnodeInfo[vSmall].handle, + bytes = IH_IWRITE(salvinfo->vnodeInfo[vSmall].handle, vnodeIndexOffset(&VnodeClassInfo[vSmall], afid->Vnode), (char*)rvnode, SIZEOF_SMALLDISKVNODE); @@ -3508,10 +3554,10 @@ CreateReadme(VolumeDiskData *volHeader, IHandle_t *alinkH, } /* update VnodeEssence for new readme vnode */ - vnodeInfo[vSmall].nAllocatedVnodes++; + salvinfo->vnodeInfo[vSmall].nAllocatedVnodes++; vep->count = 0; vep->blockCount = nBlocks(length); - vnodeInfo[vSmall].volumeBlockCount += vep->blockCount; + salvinfo->vnodeInfo[vSmall].volumeBlockCount += vep->blockCount; vep->parent = rvnode->parent; vep->unique = rvnode->uniquifier; vep->modeBits = rvnode->modeBits; @@ -3562,8 +3608,9 @@ CreateReadme(VolumeDiskData *volHeader, IHandle_t *alinkH, * @retval -1 error */ static int -CreateRootDir(VolumeDiskData *volHeader, IHandle_t *alinkH, VolumeId vid, - struct DirSummary *rootdir, Unique *maxunique) +CreateRootDir(struct SalvInfo *salvinfo, VolumeDiskData *volHeader, + IHandle_t *alinkH, VolumeId vid, struct DirSummary *rootdir, + Unique *maxunique) { FileVersion dv; int decroot = 0, decreadme = 0; @@ -3578,30 +3625,31 @@ CreateRootDir(VolumeDiskData *volHeader, IHandle_t *alinkH, VolumeId vid, Inode readmeinode; time_t now = time(NULL); - if (!vnodeInfo[vLarge].vnodes && !vnodeInfo[vSmall].vnodes) { + if (!salvinfo->vnodeInfo[vLarge].vnodes && !salvinfo->vnodeInfo[vSmall].vnodes) { Log("Not creating new root dir; volume appears to lack any vnodes\n"); goto error; } - if (!vnodeInfo[vLarge].vnodes) { + if (!salvinfo->vnodeInfo[vLarge].vnodes) { /* We don't have any large vnodes in the volume; allocate room * for one so we can recreate the root dir */ - vnodeInfo[vLarge].nVnodes = 1; - vnodeInfo[vLarge].vnodes = calloc(1, sizeof(struct VnodeEssence)); - vnodeInfo[vLarge].inodes = calloc(1, sizeof(Inode)); + salvinfo->vnodeInfo[vLarge].nVnodes = 1; + salvinfo->vnodeInfo[vLarge].vnodes = calloc(1, sizeof(struct VnodeEssence)); + salvinfo->vnodeInfo[vLarge].inodes = calloc(1, sizeof(Inode)); - assert(vnodeInfo[vLarge].vnodes); - assert(vnodeInfo[vLarge].inodes); + assert(salvinfo->vnodeInfo[vLarge].vnodes); + assert(salvinfo->vnodeInfo[vLarge].inodes); } - vep = &vnodeInfo[vLarge].vnodes[vnodeIdToBitNumber(1)]; - ip = &vnodeInfo[vLarge].inodes[vnodeIdToBitNumber(1)]; + vep = &salvinfo->vnodeInfo[vLarge].vnodes[vnodeIdToBitNumber(1)]; + ip = &salvinfo->vnodeInfo[vLarge].inodes[vnodeIdToBitNumber(1)]; if (vep->type != vNull) { Log("Not creating new root dir; existing vnode 1 is non-null\n"); goto error; } - if (CreateReadme(volHeader, alinkH, vid, maxunique, &readmeid, &readmeinode)) { + if (CreateReadme(salvinfo, volHeader, alinkH, vid, maxunique, &readmeid, + &readmeinode) != 0) { goto error; } decreadme = 1; @@ -3610,14 +3658,16 @@ CreateRootDir(VolumeDiskData *volHeader, IHandle_t *alinkH, VolumeId vid, * with a cached DV */ dv = 1 << 30; - rootinode = IH_CREATE(alinkH, fileSysDevice, fileSysPath, 0, vid, 1, 1, dv); + rootinode = IH_CREATE(alinkH, salvinfo->fileSysDevice, salvinfo->fileSysPath, + 0, vid, 1, 1, dv); if (!VALID_INO(rootinode)) { Log("CreateRootDir: IH_CREATE failed\n"); goto error; } decroot = 1; - SetSalvageDirHandle(&rootdir->dirHandle, vid, fileSysDevice, rootinode); + SetSalvageDirHandle(&rootdir->dirHandle, vid, salvinfo->fileSysDevice, + rootinode, &salvinfo->VolumeChanged); did.Volume = vid; did.Vnode = 1; did.Unique = 1; @@ -3668,7 +3718,7 @@ CreateRootDir(VolumeDiskData *volHeader, IHandle_t *alinkH, VolumeId vid, rootvnode->vnodeMagic = VnodeClassInfo[vLarge].magic; /* write it out to disk */ - bytes = IH_IWRITE(vnodeInfo[vLarge].handle, + bytes = IH_IWRITE(salvinfo->vnodeInfo[vLarge].handle, vnodeIndexOffset(&VnodeClassInfo[vLarge], 1), (char*)rootvnode, SIZEOF_LARGEDISKVNODE); @@ -3681,10 +3731,10 @@ CreateRootDir(VolumeDiskData *volHeader, IHandle_t *alinkH, VolumeId vid, } /* update VnodeEssence for the new root vnode */ - vnodeInfo[vLarge].nAllocatedVnodes++; + salvinfo->vnodeInfo[vLarge].nAllocatedVnodes++; vep->count = 0; vep->blockCount = nBlocks(length); - vnodeInfo[vLarge].volumeBlockCount += vep->blockCount; + salvinfo->vnodeInfo[vLarge].volumeBlockCount += vep->blockCount; vep->parent = rootvnode->parent; vep->unique = rootvnode->uniquifier; vep->modeBits = rootvnode->modeBits; @@ -3732,8 +3782,18 @@ CreateRootDir(VolumeDiskData *volHeader, IHandle_t *alinkH, VolumeId vid, return -1; } +/** + * salvage a volume group. + * + * @param[in] salvinfo information for the curent salvage job + * @param[in] rwIsp inode summary for rw volume + * @param[in] alinkH link table inode handle + * + * @return operation status + * @retval 0 success + */ int -SalvageVolume(struct InodeSummary *rwIsp, IHandle_t * alinkH) +SalvageVolume(struct SalvInfo *salvinfo, struct InodeSummary *rwIsp, IHandle_t * alinkH) { /* This routine, for now, will only be called for read-write volumes */ int i, j, code; @@ -3758,25 +3818,25 @@ SalvageVolume(struct InodeSummary *rwIsp, IHandle_t * alinkH) int newrootdir = 0; vid = rwIsp->volSummary->header.id; - IH_INIT(h, fileSysDevice, vid, rwIsp->volSummary->header.volumeInfo); + IH_INIT(h, salvinfo->fileSysDevice, vid, rwIsp->volSummary->header.volumeInfo); nBytes = IH_IREAD(h, 0, (char *)&volHeader, sizeof(volHeader)); assert(nBytes == sizeof(volHeader)); assert(volHeader.stamp.magic == VOLUMEINFOMAGIC); assert(volHeader.destroyMe != DESTROY_ME); /* (should not have gotten this far with DESTROY_ME flag still set!) */ - DistilVnodeEssence(vid, vLarge, rwIsp->volSummary->header.largeVnodeIndex, - &maxunique); - DistilVnodeEssence(vid, vSmall, rwIsp->volSummary->header.smallVnodeIndex, - &maxunique); + DistilVnodeEssence(salvinfo, vid, vLarge, + rwIsp->volSummary->header.largeVnodeIndex, &maxunique); + DistilVnodeEssence(salvinfo, vid, vSmall, + rwIsp->volSummary->header.smallVnodeIndex, &maxunique); - dirVnodeInfo = &vnodeInfo[vLarge]; + dirVnodeInfo = &salvinfo->vnodeInfo[vLarge]; for (i = 0; i < dirVnodeInfo->nVnodes; i++) { - SalvageDir(volHeader.name, vid, dirVnodeInfo, alinkH, i, &rootdir, - &rootdirfound); + SalvageDir(salvinfo, volHeader.name, vid, dirVnodeInfo, alinkH, i, + &rootdir, &rootdirfound); } #ifdef AFS_NT40_ENV - nt_sync(fileSysDevice); + nt_sync(salvinfo->fileSysDevice); #else sync(); /* This used to be done lower level, for every dir */ #endif @@ -3790,11 +3850,12 @@ SalvageVolume(struct InodeSummary *rwIsp, IHandle_t * alinkH) Log("Cannot find root directory for volume %lu; attempting to create " "a new one\n", afs_printable_uint32_lu(vid)); - code = CreateRootDir(&volHeader, alinkH, vid, &rootdir, &maxunique); + code = CreateRootDir(salvinfo, &volHeader, alinkH, vid, &rootdir, + &maxunique); if (code == 0) { rootdirfound = 1; newrootdir = 1; - VolumeChanged = 1; + salvinfo->VolumeChanged = 1; } } @@ -3803,8 +3864,8 @@ SalvageVolume(struct InodeSummary *rwIsp, IHandle_t * alinkH) */ oldrootdir = rootdir; for (class = 0; class < nVNODECLASSES; class++) { - for (v = 0; v < vnodeInfo[class].nVnodes; v++) { - vep = &(vnodeInfo[class].vnodes[v]); + for (v = 0; v < salvinfo->vnodeInfo[class].nVnodes; v++) { + vep = &(salvinfo->vnodeInfo[class].vnodes[v]); ThisVnode = bitNumberToVnodeNumber(v, class); ThisUnique = vep->unique; @@ -3819,7 +3880,7 @@ SalvageVolume(struct InodeSummary *rwIsp, IHandle_t * alinkH) */ if (class == vLarge) { /* directory vnode */ pv = vnodeIdToBitNumber(vep->parent); - if (vnodeInfo[vLarge].vnodes[pv].unique != 0) { + if (salvinfo->vnodeInfo[vLarge].vnodes[pv].unique != 0) { if (vep->parent == 1 && newrootdir) { /* this vnode's parent was the volume root, and * we just created the volume root. So, the parent @@ -3830,7 +3891,7 @@ SalvageVolume(struct InodeSummary *rwIsp, IHandle_t * alinkH) /* noop */ } else { - vnodeInfo[vLarge].vnodes[pv].count++; + salvinfo->vnodeInfo[vLarge].vnodes[pv].count++; } } } @@ -3865,8 +3926,9 @@ SalvageVolume(struct InodeSummary *rwIsp, IHandle_t * alinkH) DirHandle dh; /* Remove and recreate the ".." entry in this orphaned directory */ - SetSalvageDirHandle(&dh, vid, fileSysDevice, - vnodeInfo[class].inodes[v]); + SetSalvageDirHandle(&dh, vid, salvinfo->fileSysDevice, + salvinfo->vnodeInfo[class].inodes[v], + &salvinfo->VolumeChanged); pa.Vnode = LFVnode; pa.Unique = LFUnique; assert(Delete(&dh, "..") == 0); @@ -3876,7 +3938,7 @@ SalvageVolume(struct InodeSummary *rwIsp, IHandle_t * alinkH) * Here we increment the new parent's link count. */ pv = vnodeIdToBitNumber(LFVnode); - vnodeInfo[vLarge].vnodes[pv].count--; + salvinfo->vnodeInfo[vLarge].vnodes[pv].count--; } @@ -3893,7 +3955,7 @@ SalvageVolume(struct InodeSummary *rwIsp, IHandle_t * alinkH) "__ORPHANFILE__"), ThisVnode, ThisUnique); - CopyOnWrite(&rootdir); + CopyOnWrite(salvinfo, &rootdir); code = Create(&rootdir.dirHandle, npath, &pa); if (!code) break; @@ -3927,11 +3989,11 @@ SalvageVolume(struct InodeSummary *rwIsp, IHandle_t * alinkH) * will get removed here also (if requested). */ for (class = 0; class < nVNODECLASSES; class++) { - int nVnodes = vnodeInfo[class].nVnodes; + int nVnodes = salvinfo->vnodeInfo[class].nVnodes; struct VnodeClassInfo *vcp = &VnodeClassInfo[class]; - struct VnodeEssence *vnodes = vnodeInfo[class].vnodes; - FilesInVolume += vnodeInfo[class].nAllocatedVnodes; - BlocksInVolume += vnodeInfo[class].volumeBlockCount; + struct VnodeEssence *vnodes = salvinfo->vnodeInfo[class].vnodes; + FilesInVolume += salvinfo->vnodeInfo[class].nAllocatedVnodes; + BlocksInVolume += salvinfo->vnodeInfo[class].volumeBlockCount; for (i = 0; i < nVnodes; i++) { struct VnodeEssence *vnp = &vnodes[i]; VnodeId vnodeNumber = bitNumberToVnodeNumber(i, class); @@ -3940,7 +4002,7 @@ SalvageVolume(struct InodeSummary *rwIsp, IHandle_t * alinkH) * any directory entries), then it is orphaned. */ orphaned = -1; - if ((vnp->type != 0) && (orphaned = IsVnodeOrphaned(vnodeNumber))) { + if ((vnp->type != 0) && (orphaned = IsVnodeOrphaned(salvinfo, vnodeNumber))) { vnp->claimed = 0; /* Makes IsVnodeOrphaned calls faster */ vnp->changed = 1; } @@ -3948,7 +4010,7 @@ SalvageVolume(struct InodeSummary *rwIsp, IHandle_t * alinkH) if (vnp->changed || vnp->count) { int oldCount; nBytes = - IH_IREAD(vnodeInfo[class].handle, + IH_IREAD(salvinfo->vnodeInfo[class].handle, vnodeIndexOffset(vcp, vnodeNumber), (char *)&vnode, sizeof(vnode)); assert(nBytes == sizeof(vnode)); @@ -3958,7 +4020,7 @@ SalvageVolume(struct InodeSummary *rwIsp, IHandle_t * alinkH) vnode.linkCount = vnode.linkCount - vnp->count; if (orphaned == -1) - orphaned = IsVnodeOrphaned(vnodeNumber); + orphaned = IsVnodeOrphaned(salvinfo, vnodeNumber); if (orphaned) { if (!vnp->todelete) { /* Orphans should have already been attached (if requested) */ @@ -3988,12 +4050,12 @@ SalvageVolume(struct InodeSummary *rwIsp, IHandle_t * alinkH) vnode.dataVersion++; if (!Testing) { nBytes = - IH_IWRITE(vnodeInfo[class].handle, + IH_IWRITE(salvinfo->vnodeInfo[class].handle, vnodeIndexOffset(vcp, vnodeNumber), (char *)&vnode, sizeof(vnode)); assert(nBytes == sizeof(vnode)); } - VolumeChanged = 1; + salvinfo->VolumeChanged = 1; } } } @@ -4005,7 +4067,7 @@ SalvageVolume(struct InodeSummary *rwIsp, IHandle_t * alinkH) } for (class = 0; class < nVNODECLASSES; class++) { - struct VnodeInfo *vip = &vnodeInfo[class]; + struct VnodeInfo *vip = &salvinfo->vnodeInfo[class]; for (i = 0; i < vip->nVnodes; i++) if (vip->vnodes[i].name) free(vip->vnodes[i].name); @@ -4037,7 +4099,7 @@ SalvageVolume(struct InodeSummary *rwIsp, IHandle_t * alinkH) } #ifdef FSSYNC_BUILD_CLIENT - if (!Testing && VolumeChanged) { + if (!Testing && salvinfo->VolumeChanged) { afs_int32 fsync_code; fsync_code = FSYNC_VolOp(vid, NULL, FSYNC_VOL_BREAKCBKS, FSYNC_SALVAGE, NULL); @@ -4047,7 +4109,7 @@ SalvageVolume(struct InodeSummary *rwIsp, IHandle_t * alinkH) afs_printable_uint32_lu(vid), afs_printable_int32_ld(fsync_code)); } else { - VolumeChanged = 0; + salvinfo->VolumeChanged = 0; } } #endif /* FSSYNC_BUILD_CLIENT */ @@ -4056,9 +4118,9 @@ SalvageVolume(struct InodeSummary *rwIsp, IHandle_t * alinkH) volHeader.inUse = 0; /* clear flag indicating inUse@last crash */ volHeader.needsSalvaged = 0; /* clear 'damaged' flag */ volHeader.inService = 1; /* allow service again */ - volHeader.needsCallback = (VolumeChanged != 0); + volHeader.needsCallback = (salvinfo->VolumeChanged != 0); volHeader.dontSalvage = DONT_SALVAGE; - VolumeChanged = 0; + salvinfo->VolumeChanged = 0; if (!Testing) { nBytes = IH_IWRITE(h, 0, (char *)&volHeader, sizeof(volHeader)); assert(nBytes == sizeof(volHeader)); @@ -4068,8 +4130,9 @@ SalvageVolume(struct InodeSummary *rwIsp, IHandle_t * alinkH) (Testing ? "It would have " : ""), volHeader.name, volHeader.id, FilesInVolume, BlocksInVolume); } - IH_RELEASE(vnodeInfo[vSmall].handle); - IH_RELEASE(vnodeInfo[vLarge].handle); + + IH_RELEASE(salvinfo->vnodeInfo[vSmall].handle); + IH_RELEASE(salvinfo->vnodeInfo[vLarge].handle); IH_RELEASE(h); return 0; } @@ -4101,8 +4164,8 @@ ClearROInUseBit(struct VolumeSummary *summary) * deleteMe - Always do so, only a partial volume. */ void -MaybeZapVolume(struct InodeSummary *isp, char *message, int deleteMe, - int check) +MaybeZapVolume(struct SalvInfo *salvinfo, struct InodeSummary *isp, + char *message, int deleteMe, int check) { if (readOnly(isp) || deleteMe) { if (isp->volSummary && isp->volSummary->fileName) { @@ -4120,9 +4183,9 @@ MaybeZapVolume(struct InodeSummary *isp, char *message, int deleteMe, if (!Testing) { afs_int32 code; char path[64]; - sprintf(path, "%s/%s", fileSysPath, isp->volSummary->fileName); + sprintf(path, "%s/%s", salvinfo->fileSysPath, isp->volSummary->fileName); - code = VDestroyVolumeDiskHeader(fileSysPartition, isp->volumeId, isp->RWvolumeId); + code = VDestroyVolumeDiskHeader(salvinfo->fileSysPartition, isp->volumeId, isp->RWvolumeId); if (code) { Log("Error %ld destroying volume disk header for volume %lu\n", afs_printable_int32_ld(code), @@ -4158,7 +4221,7 @@ MaybeZapVolume(struct InodeSummary *isp, char *message, int deleteMe, * @note DAFS only */ static int -LockVolume(VolumeId volumeId) +LockVolume(struct SalvInfo *salvinfo, VolumeId volumeId) { afs_int32 code; int locktype; @@ -4168,7 +4231,7 @@ LockVolume(VolumeId volumeId) * try to provide what we're logically doing. */ locktype = VVolLockType(V_VOLUPD, 1); - code = VLockVolumeByIdNB(volumeId, fileSysPartition, locktype); + code = VLockVolumeByIdNB(volumeId, salvinfo->fileSysPartition, locktype); if (code) { if (code == EBUSY) { Abort("Someone else appears to be using volume %lu; Aborted\n", @@ -4179,7 +4242,7 @@ LockVolume(VolumeId volumeId) afs_printable_uint32_lu(volumeId)); } - code = FSYNC_VerifyCheckout(volumeId, fileSysPathName, FSYNC_VOL_OFF, FSYNC_SALVAGE); + code = FSYNC_VerifyCheckout(volumeId, salvinfo->fileSysPathName, FSYNC_VOL_OFF, FSYNC_SALVAGE); if (code == SYNC_DENIED) { /* need to retry checking out volumes */ return -1; @@ -4199,14 +4262,14 @@ LockVolume(VolumeId volumeId) struct VolumeDiskHeader diskHeader; struct VolumeDiskData volHeader; - code = VReadVolumeDiskHeader(volumeId, fileSysPartition, &diskHeader); + code = VReadVolumeDiskHeader(volumeId, salvinfo->fileSysPartition, &diskHeader); if (code) { return 0; } DiskToVolumeHeader(&header, &diskHeader); - IH_INIT(h, fileSysDevice, header.parent, header.volumeInfo); + IH_INIT(h, salvinfo->fileSysDevice, header.parent, header.volumeInfo); if (IH_IREAD(h, 0, (char*)&volHeader, sizeof(volHeader)) != sizeof(volHeader) || volHeader.stamp.magic != VOLUMEINFOMAGIC) { @@ -4233,7 +4296,7 @@ LockVolume(VolumeId volumeId) #endif /* AFS_DEMAND_ATTACH_FS */ void -AskOffline(VolumeId volumeId, char * partition) +AskOffline(struct SalvInfo *salvinfo, VolumeId volumeId) { afs_int32 code, i; SYNC_response res; @@ -4241,7 +4304,8 @@ AskOffline(VolumeId volumeId, char * partition) memset(&res, 0, sizeof(res)); for (i = 0; i < 3; i++) { - code = FSYNC_VolOp(volumeId, partition, FSYNC_VOL_OFF, FSYNC_SALVAGE, &res); + code = FSYNC_VolOp(volumeId, salvinfo->fileSysPartition->name, + FSYNC_VOL_OFF, FSYNC_SALVAGE, &res); if (code == SYNC_OK) { break; @@ -4275,17 +4339,18 @@ AskOffline(VolumeId volumeId, char * partition) } void -AskOnline(VolumeId volumeId, char *partition) +AskOnline(struct SalvInfo *salvinfo, VolumeId volumeId) { afs_int32 code, i; for (i = 0; i < 3; i++) { - code = FSYNC_VolOp(volumeId, partition, FSYNC_VOL_ON, FSYNC_WHATEVER, NULL); + code = FSYNC_VolOp(volumeId, salvinfo->fileSysPartition->name, + FSYNC_VOL_ON, FSYNC_WHATEVER, NULL); if (code == SYNC_OK) { break; } else if (code == SYNC_DENIED) { - Log("AskOnline: file server denied online request to volume %u partition %s; trying again...\n", volumeId, partition); + Log("AskOnline: file server denied online request to volume %u partition %s; trying again...\n", volumeId, salvinfo->fileSysPartition->name); } else if (code == SYNC_BAD_COMMAND) { Log("AskOnline: fssync protocol mismatch (bad command word '%d')\n", FSYNC_VOL_ON); @@ -4331,18 +4396,18 @@ CopyInode(Device device, Inode inode1, Inode inode2, int rwvolume) } void -PrintInodeList(void) +PrintInodeList(struct SalvInfo *salvinfo) { struct ViceInodeInfo *ip; struct ViceInodeInfo *buf; struct afs_stat status; int nInodes; - assert(afs_fstat(inodeFd, &status) == 0); + assert(afs_fstat(salvinfo->inodeFd, &status) == 0); buf = (struct ViceInodeInfo *)malloc(status.st_size); assert(buf != NULL); nInodes = status.st_size / sizeof(struct ViceInodeInfo); - assert(read(inodeFd, buf, status.st_size) == status.st_size); + assert(read(salvinfo->inodeFd, buf, status.st_size) == status.st_size); for (ip = buf; nInodes--; ip++) { Log("Inode:%s, linkCount=%d, size=%#llx, p=(%u,%u,%u,%u)\n", PrintInode(NULL, ip->inodeNumber), ip->linkCount, @@ -4353,24 +4418,24 @@ PrintInodeList(void) } void -PrintInodeSummary(void) +PrintInodeSummary(struct SalvInfo *salvinfo) { int i; struct InodeSummary *isp; - for (i = 0; i < nVolumesInInodeFile; i++) { - isp = &inodeSummary[i]; + for (i = 0; i < salvinfo->nVolumesInInodeFile; i++) { + isp = &salvinfo->inodeSummary[i]; Log("VID:%u, RW:%u, index:%d, nInodes:%d, nSpecialInodes:%d, maxUniquifier:%u, volSummary\n", isp->volumeId, isp->RWvolumeId, isp->index, isp->nInodes, isp->nSpecialInodes, isp->maxUniquifier); } } void -PrintVolumeSummary(void) +PrintVolumeSummary(struct SalvInfo *salvinfo) { int i; struct VolumeSummary *vsp; - for (i = 0, vsp = volumeSummaryp; i < nVolumes; vsp++, i++) { + for (i = 0, vsp = salvinfo->volumeSummaryp; i < salvinfo->nVolumes; vsp++, i++) { Log("fileName:%s, header, wouldNeedCallback\n", vsp->fileName); } } diff --git a/src/vol/vol-salvage.h b/src/vol/vol-salvage.h index 9331a3c461..36ac93fac9 100644 --- a/src/vol/vol-salvage.h +++ b/src/vol/vol-salvage.h @@ -45,7 +45,7 @@ struct InodeSummary { /* Inode summary file--an entry for each /* Either a pointer to the original volume * header summary, or constructed summary * information */ -} *inodeSummary; +}; #define readOnly(isp) ((isp)->volumeId != (isp)->RWvolumeId) struct VolumeSummary { /* Volume summary an entry for each @@ -110,6 +110,8 @@ struct DirSummary { IHandle_t *ds_linkH; }; +struct SalvInfo; + #define ORPH_IGNORE 0 #define ORPH_REMOVE 1 #define ORPH_ATTACH 2 @@ -144,40 +146,8 @@ extern int ForceSalvage; /* If salvage should occur despite the DONT_SALVAGE fl #define ROOTINODE 2 /* Root inode of a 4.2 Unix file system * partition */ -extern Device fileSysDevice; /* The device number of the current - * partition being salvaged */ -#ifdef AFS_NT40_ENV -extern char fileSysPath[8]; -#else -extern char *fileSysPath; /* The path of the mounted partition currently - * being salvaged, i.e. the directory - * containing the volume headers */ -#endif /* AFS_NT40_ENV */ -extern char *fileSysPathName; /* NT needs this to make name pretty in log. */ -extern IHandle_t *VGLinkH; /* Link handle for current volume group. */ -extern int VGLinkH_cnt; /* # of references to lnk handle. */ -extern struct DiskPartition64 *fileSysPartition; /* Partition being salvaged */ -#ifndef AFS_NT40_ENV -extern char *fileSysDeviceName; /* The block device where the file system - * being salvaged was mounted */ -extern char *filesysfulldev; -#endif /* AFS_NT40_ENV */ -extern int VolumeChanged; /* Set by any routine which would change the volume in - * a way which would require callback is to be broken if the - * volume was put back on line by an active file server */ - -extern VolumeDiskData VolInfo; /* A copy of the last good or salvaged volume header dealt with */ - -extern int nVolumesInInodeFile; /* Number of read-write volumes summarized */ -extern int inodeFd; /* File descriptor for inode file */ -extern struct VnodeInfo vnodeInfo[nVNODECLASSES]; - - -extern struct VolumeSummary *volumeSummaryp; /* Holds all the volumes in a part */ -extern int nVolumes; /* Number of volumes (read-write and read-only) - * in volume summary */ extern char * tmpdir; extern FILE *logFile; /* one of {/usr/afs/logs,/vice/file}/SalvageLog */ @@ -210,6 +180,7 @@ extern int nt_SetupPartitionSalvage(void *datap, int len); typedef struct { struct InodeSummary *svgp_inodeSummaryp; int svgp_count; + struct SalvInfo *svgp_salvinfo; } SVGParms_t; #endif /* AFS_NT40_ENV */ @@ -221,59 +192,66 @@ extern void Exit(int code) AFS_NORETURN; extern int Fork(void); extern int Wait(char *prog); extern char *ToString(const char *s); -extern void AskOffline(VolumeId volumeId, char * partition); -extern void AskOnline(VolumeId volumeId, char *partition); +extern void AskOffline(struct SalvInfo *salvinfo, VolumeId volumeId); +extern void AskOnline(struct SalvInfo *salvinfo, VolumeId volumeId); extern void CheckLogFile(char * log_path); #ifndef AFS_NT40_ENV extern void TimeStampLogFile(char * log_path); #endif extern void ClearROInUseBit(struct VolumeSummary *summary); -extern void CopyAndSalvage(struct DirSummary *dir); +extern void CopyAndSalvage(struct SalvInfo *salvinfo, struct DirSummary *dir); extern int CopyInode(Device device, Inode inode1, Inode inode2, int rwvolume); -extern void CopyOnWrite(struct DirSummary *dir); -extern void CountVolumeInodes(struct ViceInodeInfo *ip, int maxInodes, - struct InodeSummary *summary); -extern void DeleteExtraVolumeHeaderFile(struct VolumeSummary *vsp); -extern void DistilVnodeEssence(VolumeId vid, VnodeClass class, Inode ino, - Unique * maxu); -extern int GetInodeSummary(FILE *inodeFile, VolumeId singleVolumeNumber); -extern int GetVolumeSummary(VolumeId singleVolumeNumber); +extern void CopyOnWrite(struct SalvInfo *salvinfo, struct DirSummary *dir); +extern void CountVolumeInodes(register struct ViceInodeInfo *ip, int maxInodes, + register struct InodeSummary *summary); +extern void DeleteExtraVolumeHeaderFile(struct SalvInfo *salvinfo, + struct VolumeSummary *vsp); +extern void DistilVnodeEssence(struct SalvInfo *salvinfo, VolumeId vid, + VnodeClass class, Inode ino, Unique * maxu); +extern int GetInodeSummary(struct SalvInfo *salvinfo, FILE *inodeFile, + VolumeId singleVolumeNumber); +extern int GetVolumeSummary(struct SalvInfo *salvinfo, + VolumeId singleVolumeNumber); extern int JudgeEntry(void *dirVal, char *name, afs_int32 vnodeNumber, afs_int32 unique); -extern void MaybeZapVolume(struct InodeSummary *isp, char *message, - int deleteMe, int check); +extern void MaybeZapVolume(struct SalvInfo *salvinfo, struct InodeSummary *isp, + char *message, int deleteMe, int check); extern void ObtainSalvageLock(void); extern void ObtainSharedSalvageLock(void); -extern void PrintInodeList(void); -extern void PrintInodeSummary(void); -extern void PrintVolumeSummary(void); -extern int QuickCheck(struct InodeSummary *isp, int nVols); +extern void PrintInodeList(struct SalvInfo *salvinfo); +extern void PrintInodeSummary(struct SalvInfo *salvinfo); +extern void PrintVolumeSummary(struct SalvInfo *salvinfo); +extern int QuickCheck(struct SalvInfo *salvinfo, struct InodeSummary *isp, + int nVols); extern void RemoveTheForce(char *path); -extern void SalvageDir(char *name, VolumeId rwVid, struct VnodeInfo *dirVnodeInfo, - IHandle_t * alinkH, int i, struct DirSummary *rootdir, - int *rootdirfound); +extern void SalvageDir(struct SalvInfo *salvinfo, char *name, VolumeId rwVid, + struct VnodeInfo *dirVnodeInfo, IHandle_t * alinkH, + int i, struct DirSummary *rootdir, int *rootdirfound); extern void SalvageFileSysParallel(struct DiskPartition64 *partP); extern void SalvageFileSys(struct DiskPartition64 *partP, VolumeId singleVolumeNumber); extern void SalvageFileSys1(struct DiskPartition64 *partP, VolumeId singleVolumeNumber); -extern int SalvageHeader(struct stuff *sp, struct InodeSummary *isp, - int check, int *deleteMe); -extern int SalvageIndex(Inode ino, VnodeClass class, int RW, - struct ViceInodeInfo *ip, int nInodes, - struct VolumeSummary *volSummary, int check); -extern int SalvageVnodes(struct InodeSummary *rwIsp, - struct InodeSummary *thisIsp, - struct ViceInodeInfo *inodes, int check); -extern int SalvageVolume(struct InodeSummary *rwIsp, IHandle_t * alinkH); -extern void DoSalvageVolumeGroup(struct InodeSummary *isp, int nVols); +extern int SalvageHeader(struct SalvInfo *salvinfo, struct stuff *sp, + struct InodeSummary *isp, int check, int *deleteMe); +extern int SalvageIndex(struct SalvInfo *salvinfo, Inode ino, VnodeClass class, + int RW, struct ViceInodeInfo *ip, int nInodes, + struct VolumeSummary *volSummary, int check); +extern int SalvageVnodes(struct SalvInfo *salvinfo, struct InodeSummary *rwIsp, + struct InodeSummary *thisIsp, + struct ViceInodeInfo *inodes, int check); +extern int SalvageVolume(struct SalvInfo *salvinfo, struct InodeSummary *rwIsp, + IHandle_t * alinkH); +extern void DoSalvageVolumeGroup(struct SalvInfo *salvinfo, + struct InodeSummary *isp, int nVols); #ifdef AFS_NT40_ENV extern void SalvageVolumeGroup(struct InodeSummary *isp, int nVols); #else #define SalvageVolumeGroup DoSalvageVolumeGroup #endif -extern int SalvageVolumeHeaderFile(struct InodeSummary *isp, - struct ViceInodeInfo *inodes, int RW, - int check, int *deleteMe); +extern int SalvageVolumeHeaderFile(struct SalvInfo *salvinfo, + struct InodeSummary *isp, + struct ViceInodeInfo *inodes, int RW, + int check, int *deleteMe); extern void showlog(void); extern int UseTheForceLuke(char *path); diff --git a/src/vol/vol_internal.h b/src/vol/vol_internal.h index ad34d4a928..095f72fd23 100644 --- a/src/vol/vol_internal.h +++ b/src/vol/vol_internal.h @@ -2,6 +2,7 @@ #define AFS_SRC_VOL_INTERNAL_H /* physio.c */ -extern void SetSalvageDirHandle(DirHandle *, afs_int32, Device, Inode); +extern void SetSalvageDirHandle(DirHandle *, afs_int32, Device, Inode, + int *); #endif