PERFORCE change 125011 for review

Xin LI delphij at FreeBSD.org
Fri Aug 10 05:32:32 PDT 2007


http://perforce.freebsd.org/chv.cgi?CH=125011

Change 125011 by delphij at charlie on 2007/08/10 12:31:55

	IFC

Affected files ...

.. //depot/projects/delphij_fork/etc/rc.d/nscd#2 integrate
.. //depot/projects/delphij_fork/sbin/fsck_ffs/main.c#2 integrate
.. //depot/projects/delphij_fork/share/man/man4/ddb.4#2 integrate
.. //depot/projects/delphij_fork/share/man/man9/locking.9#2 integrate
.. //depot/projects/delphij_fork/sys/dev/wi/if_wi.c#3 integrate
.. //depot/projects/delphij_fork/sys/fs/tmpfs/tmpfs.h#5 integrate
.. //depot/projects/delphij_fork/sys/fs/tmpfs/tmpfs_subr.c#5 integrate
.. //depot/projects/delphij_fork/sys/fs/tmpfs/tmpfs_vfsops.c#6 integrate
.. //depot/projects/delphij_fork/sys/fs/tmpfs/tmpfs_vnops.c#4 integrate
.. //depot/projects/delphij_fork/sys/i386/i386/machdep.c#2 integrate
.. //depot/projects/delphij_fork/sys/i386/include/cpufunc.h#2 integrate
.. //depot/projects/delphij_fork/tools/regression/tmpfs/h_tools.c#2 integrate
.. //depot/projects/delphij_fork/tools/regression/tmpfs/t_mount#2 integrate
.. //depot/projects/delphij_fork/tools/regression/tmpfs/t_rename#2 integrate
.. //depot/projects/delphij_fork/usr.sbin/nscd/Makefile#2 integrate
.. //depot/projects/delphij_fork/usr.sbin/nscd/agent.h#2 integrate
.. //depot/projects/delphij_fork/usr.sbin/nscd/cachelib.h#2 integrate
.. //depot/projects/delphij_fork/usr.sbin/nscd/cacheplcs.h#2 integrate
.. //depot/projects/delphij_fork/usr.sbin/nscd/config.h#2 integrate
.. //depot/projects/delphij_fork/usr.sbin/nscd/debug.h#2 integrate
.. //depot/projects/delphij_fork/usr.sbin/nscd/log.c#2 integrate
.. //depot/projects/delphij_fork/usr.sbin/nscd/log.h#2 integrate
.. //depot/projects/delphij_fork/usr.sbin/nscd/mp_rs_query.c#2 integrate
.. //depot/projects/delphij_fork/usr.sbin/nscd/mp_rs_query.h#2 integrate
.. //depot/projects/delphij_fork/usr.sbin/nscd/mp_ws_query.c#2 integrate
.. //depot/projects/delphij_fork/usr.sbin/nscd/mp_ws_query.h#2 integrate
.. //depot/projects/delphij_fork/usr.sbin/nscd/nscd.8#2 integrate
.. //depot/projects/delphij_fork/usr.sbin/nscd/nscd.c#2 integrate
.. //depot/projects/delphij_fork/usr.sbin/nscd/nscd.conf.5#2 integrate
.. //depot/projects/delphij_fork/usr.sbin/nscd/nscdcli.c#2 integrate
.. //depot/projects/delphij_fork/usr.sbin/nscd/nscdcli.h#2 integrate
.. //depot/projects/delphij_fork/usr.sbin/nscd/parser.h#2 integrate
.. //depot/projects/delphij_fork/usr.sbin/nscd/protocol.h#2 integrate
.. //depot/projects/delphij_fork/usr.sbin/nscd/query.c#2 integrate
.. //depot/projects/delphij_fork/usr.sbin/nscd/query.h#2 integrate
.. //depot/projects/delphij_fork/usr.sbin/nscd/singletons.h#2 integrate

Differences ...

==== //depot/projects/delphij_fork/etc/rc.d/nscd#2 (text+ko) ====

@@ -1,32 +1,32 @@
 #!/bin/sh
 #
-# $FreeBSD: src/etc/rc.d/nscd,v 1.3 2006/06/06 15:34:50 ume Exp $
+# $FreeBSD: src/etc/rc.d/nscd,v 1.4 2007/08/09 13:06:11 bushman Exp $
 #
 
-# PROVIDE: cached
+# PROVIDE: nscd
 # REQUIRE: DAEMON
 # BEFORE: LOGIN
 
 #
 # Add the following lines to /etc/rc.conf to enable cached:
 #
-# cached_enable="YES"
+# nscd_enable="YES"
 #
-# See cached(8) for flags
+# See nscd(8) for flags
 #
 
 . /etc/rc.subr
 
-name=cached
+name=nscd
 rcvar=`set_rcvar`
 
-command=/usr/sbin/cached
+command=/usr/sbin/nscd
 extra_commands="flush"
 flush_cmd="${command} -I all"
 
