Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 8 May 2008 12:02:47 -0400
From:      "Josh Carroll" <josh.carroll@gmail.com>
To:        "Eygene Ryabinkin" <rea-fbsd@codelabs.ru>
Cc:        pluknet <pluknet@gmail.com>, Coleman Kane <cokane@freebsd.org>, freebsd-current@freebsd.org
Subject:   Re: panic mounting ntfs
Message-ID:  <8cb6106e0805080902m6d72d91ft8315db19ca8bb497@mail.gmail.com>
In-Reply-To: <TfxE9AYpsGcM2odJJk%2B2PzF/RR4@tuQFyl9pqXYkbrygWcrojXcyvbA>
References:  <8cb6106e0805062004r681045b5ge2981ae73e777a49@mail.gmail.com> <1210163153.2043.11.camel@localhost> <8cb6106e0805070800m46101f21sa8298b33e82bbfbd@mail.gmail.com> <1210172870.2043.17.camel@localhost> <8cb6106e0805070841p12d95c2k6e76a5ce5d8b512e@mail.gmail.com> <a31046fc0805070821i742a0065i9f938e9964bb144e@mail.gmail.com> <TfxE9AYpsGcM2odJJk%2B2PzF/RR4@tuQFyl9pqXYkbrygWcrojXcyvbA>

next in thread | previous in thread | raw e-mail | index | archive | help

