DF-3093 / instr.patch
--- a/sys/vfs/msdosfs/msdosfs_fat.c +++ b/sys/vfs/msdosfs/msdosfs_fat.c @@ -55,18 +55,30 @@ #include <sys/buf.h> #include <sys/mount.h> #include <sys/vnode.h> #include <sys/buf2.h> +#include <sys/sysctl.h> #include <vfs/msdosfs/bpb.h> #include <vfs/msdosfs/direntry.h> #include <vfs/msdosfs/denode.h> #include <vfs/msdosfs/fat.h> #include <vfs/msdosfs/msdosfsmount.h> #define FULL_RUN ((u_int)0xffffffff) + +/* DF-3093 instrumentation (diagnostic build only) */ +static int df3093_inflight = 0; +static long df3093_overlaps = 0; +static long df3093_double = 0; +SYSCTL_INT(_debug, OID_AUTO, df3093_inflight, CTLFLAG_RD, &df3093_inflight, 0, + "DFDBG concurrent clusteralloc depth"); +SYSCTL_LONG(_debug, OID_AUTO, df3093_overlaps, CTLFLAG_RD, &df3093_overlaps, 0, + "DFDBG clusteralloc overlap events"); +SYSCTL_LONG(_debug, OID_AUTO, df3093_double, CTLFLAG_RD, &df3093_double, 0, + "DFDBG double usemap_alloc events"); static void fc_lookup(struct denode *dep, u_long findcn, u_long *frcnp, u_long *fsrcnp); static int clusteralloc1(struct msdosfsmount *pmp, u_long start, u_long count, u_long fillwith, u_long *retcluster, @@ -370,10 +382,19 @@ * */ static __inline void usemap_alloc(struct msdosfsmount *pmp, u_long cn) { + /* DF-3093 instrumentation: INVARIANTS KASSERT, print-only form */ + if (pmp->pm_inusemap[cn / N_INUSEBITS] & + (1U << (cn % N_INUSEBITS))) { + atomic_fetchadd_long(&df3093_double, 1); + if (df3093_double < 200) + kprintf("DFDBG: DOUBLE usemap_alloc cn=%lu max=%lu\n", + cn, pmp->pm_maxcluster); + } + MSDOSFS_ASSERT_MP_LOCKED(pmp); KASSERT(cn <= pmp->pm_maxcluster, ("cn too large %lu %lu", cn, pmp->pm_maxcluster)); KASSERT((pmp->pm_flags & MSDOSFSMNT_RONLY) == 0, @@ -725,14 +746,20 @@ int clusteralloc(struct msdosfsmount *pmp, u_long start, u_long count, u_long fillwith, u_long *retcluster, u_long *got) { int error; - - MSDOSFS_LOCK_MP(pmp); + int ent = atomic_fetchadd_int(&df3093_inflight, 1) + 1; + + if (ent > 1) { + atomic_fetchadd_long(&df3093_overlaps, 1); + if (df3093_overlaps < 200) + kprintf("DFDBG: clusteralloc overlap depth=%d " + "count=%lu\n", ent, count); + } error = clusteralloc1(pmp, start, count, fillwith, retcluster, got); - MSDOSFS_UNLOCK_MP(pmp); + atomic_subtract_int(&df3093_inflight, 1); return (error); } static int clusteralloc1(struct msdosfsmount *pmp, u_long start, u_long count, |