-cached_enable=${cached_enable:-"NO"}
-cached_pidfile=${cached_pidfile:-"/var/run/cached.pid"}
-cached_flags=${cached_flags:-""}
+nscd_enable=${nscd_enable:-"NO"}
+nscd_pidfile=${nscd_pidfile:-"/var/run/nscd.pid"}
+nscd_flags=${nscd_flags:-""}
 
 load_rc_config $name
 run_rc_command "$1"

==== //depot/projects/delphij_fork/sbin/fsck_ffs/main.c#2 (text+ko) ====

@@ -39,7 +39,7 @@
 #endif /* not lint */
 #endif
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sbin/fsck_ffs/main.c,v 1.45 2006/10/31 22:06:56 pjd Exp $");
+__FBSDID("$FreeBSD: src/sbin/fsck_ffs/main.c,v 1.46 2007/08/10 06:29:54 pjd Exp $");
 
 #include <sys/param.h>
 #include <sys/stat.h>
@@ -67,6 +67,7 @@
 static void usage(void) __dead2;
 static int argtoi(int flag, const char *req, const char *str, int base);
 static int checkfilesys(char *filesys);
+static int chkdoreload(struct statfs *mntp);
 static struct statfs *getmntpt(const char *);
 
 int
@@ -197,7 +198,7 @@
 	struct stat snapdir;
 	struct group *grp;
 	ufs2_daddr_t blks;
-	int cylno, ret;
+	int cylno;
 	ino_t files;
 	size_t size;
 
@@ -253,7 +254,9 @@
 			}
 			if ((sblock.fs_flags & (FS_UNCLEAN | FS_NEEDSFSCK)) == 0) {
 				gjournal_check(filesys);
-				exit(0);
+				if (chkdoreload(mntp) == 0)
+					exit(0);
+				exit(4);
 			} else {
 				pfatal("UNEXPECTED INCONSISTENCY, %s\n",
 				    "CANNOT RUN FAST FSCK\n");
@@ -483,23 +486,7 @@
 		printf("\n***** FILE SYSTEM WAS MODIFIED *****\n");
 	if (rerun)
 		printf("\n***** PLEASE RERUN FSCK *****\n");
-	if (mntp != NULL) {
-		/*
-		 * We modified a mounted file system.  Do a mount update on
-		 * it unless it is read-write, so we can continue using it
-		 * as safely as possible.
-		 */
-		if (mntp->f_flags & MNT_RDONLY) {
-			args.fspec = 0;
-			args.export.ex_flags = 0;
-			args.export.ex_root = 0;
-			ret = mount("ufs", mntp->f_mntonname,
-			    mntp->f_flags | MNT_UPDATE | MNT_RELOAD, &args);
-			if (ret == 0)
-				return (0);
-			pwarn("mount reload of '%s' failed: %s\n\n",
-			    mntp->f_mntonname, strerror(errno));
-		}
+	if (chkdoreload(mntp) != 0) {
 		if (!fsmodified)
 			return (0);
 		if (!preen)
@@ -510,6 +497,36 @@
 	return (0);
 }
 
+static int
+chkdoreload(struct statfs *mntp)
+{
+	struct ufs_args args;
+
+	if (mntp == NULL)
+		return (0);
+	/*
+	 * We modified a mounted file system.  Do a mount update on
+	 * it unless it is read-write, so we can continue using it
+	 * as safely as possible.
+	 */
+	if (mntp->f_flags & MNT_RDONLY) {
+		memset(&args, 0, sizeof args);
+		/*
+		 * args.fspec = 0;
+		 * args.export.ex_flags = 0;
+		 * args.export.ex_root = 0;
+		 */
+		if (mount("ufs", mntp->f_mntonname,
+		    mntp->f_flags | MNT_UPDATE | MNT_RELOAD, &args) == 0) {
+			return (0);
+		}
+		pwarn("mount reload of '%s' failed: %s\n\n",
+		    mntp->f_mntonname, strerror(errno));
+		return (1);
+	}
+	return (0);
+}
+
 /*
  * Get the mount point information for name.
  */

==== //depot/projects/delphij_fork/share/man/man4/ddb.4#2 (text+ko) ====

@@ -57,9 +57,9 @@
 .\" 	Created.
 .\" 	[90/08/30            dbg]
 .\"
-.\" $FreeBSD: src/share/man/man4/ddb.4,v 1.41 2006/10/30 12:55:06 ru Exp $
+.\" $FreeBSD: src/share/man/man4/ddb.4,v 1.42 2007/08/09 20:14:35 njl Exp $
 .\"
-.Dd October 27, 2006
+.Dd August 6, 2007
 .Dt DDB 4
 .Os
 .Sh NAME
@@ -522,6 +522,12 @@
 modifier depends on the machine.
 If not supported, incorrect information will be displayed.
 .Pp
+.It Ic show Cm sysregs
+Show system registers (e.g.,
+.Li cr0-4
+on i386.)
+Not present on some platforms.
+.Pp
 .It Ic show Cm geom Op Ar addr
 If the
 .Ar addr

==== //depot/projects/delphij_fork/share/man/man9/locking.9#2 (text+ko) ====

@@ -22,7 +22,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD: src/share/man/man9/locking.9,v 1.10 2007/06/21 16:39:25 brueffer Exp $
+.\" $FreeBSD: src/share/man/man9/locking.9,v 1.11 2007/08/09 21:09:56 julian Exp $
 .\"
 .Dd March 14, 2007
 .Dt LOCKING 9
@@ -67,7 +67,8 @@
 .El
 .Pp
 The primitives interact and have a number of rules regarding how
-they can and can not be combined. There are too many for the average
+they can and can not be combined.
+There are too many for the average
 human mind and they keep changing.
 (if you disagree, please write replacement text)  :-)
 .Pp
@@ -85,63 +86,70 @@
 If you don't own it then you just spin, waiting for the holder (on
 another CPU) to release it.
 Hopefully they are doing something fast.
