static int IsVnodeOrphaned(struct SalvInfo *salvinfo, VnodeId vnode);
static int AskVolumeSummary(struct SalvInfo *salvinfo,
VolumeId singleVolumeNumber);
+static void MaybeAskOnline(struct SalvInfo *salvinfo, VolumeId volumeId);
#ifdef AFS_DEMAND_ATTACH_FS
static int LockVolume(struct SalvInfo *salvinfo, VolumeId volumeId);
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;
OS_SEEK(salvinfo->inodeFd, 0L, SEEK_SET);
if (ListInodeOption) {
PrintInodeList(salvinfo);
+ if (singleVolumeNumber) {
+ /* We've checked out the volume from the fileserver, and we need
+ * to give it back. We don't know if the volume exists or not,
+ * so we don't know whether to AskOnline or not. Try to determine
+ * if the volume exists by trying to read the volume header, and
+ * AskOnline if it is readable. */
+ MaybeAskOnline(salvinfo, singleVolumeNumber);
+ }
return;
}
/* enumerate volumes in the partition.
}
if (!foundSVN) {
- /* singleVolumeNumber generally should always be in the constructed
- * volumeSummary, but just in case it's not... */
- AskOnline(salvinfo, singleVolumeNumber);
+ /* If singleVolumeNumber is not in our volumeSummary, it means that
+ * at least one other volume in the VG is on the partition, but the
+ * RW volume is not. We've already AskOffline'd it by now, though,
+ * so make sure we don't still have the volume checked out. */
+ AskDelete(salvinfo, singleVolumeNumber);
}
for (j = 0; j < salvinfo->nVolumes; j++) {
return ret;
}
+static void
+MaybeAskOnline(struct SalvInfo *salvinfo, VolumeId volumeId)
+{
+ struct VolumeDiskHeader diskHdr;
+ int code;
+ code = VReadVolumeDiskHeader(volumeId, salvinfo->fileSysPartition, &diskHdr);
+ if (code) {
+ /* volume probably does not exist; no need to bring back online */
+ return;
+ }
+ AskOnline(salvinfo, volumeId);
+}
+
void
AskOnline(struct SalvInfo *salvinfo, VolumeId volumeId)
{
AskDelete(struct SalvInfo *salvinfo, VolumeId volumeId)
{
afs_int32 code, i;
+ SYNC_response res;
for (i = 0; i < 3; i++) {
+ memset(&res, 0, sizeof(res));
code = FSYNC_VolOp(volumeId, salvinfo->fileSysPartition->name,
- FSYNC_VOL_DONE, FSYNC_SALVAGE, NULL);
+ FSYNC_VOL_DONE, FSYNC_SALVAGE, &res);
if (code == SYNC_OK) {
break;
#endif
}
break;
+ } else if (code == SYNC_FAILED &&
+ (res.hdr.reason == FSYNC_UNKNOWN_VOLID ||
+ res.hdr.reason == FSYNC_WRONG_PART)) {
+ /* volume is already effectively 'deleted' */
+ break;
} else if (i < 2) {
/* try it again */
Log("AskOnline: request for fileserver to delete volume failed; trying again...\n");