fsid change of ZFS?
Rick Macklem
rmacklem at uoguelph.ca
Tue Aug 23 20:11:28 UTC 2011
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 <sys/param.h>
#include <sys/systm.h>
+#include <sys/hash.h>
#include <sys/kernel.h>
#include <sys/linker.h>
#include <sys/mount.h>
@@ -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);
/*
More information about the freebsd-current
mailing list