-You can not do anything that deschedules the thread while you
+You 
+.Em must not
+do anything that deschedules the thread while you
 are holding a SPIN mutex.
-.Ss Sleep Mutexes
-Basically sleep (regular) mutexes will deschedule the thread if the
+.Ss Mutexes
+Basically (regular) mutexes will deschedule the thread if the
 mutex can not be acquired.
+A non-spin mutex can be considered to be equivalent
+to getting a write lock on an 
+.Em rw_lock
+(see below), and in fact non-spin mutexes and rw_locks may soon become the same thing.
 As in spin mutexes, you either get it or you don't.
-You may call the
+You may only call the
 .Xr sleep 9
-call
+call via
 .Fn msleep
 or the new
 .Fn mtx_sleep
-variant. These will atomically drop the mutex and reacquire it
+variant.
+These will atomically drop the mutex and reacquire it
 as part of waking up.
+This is often however a
+.Em BAD
+idea because it generally relies on you having
+such a good knowledge of all the call graph above you
+and what assumptions it is making that there are a lot
+of ways to make hard-to-find mistakes.
+For example you MUST re-test all the assumptions you made before,
+all the way up the call graph to where you got the lock.
+You can not just assume that mtx_sleep can be inserted anywhere.
+If any caller above you has any mutex or
+rwlock, your sleep, will cause a panic.
+If the sleep only happens rarely it may be years before the 
+bad code path is found.
 .Ss Pool Mutexes
-A variant of SLEEP mutexes where the allocation of the mutex is handled
+A variant of regular mutexes where the allocation of the mutex is handled
 more by the system.
-.Ss Sx_locks
-Shared/exclusive locks are used to protect data that are read far more often
-than they are written.
-Mutexes are inherently more efficient than shared/exclusive locks, so
-shared/exclusive locks should be used prudently.
-A thread may hold a shared or exclusive lock on an
-.Em sx_lock
-lock while sleeping.
-As a result, an
-.Em sx_lock
-lock may not be acquired while holding a mutex.
-Otherwise, if one thread slept while holding an
-.Em sx_lock
-lock while another thread blocked on the same
-.Em sx_lock
-lock after acquiring a mutex, then the second thread would effectively
-end up sleeping while holding a mutex, which is not allowed.
 .Ss Rw_locks
 Reader/writer locks allow shared access to protected data by multiple threads,
 or exclusive access by a single thread.
 The threads with shared access are known as
 .Em readers
-since they only read the protected data.
+since they should only read the protected data.
 A thread with exclusive access is known as a
 .Em writer
-since it can modify protected data.
+since it may modify protected data.
 .Pp
 Although reader/writer locks look very similar to
 .Xr sx 9
