summaryrefslogtreecommitdiff
path: root/usr
diff options
context:
space:
mode:
authorjmcp <James.McPherson@Sun.COM>2010-06-10 16:27:13 -0700
committerjmcp <James.McPherson@Sun.COM>2010-06-10 16:27:13 -0700
commitbfbb13c994c87d0453ca6bb826470ec99a909992 (patch)
treeee27888ec698913e010e5b7b7bf487b6ce3f21f6 /usr
parent44f92b7dbae22574cbeb46a120d108f45d9e2f29 (diff)
downloadillumos-joyent-bfbb13c994c87d0453ca6bb826470ec99a909992.tar.gz
backout 6930814: causes 6960023
Diffstat (limited to 'usr')
-rw-r--r--usr/src/lib/libshare/common/libshare.c3
-rw-r--r--usr/src/lib/libshare/common/libshare.h1
-rw-r--r--usr/src/lib/libshare/nfs/libshare_nfs.c8
-rw-r--r--usr/src/pkg/manifests/system-header.mf1
-rw-r--r--usr/src/uts/common/Makefile.files1
-rw-r--r--usr/src/uts/common/fs/nfs/nfs4_idmap.c65
-rw-r--r--usr/src/uts/common/fs/nfs/nfs4_srv_ns.c65
-rw-r--r--usr/src/uts/common/fs/nfs/nfs_auth.c2
-rw-r--r--usr/src/uts/common/fs/nfs/nfs_export.c363
-rw-r--r--usr/src/uts/common/fs/pkp_hash.c70
-rw-r--r--usr/src/uts/common/fs/sharefs/sharetab.c41
-rw-r--r--usr/src/uts/common/nfs/export.h20
-rw-r--r--usr/src/uts/common/nfs/nfs4_idmap_impl.h13
-rw-r--r--usr/src/uts/common/sharefs/sharetab.h31
-rw-r--r--usr/src/uts/common/sys/Makefile1
-rw-r--r--usr/src/uts/common/sys/pkp_hash.h48
16 files changed, 410 insertions, 323 deletions
diff --git a/usr/src/lib/libshare/common/libshare.c b/usr/src/lib/libshare/common/libshare.c
index 1d17d5fea7..30c2c486f1 100644
--- a/usr/src/lib/libshare/common/libshare.c
+++ b/usr/src/lib/libshare/common/libshare.c
@@ -221,9 +221,6 @@ sa_errorstr(int err)
case SA_PASSWORD_ENC:
ret = dgettext(TEXT_DOMAIN, "passwords must be encrypted");
break;
- case SA_SHARE_EXISTS:
- ret = dgettext(TEXT_DOMAIN, "path or file is already shared");
- break;
default:
(void) snprintf(errstr, sizeof (errstr),
dgettext(TEXT_DOMAIN, "unknown %d"), err);
diff --git a/usr/src/lib/libshare/common/libshare.h b/usr/src/lib/libshare/common/libshare.h
index 283a499a8e..5d32f60e8f 100644
--- a/usr/src/lib/libshare/common/libshare.h
+++ b/usr/src/lib/libshare/common/libshare.h
@@ -87,7 +87,6 @@ typedef void *sa_handle_t; /* opaque handle to access core functions */
#define SA_NO_SUCH_SECTION 30 /* no section found */
#define SA_NO_PROPERTIES 31 /* no properties found */
#define SA_PASSWORD_ENC 32 /* passwords must be encrypted */
-#define SA_SHARE_EXISTS 33 /* path or file is already shared */
/* API Initialization */
#define SA_INIT_SHARE_API 0x0001 /* init share specific interface */
diff --git a/usr/src/lib/libshare/nfs/libshare_nfs.c b/usr/src/lib/libshare/nfs/libshare_nfs.c
index 3173e47d7f..6a9f7fafba 100644
--- a/usr/src/lib/libshare/nfs/libshare_nfs.c
+++ b/usr/src/lib/libshare/nfs/libshare_nfs.c
@@ -20,7 +20,8 @@
*/
/*
- * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
*/
/*
@@ -1951,10 +1952,7 @@ nfs_enable_share(sa_share_t share)
break;
}
err = SA_NO_PERMISSION;
- break;
- case EEXIST:
- err = SA_SHARE_EXISTS;
- break;
+ /* FALLTHROUGH */
default:
break;
}
diff --git a/usr/src/pkg/manifests/system-header.mf b/usr/src/pkg/manifests/system-header.mf
index 3d72a44f27..25b41f849d 100644
--- a/usr/src/pkg/manifests/system-header.mf
+++ b/usr/src/pkg/manifests/system-header.mf
@@ -1284,7 +1284,6 @@ file path=usr/include/sys/pghw.h
file path=usr/include/sys/physmem.h
$(i386_ONLY)file path=usr/include/sys/pic.h
$(i386_ONLY)file path=usr/include/sys/pit.h
-file path=usr/include/sys/pkp_hash.h
file path=usr/include/sys/pm.h
$(i386_ONLY)file path=usr/include/sys/pmem.h
file path=usr/include/sys/policy.h
diff --git a/usr/src/uts/common/Makefile.files b/usr/src/uts/common/Makefile.files
index fd94035afe..d72125bf54 100644
--- a/usr/src/uts/common/Makefile.files
+++ b/usr/src/uts/common/Makefile.files
@@ -255,7 +255,6 @@ GENUNIX_OBJS += \
pgrp.o \
pgrpsys.o \
pid.o \
- pkp_hash.o \
policy.o \
poll.o \
pool.o \
diff --git a/usr/src/uts/common/fs/nfs/nfs4_idmap.c b/usr/src/uts/common/fs/nfs/nfs4_idmap.c
index 35afec00d2..a5f05a5d34 100644
--- a/usr/src/uts/common/fs/nfs/nfs4_idmap.c
+++ b/usr/src/uts/common/fs/nfs/nfs4_idmap.c
@@ -19,7 +19,8 @@
* CDDL HEADER END
*/
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
*/
@@ -123,7 +124,6 @@
#include <sys/sunddi.h>
#include <sys/dnlc.h>
#include <sys/sdt.h>
-#include <sys/pkp_hash.h>
#include <nfs/nfs4.h>
#include <nfs/rnode4.h>
#include <nfs/nfsid_map.h>
@@ -137,6 +137,7 @@ zone_key_t nfsidmap_zone_key;
static list_t nfsidmap_globals_list;
static kmutex_t nfsidmap_globals_lock;
static kmem_cache_t *nfsidmap_cache;
+static uint_t pkp_tab[NFSID_CACHE_ANCHORS];
static int nfs4_idcache_tout;
/*
@@ -146,11 +147,31 @@ static int nfs4_idcache_tout;
#define _CACHE_TOUT (60*60) /* secs in 1 hour */
#define TIMEOUT(x) (gethrestime_sec() > \
((x) + nfs4_idcache_tout))
+
/*
* Max length of valid id string including the trailing null
*/
#define _MAXIDSTRLEN 11
+/*
+ * Pearson's string hash
+ *
+ * See: Communications of the ACM, June 1990 Vol 33 pp 677-680
+ * http://www.acm.org/pubs/citations/journals/cacm/1990-33-6/p677-pearson
+ */
+#define PS_HASH(msg, hash, len) \
+{ \
+ uint_t key = 0x12345678; /* arbitrary value */ \
+ int i; \
+ \
+ (hash) = MOD2((key + (len)), NFSID_CACHE_ANCHORS); \
+ \
+ for (i = 0; i < (len); i++) { \
+ (hash) = MOD2(((hash) + (msg)[i]), NFSID_CACHE_ANCHORS); \
+ (hash) = pkp_tab[(hash)]; \
+ } \
+}
+
#define ID_HASH(id, hash) \
{ \
(hash) = MOD2(((id) ^ NFSID_CACHE_ANCHORS), NFSID_CACHE_ANCHORS); \
@@ -164,6 +185,7 @@ static void *nfs_idmap_init_zone(zoneid_t);
static void nfs_idmap_fini_zone(zoneid_t, void *);
static int is_stringified_id(utf8string *);
+static void init_pkp_tab(void);
static void nfs_idmap_i2s_literal(uid_t, utf8string *);
static int nfs_idmap_s2i_literal(utf8string *, uid_t *, int);
static void nfs_idmap_reclaim(void *);
@@ -193,6 +215,10 @@ void
nfs_idmap_init(void)
{
/*
+ * Initialize Pearson's Table
+ */
+ init_pkp_tab();
+ /*
* Initialize the kmem cache
*/
nfsidmap_cache = kmem_cache_create("NFS_idmap_cache",
@@ -1277,6 +1303,7 @@ nfs_idmap_cache_s2i_lkup(idmap_cache_info_t *cip, /* cache info ptr */
nfsidmap_t *p;
nfsidmap_t *pnext;
nfsidhq_t *hq;
+ uint_t hash;
char *rqst_c_str;
uint_t rqst_len;
uint_t found_stat = 0;
@@ -1291,8 +1318,9 @@ nfs_idmap_cache_s2i_lkup(idmap_cache_info_t *cip, /* cache info ptr */
/*
* Compute hash queue
*/
- *hashno = pkp_tab_hash(rqst_c_str, rqst_len - 1);
- hq = &cip->table[*hashno];
+ PS_HASH(rqst_c_str, hash, rqst_len - 1);
+ *hashno = hash;
+ hq = &cip->table[hash];
/*
* Look for the entry in the HQ
@@ -1379,7 +1407,7 @@ nfs_idmap_cache_s2i_insert(idmap_cache_info_t *cip, /* cache info ptr */
case HQ_HASH_FIND:
default:
- hashno = pkp_tab_hash(c_str, c_len - 1);
+ PS_HASH(c_str, hashno, c_len - 1);
break;
}
hq = &cip->table[hashno];
@@ -1676,6 +1704,33 @@ nfs_idmap_i2s_literal(uid_t id, utf8string *u8s)
/* -- Utility functions -- */
+/*
+ * Initialize table in pseudo-random fashion
+ * for use in Pearson's string hash algorithm.
+ *
+ * See: Communications of the ACM, June 1990 Vol 33 pp 677-680
+ * http://www.acm.org/pubs/citations/journals/cacm/1990-33-6/p677-pearson
+ */
+static void
+init_pkp_tab(void)
+{
+ int i;
+ int j;
+ int k = 7;
+ uint_t s;
+
+ for (i = 0; i < NFSID_CACHE_ANCHORS; i++)
+ pkp_tab[i] = i;
+
+ for (j = 0; j < 4; j++)
+ for (i = 0; i < NFSID_CACHE_ANCHORS; i++) {
+ s = pkp_tab[i];
+ k = MOD2((k + s), NFSID_CACHE_ANCHORS);
+ pkp_tab[i] = pkp_tab[k];
+ pkp_tab[k] = s;
+ }
+}
+
char *
utf8_strchr(utf8string *u8s, const char c)
{
diff --git a/usr/src/uts/common/fs/nfs/nfs4_srv_ns.c b/usr/src/uts/common/fs/nfs/nfs4_srv_ns.c
index 8e5aefc829..bc15ca0552 100644
--- a/usr/src/uts/common/fs/nfs/nfs4_srv_ns.c
+++ b/usr/src/uts/common/fs/nfs/nfs4_srv_ns.c
@@ -137,21 +137,38 @@ nfs4_vget_pseudo(struct exportinfo *exi, vnode_t **vpp, fid_t *fidp)
* a) its export root is VROOT
* b) a descendant of the export root is shared
*/
-struct exportinfo *
-pseudo_exportfs(vnode_t *vp, fid_t *fid, struct exp_visible *vis_head,
- struct exportdata *exdata)
+int
+pseudo_exportfs(vnode_t *vp, struct exp_visible *vis_head,
+ struct exportdata *exdata, struct exportinfo **exi_retp)
{
struct exportinfo *exi;
struct exportdata *kex;
+ fid_t fid;
fsid_t fsid;
- int vpathlen;
+ int error, vpathlen;
ASSERT(RW_WRITE_HELD(&exported_lock));
+ /*
+ * Get the vfs id
+ */
+ bzero(&fid, sizeof (fid));
+ fid.fid_len = MAXFIDSZ;
+ error = vop_fid_pseudo(vp, &fid);
+ if (error) {
+ /*
+ * If VOP_FID returns ENOSPC then the fid supplied
+ * is too small. For now we simply return EREMOTE.
+ */
+ if (error == ENOSPC)
+ error = EREMOTE;
+ return (error);
+ }
+
fsid = vp->v_vfsp->vfs_fsid;
exi = kmem_zalloc(sizeof (*exi), KM_SLEEP);
exi->exi_fsid = fsid;
- exi->exi_fid = *fid;
+ exi->exi_fid = fid;
exi->exi_vp = vp;
VN_HOLD(exi->exi_vp);
exi->exi_visible = vis_head;
@@ -195,7 +212,14 @@ pseudo_exportfs(vnode_t *vp, fid_t *fid, struct exp_visible *vis_head,
*/
export_link(exi);
- return (exi);
+ /*
+ * If exi_retp is non-NULL return a pointer to the new
+ * exportinfo structure.
+ */
+ if (exi_retp)
+ *exi_retp = exi;
+
+ return (0);
}
/*
@@ -315,7 +339,7 @@ tree_remove_node(treenode_t *node)
* share /x/y/a/b
*
* When more_visible() is called during the second share,
- * the existing namespace is following:
+ * the existing namespace is folowing:
* exp_visible_t
* treenode_t exportinfo_t v0 v1
* ns_root+---+ +------------+ +---+ +---+
@@ -357,7 +381,7 @@ tree_remove_node(treenode_t *node)
* - add t4, t5, t6 as a child of t1 (t4 will become sibling of t2)
* - add v3 to the end of E0->exi_visible
*
- * Note that v4 and v5 were already processed in pseudo_exportfs() and
+ * Note that v4 and v5 were already proccesed in pseudo_exportfs() and
* added to E2. The outer loop of more_visible() will loop only over v2
* and v3. The inner loop of more_visible() always loops over v0 and v1.
*
@@ -655,8 +679,10 @@ treeclimb_export(struct exportinfo *exip)
* this as a pseudo export so that an NFS v4
* client can do lookups in it.
*/
- new_exi = pseudo_exportfs(vp, &fid, vis_head,
- NULL);
+ error = pseudo_exportfs(vp, vis_head, NULL,
+ &new_exi);
+ if (error)
+ break;
vis_head = NULL;
}
@@ -737,8 +763,9 @@ treeclimb_export(struct exportinfo *exip)
/*
* We can have set error due to error in:
* 1. vop_fid_pseudo()
- * 2. VOP_GETATTR()
- * 3. VOP_LOOKUP()
+ * 2. pseudo_exportfs() which can fail only in vop_fid_pseudo()
+ * 3. VOP_GETATTR()
+ * 4. VOP_LOOKUP()
* We must free pseudo exportinfos, visibles and treenodes.
* Visibles are referenced from treenode_t::tree_vis and
* exportinfo_t::exi_visible. To avoid double freeing, only
@@ -758,7 +785,8 @@ treeclimb_export(struct exportinfo *exip)
exportinfo_t *e = tree_head->tree_exi;
/* exip will be freed in exportfs() */
if (e && e != exip) {
- export_unlink(e);
+ (void) export_unlink(&e->exi_fsid, &e->exi_fid,
+ e->exi_vp, NULL);
exi_rele(e);
}
tree_head = tree_head->tree_child_first;
@@ -784,6 +812,7 @@ treeclimb_export(struct exportinfo *exip)
void
treeclimb_unexport(struct exportinfo *exip)
{
+ struct exportinfo *exi;
treenode_t *tnode, *old_nd;
ASSERT(RW_WRITE_HELD(&exported_lock));
@@ -808,13 +837,17 @@ treeclimb_unexport(struct exportinfo *exip)
/* Release pseudo export if it has no child */
if (TREE_ROOT(tnode) && !TREE_EXPORTED(tnode) &&
tnode->tree_child_first == 0) {
- export_unlink(tnode->tree_exi);
+ exi = tnode->tree_exi;
+ (void) export_unlink(&exi->exi_fsid, &exi->exi_fid,
+ exi->exi_vp, NULL);
exi_rele(tnode->tree_exi);
}
/* Release visible in parent's exportinfo */
- if (tnode->tree_vis)
- less_visible(vis2exi(tnode), tnode->tree_vis);
+ if (tnode->tree_vis) {
+ exi = vis2exi(tnode);
+ less_visible(exi, tnode->tree_vis);
+ }
/* Continue with parent */
old_nd = tnode;
diff --git a/usr/src/uts/common/fs/nfs/nfs_auth.c b/usr/src/uts/common/fs/nfs/nfs_auth.c
index 00a25566e4..d803531e09 100644
--- a/usr/src/uts/common/fs/nfs/nfs_auth.c
+++ b/usr/src/uts/common/fs/nfs/nfs_auth.c
@@ -1145,7 +1145,7 @@ exi_cache_reclaim(void *cdrarg)
rw_enter(&exported_lock, RW_READER);
for (i = 0; i < EXPTABLESIZE; i++) {
- for (exi = exptable[i]; exi; exi = exi->fid_hash.next) {
+ for (exi = exptable[i]; exi; exi = exi->exi_hash) {
exi_cache_trim(exi);
}
}
diff --git a/usr/src/uts/common/fs/nfs/nfs_export.c b/usr/src/uts/common/fs/nfs/nfs_export.c
index 138cced588..315fdb8385 100644
--- a/usr/src/uts/common/fs/nfs/nfs_export.c
+++ b/usr/src/uts/common/fs/nfs/nfs_export.c
@@ -62,14 +62,12 @@
#include <nfs/nfs_log.h>
#include <nfs/lm.h>
#include <sys/sunddi.h>
-#include <sys/pkp_hash.h>
treenode_t *ns_root;
-struct exportinfo *exptable_path_hash[PKP_HASH_SIZE];
struct exportinfo *exptable[EXPTABLESIZE];
-static void unexport(exportinfo_t *);
+static int unexport(fsid_t *, fid_t *, vnode_t *);
static void exportfree(exportinfo_t *);
static int loadindex(exportdata_t *);
@@ -114,36 +112,61 @@ fhandle_t nullfh2; /* for comparing V2 filehandles */
#define exptablehash(fsid, fid) (nfs_fhhash((fsid), (fid)) & (EXPTABLESIZE - 1))
-static uint8_t
-xor_hash(uint8_t *data, int len)
-{
- uint8_t h = 0;
-
- while (len--)
- h ^= *data++;
-
- return (h);
-}
-
/*
- * File handle hash function, XOR over all bytes in fsid and fid.
+ * File handle hash function, good for producing hash values 16 bits wide.
*/
-static unsigned
+int
nfs_fhhash(fsid_t *fsid, fid_t *fid)
{
- int len;
- uint8_t h;
+ short *data;
+ int i, len;
+ short h;
+
+ ASSERT(fid != NULL);
- h = xor_hash((uint8_t *)fsid, sizeof (fsid_t));
+ data = (short *)fid->fid_data;
+
+ /* fid_data must be aligned on a short */
+ ASSERT((((uintptr_t)data) & (sizeof (short) - 1)) == 0);
+
+ if (fid->fid_len == 10) {
+ /*
+ * probably ufs: hash on bytes 4,5 and 8,9
+ */
+ return (fsid->val[0] ^ data[2] ^ data[4]);
+ }
+
+ if (fid->fid_len == 6) {
+ /*
+ * probably hsfs: hash on bytes 0,1 and 4,5
+ */
+ return ((fsid->val[0] ^ data[0] ^ data[2]));
+ }
+
+ /*
+ * Some other file system. Assume that every byte is
+ * worth hashing.
+ */
+ h = (short)fsid->val[0];
/*
* Sanity check the length before using it
* blindly in case the client trashed it.
*/
- len = fid->fid_len > NFS_FH4MAXDATA ? 0 : fid->fid_len;
- h ^= xor_hash((uint8_t *)fid->fid_data, len);
+ if (fid->fid_len > NFS_FHMAXDATA)
+ len = 0;
+ else
+ len = fid->fid_len / sizeof (short);
+
+ /*
+ * This will ignore one byte if len is not a multiple of
+ * of sizeof (short). No big deal since we at least get some
+ * variation with fsid->val[0];
+ */
+ for (i = 0; i < len; i++)
+ h ^= data[i];
- return ((unsigned)h);
+ return ((int)h);
}
/*
@@ -166,6 +189,7 @@ srv_secinfo_entry_free(struct secinfo *secp)
sizeof (rpc_gss_OID_desc));
secp->s_secinfo.sc_gss_mech_type = NULL;
}
+
}
/*
@@ -759,35 +783,13 @@ srv_secinfo_treeclimb(exportinfo_t *exip, secinfo_t *sec, int seccnt, int isadd)
}
}
-/* hash_name is a text substitution for either fid_hash or path_hash */
-#define exp_hash_unlink(exi, hash_name) \
- if (*(exi)->hash_name.bckt == (exi)) \
- *(exi)->hash_name.bckt = (exi)->hash_name.next; \
- if ((exi)->hash_name.prev) \
- (exi)->hash_name.prev->hash_name.next = (exi)->hash_name.next; \
- if ((exi)->hash_name.next) \
- (exi)->hash_name.next->hash_name.prev = (exi)->hash_name.prev; \
- (exi)->hash_name.bckt = NULL;
-
-#define exp_hash_link(exi, hash_name, bucket) \
- (exi)->hash_name.bckt = (bucket); \
- (exi)->hash_name.prev = NULL; \
- (exi)->hash_name.next = *(bucket); \
- if ((exi)->hash_name.next) \
- (exi)->hash_name.next->hash_name.prev = (exi); \
- *(bucket) = (exi);
-
void
-export_link(exportinfo_t *exi)
-{
- exportinfo_t **bckt;
+export_link(exportinfo_t *exi) {
+ int exporthash;
- bckt = &exptable[exptablehash(&exi->exi_fsid, &exi->exi_fid)];
- exp_hash_link(exi, fid_hash, bckt);
-
- bckt = &exptable_path_hash[pkp_tab_hash(exi->exi_export.ex_path,
- strlen(exi->exi_export.ex_path))];
- exp_hash_link(exi, path_hash, bckt);
+ exporthash = exptablehash(&exi->exi_fsid, &exi->exi_fid);
+ exi->exi_hash = exptable[exporthash];
+ exptable[exporthash] = exi;
}
/*
@@ -946,7 +948,7 @@ rfs_gsscallback(struct svc_req *req, gss_cred_id_t deleg, void *gss_context,
}
}
}
- exi = exi->fid_hash.next;
+ exi = exi->exi_hash;
}
}
done:
@@ -996,7 +998,7 @@ exportfs(struct exportfs_args *args, model_t model, cred_t *cr)
vnode_t *dvp;
struct exportdata *kex;
struct exportinfo *exi = NULL;
- struct exportinfo *ex, *ex1, *ex2;
+ struct exportinfo *ex, *prev;
fid_t fid;
fsid_t fsid;
int error;
@@ -1016,46 +1018,9 @@ exportfs(struct exportfs_args *args, model_t model, cred_t *cr)
struct secinfo oldsec[MAX_FLAVORS];
int oldcnt;
int i;
- struct pathname lookpn;
STRUCT_SET_HANDLE(uap, model, args);
- /* Read in pathname from userspace */
- if (error = pn_get(STRUCT_FGETP(uap, dname), UIO_USERSPACE, &lookpn))
- return (error);
-
- /* Walk the export list looking for that pathname */
- rw_enter(&exported_lock, RW_READER);
- DTRACE_PROBE(nfss__i__exported_lock1_start);
- for (ex1 = exptable_path_hash[pkp_tab_hash(lookpn.pn_path,
- strlen(lookpn.pn_path))]; ex1; ex1 = ex1->path_hash.next) {
- if (ex1 != exi_root && 0 ==
- strcmp(ex1->exi_export.ex_path, lookpn.pn_path)) {
- exi_hold(ex1);
- break;
- }
- }
- DTRACE_PROBE(nfss__i__exported_lock1_stop);
- rw_exit(&exported_lock);
-
- /* Is this an unshare? */
- if (STRUCT_FGETP(uap, uex) == NULL) {
- pn_free(&lookpn);
- rw_enter(&exported_lock, RW_WRITER);
- /* Check if ex1 is still linked in the export table */
- if (ex1 == NULL || !EXP_LINKED(ex1) || PSEUDO(ex1)) {
- rw_exit(&exported_lock);
- if (ex1)
- exi_rele(ex1);
- return (EINVAL);
- }
- unexport(ex1);
- rw_exit(&exported_lock);
- exi_rele(ex1);
- return (0);
- }
-
- /* It is a share or a re-share */
error = lookupname(STRUCT_FGETP(uap, dname), UIO_USERSPACE,
FOLLOW, &dvp, &vp);
if (error == EINVAL) {
@@ -1069,18 +1034,87 @@ exportfs(struct exportfs_args *args, model_t model, cred_t *cr)
dvp = NULL;
}
if (!error && vp == NULL) {
- /* Last component of fname not found */
- if (dvp != NULL)
+ /*
+ * Last component of fname not found
+ */
+ if (dvp != NULL) {
VN_RELE(dvp);
+ }
error = ENOENT;
}
+
if (error) {
- pn_free(&lookpn);
- if (ex1)
- exi_rele(ex1);
- return (error);
+ /*
+ * If this is a request to unexport, indicated by the
+ * uex pointer being NULL, it is possible that the
+ * directory has already been removed or shared filesystem
+ * could have been forcibly unmounted. In which case
+ * we scan the export list which records the pathname
+ * originally exported.
+ */
+ if (STRUCT_FGETP(uap, uex) == NULL) {
+ char namebuf[TYPICALMAXPATHLEN];
+ struct pathname lookpn;
+ int i;
+
+ /* Read in pathname from userspace */
+ error = pn_get_buf(STRUCT_FGETP(uap, dname),
+ UIO_USERSPACE, &lookpn, namebuf, sizeof (namebuf));
+ if (error == ENAMETOOLONG) {
+ /*
+ * pathname > TYPICALMAXPATHLEN, use
+ * pn_get() instead. Remember to
+ * pn_free() afterwards.
+ */
+ error = pn_get(STRUCT_FGETP(uap, dname),
+ UIO_USERSPACE, &lookpn);
+ }
+
+ if (error)
+ return (error);
+
+ /* Walk the export list looking for that pathname */
+ rw_enter(&exported_lock, RW_READER);
+ for (i = 0; i < EXPTABLESIZE; i++) {
+ exi = exptable[i];
+ while (exi) {
+ if (strcmp(exi->exi_export.ex_path,
+ lookpn.pn_path) == 0) {
+ goto exi_scan_end;
+ }
+ exi = exi->exi_hash;
+ }
+ }
+exi_scan_end:
+ rw_exit(&exported_lock);
+ if (exi) {
+ /* Found a match, use it. */
+ vp = exi->exi_vp;
+ dvp = exi->exi_dvp;
+ DTRACE_PROBE2(nfss__i__nmspc__tree,
+ char *,
+ "unsharing removed dir/unmounted fs",
+ char *, lookpn.pn_path);
+ VN_HOLD(vp);
+ VN_HOLD(dvp);
+ error = 0;
+ } else {
+ /* Still no match, set error */
+ error = ENOENT;
+ }
+ if (lookpn.pn_buf != namebuf) {
+ /*
+ * We didn't use namebuf, so make
+ * sure we free the allocated memory
+ */
+ pn_free(&lookpn);
+ }
+ }
}
+ if (error)
+ return (error);
+
/*
* 'vp' may be an AUTOFS node, so we perform a
* VOP_ACCESS() to trigger the mount of the
@@ -1101,22 +1135,10 @@ exportfs(struct exportfs_args *args, model_t model, cred_t *cr)
VN_RELE(vp);
if (dvp != NULL)
VN_RELE(dvp);
- pn_free(&lookpn);
- if (ex1)
- exi_rele(ex1);
return (error);
}
}
- /* Do not allow sharing another vnode for already shared path */
- if (ex1 && !PSEUDO(ex1) && !VN_CMP(ex1->exi_vp, vp)) {
- pn_free(&lookpn);
- exi_rele(ex1);
- return (EEXIST);
- }
- if (ex1)
- exi_rele(ex1);
-
/*
* Get the vfs id
*/
@@ -1125,7 +1147,13 @@ exportfs(struct exportfs_args *args, model_t model, cred_t *cr)
error = VOP_FID(vp, &fid, NULL);
fsid = vp->v_vfsp->vfs_fsid;
- if (error) {
+ /*
+ * Allow unshare request for forcibly unmounted shared filesystem.
+ */
+ if (error == EIO && exi) {
+ fid = exi->exi_fid;
+ fsid = exi->exi_fsid;
+ } else if (error) {
VN_RELE(vp);
if (dvp != NULL)
VN_RELE(dvp);
@@ -1135,30 +1163,16 @@ exportfs(struct exportfs_args *args, model_t model, cred_t *cr)
*/
if (error == ENOSPC)
error = EREMOTE;
- pn_free(&lookpn);
return (error);
}
- /*
- * Do not allow re-sharing a shared vnode under a different path
- * PSEUDO export has ex_path fabricated, e.g. "/tmp (pseudo)", skip it.
- */
- rw_enter(&exported_lock, RW_READER);
- DTRACE_PROBE(nfss__i__exported_lock2_start);
- for (ex2 = exptable[exptablehash(&fsid, &fid)]; ex2;
- ex2 = ex2->fid_hash.next) {
- if (ex2 != exi_root && !PSEUDO(ex2) &&
- VN_CMP(ex2->exi_vp, vp) &&
- strcmp(ex2->exi_export.ex_path, lookpn.pn_path) != 0) {
- DTRACE_PROBE(nfss__i__exported_lock2_stop);
- rw_exit(&exported_lock);
- pn_free(&lookpn);
- return (EEXIST);
- }
+ if (STRUCT_FGETP(uap, uex) == NULL) {
+ error = unexport(&fsid, &fid, vp);
+ VN_RELE(vp);
+ if (dvp != NULL)
+ VN_RELE(dvp);
+ return (error);
}
- DTRACE_PROBE(nfss__i__exported_lock2_stop);
- rw_exit(&exported_lock);
- pn_free(&lookpn);
exi = kmem_zalloc(sizeof (*exi), KM_SLEEP);
exi->exi_fsid = fsid;
@@ -1433,7 +1447,6 @@ exportfs(struct exportfs_args *args, model_t model, cred_t *cr)
* Insert the new entry at the front of the export list
*/
rw_enter(&exported_lock, RW_WRITER);
- DTRACE_PROBE(nfss__i__exported_lock3_start);
export_link(exi);
@@ -1442,9 +1455,10 @@ exportfs(struct exportfs_args *args, model_t model, cred_t *cr)
* If one is found then unlink it, wait until this is the
* only reference and then free it.
*/
- for (ex = exi->fid_hash.next; ex != NULL; ex = ex->fid_hash.next) {
+ prev = exi;
+ for (ex = prev->exi_hash; ex != NULL; prev = ex, ex = ex->exi_hash) {
if (ex != exi_root && VN_CMP(ex->exi_vp, vp)) {
- export_unlink(ex);
+ prev->exi_hash = ex->exi_hash;
break;
}
}
@@ -1539,7 +1553,6 @@ exportfs(struct exportfs_args *args, model_t model, cred_t *cr)
ex->exi_visible = NULL;
}
- DTRACE_PROBE(nfss__i__exported_lock3_stop);
rw_exit(&exported_lock);
if (exi_public == exi || kex->ex_flags & EX_LOG) {
@@ -1556,8 +1569,7 @@ exportfs(struct exportfs_args *args, model_t model, cred_t *cr)
out7:
/* Unlink the new export in exptable. */
- export_unlink(exi);
- DTRACE_PROBE(nfss__i__exported_lock3_stop);
+ (void) export_unlink(&exi->exi_fsid, &exi->exi_fid, exi->exi_vp, NULL);
rw_exit(&exported_lock);
out6:
if (kex->ex_flags & EX_INDEX)
@@ -1595,27 +1607,70 @@ out1:
/*
* Remove the exportinfo from the export list
*/
-void
-export_unlink(struct exportinfo *exi)
+int
+export_unlink(fsid_t *fsid, fid_t *fid, vnode_t *vp, struct exportinfo **exip)
{
+ struct exportinfo **tail;
+
ASSERT(RW_WRITE_HELD(&exported_lock));
- exp_hash_unlink(exi, fid_hash);
- exp_hash_unlink(exi, path_hash);
+ tail = &exptable[exptablehash(fsid, fid)];
+ while (*tail != NULL) {
+ if (exportmatch(*tail, fsid, fid)) {
+ /*
+ * If vp is given, check if vp is the
+ * same vnode as the exported node.
+ *
+ * Since VOP_FID of a lofs node returns the
+ * fid of its real node (ufs), the exported
+ * node for lofs and (pseudo) ufs may have
+ * the same fsid and fid.
+ */
+ if (vp == NULL || vp == (*tail)->exi_vp) {
+
+ if (exip != NULL)
+ *exip = *tail;
+ *tail = (*tail)->exi_hash;
+
+ return (0);
+ }
+ }
+ tail = &(*tail)->exi_hash;
+ }
+
+ return (EINVAL);
}
/*
* Unexport an exported filesystem
*/
-void
-unexport(struct exportinfo *exi)
+int
+unexport(fsid_t *fsid, fid_t *fid, vnode_t *vp)
{
+ struct exportinfo *exi = NULL;
+ int error;
struct secinfo cursec[MAX_FLAVORS];
int curcnt;
- ASSERT(RW_WRITE_HELD(&exported_lock));
+ rw_enter(&exported_lock, RW_WRITER);
- export_unlink(exi);
+ error = export_unlink(fsid, fid, vp, &exi);
+
+ if (error) {
+ rw_exit(&exported_lock);
+ return (error);
+ }
+
+ /* pseudo node is not a real exported filesystem */
+ if (PSEUDO(exi)) {
+ /*
+ * Put the pseudo node back into the export table
+ * before erroring out.
+ */
+ export_link(exi);
+ rw_exit(&exported_lock);
+ return (EINVAL);
+ }
/*
* Remove security flavors before treeclimb_unexport() is called
@@ -1633,17 +1688,25 @@ unexport(struct exportinfo *exi)
if (exi->exi_visible) {
struct exportinfo *newexi;
- newexi = pseudo_exportfs(exi->exi_vp, &exi->exi_fid,
- exi->exi_visible, &exi->exi_export);
- exi->exi_visible = NULL;
+ error = pseudo_exportfs(exi->exi_vp, exi->exi_visible,
+ &exi->exi_export, &newexi);
+ if (error)
+ goto done;
- /* interconnect the existing treenode with the new exportinfo */
+ exi->exi_visible = NULL;
+ /*
+ * pseudo_exportfs() has allocated new exportinfo,
+ * update the treenode.
+ */
newexi->exi_tree = exi->exi_tree;
newexi->exi_tree->tree_exi = newexi;
+
} else {
treeclimb_unexport(exi);
}
+ rw_exit(&exported_lock);
+
/*
* Need to call into the NFSv4 server and release all data
* held on this particular export. This is important since
@@ -1673,6 +1736,12 @@ unexport(struct exportinfo *exi)
}
exi_rele(exi);
+ return (error);
+
+done:
+ rw_exit(&exported_lock);
+ exi_rele(exi);
+ return (error);
}
/*
@@ -2456,7 +2525,7 @@ checkexport(fsid_t *fsid, fid_t *fid)
rw_enter(&exported_lock, RW_READER);
for (exi = exptable[exptablehash(fsid, fid)];
exi != NULL;
- exi = exi->fid_hash.next) {
+ exi = exi->exi_hash) {
if (exportmatch(exi, fsid, fid)) {
/*
* If this is the place holder for the
@@ -2494,7 +2563,7 @@ checkexport4(fsid_t *fsid, fid_t *fid, vnode_t *vp)
for (exi = exptable[exptablehash(fsid, fid)];
exi != NULL;
- exi = exi->fid_hash.next) {
+ exi = exi->exi_hash) {
if (exportmatch(exi, fsid, fid)) {
/*
* If this is the place holder for the
diff --git a/usr/src/uts/common/fs/pkp_hash.c b/usr/src/uts/common/fs/pkp_hash.c
deleted file mode 100644
index ee74adf008..0000000000
--- a/usr/src/uts/common/fs/pkp_hash.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
- */
-
-#include <sys/pkp_hash.h>
-
-/*
- * Pearson's string hash
- *
- * See: Communications of the ACM, June 1990 Vol 33 pp 677-680
- * http://portal.acm.org/citation.cfm?doid=78973.78978
- */
-
-#define MOD2(a, pow_of_2) ((a) & ((pow_of_2) - 1))
-
-static uint_t pkp_tab[PKP_HASH_SIZE] = {
-1, 87, 49, 12, 176, 178, 102, 166, 121, 193, 6, 84, 249, 230, 44, 163,
-14, 197, 213, 181, 161, 85, 218, 80, 64, 239, 24, 226, 236, 142, 38, 200,
-110, 177, 104, 103, 141, 253, 255, 50, 77, 101, 81, 18, 45, 96, 31, 222,
-25, 107, 190, 70, 86, 237, 240, 34, 72, 242, 20, 214, 244, 227, 149, 235,
-97, 234, 57, 22, 60, 250, 82, 175, 208, 5, 127, 199, 111, 62, 135, 248,
-174, 169, 211, 58, 66, 154, 106, 195, 245, 171, 17, 187, 182, 179, 0, 243,
-132, 56, 148, 75, 128, 133, 158, 100, 130, 126, 91, 13, 153, 246, 216, 219,
-119, 68, 223, 78, 83, 88, 201, 99, 122, 11, 92, 32, 136, 114, 52, 10,
-138, 30, 48, 183, 156, 35, 61, 26, 143, 74, 251, 94, 129, 162, 63, 152,
-170, 7, 115, 167, 241, 206, 3, 150, 55, 59, 151, 220, 90, 53, 23, 131,
-125, 173, 15, 238, 79, 95, 89, 16, 105, 137, 225, 224, 217, 160, 37, 123,
-118, 73, 2, 157, 46, 116, 9, 145, 134, 228, 207, 212, 202, 215, 69, 229,
-27, 188, 67, 124, 168, 252, 42, 4, 29, 108, 21, 247, 19, 205, 39, 203,
-233, 40, 186, 147, 198, 192, 155, 33, 164, 191, 98, 204, 165, 180, 117, 76,
-140, 36, 210, 172, 41, 54, 159, 8, 185, 232, 113, 196, 231, 47, 146, 120,
-51, 65, 28, 144, 254, 221, 93, 189, 194, 139, 112, 43, 71, 109, 184, 209
-};
-
-uint_t
-pkp_tab_hash(char *str, int len)
-{
- uint_t key = 0x12345678; /* arbitrary value */
- uint_t hash;
- int i;
-
- hash = MOD2((key + len), PKP_HASH_SIZE);
-
- for (i = 0; i < len; i++) {
- hash = MOD2((hash + str[i]), PKP_HASH_SIZE);
- hash = pkp_tab[hash];
- }
-
- return (hash);
-}
diff --git a/usr/src/uts/common/fs/sharefs/sharetab.c b/usr/src/uts/common/fs/sharefs/sharetab.c
index 5036cd3f17..53d4ae4a2b 100644
--- a/usr/src/uts/common/fs/sharefs/sharetab.c
+++ b/usr/src/uts/common/fs/sharefs/sharetab.c
@@ -20,9 +20,12 @@
*/
/*
- * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
*/
+#pragma ident "%Z%%M% %I% %E% SMI"
+
#include <sys/types.h>
#include <sys/types32.h>
#include <sys/param.h>
@@ -83,6 +86,36 @@ timestruc_t sharetab_snap_time;
uint_t sharetab_generation; /* Only increments and wraps! */
+static uint_t pkp_tab[SHARETAB_HASHES];
+
+/*
+ * Initialize table in pseudo-random fashion
+ * for use in Pearson's string hash algorithm.
+ *
+ * See: Communications of the ACM, June 1990 Vol 33 pp 677-680
+ * http://www.acm.org/pubs/citations/journals/cacm/1990-33-6/p677-pearson
+ */
+static void
+init_pkp_tab(void)
+{
+ int i;
+ int j;
+ int k = 7;
+ uint_t s;
+
+ for (i = 0; i < SHARETAB_HASHES; i++)
+ pkp_tab[i] = i;
+
+ for (j = 0; j < 4; j++) {
+ for (i = 0; i < SHARETAB_HASHES; i++) {
+ s = pkp_tab[i];
+ k = MOD2((k + s), SHARETAB_HASHES);
+ pkp_tab[i] = pkp_tab[k];
+ pkp_tab[k] = s;
+ }
+ }
+}
+
/*
* Take care of cleaning up a share.
* If passed in a length array, use it to determine how much
@@ -135,7 +168,7 @@ sharefs_remove(share_t *sh, sharefs_lens_t *shl)
}
iPath = shl ? shl->shl_path : strlen(sh->sh_path);
- iHash = pkp_tab_hash(sh->sh_path, strlen(sh->sh_path));
+ SHARETAB_HASH_IT(iHash, sh->sh_path);
/*
* Now walk down the hash table and find the entry to free!
@@ -230,7 +263,7 @@ sharefs_add(share_t *sh, sharefs_lens_t *shl)
/*
* Now we need to find where we have to add the entry.
*/
- iHash = pkp_tab_hash(sh->sh_path, strlen(sh->sh_path));
+ SHARETAB_HASH_IT(iHash, sh->sh_path);
iPath = shl ? shl->shl_path : strlen(sh->sh_path);
@@ -314,6 +347,8 @@ sharefs_add(share_t *sh, sharefs_lens_t *shl)
void
sharefs_sharetab_init(void)
{
+ init_pkp_tab();
+
rw_init(&sharetab_lock, NULL, RW_DEFAULT, NULL);
rw_init(&sharefs_lock, NULL, RW_DEFAULT, NULL);
diff --git a/usr/src/uts/common/nfs/export.h b/usr/src/uts/common/nfs/export.h
index 56d8e2b0de..5d6072c2f7 100644
--- a/usr/src/uts/common/nfs/export.h
+++ b/usr/src/uts/common/nfs/export.h
@@ -419,13 +419,7 @@ typedef struct treenode {
/* Root of nfs pseudo namespace */
extern treenode_t *ns_root;
-#define EXPTABLESIZE 256
-
-struct exp_hash {
- struct exportinfo *prev; /* ptr to the previous exportinfo */
- struct exportinfo *next; /* ptr to the next exportinfo */
- struct exportinfo **bckt; /* backpointer to the hash bucket */
-};
+#define EXPTABLESIZE 16
/*
* A node associated with an export entry on the
@@ -447,8 +441,7 @@ struct exportinfo {
struct exportdata exi_export;
fsid_t exi_fsid;
struct fid exi_fid;
- struct exp_hash fid_hash;
- struct exp_hash path_hash;
+ struct exportinfo *exi_hash;
struct treenode *exi_tree;
fhandle_t exi_fh;
krwlock_t exi_cache_lock;
@@ -512,7 +505,6 @@ struct exp_visible {
typedef struct exp_visible exp_visible_t;
#define PSEUDO(exi) ((exi)->exi_export.ex_flags & EX_PSEUDO)
-#define EXP_LINKED(exi) ((exi)->fid_hash.bckt != NULL)
#define EQFSID(fsidp1, fsidp2) \
(((fsidp1)->val[0] == (fsidp2)->val[0]) && \
@@ -541,6 +533,7 @@ extern int nfsauth4_access(struct exportinfo *, vnode_t *,
struct svc_req *);
extern int nfsauth4_secinfo_access(struct exportinfo *,
struct svc_req *, int, int);
+extern int nfs_fhhash(fsid_t *, fid_t *);
extern int nfs_fhbcmp(char *, char *, int);
extern int nfs_exportinit(void);
extern void nfs_exportfini(void);
@@ -562,7 +555,8 @@ extern struct exportinfo *nfs_vptoexi(vnode_t *, vnode_t *, cred_t *, int *,
extern int nfs_check_vpexi(vnode_t *, vnode_t *, cred_t *,
struct exportinfo **);
extern void export_link(struct exportinfo *);
-extern void export_unlink(struct exportinfo *);
+extern int export_unlink(fsid_t *, fid_t *, vnode_t *,
+ struct exportinfo **);
extern vnode_t *untraverse(vnode_t *);
extern int vn_is_nfs_reparse(vnode_t *, cred_t *);
extern int client_is_downrev(struct svc_req *);
@@ -579,8 +573,8 @@ extern int nfs_visible_inode(struct exportinfo *, ino64_t, int *);
extern int has_visible(struct exportinfo *, vnode_t *);
extern void free_visible(struct exp_visible *);
extern int nfs_exported(struct exportinfo *, vnode_t *);
-extern struct exportinfo *pseudo_exportfs(vnode_t *, fid_t *,
- struct exp_visible *, struct exportdata *);
+extern int pseudo_exportfs(vnode_t *, struct exp_visible *,
+ struct exportdata *, struct exportinfo **);
extern int vop_fid_pseudo(vnode_t *, fid_t *fidp);
extern int nfs4_vget_pseudo(struct exportinfo *, vnode_t **, fid_t *);
/*
diff --git a/usr/src/uts/common/nfs/nfs4_idmap_impl.h b/usr/src/uts/common/nfs/nfs4_idmap_impl.h
index f0f166688d..344e98213a 100644
--- a/usr/src/uts/common/nfs/nfs4_idmap_impl.h
+++ b/usr/src/uts/common/nfs/nfs4_idmap_impl.h
@@ -2,8 +2,9 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -19,15 +20,17 @@
* CDDL HEADER END
*/
/*
- * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
*/
#ifndef _NFS4_IDMAP_IMPL_H
#define _NFS4_IDMAP_IMPL_H
+#pragma ident "%Z%%M% %I% %E% SMI"
+
#include <sys/list.h>
#include <sys/door.h>
-#include <sys/pkp_hash.h>
/*
* This is a private header file. Applications should not directly include
@@ -41,7 +44,7 @@ extern "C" {
/*
* Cache Entry Definitions
*/
-#define NFSID_CACHE_ANCHORS PKP_HASH_SIZE
+#define NFSID_CACHE_ANCHORS 256
typedef struct nfsidmap {
struct nfsidmap *id_chain[2]; /* must be first */
diff --git a/usr/src/uts/common/sharefs/sharetab.h b/usr/src/uts/common/sharefs/sharetab.h
index f1a3fd620c..9271c07a8d 100644
--- a/usr/src/uts/common/sharefs/sharetab.h
+++ b/usr/src/uts/common/sharefs/sharetab.h
@@ -18,14 +18,16 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
*/
#ifndef _SHAREFS_SHARETAB_H
#define _SHAREFS_SHARETAB_H
-#include <sys/pkp_hash.h>
+#pragma ident "%Z%%M% %I% %E% SMI"
/*
* This header defines the glue to keeping a sharetab in memory.
@@ -52,7 +54,7 @@ typedef struct sharefs_hash_head {
uint_t ssh_count;
} sharefs_hash_head_t;
-#define SHARETAB_HASHES PKP_HASH_SIZE
+#define SHARETAB_HASHES 256
typedef struct sharetab {
sharefs_hash_head_t s_buckets[SHARETAB_HASHES];
@@ -61,6 +63,29 @@ typedef struct sharetab {
uint_t s_count;
} sharetab_t;
+#define MOD2(a, pow_of_2) (a) & ((pow_of_2) - 1)
+
+/*
+ * Pearson's string hash
+ *
+ * See: Communications of the ACM, June 1990 Vol 33 pp 677-680
+ * http://www.acm.org/pubs/citations/journals/cacm/1990-33-6/p677-pearson
+ */
+#define SHARETAB_HASH_IT(hash, path) \
+{ \
+ uint_t key = 0x12345678; /* arbitrary value */ \
+ int i, len; \
+ \
+ len = strlen((path)); \
+ \
+ (hash) = MOD2((key + len), SHARETAB_HASHES); \
+ \
+ for (i = 0; i < len; i++) { \
+ (hash) = MOD2(((hash) + (path)[i]), SHARETAB_HASHES); \
+ (hash) = pkp_tab[(hash)]; \
+ } \
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/uts/common/sys/Makefile b/usr/src/uts/common/sys/Makefile
index fbcbd7fc5c..63883cfcbb 100644
--- a/usr/src/uts/common/sys/Makefile
+++ b/usr/src/uts/common/sys/Makefile
@@ -431,7 +431,6 @@ CHKHDRS= \
pg.h \
pghw.h \
physmem.h \
- pkp_hash.h \
pm.h \
policy.h \
poll.h \
diff --git a/usr/src/uts/common/sys/pkp_hash.h b/usr/src/uts/common/sys/pkp_hash.h
deleted file mode 100644
index e7602304bf..0000000000
--- a/usr/src/uts/common/sys/pkp_hash.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
- */
-
-#ifndef _PKP_HASH_H_
-#define _PKP_HASH_H_
-
-#include <sys/types.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Pearson's string hash
- *
- * See: Communications of the ACM, June 1990 Vol 33 pp 677-680
- * http://portal.acm.org/citation.cfm?doid=78973.78978
- */
-#define PKP_HASH_SIZE 256
-
-extern uint_t pkp_tab_hash(char *, int);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKP_HASH_H_ */