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 ObliterateRegion(avp, aclass, afile, aoffset)
95 StreamHandle_t *afile;
98 register struct VnodeClassInfo *vcp;
99 Inode inodes[MAXOBLITATONCE];
100 register afs_int32 iindex, nscanned;
102 char buf[SIZEOF_LARGEDISKVNODE];
105 register afs_int32 code;
106 register struct VnodeDiskObject *vnode = (struct VnodeDiskObject *) buf;
109 vcp = &VnodeClassInfo[aclass];
110 offset = *aoffset; /* original offset */
113 /* advance over up to MAXOBLITATONCE inodes. nscanned tells us how many we examined.
114 We remember the inodes in an array, and idec them after zeroing them in the index.
115 The reason for these contortions is to make volume deletion idempotent, even
116 if we crash in the middle of a delete operation. */
117 STREAM_SEEK(afile, offset, 0);
119 if (iindex >= MAXOBLITATONCE) {
122 code = STREAM_READ(vnode, vcp->diskSize, 1, afile);
124 offset += vcp->diskSize;
129 if (vnode->type != vNull) {
130 if (vnode->vnodeMagic != vcp->magic)
131 goto fail; /* something really wrong; let salvager take care of it */
132 if (VNDISK_GET_INO(vnode))
133 inodes[iindex++] = VNDISK_GET_INO(vnode);
137 /* next, obliterate the index and fflush (and fsync) it */
138 STREAM_SEEK(afile, *aoffset, 0); /* seek back to start of vnode index region */
139 memset(buf, 0, sizeof(buf)); /* zero out our proto-vnode */
140 for(i=0;i<nscanned;i++) {
141 if (STREAM_WRITE(buf, vcp->diskSize, 1, afile) != 1)
144 STREAM_FLUSH(afile); /* ensure 0s are on the disk */
145 OS_SYNC(afile->str_fd);
147 /* finally, do the idec's */
148 for(i=0;i<iindex;i++) {
149 IH_DEC(V_linkHandle(avp), inodes[i], V_parentId(avp));
153 /* return the new offset */
155 return hitEOF; /* return 1 if hit EOF (don't call again), otherwise 0 */
161 void PurgeIndex(Volume *vp, VnodeClass class)
164 PurgeIndex_r(vp, class);
168 void PurgeIndex_r(Volume *vp, VnodeClass class)
170 StreamHandle_t *ifile;
171 struct VnodeClassInfo *vcp = &VnodeClassInfo[class];
173 register afs_int32 code;
177 fdP = IH_OPEN(vp->vnodeIndex[class].handle);
181 ifile = FDH_FDOPEN(fdP, "r+");
183 FDH_REALLYCLOSE(fdP);
187 offset = vcp->diskSize;
189 code = ObliterateRegion(vp, class, ifile, &offset);
190 if (code) break; /* if error or hit EOF */
196 void PurgeHeader(Volume *vp)
203 void PurgeHeader_r(Volume *vp)
205 IH_REALLYCLOSE(V_diskDataHandle(vp));
206 IH_DEC(V_linkHandle(vp), vp->vnodeIndex[vLarge].handle->ih_ino, V_id(vp));
207 IH_DEC(V_linkHandle(vp), vp->vnodeIndex[vSmall].handle->ih_ino, V_id(vp));
208 IH_DEC(V_linkHandle(vp), vp->diskDataHandle->ih_ino, V_id(vp));
210 /* And last, but not least, the link count table itself. */
211 IH_REALLYCLOSE(V_linkHandle(vp));
212 IH_DEC(V_linkHandle(vp), vp->linkHandle->ih_ino, V_parentId(vp));