-locks, their usage pattern is different.
-Reader/writer locks can be treated as mutexes (see
+(see below) locks, their usage pattern is different.
+Reader/writer locks can be treated as mutexes (see above and
 .Xr mutex 9 )
 with shared/exclusive semantics.
-Unlike
-.Xr sx 9 ,
-an
+More specifically, regular mutexes can be 
+considered to be equivalent to a write-lock on an
+.Em rw_lock.
+In the future this may in fact
+become literally the fact.
+An
 .Em rw_lock
-can be locked while holding a non-spin mutex, and an
-.Em rw_lock
-cannot be held while sleeping.
+can be locked while holding a regular mutex, but 
+can
+.Em not
+be held while sleeping.
 The
 .Em rw_lock
 locks have priority propagation like mutexes, but priority
@@ -150,8 +158,36 @@
 are anonymous.
 Another important property is that shared holders of
 .Em rw_lock
-can recurse,
-but exclusive locks are not allowed to recurse.
+can recurse, but exclusive locks are not allowed to recurse.
+This ability should not be used lightly and 
+.Em may go away.
+Users of recursion in any locks should be prepared to 
+defend their decision against vigorous criticism.
+.Ss Sx_locks
+Shared/exclusive locks are used to protect data that are read far more often
+than they are written.
+Mutexes are inherently more efficient than shared/exclusive locks, so
+shared/exclusive locks should be used prudently.
+The main reason for using an
+.Em sx_lock
+is that a thread may hold a shared or exclusive lock on an
+.Em sx_lock
+lock while sleeping.
+As a consequence of this however, an
+.Em sx_lock
+lock may not be acquired while holding a mutex.
+The reason for this is that, if one thread slept while holding an
+.Em sx_lock
+lock while another thread blocked on the same
+.Em sx_lock
+lock after acquiring a mutex, then the second thread would effectively
+end up sleeping while holding a mutex, which is not allowed.
+The
+.Em sx_lock
+should be considered to be closely related to
+.Xr sleep 9 .
+In fact it could in some cases be 
+considered a conditional sleep.
 .Ss Turnstiles
 Turnstiles are used to hold a queue of threads blocked on
 non-sleepable locks.
@@ -160,6 +196,7 @@
 are assigned to a lock held by an owning thread.
 Thus, when one thread is enqueued onto a turnstile, it can lend its
 priority to the owning thread.
+If this sounds confusing, we need to describe it better.
 .Ss Semaphores
 .Ss Condition variables
 Condition variables are used in conjunction with mutexes to wait for
@@ -182,7 +219,7 @@
 .It
 You can sleep while it has recursed, but other recursive locks cannot.
 .It
-Giant must be locked first.
+Giant must be locked first before other locks.
 .It
 There are places in the kernel that drop Giant and pick it back up
 again.
@@ -249,7 +286,8 @@
 mutex before the function returns.
 .Pp
 .Ss lockmanager locks
-Largely deprecated. See the
+Largely deprecated.
+See the
 .Xr lock 9
 page for more information.
 I don't know what the downsides are but I'm sure someone will fill in this part.
@@ -269,10 +307,12 @@
 .El
 .Pp
 .Em *1
-Recursion is defined per lock. Lock order is important.
+Recursion is defined per lock.
+Lock order is important.
 .Pp
 .Em *2
-readers can recurse though writers can not. Lock order is important.
+readers can recurse though writers can not.
+Lock order is important.
 .Pp
 .Em *3
 There are calls atomically release this primitive when going to sleep
@@ -302,6 +342,7 @@
 .Xr condvar 9 ,
 .Xr lock 9 ,
 .Xr mtx_pool 9 ,
+.Xr mutex 9 ,
 .Xr rwlock 9 ,
 .Xr sema 9 ,
 .Xr sleep 9 ,

==== //depot/projects/delphij_fork/sys/dev/wi/if_wi.c#3 (text+ko) ====

@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/wi/if_wi.c,v 1.211 2007/07/11 21:25:48 thompsa Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/wi/if_wi.c,v 1.212 2007/08/09 13:29:26 avatar Exp $");
 
 #define WI_HERMES_AUTOINC_WAR	/* Work around data write autoinc bug. */
 #define WI_HERMES_STATS_WAR	/* Work around stats counter bug. */
@@ -267,12 +267,12 @@
 	int error;
 
 	ifp = sc->sc_ifp = if_alloc(IFT_ETHER);
-	ifp->if_softc = sc;
 	if (ifp == NULL) {
 		device_printf(dev, "can not if_alloc\n");
 		wi_free(dev);
 		return (ENOSPC);
 	}
+	ifp->if_softc = sc;
 
 	/*
 	 * NB: no locking is needed here; don't put it here

==== //depot/projects/delphij_fork/sys/fs/tmpfs/tmpfs.h#5 (text+ko) ====

@@ -1,7 +1,7 @@
-/*	$NetBSD: tmpfs.h,v 1.18 2006/03/31 20:27:49 riz Exp $	*/
+/*	$NetBSD: tmpfs.h,v 1.26 2007/02/22 06:37:00 thorpej Exp $	*/
 
 /*
- * Copyright (c) 2005 The NetBSD Foundation, Inc.
+ * Copyright (c) 2005, 2006 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -36,7 +36,7 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/fs/tmpfs/tmpfs.h,v 1.9 2007/08/03 06:24:31 delphij Exp $
+ * $FreeBSD: src/sys/fs/tmpfs/tmpfs.h,v 1.11 2007/08/10 11:00:30 delphij Exp $
  */
 
 #ifndef _FS_TMPFS_TMPFS_H_
@@ -97,11 +97,74 @@
  * importantly, to remove redundancy. */
 TAILQ_HEAD(tmpfs_dir, tmpfs_dirent);
 
-#define	TMPFS_DIRCOOKIE(dirent)	((off_t)(uintptr_t)(dirent))
+/* Each entry in a directory has a cookie that identifies it.  Cookies
+ * supersede offsets within directories because, given how tmpfs stores
+ * directories in memory, there is no such thing as an offset.  (Emulating
+ * a real offset could be very difficult.)
+ * 
+ * The '.', '..' and the end of directory markers have fixed cookies which
+ * cannot collide with the cookies generated by other entries.  The cookies
+ * fot the other entries are generated based on the memory address on which
+ * stores their information is stored.
+ *
+ * Ideally, using the entry's memory pointer as the cookie would be enough
+ * to represent it and it wouldn't cause collisions in any system.
+ * Unfortunately, this results in "offsets" with very large values which
+ * later raise problems in the Linux compatibility layer (and maybe in other
+ * places) as described in PR kern/32034.  Hence we need to workaround this
+ * with a rather ugly hack.
+ *
+ * Linux 32-bit binaries, unless built with _FILE_OFFSET_BITS=64, have off_t
+ * set to 'long', which is a 32-bit *signed* long integer.  Regardless of
+ * the macro value, GLIBC (2.3 at least) always uses the getdents64
+ * system call (when calling readdir) which internally returns off64_t
+ * offsets.  In order to make 32-bit binaries work, *GLIBC* converts the
+ * 64-bit values returned by the kernel to 32-bit ones and aborts with
+ * EOVERFLOW if the conversion results in values that won't fit in 32-bit
+ * integers (which it assumes is because the directory is extremely large).
+ * This wouldn't cause problems if we were dealing with unsigned integers,
+ * but as we have signed integers, this check fails due to sign expansion.
+ *
+ * For example, consider that the kernel returns the 0xc1234567 cookie to
+ * userspace in a off64_t integer.  Later on, GLIBC casts this value to
+ * off_t (remember, signed) with code similar to:
+ *     system call returns the offset in kernel_value;
+ *     off_t casted_value = kernel_value;
+ *     if (sizeof(off_t) != sizeof(off64_t) &&
+ *         kernel_value != casted_value)
+ *             error!
+ * In this case, casted_value still has 0xc1234567, but when it is compared
+ * for equality against kernel_value, it is promoted to a 64-bit integer and
+ * becomes 0xffffffffc1234567, which is different than 0x00000000c1234567.
+ * Then, GLIBC assumes this is because the directory is very large.
+ *
+ * Given that all the above happens in user-space, we have no control over
+ * it; therefore we must workaround the issue here.  We do this by
+ * truncating the pointer value to a 32-bit integer and hope that there
+ * won't be collisions.  In fact, this will not cause any problems in
+ * 32-bit platforms but some might arise in 64-bit machines (I'm not sure
+ * if they can happen at all in practice).
+ *
+ * XXX A nicer solution shall be attempted. */
+#ifdef _KERNEL
 #define	TMPFS_DIRCOOKIE_DOT	0
 #define	TMPFS_DIRCOOKIE_DOTDOT	1
 #define	TMPFS_DIRCOOKIE_EOF	2
+static __inline
+off_t
+tmpfs_dircookie(struct tmpfs_dirent *de)
+{
+	off_t cookie;
+
+	cookie = ((off_t)(uintptr_t)de >> 1) & 0x7FFFFFFF;
+	MPASS(cookie != TMPFS_DIRCOOKIE_DOT);
+	MPASS(cookie != TMPFS_DIRCOOKIE_DOTDOT);
+	MPASS(cookie != TMPFS_DIRCOOKIE_EOF);
 
+	return cookie;
+}
+#endif
+
 /* --------------------------------------------------------------------- */
 
 /*
@@ -353,8 +416,8 @@
 	    const char *, uint16_t, struct tmpfs_dirent **);
 void	tmpfs_free_dirent(struct tmpfs_mount *, struct tmpfs_dirent *,
 	    boolean_t);
-int	tmpfs_alloc_vp(struct mount *, struct tmpfs_node *, struct vnode **,
-	    struct thread *td);
+int	tmpfs_alloc_vp(struct mount *, struct tmpfs_node *, int,
+	    struct vnode **, struct thread *);
 void	tmpfs_free_vp(struct vnode *);
 int	tmpfs_alloc_file(struct vnode *, struct vnode **, struct vattr *,
 	    struct componentname *, char *);
@@ -408,7 +471,7 @@
     MPASS((node)->tn_type == VDIR); \
     MPASS((node)->tn_size % sizeof(struct tmpfs_dirent) == 0); \
     MPASS((node)->tn_dir.tn_readdir_lastp == NULL || \
-	TMPFS_DIRCOOKIE((node)->tn_dir.tn_readdir_lastp) == (node)->tn_dir.tn_readdir_lastn);
+	tmpfs_dircookie((node)->tn_dir.tn_readdir_lastp) == (node)->tn_dir.tn_readdir_lastn);
 
 /* --------------------------------------------------------------------- */
 

==== //depot/projects/delphij_fork/sys/fs/tmpfs/tmpfs_subr.c#5 (text+ko) ====

@@ -1,4 +1,4 @@
-/*	$NetBSD: tmpfs_subr.c,v 1.21 2006/06/07 22:33:39 kardel Exp $	*/
+/*	$NetBSD: tmpfs_subr.c,v 1.35 2007/07/09 21:10:50 ad Exp $	*/
 
 /*
  * Copyright (c) 2005 The NetBSD Foundation, Inc.
@@ -41,7 +41,7 @@
  * Efficient memory file system supporting functions.
  */
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/fs/tmpfs/tmpfs_subr.c,v 1.10 2007/08/03 06:24:31 delphij Exp $");
+__FBSDID("$FreeBSD: src/sys/fs/tmpfs/tmpfs_subr.c,v 1.12 2007/08/10 11:00:30 delphij Exp $");
 
 #include <sys/param.h>
 #include <sys/namei.h>
@@ -188,6 +188,12 @@
 {
 	size_t pages = 0;
 
+#ifdef INVARIANTS
+	TMPFS_NODE_LOCK(node);
+	MPASS(node->tn_vnode == NULL);
+	TMPFS_NODE_UNLOCK(node);
+#endif
+
 	TMPFS_LOCK(tmp);
 	LIST_REMOVE(node, tn_entries);
 	tmp->tm_nodes_inuse--;
@@ -302,17 +308,20 @@
  * Returns zero on success or an appropriate error code on failure.
  */
 int
-tmpfs_alloc_vp(struct mount *mp, struct tmpfs_node *node, struct vnode **vpp,
-    struct thread *td)
+tmpfs_alloc_vp(struct mount *mp, struct tmpfs_node *node, int lkflag,
+    struct vnode **vpp, struct thread *td)
 {
-	int error;
+	int error = 0;
 	struct vnode *vp;
 
 loop:
+	TMPFS_NODE_LOCK(node);
 	if ((vp = node->tn_vnode) != NULL) {
-		error = vget(vp, LK_EXCLUSIVE | LK_RETRY, td);
-		if (error)
-			return error;
+		VI_LOCK(vp);
+		TMPFS_NODE_UNLOCK(node);
+		vholdl(vp);
+		(void) vget(vp, lkflag | LK_INTERLOCK | LK_RETRY, td);
+		vdrop(vp);
 
 		/*
 		 * Make sure the vnode is still there after
@@ -330,12 +339,11 @@
 	 * otherwise lock the vp list while we call getnewvnode
 	 * since that can block.
 	 */
-	TMPFS_NODE_LOCK(node);
 	if (node->tn_vpstate & TMPFS_VNODE_ALLOCATING) {
 		node->tn_vpstate |= TMPFS_VNODE_WANT;
 		error = msleep((caddr_t) &node->tn_vpstate,
 		    TMPFS_NODE_MTX(node), PDROP | PCATCH,
-		    "tmpfs_vplock", 0);
+		    "tmpfs_alloc_vp", 0);
 		if (error)
 			return error;
 
@@ -351,13 +359,7 @@
 		goto unlock;
 	MPASS(vp != NULL);
 
-	error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
-	if (error != 0) {
-		vp->v_data = NULL;
-		vput(vp);
-		vp = NULL;
-		goto unlock;
-	}
+	(void) vn_lock(vp, lkflag | LK_RETRY, td);
 
 	vp->v_data = node;
 	vp->v_type = node->tn_type;
@@ -386,23 +388,15 @@
 
 	vnode_pager_setsize(vp, node->tn_size);
 	error = insmntque(vp, mp);
-	if (error) {
-		node->tn_vnode = NULL;
-		TMPFS_NODE_LOCK(node);
-		if (node->tn_vpstate & TMPFS_VNODE_WANT) {
-			node->tn_vpstate &= ~TMPFS_VNODE_WANT;
-			TMPFS_NODE_UNLOCK(node);
-			wakeup((caddr_t) &node->tn_vpstate);
-		} else
-			TMPFS_NODE_UNLOCK(node);
-		return error;
-	}
-	node->tn_vnode = vp;
+	if (error)
+		vp = NULL;
 
 unlock:
 	TMPFS_NODE_LOCK(node);
+
 	MPASS(node->tn_vpstate & TMPFS_VNODE_ALLOCATING);
 	node->tn_vpstate &= ~TMPFS_VNODE_ALLOCATING;
+	node->tn_vnode = vp;
 
 	if (node->tn_vpstate & TMPFS_VNODE_WANT) {
 		node->tn_vpstate &= ~TMPFS_VNODE_WANT;
@@ -415,7 +409,11 @@
 	*vpp = vp;
 
 	MPASS(IFF(error == 0, *vpp != NULL && VOP_ISLOCKED(*vpp, td)));
+#ifdef INVARIANTS
+	TMPFS_NODE_LOCK(node);
 	MPASS(*vpp == node->tn_vnode);
+	TMPFS_NODE_UNLOCK(node);
+#endif
 
 	return error;
 }
@@ -433,8 +431,10 @@
 
 	node = VP_TO_TMPFS_NODE(vp);
 
+	TMPFS_NODE_LOCK(node);
 	node->tn_vnode = NULL;
 	vp->v_data = NULL;
+	TMPFS_NODE_UNLOCK(node);
 }
 
 /* --------------------------------------------------------------------- */
@@ -499,7 +499,8 @@
 	}
 
 	/* Allocate a vnode for the new file. */
-	error = tmpfs_alloc_vp(dvp->v_mount, node, vpp, cnp->cn_thread);
+	error = tmpfs_alloc_vp(dvp->v_mount, node, LK_EXCLUSIVE, vpp,
+	    cnp->cn_thread);
 	if (error != 0) {
 		tmpfs_free_dirent(tmp, de, TRUE);
 		tmpfs_free_node(tmp, node);
@@ -672,7 +673,7 @@
 			if (de == NULL)
 				uio->uio_offset = TMPFS_DIRCOOKIE_EOF;
 			else
-				uio->uio_offset = TMPFS_DIRCOOKIE(de);
+				uio->uio_offset = tmpfs_dircookie(de);
 		}
 	}
 
@@ -697,7 +698,7 @@
 	}
 
 	TAILQ_FOREACH(de, &node->tn_dir.tn_dirhead, td_entries) {
-		if (TMPFS_DIRCOOKIE(de) == cookie) {
+		if (tmpfs_dircookie(de) == cookie) {
 			break;
 		}
 	}
@@ -805,7 +806,7 @@
 		node->tn_dir.tn_readdir_lastn = 0;
 		node->tn_dir.tn_readdir_lastp = NULL;
 	} else {
-		node->tn_dir.tn_readdir_lastn = uio->uio_offset = TMPFS_DIRCOOKIE(de);
+		node->tn_dir.tn_readdir_lastn = uio->uio_offset = tmpfs_dircookie(de);
 		node->tn_dir.tn_readdir_lastp = de;
 	}
 

