void PrintHeader(Volume * vp) { Vdiskused = V_diskused(vp); if (dsizeOnly || saveinodes) return; printf("Volume header for volume %u (%s)\n", V_id(vp), V_name(vp)); printf("stamp.magic = %x, stamp.version = %u\n", V_stamp(vp).magic, V_stamp(vp).version); printf ("inUse = %d, inService = %d, blessed = %d, needsSalvaged = %d, dontSalvage = %d\n", V_inUse(vp), V_inService(vp), V_blessed(vp), V_needsSalvaged(vp), V_dontSalvage(vp)); printf ("type = %d (%s), uniquifier = %u, needsCallback = %d, destroyMe = %x\n", V_type(vp), typestring(V_type(vp)), V_uniquifier(vp), V_needsCallback(vp), V_destroyMe(vp)); printf ("id = %u, parentId = %u, cloneId = %u, backupId = %u, restoredFromId = %u\n", V_id(vp), V_parentId(vp), V_cloneId(vp), V_backupId(vp), V_restoredFromId(vp)); printf ("maxquota = %d, minquota = %d, maxfiles = %d, filecount = %d, diskused = %d\n", V_maxquota(vp), V_minquota(vp), V_maxfiles(vp), V_filecount(vp), V_diskused(vp)); printf("creationDate = %s, copyDate = %s\n", date(V_creationDate(vp)), date(V_copyDate(vp))); printf("backupDate = %s, expirationDate = %s\n", date(V_backupDate(vp)), date(V_expirationDate(vp))); printf("accessDate = %s, updateDate = %s\n", date(V_accessDate(vp)), date(V_updateDate(vp))); printf("owner = %u, accountNumber = %u\n", V_owner(vp), V_accountNumber(vp)); printf ("dayUse = %u; week = (%u, %u, %u, %u, %u, %u, %u), dayUseDate = %s\n", V_dayUse(vp), V_weekUse(vp)[0], V_weekUse(vp)[1], V_weekUse(vp)[2], V_weekUse(vp)[3], V_weekUse(vp)[4], V_weekUse(vp)[5], V_weekUse(vp)[6], date(V_dayUseDate(vp))); printf("volUpdateCounter = %u\n", V_volUpCounter(vp)); }
static int DumpVolumeHeader(int dumpfd, register Volume * vp) { int code = 0; if (verbose) fprintf(stderr, "dumping volume header\n"); if (!code) code = DumpTag(dumpfd, D_VOLUMEHEADER); if (!code) code = DumpInt32(dumpfd, 'i', V_id(vp)); if (!code) code = DumpInt32(dumpfd, 'v', V_stamp(vp).version); if (!code) code = DumpString(dumpfd, 'n', V_name(vp)); if (!code) code = DumpBool(dumpfd, 's', V_inService(vp)); if (!code) code = DumpBool(dumpfd, 'b', V_blessed(vp)); if (!code) code = DumpInt32(dumpfd, 'u', V_uniquifier(vp)); if (!code) code = DumpByte(dumpfd, 't', (byte) V_type(vp)); if (!code) code = DumpInt32(dumpfd, 'p', V_parentId(vp)); if (!code) code = DumpInt32(dumpfd, 'c', V_cloneId(vp)); if (!code) code = DumpInt32(dumpfd, 'q', V_maxquota(vp)); if (!code) code = DumpInt32(dumpfd, 'm', V_minquota(vp)); if (!code) code = DumpInt32(dumpfd, 'd', V_diskused(vp)); if (!code) code = DumpInt32(dumpfd, 'f', V_filecount(vp)); if (!code) code = DumpInt32(dumpfd, 'a', V_accountNumber(vp)); if (!code) code = DumpInt32(dumpfd, 'o', V_owner(vp)); if (!code) code = DumpInt32(dumpfd, 'C', V_creationDate(vp)); /* Rw volume creation date */ if (!code) code = DumpInt32(dumpfd, 'A', V_accessDate(vp)); if (!code) code = DumpInt32(dumpfd, 'U', V_updateDate(vp)); if (!code) code = DumpInt32(dumpfd, 'E', V_expirationDate(vp)); if (!code) code = DumpInt32(dumpfd, 'B', V_backupDate(vp)); /* Rw volume backup clone date */ if (!code) code = DumpString(dumpfd, 'O', V_offlineMessage(vp)); /* * We do NOT dump the detailed volume statistics residing in the old * motd field, since we cannot tell from the info in a dump whether * statistics data has been put there. Instead, we dump a null string, * just as if that was what the motd contained. */ if (!code) code = DumpString(dumpfd, 'M', ""); if (!code) code = DumpArrayInt32(dumpfd, 'W', (afs_uint32 *) V_weekUse(vp), sizeof(V_weekUse(vp)) / sizeof(V_weekUse(vp)[0])); if (!code) code = DumpInt32(dumpfd, 'D', V_dayUseDate(vp)); if (!code) code = DumpInt32(dumpfd, 'Z', V_dayUse(vp)); if (!code) code = DumpInt32(dumpfd, 'V', V_volUpCounter(vp)); return code; }
static int DumpVnode(int dumpfd, struct VnodeDiskObject *v, int volid, int vnodeNumber, int dumpEverything, struct Volume *vp) { int code = 0; IHandle_t *ihP; FdHandle_t *fdP; if (verbose) fprintf(stderr, "dumping vnode %d\n", vnodeNumber); if (!v || v->type == vNull) return code; if (!code) code = DumpDouble(dumpfd, D_VNODE, vnodeNumber, v->uniquifier); if (!dumpEverything) return code; if (!code) code = DumpByte(dumpfd, 't', (byte) v->type); if (!code) code = DumpShort(dumpfd, 'l', v->linkCount); /* May not need this */ if (!code) code = DumpInt32(dumpfd, 'v', v->dataVersion); if (!code) code = DumpInt32(dumpfd, 'm', v->unixModifyTime); if (!code) code = DumpInt32(dumpfd, 'a', v->author); if (!code) code = DumpInt32(dumpfd, 'o', v->owner); if (!code && v->group) code = DumpInt32(dumpfd, 'g', v->group); /* default group is 0 */ if (!code) code = DumpShort(dumpfd, 'b', v->modeBits); if (!code) code = DumpInt32(dumpfd, 'p', v->parent); if (!code) code = DumpInt32(dumpfd, 's', v->serverModifyTime); if (v->type == vDirectory) { acl_HtonACL(VVnodeDiskACL(v)); if (!code) code = DumpByteString(dumpfd, 'A', (byte *) VVnodeDiskACL(v), VAclDiskSize(v)); } if (VNDISK_GET_INO(v)) { IH_INIT(ihP, V_device(vp), V_parentId(vp), VNDISK_GET_INO(v)); fdP = IH_OPEN(ihP); if (fdP == NULL) { fprintf(stderr, "Unable to open inode %s for vnode %u (volume %i); not dumped, error %d\n", PrintInode(NULL, VNDISK_GET_INO(v)), vnodeNumber, volid, errno); } else { if (verbose) fprintf(stderr, "about to dump inode %s for vnode %u\n", PrintInode(NULL, VNDISK_GET_INO(v)), vnodeNumber); code = DumpFile(dumpfd, vnodeNumber, fdP, v); FDH_CLOSE(fdP); } IH_RELEASE(ihP); } if (verbose) fprintf(stderr, "done dumping vnode %d\n", vnodeNumber); return code; }
/* delete a portion of an index, adjusting offset appropriately. Returns 0 if things work and we should be called again, 1 if success full and done, and -1 if an error occurred. It adjusts offset appropriately on 0 or 1 return codes, and otherwise doesn't touch it */ static int ObliterateRegion(Volume * avp, VnodeClass aclass, StreamHandle_t * afile, afs_int32 * aoffset) { register struct VnodeClassInfo *vcp; Inode inodes[MAXOBLITATONCE]; register afs_int32 iindex, nscanned; afs_int32 offset; char buf[SIZEOF_LARGEDISKVNODE]; int hitEOF; register int i; register afs_int32 code; register struct VnodeDiskObject *vnode = (struct VnodeDiskObject *)buf; hitEOF = 0; vcp = &VnodeClassInfo[aclass]; offset = *aoffset; /* original offset */ iindex = 0; nscanned = 0; /* advance over up to MAXOBLITATONCE inodes. nscanned tells us how many we examined. * We remember the inodes in an array, and idec them after zeroing them in the index. * The reason for these contortions is to make volume deletion idempotent, even * if we crash in the middle of a delete operation. */ STREAM_SEEK(afile, offset, 0); while (1) { if (iindex >= MAXOBLITATONCE) { break; } code = STREAM_READ(vnode, vcp->diskSize, 1, afile); nscanned++; offset += vcp->diskSize; if (code != 1) { hitEOF = 1; break; } if (vnode->type != vNull) { if (vnode->vnodeMagic != vcp->magic) goto fail; /* something really wrong; let salvager take care of it */ if (VNDISK_GET_INO(vnode)) inodes[iindex++] = VNDISK_GET_INO(vnode); } } /* next, obliterate the index and fflush (and fsync) it */ STREAM_SEEK(afile, *aoffset, 0); /* seek back to start of vnode index region */ memset(buf, 0, sizeof(buf)); /* zero out our proto-vnode */ for (i = 0; i < nscanned; i++) { if (STREAM_WRITE(buf, vcp->diskSize, 1, afile) != 1) goto fail; } STREAM_FLUSH(afile); /* ensure 0s are on the disk */ OS_SYNC(afile->str_fd); /* finally, do the idec's */ for (i = 0; i < iindex; i++) { IH_DEC(V_linkHandle(avp), inodes[i], V_parentId(avp)); DOPOLL; } /* return the new offset */ *aoffset = offset; return hitEOF; /* return 1 if hit EOF (don't call again), otherwise 0 */ fail: return -1; }