2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
13 Institution: The Information Technology Center, Carnegie-Mellon University
16 #include <afsconfig.h>
17 #include <afs/param.h>
26 #include <sys/param.h>
38 #include <afs/assert.h>
41 #include "afs/afsint.h"
45 #include <afs/afssyscalls.h>
52 #include "viceinode.h"
53 #include "partition.h"
56 /* forward declarations */
57 void PurgeIndex_r(Volume *vp, VnodeClass class);
58 void PurgeHeader_r(Volume *vp);
60 void VPurgeVolume_r(Error *ec, Volume *vp)
62 struct DiskPartition *tpartp = vp->partition;
63 char purgePath[MAXPATHLEN];
65 /* N.B. it's important here to use the partition pointed to by the
66 * volume header. This routine can, under some circumstances, be called
67 * when two volumes with the same id exist on different partitions.
69 sprintf(purgePath, "%s/%s", VPartitionPath(vp->partition),
70 VolumeExternalName(V_id(vp)));
71 PurgeIndex_r(vp, vLarge);
72 PurgeIndex_r(vp, vSmall);
76 * Call the fileserver to break all call backs for that volume
78 FSYNC_askfs(V_id(vp), tpartp->name, FSYNC_RESTOREVOLUME, 0);
81 void VPurgeVolume(Error *ec, Volume *vp)
84 VPurgeVolume_r(ec, vp);
88 #define MAXOBLITATONCE 200
89 /* delete a portion of an index, adjusting offset appropriately. Returns 0 if
90 things work and we should be called again, 1 if success full and done, and -1
91 if an error occurred. It adjusts offset appropriately on 0 or 1 return codes,
92 and otherwise doesn't touch it */
93 static int ObliterateRegion(Volume *avp, VnodeClass aclass,
94 StreamHandle_t *afile, afs_int32 *aoffset)
96 register struct VnodeClassInfo *vcp;
97 Inode inodes[MAXOBLITATONCE];
98 register afs_int32 iindex, nscanned;
100 char buf[SIZEOF_LARGEDISKVNODE];
103 register afs_int32 code;
104 register struct VnodeDiskObject *vnode = (struct VnodeDiskObject *) buf;
107 vcp = &VnodeClassInfo[aclass];
108 offset = *aoffset; /* original offset */
111 /* advance over up to MAXOBLITATONCE inodes. nscanned tells us how many we examined.
112 We remember the inodes in an array, and idec them after zeroing them in the index.
113 The reason for these contortions is to make volume deletion idempotent, even
114 if we crash in the middle of a delete operation. */
115 STREAM_SEEK(afile, offset, 0);
117 if (iindex >= MAXOBLITATONCE) {
120 code = STREAM_READ(vnode, vcp->diskSize, 1, afile);
122 offset += vcp->diskSize;
127 if (vnode->type != vNull) {
128 if (vnode->vnodeMagic != vcp->magic)
129 goto fail; /* something really wrong; let salvager take care of it */
130 if (VNDISK_GET_INO(vnode))
131 inodes[iindex++] = VNDISK_GET_INO(vnode);
135 /* next, obliterate the index and fflush (and fsync) it */
136 STREAM_SEEK(afile, *aoffset, 0); /* seek back to start of vnode index region */
137 memset(buf, 0, sizeof(buf)); /* zero out our proto-vnode */
138 for(i=0;i<nscanned;i++) {
139 if (STREAM_WRITE(buf, vcp->diskSize, 1, afile) != 1)
142 STREAM_FLUSH(afile); /* ensure 0s are on the disk */
143 OS_SYNC(afile->str_fd);
145 /* finally, do the idec's */
146 for(i=0;i<iindex;i++) {
147 IH_DEC(V_linkHandle(avp), inodes[i], V_parentId(avp));
151 /* return the new offset */
153 return hitEOF; /* return 1 if hit EOF (don't call again), otherwise 0 */
159 void PurgeIndex(Volume *vp, VnodeClass class)
162 PurgeIndex_r(vp, class);
166 void PurgeIndex_r(Volume *vp, VnodeClass class)
168 StreamHandle_t *ifile;
169 struct VnodeClassInfo *vcp = &VnodeClassInfo[class];
171 register afs_int32 code;
175 fdP = IH_OPEN(vp->vnodeIndex[class].handle);
179 ifile = FDH_FDOPEN(fdP, "r+");
181 FDH_REALLYCLOSE(fdP);
185 offset = vcp->diskSize;
187 code = ObliterateRegion(vp, class, ifile, &offset);
188 if (code) break; /* if error or hit EOF */
194 void PurgeHeader(Volume *vp)
201 void PurgeHeader_r(Volume *vp)
203 IH_REALLYCLOSE(V_diskDataHandle(vp));
204 IH_DEC(V_linkHandle(vp), vp->vnodeIndex[vLarge].handle->ih_ino, V_id(vp));
205 IH_DEC(V_linkHandle(vp), vp->vnodeIndex[vSmall].handle->ih_ino, V_id(vp));
206 IH_DEC(V_linkHandle(vp), vp->diskDataHandle->ih_ino, V_id(vp));
208 /* And last, but not least, the link count table itself. */
209 IH_REALLYCLOSE(V_linkHandle(vp));
210 IH_DEC(V_linkHandle(vp), vp->linkHandle->ih_ino, V_parentId(vp));