==== //depot/projects/delphij_fork/sys/fs/tmpfs/tmpfs_vfsops.c#6 (text+ko) ====

@@ -48,7 +48,7 @@
  * allocate and release resources.
  */
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/fs/tmpfs/tmpfs_vfsops.c,v 1.8 2007/07/24 17:14:53 delphij Exp $");
+__FBSDID("$FreeBSD: src/sys/fs/tmpfs/tmpfs_vfsops.c,v 1.9 2007/08/10 05:24:49 delphij Exp $");
 
 #include <sys/param.h>
 #include <sys/limits.h>
@@ -390,7 +390,7 @@
 tmpfs_root(struct mount *mp, int flags, struct vnode **vpp, struct thread *td)
 {
 	int error;
-	error = tmpfs_alloc_vp(mp, VFS_TO_TMPFS(mp)->tm_root, vpp, td);
+	error = tmpfs_alloc_vp(mp, VFS_TO_TMPFS(mp)->tm_root, flags, vpp, td);
 
 	if (!error)
 		(*vpp)->v_vflag |= VV_ROOT;
@@ -429,7 +429,10 @@
 	}
 	TMPFS_UNLOCK(tmp);
 
-	return found ? tmpfs_alloc_vp(mp, node, vpp, curthread) : EINVAL;
+	if (found)
+		return (tmpfs_alloc_vp(mp, node, LK_EXCLUSIVE, vpp, curthread));
+
+	return (EINVAL);
 }
 
 /* --------------------------------------------------------------------- */

