#else
# include <opr/lockstub.h>
#endif
+#include <opr/ffs.h>
#include <afs/afsint.h>
static void VInitVolumeHash(void);
-#ifndef AFS_HAVE_FFS
-/* This macro is used where an ffs() call does not exist. Was in util/ffs.c */
-ffs(x)
-{
- afs_int32 ffs_i;
- afs_int32 ffs_tmp = x;
- if (ffs_tmp == 0)
- return (-1);
- else
- for (ffs_i = 1;; ffs_i++) {
- if (ffs_tmp & 1)
- return (ffs_i);
- else
- ffs_tmp >>= 1;
- }
-}
-#endif /* !AFS_HAVE_FFS */
-
#ifdef AFS_PTHREAD_ENV
/**
* disk partition queue element
V_checkoutMode(vp) = mode;
}
- AddVolumeToHashTable(vp, V_id(vp));
+ AddVolumeToHashTable(vp, vp->hashid);
#ifdef AFS_DEMAND_ATTACH_FS
if (VCanUnlockAttached() && (V_attachFlags(vp) & VOL_LOCKED)) {
VUnlockVolume(vp);
*ec = VSALVAGE;
code = 1;
}
+ if ((flags & VOL_SALVAGE_NO_OFFLINE)) {
+ /* Here, we free the header for the volume, but make sure to only
+ * do this if VOL_SALVAGE_NO_OFFLINE is specified. The reason for
+ * this requires a bit of explanation.
+ *
+ * Normally, the volume header will be freed when the volume goes
+ * goes offline. However, if VOL_SALVAGE_NO_OFFLINE has been
+ * specified, the volume was in the process of being attached when
+ * we discovered that it needed salvaging. Thus, the volume will
+ * never go offline, since it never went fully online in the first
+ * place. Specifically, we do not call VOfflineForSalvage_r above,
+ * and we never get rid of the volume via VPutVolume_r; the volume
+ * has not been initialized enough for those to work.
+ *
+ * So instead, explicitly free the volume header here. If we do not
+ * do this, we are wasting a header that some other volume could be
+ * using, since the header remains attached to the volume. Also if
+ * we do not free the header here, we end up with a volume where
+ * nUsers == 0, but the volume has a header that is not on the
+ * header LRU. Some code expects that all nUsers == 0 volumes have
+ * their header on the header LRU (or have no header).
+ *
+ * Also note that we must not free the volume header here if
+ * VOL_SALVAGE_NO_OFFLINE is not set. Since, if
+ * VOL_SALVAGE_NO_OFFLINE is not set, someone else may have a
+ * reference to this volume, and they assume they can use the
+ * volume's header. If we free the volume out from under them, they
+ * can easily segfault.
+ */
+ FreeVolumeHeader(vp);
+ }
}
return code;
}
index->bitmapOffset = (afs_uint32) (bp - index->bitmap);
while (*bp == 0xff)
bp++;
- o = ffs(~*bp) - 1; /* ffs is documented in BSTRING(3) */
+ o = opr_ffs(~*bp) - 1;
*bp |= (1 << o);
ret = ((bp - index->bitmap) * 8 + o);
#ifdef AFS_DEMAND_ATTACH_FS