From owner-svn-src-head@FreeBSD.ORG Tue Sep 13 21:01:26 2011 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id DC6E01065673; Tue, 13 Sep 2011 21:01:26 +0000 (UTC) (envelope-from rmacklem@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id C24468FC12; Tue, 13 Sep 2011 21:01:26 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id p8DL1QRs096364; Tue, 13 Sep 2011 21:01:26 GMT (envelope-from rmacklem@svn.freebsd.org) Received: (from rmacklem@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p8DL1QOI096361; Tue, 13 Sep 2011 21:01:26 GMT (envelope-from rmacklem@svn.freebsd.org) Message-Id: <201109132101.p8DL1QOI096361@svn.freebsd.org> From: Rick Macklem Date: Tue, 13 Sep 2011 21:01:26 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r225537 - in head: . sys/kern X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 13 Sep 2011 21:01:27 -0000 Author: rmacklem Date: Tue Sep 13 21:01:26 2011 New Revision: 225537 URL: http://svn.freebsd.org/changeset/base/225537 Log: Modify vfs_register() to use a hash calculation on vfc_name to set vfc_typenum, so that vfc_typenum doesn't change when file systems are loaded in different orders. This keeps NFS file handles from changing, for file systems that use vfc_typenum in their fsid. This change is controlled via a loader.conf variable called vfs.typenumhash, since vfc_typenum will change once when this is enabled. It defaults to 1 for 9.0, but will default to 0 when MFC'd to stable/8. Tested by: hrs Reviewed by: jhb, pjd (earlier version) Approved by: re (kib) MFC after: 1 month Modified: head/UPDATING head/sys/kern/vfs_init.c Modified: head/UPDATING ============================================================================== --- head/UPDATING Tue Sep 13 20:35:34 2011 (r225536) +++ head/UPDATING Tue Sep 13 21:01:26 2011 (r225537) @@ -22,6 +22,18 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 9. machines to maximize performance. (To disable malloc debugging, run ln -s aj /etc/malloc.conf.) +20110913: + This commit modifies vfs_register() so that it uses a hash + calculation to set vfc_typenum, which is enabled by default. + The first time a system is booted after this change, the + vfc_typenum values will change for all file systems. The + main effect of this is a change to the NFS server file handles + for file systems that use vfc_typenum in their fsid, such as ZFS. + It will, however, prevent vfc_typenum from changing when file + systems are loaded in a different order for subsequent reboots. + To disable this, you can set vfs.typenumhash=0 in /boot/loader.conf + until you are ready to remount all NFS clients after a reboot. + 20110828: Bump the shared library version numbers for libraries that do not use symbol versioning, have changed the ABI compared Modified: head/sys/kern/vfs_init.c ============================================================================== --- head/sys/kern/vfs_init.c Tue Sep 13 20:35:34 2011 (r225536) +++ head/sys/kern/vfs_init.c Tue Sep 13 21:01:26 2011 (r225537) @@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -65,6 +66,18 @@ int maxvfsconf = VFS_GENERIC + 1; struct vfsconfhead vfsconf = TAILQ_HEAD_INITIALIZER(vfsconf); /* + * Loader.conf variable vfs.typenumhash enables setting vfc_typenum using a hash + * calculation on vfc_name, so that it doesn't change when file systems are + * loaded in a different order. This will avoid the NFS server file handles from + * changing for file systems that use vfc_typenum in their fsid. + */ +static int vfs_typenumhash = 1; +TUNABLE_INT("vfs.typenumhash", &vfs_typenumhash); +SYSCTL_INT(_vfs, OID_AUTO, typenumhash, CTLFLAG_RDTUN, &vfs_typenumhash, 0, + "Set vfc_typenum using a hash calculation on vfc_name, so that it does not" + "change when file systems are loaded in a different order."); + +/* * A Zen vnode attribute structure. * * Initialized when the first filesystem registers by vfs_register(). @@ -138,6 +151,9 @@ vfs_register(struct vfsconf *vfc) struct sysctl_oid *oidp; struct vfsops *vfsops; static int once; + struct vfsconf *tvfc; + uint32_t hashval; + int secondpass; if (!once) { vattr_null(&va_null); @@ -152,7 +168,34 @@ vfs_register(struct vfsconf *vfc) if (vfs_byname(vfc->vfc_name) != NULL) return EEXIST; - vfc->vfc_typenum = maxvfsconf++; + if (vfs_typenumhash != 0) { + /* + * Calculate a hash on vfc_name to use for vfc_typenum. Unless + * all of 1<->255 are assigned, it is limited to 8bits since + * that is what ZFS uses from vfc_typenum and is also the + * preferred range for vfs_getnewfsid(). + */ + hashval = fnv_32_str(vfc->vfc_name, FNV1_32_INIT); + hashval &= 0xff; + secondpass = 0; + do { + /* Look for and fix any collision. */ + TAILQ_FOREACH(tvfc, &vfsconf, vfc_list) { + if (hashval == tvfc->vfc_typenum) { + if (hashval == 255 && secondpass == 0) { + hashval = 1; + secondpass = 1; + } else + hashval++; + break; + } + } + } while (tvfc != NULL); + vfc->vfc_typenum = hashval; + if (vfc->vfc_typenum >= maxvfsconf) + maxvfsconf = vfc->vfc_typenum + 1; + } else + vfc->vfc_typenum = maxvfsconf++; TAILQ_INSERT_TAIL(&vfsconf, vfc, vfc_list); /*