==== //depot/projects/delphij_fork/sys/fs/tmpfs/tmpfs_vnops.c#4 (text+ko) ====

@@ -1,7 +1,7 @@
-/*	$NetBSD: tmpfs_vnops.c,v 1.35 2007/01/04 15:42:37 elad Exp $	*/
+/*	$NetBSD: tmpfs_vnops.c,v 1.39 2007/07/23 15:41:01 jmmv Exp $	*/
 
 /*
- * Copyright (c) 2005 The NetBSD Foundation, Inc.
+ * Copyright (c) 2005, 2006 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -41,7 +41,7 @@
  * tmpfs vnode interface.
  */
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/fs/tmpfs/tmpfs_vnops.c,v 1.8 2007/07/19 03:34:50 delphij Exp $");
+__FBSDID("$FreeBSD: src/sys/fs/tmpfs/tmpfs_vnops.c,v 1.10 2007/08/10 11:00:30 delphij Exp $");
 
 #include <sys/param.h>
 #include <sys/fcntl.h>
@@ -95,12 +95,17 @@
 	    !(cnp->cn_flags & ISDOTDOT)));
 
 	if (cnp->cn_flags & ISDOTDOT) {
+		int ltype = 0;
+
+		ltype = VOP_ISLOCKED(dvp, td);
+		vhold(dvp);
 		VOP_UNLOCK(dvp, 0, td);
-
 		/* Allocate a new vnode on the matching entry. */
-		error = tmpfs_alloc_vp(dvp->v_mount, dnode->tn_dir.tn_parent, vpp, td);
+		error = tmpfs_alloc_vp(dvp->v_mount, dnode->tn_dir.tn_parent,
+		    cnp->cn_lkflags, vpp, td);
 
-		vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, td);
+		vn_lock(dvp, ltype | LK_RETRY, td);
+		vdrop(dvp);
 
 		dnode->tn_dir.tn_parent->tn_lookup_dirent = NULL;
 	} else if (cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.') {
@@ -160,7 +165,8 @@
 					goto out;
 
 				/* Allocate a new vnode on the matching entry. */
-				error = tmpfs_alloc_vp(dvp->v_mount, tnode, vpp, td);
+				error = tmpfs_alloc_vp(dvp->v_mount, tnode,
+						cnp->cn_lkflags, vpp, td);
 				if (error != 0)
 					goto out;
 
@@ -174,10 +180,10 @@
 				}
 				tnode->tn_lookup_dirent = de;
 				cnp->cn_flags |= SAVENAME;