[-- Attachment #1 --]
> I am a bit late, but could you please try the patch from the
>  http://www.freebsd.org/cgi/query-pr.cgi?pr=kern/120483
>
> It was ported from NetBSD and seems like it is a bit more complete
> than the one proposed by pluknet.

It did not patch cleanly against a recently csup'd source tree, but
there was only one hunk that failed, which I manually fixed.

Attached is the updated diff, if pluknet wants to give it a shot. I
just finished building the kernel and it does indeed fix the problem.
I was able to mount the NTFS filesystem here and copy a file off of it
without issue.

Let me know if you'd like me to respond to the PR and attach this
patch there as well.

Thanks!
Josh

[-- Attachment #2 --]
diff -urN /root/ntfs/ntfs_ihash.c ./ntfs_ihash.c
--- /root/ntfs/ntfs_ihash.c	2008-05-08 11:08:10.000000000 -0400
+++ ./ntfs_ihash.c	2008-05-08 11:08:42.000000000 -0400
@@ -40,6 +40,7 @@
 #include <sys/malloc.h>
 #include <sys/mount.h>
 #include <sys/mutex.h>
+#include <sys/condvar.h>
 
 #include <fs/ntfs/ntfs.h>
 #include <fs/ntfs/ntfs_inode.h>
@@ -54,7 +55,7 @@
 static u_long	ntfs_nthash;		/* size of hash table - 1 */
 #define	NTNOHASH(device, inum)	(&ntfs_nthashtbl[(minor(device) + (inum)) & ntfs_nthash])
 static struct mtx ntfs_nthash_mtx;
-struct lock ntfs_hashlock;
+struct mtx ntfs_hashlock_mtx;
 
 /*
  * Initialize inode hash table.
@@ -62,9 +63,9 @@
 void
 ntfs_nthashinit()
 {
-	lockinit(&ntfs_hashlock, PINOD, "ntfs_nthashlock", 0, 0);
-	ntfs_nthashtbl = hashinit(desiredvnodes, M_NTFSNTHASH, &ntfs_nthash);
+	mtx_init(&ntfs_hashlock_mtx, "ntfs hashlock", NULL, MTX_DEF);
 	mtx_init(&ntfs_nthash_mtx, "ntfs nthash", NULL, MTX_DEF);
+	ntfs_nthashtbl = hashinit(desiredvnodes, M_NTFSNTHASH, &ntfs_nthash);
 }
 
 /*
@@ -74,7 +75,7 @@
 ntfs_nthashdestroy(void)
 {
 	hashdestroy(ntfs_nthashtbl, M_NTFSNTHASH, ntfs_nthash);
-	lockdestroy(&ntfs_hashlock);
+	mtx_destroy(&ntfs_hashlock_mtx);
 	mtx_destroy(&ntfs_nthash_mtx);
 }
 
diff -urN /root/ntfs/ntfs_ihash.h ./ntfs_ihash.h
--- /root/ntfs/ntfs_ihash.h	2008-05-08 11:08:10.000000000 -0400
+++ ./ntfs_ihash.h	2008-05-08 11:08:42.000000000 -0400
@@ -28,7 +28,7 @@
  * $FreeBSD: src/sys/fs/ntfs/ntfs_ihash.h,v 1.8 2004/06/16 09:47:04 phk Exp $
  */
 
-extern struct lock ntfs_hashlock;
+extern struct mtx ntfs_hashlock_mtx;
 void ntfs_nthashinit(void);
 void ntfs_nthashdestroy(void);
 struct ntnode   *ntfs_nthashlookup(struct cdev *, ino_t);
diff -urN /root/ntfs/ntfs_inode.h ./ntfs_inode.h
--- /root/ntfs/ntfs_inode.h	2008-05-08 11:08:10.000000000 -0400
+++ ./ntfs_inode.h	2008-05-08 11:08:42.000000000 -0400
@@ -53,9 +53,10 @@
 	u_int32_t       i_flag;
 
 	/* locking */
-	struct lock	i_lock;
+	struct cv	i_lock;
 	struct mtx	i_interlock;
 	int		i_usecount;
+	int		i_busy;
 
 	LIST_HEAD(,fnode)	i_fnlist;
 	LIST_HEAD(,ntvattr)	i_valist;
diff -urN /root/ntfs/ntfs_subr.c ./ntfs_subr.c
--- /root/ntfs/ntfs_subr.c	2008-05-08 11:08:10.000000000 -0400
+++ ./ntfs_subr.c	2008-05-08 11:13:21.000000000 -0400
@@ -32,6 +32,7 @@
 #include <sys/types.h>
 #include <sys/systm.h>
 #include <sys/namei.h>
+#include <sys/proc.h>
 #include <sys/kernel.h>
 #include <sys/vnode.h>
 #include <sys/mount.h>
@@ -41,6 +42,8 @@
 #include <sys/malloc.h>
 #include <sys/lock.h>
 #include <sys/iconv.h>
+#include <sys/condvar.h>
+#include <sys/sx.h>
 
 /* #define NTFS_DEBUG 1 */
 #include <fs/ntfs/ntfs.h>
@@ -65,7 +68,7 @@
  * ntfs mount, freed upon last ntfs umount */
 static wchar *ntfs_toupper_tab;
 #define NTFS_TOUPPER(ch)	(ntfs_toupper_tab[(ch)])
-static struct lock ntfs_toupper_lock;
+static struct sx ntfs_toupper_lock_sx;
 static signed int ntfs_toupper_usecount;
 
 struct iconv_functions *ntfs_iconv = NULL;
@@ -358,7 +361,11 @@
 
 	mtx_lock(&ip->i_interlock);
 	ip->i_usecount++;
-	lockmgr(&ip->i_lock, LK_EXCLUSIVE | LK_INTERLOCK, &ip->i_interlock);
+	while (ip->i_busy != 0) {
+		cv_wait(&ip->i_lock, &ip->i_interlock);
+	}
+	ip->i_busy = 1;
+	mtx_unlock(&ip->i_interlock);
 
 	return 0;
 }
@@ -380,21 +387,29 @@
 
 	dprintf(("ntfs_ntlookup: looking for ntnode %d\n", ino));
 
-	do {
-		ip = ntfs_nthashlookup(ntmp->ntm_devvp->v_rdev, ino);
-		if (ip != NULL) {
-			ntfs_ntget(ip);
-			dprintf(("ntfs_ntlookup: ntnode %d: %p, usecount: %d\n",
-				ino, ip, ip->i_usecount));
-			*ipp = ip;
-			return (0);
-		}
-	} while (lockmgr(&ntfs_hashlock, LK_EXCLUSIVE | LK_SLEEPFAIL, NULL));
+	*ipp = ntfs_nthashlookup(ntmp->ntm_devvp->v_rdev, ino);
+	if (*ipp != NULL) {
+		ntfs_ntget(*ipp);
+		dprintf(("ntfs_ntlookup: ntnode %d: %p, usecount: %d\n",
+			ino, ipp, (*ipp)->i_usecount));
+		return (0);
+	}
 
 	MALLOC(ip, struct ntnode *, sizeof(struct ntnode), M_NTFSNTNODE,
 		M_WAITOK | M_ZERO);
 	ddprintf(("ntfs_ntlookup: allocating ntnode: %d: %p\n", ino, ip));
 
+	mtx_lock(&ntfs_hashlock_mtx);
+	*ipp = ntfs_nthashlookup(ntmp->ntm_devvp->v_rdev, ino);
+	if (*ipp != NULL) {
+		mtx_unlock(&ntfs_hashlock_mtx);
+		ntfs_ntget(*ipp);
+		FREE(ip, M_NTFSNTNODE);
+		dprintf(("ntfs_ntlookup: ntnode %d: %p, usecount: %d\n",
+			ino, ipp, (*ipp)->i_usecount));
+		return (0);
+	}
+
 	/* Generic initialization */
 	ip->i_devvp = ntmp->ntm_devvp;
 	ip->i_dev = ntmp->ntm_devvp->v_rdev;
@@ -405,13 +420,13 @@
 	VREF(ip->i_devvp);
 
 	/* init lock and lock the newborn ntnode */
-	lockinit(&ip->i_lock, PINOD, "ntnode", 0, LK_EXCLUSIVE);
+	cv_init(&ip->i_lock, "ntfslk");
 	mtx_init(&ip->i_interlock, "ntnode interlock", NULL, MTX_DEF);
 	ntfs_ntget(ip);
 
 	ntfs_nthashins(ip);
 
-	lockmgr(&ntfs_hashlock, LK_RELEASE, NULL);
+	mtx_unlock(&ntfs_hashlock_mtx);
 
 	*ipp = ip;
 
@@ -446,27 +461,28 @@
 	}
 #endif
 
