From owner-p4-projects@FreeBSD.ORG Fri Aug 10 12:32:32 2007 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 60B6C16A41A; Fri, 10 Aug 2007 12:32:32 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 1FB5316A419 for ; Fri, 10 Aug 2007 12:32:32 +0000 (UTC) (envelope-from delphij@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 0E2EA13C457 for ; Fri, 10 Aug 2007 12:32:32 +0000 (UTC) (envelope-from delphij@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id l7ACWVsB011434 for ; Fri, 10 Aug 2007 12:32:31 GMT (envelope-from delphij@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id l7ACWVnP011431 for perforce@freebsd.org; Fri, 10 Aug 2007 12:32:31 GMT (envelope-from delphij@freebsd.org) Date: Fri, 10 Aug 2007 12:32:31 GMT Message-Id: <200708101232.l7ACWVnP011431@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to delphij@freebsd.org using -f From: Xin LI To: Perforce Change Reviews Cc: Subject: PERFORCE change 125011 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 10 Aug 2007 12:32:32 -0000 http://perforce.freebsd.org/chv.cgi?CH=125011 Change 125011 by delphij@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 -__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 #include @@ -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 -__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 -__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 #include @@ -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 -__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 #include @@ -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 -__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 #include @@ -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) <<<