+			} else {
+				error = tmpfs_alloc_vp(dvp->v_mount, tnode,
+						cnp->cn_lkflags, vpp, td);
 			}
-			else
-				error = tmpfs_alloc_vp(dvp->v_mount, tnode, vpp, td);
-
 		}
 	}
 
@@ -478,7 +484,7 @@
 		vm_page_wakeup(m);
 		VM_OBJECT_UNLOCK(vobj);
 		return	(error);
-	} 
+	}
 	VM_OBJECT_UNLOCK(vobj);
 nocache:
 	VM_OBJECT_LOCK(tobj);
@@ -886,13 +892,13 @@
 	struct vnode *tdvp = v->a_tdvp;
 	struct vnode *tvp = v->a_tvp;
 	struct componentname *tcnp = v->a_tcnp;
-	struct tmpfs_node *tnode = 0; /* pacify gcc */
 
 	char *newname;
 	int error;
 	struct tmpfs_dirent *de;
 	struct tmpfs_node *fdnode;
 	struct tmpfs_node *fnode;
+	struct tmpfs_node *tnode;
 	struct tmpfs_node *tdnode;
 
 	MPASS(VOP_ISLOCKED(tdvp, tcnp->cn_thread));
@@ -902,6 +908,7 @@
 
 	fdnode = VP_TO_TMPFS_DIR(fdvp);
 	fnode = VP_TO_TMPFS_NODE(fvp);