-	if (ip->i_usecount > 0) {
-		lockmgr(&ip->i_lock, LK_RELEASE|LK_INTERLOCK, &ip->i_interlock);
-		return;
-	}
-
-	dprintf(("ntfs_ntput: deallocating ntnode: %d\n", ip->i_number));
-
-	if (LIST_FIRST(&ip->i_fnlist))
-		panic("ntfs_ntput: ntnode has fnodes\n");
-
-	ntfs_nthashrem(ip);
-
-	while ((vap = LIST_FIRST(&ip->i_valist)) != NULL) {
-		LIST_REMOVE(vap,va_list);
-		ntfs_freentvattr(vap);
+ 	ip->i_busy = 0;
+ 	cv_signal(&ip->i_lock);
+ 	mtx_unlock(&ip->i_interlock);
+  
+ 	if (ip->i_usecount == 0) {
+ 		dprintf(("ntfs_ntput: deallocating ntnode: %d\n",
+ 			 ip->i_number));
+ 
+ 		if (LIST_FIRST(&ip->i_fnlist))
+ 			panic("ntfs_ntput: ntnode has fnodes\n");
+ 
+ 		ntfs_nthashrem(ip);
+ 
+ 		while ((vap = LIST_FIRST(&ip->i_valist)) != NULL) {
+ 			LIST_REMOVE(vap,va_list);
+ 			ntfs_freentvattr(vap);
+ 		}
+ 		mtx_destroy(&ip->i_interlock);
+ 		cv_destroy(&ip->i_lock);
+ 		vrele(ip->i_devvp);
+ 		FREE(ip, M_NTFSNTNODE);
 	}
-	lockmgr(&ip->i_lock, LK_RELEASE | LK_INTERLOCK, &ip->i_interlock);
-	mtx_destroy(&ip->i_interlock);
-	lockdestroy(&ip->i_lock);
-	vrele(ip->i_devvp);
-	FREE(ip, M_NTFSNTNODE);
 }
 
 /*
@@ -1955,7 +1971,7 @@
 ntfs_toupper_init()
 {
 	ntfs_toupper_tab = (wchar *) NULL;
-	lockinit(&ntfs_toupper_lock, PVFS, "ntfs_toupper", 0, 0);
+	sx_init(&ntfs_toupper_lock_sx, "ntfs toupper lock");
 	ntfs_toupper_usecount = 0;
 }
 
@@ -1963,7 +1979,7 @@
 ntfs_toupper_destroy(void)
 {
 
-	lockdestroy(&ntfs_toupper_lock);
+       sx_destroy(&ntfs_toupper_lock_sx);
 }
 
 /*
@@ -1979,7 +1995,7 @@
 	struct vnode *vp;
 
 	/* get exclusive access */
-	lockmgr(&ntfs_toupper_lock, LK_EXCLUSIVE, NULL);
+	sx_xlock(&ntfs_toupper_lock_sx);
 	
 	/* only read the translation data from a file if it hasn't been
 	 * read already */
@@ -2002,7 +2018,7 @@
 
     out:
 	ntfs_toupper_usecount++;
-	lockmgr(&ntfs_toupper_lock, LK_RELEASE, NULL);
+	sx_xunlock(&ntfs_toupper_lock_sx);
 	return (error);
 }
 
@@ -2014,7 +2030,7 @@
 ntfs_toupper_unuse()
 {
 	/* get exclusive access */
-	lockmgr(&ntfs_toupper_lock, LK_EXCLUSIVE, NULL);
+	sx_xlock(&ntfs_toupper_lock_sx);
 
 	ntfs_toupper_usecount--;
 	if (ntfs_toupper_usecount == 0) {
@@ -2029,7 +2045,7 @@
 #endif
 	
 	/* release the lock */
-	lockmgr(&ntfs_toupper_lock, LK_RELEASE, NULL);
+	sx_xunlock(&ntfs_toupper_lock_sx);
 } 
 
 int
diff -urN /root/ntfs/ntfs_vfsops.c ./ntfs_vfsops.c
--- /root/ntfs/ntfs_vfsops.c	2008-05-08 11:08:10.000000000 -0400
+++ ./ntfs_vfsops.c	2008-05-08 11:08:42.000000000 -0400
@@ -43,6 +43,7 @@
 #include <sys/malloc.h>
 #include <sys/stat.h>
 #include <sys/systm.h>
+#include <sys/condvar.h>
 
 #include <geom/geom.h>
 #include <geom/geom_vfs.h>
diff -urN /root/ntfs/ntfs_vnops.c ./ntfs_vnops.c
--- /root/ntfs/ntfs_vnops.c	2008-05-08 11:08:10.000000000 -0400
+++ ./ntfs_vnops.c	2008-05-08 11:08:42.000000000 -0400
@@ -48,6 +48,7 @@
 #include <sys/bio.h>
 #include <sys/buf.h>
 #include <sys/dirent.h>
+#include <sys/condvar.h>
 
 #include <vm/vm.h>
 #include <vm/vm_param.h>

Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?8cb6106e0805080902m6d72d91ft8315db19ca8bb497>