From owner-freebsd-current@FreeBSD.ORG Tue Aug 23 20:11:28 2011 Return-Path: Delivered-To: current@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 32DE4106566B; Tue, 23 Aug 2011 20:11:28 +0000 (UTC) (envelope-from rmacklem@uoguelph.ca) Received: from esa-jnhn.mail.uoguelph.ca (esa-jnhn.mail.uoguelph.ca [131.104.91.44]) by mx1.freebsd.org (Postfix) with ESMTP id A3F768FC15; Tue, 23 Aug 2011 20:11:27 +0000 (UTC) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Ap4EALcIVE6DaFvO/2dsb2JhbABCFoQ2pBCBQAEBBSMEUhsYAgINGQJZBi6HWqsykh6BLIQMgRAEkxmRFg X-IronPort-AV: E=Sophos;i="4.68,271,1312171200"; d="scan'208";a="135309785" Received: from erie.cs.uoguelph.ca (HELO zcs3.mail.uoguelph.ca) ([131.104.91.206]) by esa-jnhn-pri.mail.uoguelph.ca with ESMTP; 23 Aug 2011 16:11:20 -0400 Received: from zcs3.mail.uoguelph.ca (localhost.localdomain [127.0.0.1]) by zcs3.mail.uoguelph.ca (Postfix) with ESMTP id 82FB1B3F28; Tue, 23 Aug 2011 16:11:20 -0400 (EDT) Date: Tue, 23 Aug 2011 16:11:20 -0400 (EDT) From: Rick Macklem To: Pawel Jakub Dawidek Message-ID: <1614657395.247867.1314130280524.JavaMail.root@erie.cs.uoguelph.ca> In-Reply-To: <20110823151041.GA1697@garage.freebsd.pl> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-Originating-IP: [172.17.91.201] X-Mailer: Zimbra 6.0.10_GA_2692 (ZimbraWebClient - FF3.0 (Win)/6.0.10_GA_2692) Cc: Hiroki Sato , current@FreeBSD.org, Benjamin Kaduk Subject: Re: fsid change of ZFS? X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 23 Aug 2011 20:11:28 -0000 Pawel Jakub Dawidek wrote: > On Tue, Aug 23, 2011 at 10:09:41AM -0400, Rick Macklem wrote: > > Ok, I'll admit I wasn't very fond of a fixed table that would > > inevitably > > get out of date someday, either. > > > > I didn't think hashing for the cases not in the table was worth the > > effort, > > but doing a hash instead of a table seems reasonable. > > > > I see that ZFS only uses the low order 8 bits, so I'll try and come > > up > > with an 8bit hash solution and will post a patch for testing/review > > soon. > > > > I don't think the vfs_sysctl() is that great a concern, given that > > it > > appears to be deprecated already anyhow. (With an 8bit hash, > > vfs_typenum > > won't be that sparse.) I'll also make sure that whatever hash I use > > doesn't collide for the current list of file names (although I will > > include > > code that handles a collision in the patch). > > Sounds great. Thanks! > Here's the patch. (Hiroki could you please test this, thanks, rick.) ps: If the white space gets trashed, the same patch is at: http://people.freebsd.org/~rmacklem/fsid.patch --- kern/vfs_init.c.sav 2011-06-11 18:58:33.000000000 -0400 +++ kern/vfs_init.c 2011-08-23 15:55:30.000000000 -0400 @@ -39,6 +39,7 @@ __FBSDID("$FreeBSD: head/sys/kern/vfs_in #include #include +#include #include #include #include @@ -138,6 +139,8 @@ vfs_register(struct vfsconf *vfc) struct sysctl_oid *oidp; struct vfsops *vfsops; static int once; + struct vfsconf *tvfc; + uint32_t hashval; if (!once) { vattr_null(&va_null); @@ -152,7 +155,27 @@ vfs_register(struct vfsconf *vfc) if (vfs_byname(vfc->vfc_name) != NULL) return EEXIST; - vfc->vfc_typenum = maxvfsconf++; + /* + * Calculate a hash on vfc_name to use for vfc_typenum. Unless + * a collision occurs, it is limited to 8bits since that is + * what ZFS uses from vfc_typenum and that also limits how sparsely + * distributed vfc_typenum becomes. + */ + hashval = hash32_str(vfc->vfc_name, 0); + hashval = ((hashval & 0xff) + ((hashval >> 8) & 0xff) + + ((hashval >> 16) & 0xff) + (hashval >> 24)) & 0xff; + do { + /* Look for and fix any collision. */ + TAILQ_FOREACH(tvfc, &vfsconf, vfc_list) { + if (hashval == tvfc->vfc_typenum) { + hashval++; /* Can exceed 8bits, if needed. */ + break; + } + } + } while (tvfc != NULL); + vfc->vfc_typenum = hashval; + if (vfc->vfc_typenum >= maxvfsconf) + maxvfsconf = vfc->vfc_typenum + 1; TAILQ_INSERT_TAIL(&vfsconf, vfc, vfc_list); /*