+  	tnode = (tvp == NULL) ? NULL : VP_TO_TMPFS_NODE(tvp);
 	de = fnode->tn_lookup_dirent;
 
 	/* Disallow cross-device renames.
@@ -934,7 +941,7 @@
 	 * Kern_rename gurantees the destination to be a directory
 	 * if the source is one. */
 	if (tvp != NULL) {
-		tnode = VP_TO_TMPFS_NODE(tvp);
+		MPASS(tnode != NULL);
 
 		if ((tnode->tn_flags & (NOUNLINK | IMMUTABLE | APPEND)) ||
 		    (tdnode->tn_flags & (APPEND | IMMUTABLE))) {
@@ -942,9 +949,20 @@
 			goto out;
 		}
 
-		if ((de->td_node->tn_type == VDIR) && (tnode->tn_size > 0)) {
-			error = ENOTEMPTY;
+		if (fnode->tn_type == VDIR && tnode->tn_type == VDIR) {
+			if (tnode->tn_size > 0) {
+				error = ENOTEMPTY;
+				goto out;
+			}
+		} else if (fnode->tn_type == VDIR && tnode->tn_type != VDIR) {
+			error = ENOTDIR;
+			goto out;
+		} else if (fnode->tn_type != VDIR && tnode->tn_type == VDIR) {
+			error = EISDIR;
 			goto out;
+		} else {
+			MPASS(fnode->tn_type != VDIR &&
+				tnode->tn_type != VDIR);
 		}
 	}
 
@@ -1190,50 +1208,36 @@
 
 	int error;
 	off_t startoff;
-	off_t cnt;
+	off_t cnt = 0;
 	struct tmpfs_node *node;
 
 	/* This operation only makes sense on directory nodes. */
-	if (vp->v_type != VDIR) {
-		error = ENOTDIR;
-		goto out;
-	}
+	if (vp->v_type != VDIR)
+		return ENOTDIR;
 
 	node = VP_TO_TMPFS_DIR(vp);
 
 	startoff = uio->uio_offset;
 
-	cnt = 0;
-	if (uio->uio_offset == TMPFS_DIRCOOKIE_DOT) {
+	switch (startoff) {
+	case TMPFS_DIRCOOKIE_DOT:
 		error = tmpfs_dir_getdotdent(node, uio);
-		if (error == -1) {
-			error = 0;
-			goto outok;
-		} else if (error != 0)
-			goto outok;
-		cnt++;
-	}
-
-	if (uio->uio_offset == TMPFS_DIRCOOKIE_DOTDOT) {
+		if (error == 0)
+			cnt++;
+		break;
+	case TMPFS_DIRCOOKIE_DOTDOT:
 		error = tmpfs_dir_getdotdotdent(node, uio);
-		if (error == -1) {
-			error = 0;
-			goto outok;
-		} else if (error != 0)
-			goto outok;
-		cnt++;
+		if (error == 0)
+			cnt++;
+		break;
+	default:
+		error = tmpfs_dir_getdents(node, uio, &cnt);
+		MPASS(error >= -1);
 	}
 
-	error = tmpfs_dir_getdents(node, uio, &cnt);
 	if (error == -1)
 		error = 0;
-	MPASS(error >= 0);
 
-outok:
-	/* This label assumes that startoff has been
-	 * initialized.  If the compiler didn't spit out warnings, we'd
-	 * simply make this one be 'out' and drop 'outok'. */
-
 	if (eofflag != NULL)
 		*eofflag =
 		    (error == 0 && uio->uio_offset == TMPFS_DIRCOOKIE_EOF);
@@ -1262,11 +1266,10 @@
 					MPASS(de != NULL);
 					de = TAILQ_NEXT(de, td_entries);
 				}
-				if (de == NULL) {
+				if (de == NULL)
 					off = TMPFS_DIRCOOKIE_EOF;
-				} else {
-					off = TMPFS_DIRCOOKIE(de);
-				}
+				else
+					off = tmpfs_dircookie(de);
 			}
 
 			(*cookies)[i] = off;
@@ -1274,7 +1277,6 @@

>>> TRUNCATED FOR MAIL (1000 lines) <<<


More information about the p4-projects mailing list