⬢ DragonFlyBSD Kernel Audit
DF-3250 / instrument.diff
← back to finding ↓ download raw
--- /home/maxx/dfbsd/dfbsd/sys/vfs/ext2fs/ext2_ihash.c	2026-06-29 12:51:19.000000000 +0000
+++ ext2_ihash.c	2026-09-09 12:30:20.883552710 +0000
@@ -52,6 +52,11 @@
 static u_long	ext2_ihash;		/* size of hash table - 1 */
 static struct lwkt_token ext2_ihash_token;
 
+/* DF3250 instrumentation */
+long df3250_ins_calls;
+long df3250_ebusy_hits;
+long df3250_rem_calls;
+
 #define	INOHASH(device, inum)	(&ext2_ihashtbl[(minor(device) + (inum)) & ext2_ihash])
 
 /*
@@ -129,9 +134,15 @@
 
 	KKASSERT((ip->i_flag & IN_HASHED) == 0);
 	lwkt_gettoken(&ext2_ihash_token);
+	atomic_add_long(&df3250_ins_calls, 1);
 	ipp = INOHASH(ip->i_dev, ip->i_number);
 	while ((iq = *ipp) != NULL) {
 		if (ip->i_dev == iq->i_dev && ip->i_number == iq->i_number) {
+			atomic_add_long(&df3250_ebusy_hits, 1);
+			printf("DF3250[ihash]: EBUSY! dev=%p ino=%llu "
+			    "(ins=%ld ebusy=%ld)\n", ip->i_dev,
+			    (unsigned long long)ip->i_number,
+			    df3250_ins_calls, df3250_ebusy_hits);
 			lwkt_reltoken(&ext2_ihash_token);
 			return (EBUSY);
 		}
--- /home/maxx/dfbsd/dfbsd/sys/vfs/ext2fs/ext2_vfsops.c	2026-06-29 12:51:19.000000000 +0000
+++ ext2_vfsops.c	2026-09-09 12:31:04.799020851 +0000
@@ -40,6 +40,7 @@
 
 #include <sys/param.h>
 #include <sys/systm.h>
+#include <sys/sysctl.h>
 #include <sys/namei.h>
 #include <sys/caps.h>
 #include <sys/proc.h>
@@ -122,6 +123,19 @@
 
 static int ext2fs_inode_hash_lock;
 
+/* DF3250 instrumentation */
+extern long df3250_ins_calls;
+extern long df3250_ebusy_hits;
+long df3250_alloc_calls;
+long df3250_alloc_slept;
+long df3250_alloc_crit;		/* threads inside critical section */
+void df3250_report_ebusy(cdev_t dev, ino_t ino);
+SYSCTL_LONG(_debug, OID_AUTO, df3250_ins, CTLFLAG_RD, &df3250_ins_calls, 0, "");
+SYSCTL_LONG(_debug, OID_AUTO, df3250_ebusy, CTLFLAG_RD, &df3250_ebusy_hits, 0, "");
+SYSCTL_LONG(_debug, OID_AUTO, df3250_alloc, CTLFLAG_RD, &df3250_alloc_calls, 0, "");
+SYSCTL_LONG(_debug, OID_AUTO, df3250_slept, CTLFLAG_RD, &df3250_alloc_slept, 0, "");
+SYSCTL_LONG(_debug, OID_AUTO, df3250_crit, CTLFLAG_RD, &df3250_alloc_crit, 0, "");
+
 /*
  * VFS Operations.
  *
@@ -1272,20 +1286,24 @@
 	 * case getnewvnode() or MALLOC() blocks, otherwise a duplicate
 	 * may occur!
 	 */
+	atomic_add_long(&df3250_alloc_calls, 1);
 	if (ext2fs_inode_hash_lock) {
 		while (ext2fs_inode_hash_lock) {
+			atomic_add_long(&df3250_alloc_slept, 1);
 			ext2fs_inode_hash_lock = -1;
 			tsleep(&ext2fs_inode_hash_lock, 0, "e2vget", 0);
 		}
 		return (-1);
 	}
 	ext2fs_inode_hash_lock = 1;
+	atomic_add_long(&df3250_alloc_crit, 1);
 
 	ip = malloc(sizeof(struct inode), M_EXT2NODE, M_WAITOK | M_ZERO);
 
 	/* Allocate a new vnode/inode. */
 	if ((error = getnewvnode(VT_EXT2FS, mp, &vp, VLKTIMEOUT,
 	    LK_CANRECURSE)) != 0) {
+		atomic_add_long(&df3250_alloc_crit, -1);
 		if (ext2fs_inode_hash_lock < 0)
 			wakeup(&ext2fs_inode_hash_lock);
 		ext2fs_inode_hash_lock = 0;
@@ -1311,6 +1329,7 @@
 	 * contents of the disk portion of this inode to be read.
 	 */
 	if (ext2_ihashins(ip)) {
+		atomic_add_long(&df3250_alloc_crit, -1);
 		printf("ext2_alloc_vnode: ihashins collision, retrying inode %ld\n",
 		    (long)ip->i_number);
 		*vpp = NULL;
@@ -1320,6 +1339,7 @@
 		return (-1);
 	}
 
+	atomic_add_long(&df3250_alloc_crit, -1);
 	if (ext2fs_inode_hash_lock < 0)
 		wakeup(&ext2fs_inode_hash_lock);
 	ext2fs_inode_hash_lock = 0;