#include "nfslib.h"
#include "exportfs.h"
-nfs_export *exportlist[MCL_MAXTYPES] = { NULL, };
+exp_hash_table exportlist[MCL_MAXTYPES] = {{NULL, {{NULL,NULL}, }}, };
+static int export_hash(char *);
static void export_init(nfs_export *exp, nfs_client *clp,
struct exportent *nep);
return new;
}
-
-void
+/*
+ * Add export entry to hash table
+ */
+void
export_add(nfs_export *exp)
{
- nfs_export **epp;
- int type = exp->m_client->m_type;
- int slen = strlen(exp->m_export.e_path);
-
- if (type < 0 || type >= MCL_MAXTYPES)
- xlog(L_FATAL, "unknown client type in export_add");
-
- epp = exportlist + type;
- while (*epp && slen <= strlen((*epp)->m_export.e_path))
- epp = &((*epp)->m_next);
- exp->m_next = *epp;
- *epp = exp;
+ exp_hash_table *p_tbl;
+ exp_hash_entry *p_hen;
+ nfs_export *p_next;
+
+ int type = exp->m_client->m_type;
+ int pos;
+
+ pos = export_hash(exp->m_export.e_path);
+ p_tbl = &(exportlist[type]); /* pointer to hash table */
+ p_hen = &(p_tbl->entries[pos]); /* pointer to hash table entry */
+
+ if (!(p_hen->p_first)) { /* hash table entry is empty */
+ p_hen->p_first = exp;
+ p_hen->p_last = exp;
+
+ exp->m_next = p_tbl->p_head;
+ p_tbl->p_head = exp;
+ } else { /* hash table entry is NOT empty */
+ p_next = p_hen->p_last->m_next;
+ p_hen->p_last->m_next = exp;
+ exp->m_next = p_next;
+ p_hen->p_last = exp;
+ }
}
nfs_export *
int i;
for (i = 0; i < MCL_MAXTYPES; i++) {
- for (exp = exportlist[i]; exp; exp = exp->m_next) {
+ for (exp = exportlist[i].p_head; exp; exp = exp->m_next) {
if (!export_check(exp, hp, path))
continue;
if (exp->m_client->m_type == MCL_FQDN)
int i;
for (i = 0; i < MCL_MAXTYPES; i++) {
- for (exp = exportlist[i]; exp; exp = exp->m_next) {
+ for (exp = exportlist[i].p_head; exp; exp = exp->m_next) {
if (!exp->m_mayexport ||
!export_check(exp, hp, path))
continue;
return NULL;
}
+/*
+ * Search hash table for export entry.
+ */
nfs_export *
-export_lookup(char *hname, char *path, int canonical)
+export_lookup(char *hname, char *path, int canonical)
{
- nfs_client *clp;
- nfs_export *exp;
+ nfs_client *clp;
+ nfs_export *exp;
+ exp_hash_entry *p_hen;
+
+ int pos;
- if (!(clp = client_lookup(hname, canonical)))
+ clp = client_lookup(hname, canonical);
+ if(clp == NULL)
return NULL;
- for (exp = exportlist[clp->m_type]; exp; exp = exp->m_next)
- if (exp->m_client == clp && !strcmp(exp->m_export.e_path, path))
- return exp;
+
+ pos = export_hash(path);
+ p_hen = &(exportlist[clp->m_type].entries[pos]);
+ for(exp = p_hen->p_first; exp && (exp != p_hen->p_last->m_next);
+ exp = exp->m_next) {
+ if (exp->m_client == clp && !strcmp(exp->m_export.e_path, path)) {
+ return exp;
+ }
+ }
return NULL;
}
export_freeall(void)
{
nfs_export *exp, *nxt;
- int i;
+ int i, j;
for (i = 0; i < MCL_MAXTYPES; i++) {
- for (exp = exportlist[i]; exp; exp = nxt) {
+ for (exp = exportlist[i].p_head; exp; exp = nxt) {
nxt = exp->m_next;
client_release(exp->m_client);
if (exp->m_export.e_squids)
xfree(exp->m_export.e_hostname);
xfree(exp);
}
- exportlist[i] = NULL;
+ for(j = 0; j < HASH_TABLE_SIZE; j++) {
+ exportlist[i].entries[j].p_first = NULL;
+ exportlist[i].entries[j].p_last = NULL;
+ }
+ exportlist[i].p_head = NULL;
}
client_freeall();
}
+
+/*
+ * Compute and returns integer from string.
+ * Note: Its understood the smae integers can be same for
+ * different strings, but it should not matter.
+ */
+static unsigned int
+strtoint(char *str)
+{
+ int i = 0;
+ unsigned int n = 0;
+
+ while ( str[i] != '\0') {
+ n+=((int)str[i])*i;
+ i++;
+ }
+ return n;
+}
+
+/*
+ * Hash function
+ */
+static int
+export_hash(char *str)
+{
+ int num = strtoint(str);
+
+ return num % HASH_TABLE_SIZE;
+}
setexportent(xtabtmp, "w");
for (i = 0; i < MCL_MAXTYPES; i++) {
- for (exp = exportlist[i]; exp; exp = exp->m_next) {
+ for (exp = exportlist[i].p_head; exp; exp = exp->m_next) {
if (is_export && !exp->m_xtabent)
continue;
if (!is_export && ! exp->m_exported)
* matching one client */
} nfs_export;
+#define HASH_TABLE_SIZE 1021
+
+typedef struct _exp_hash_entry {
+ nfs_export * p_first;
+ nfs_export * p_last;
+} exp_hash_entry;
+
+typedef struct _exp_hash_table {
+ nfs_export * p_head;
+ exp_hash_entry entries[HASH_TABLE_SIZE];
+} exp_hash_table;
+
+extern exp_hash_table exportlist[MCL_MAXTYPES];
+
extern nfs_client * clientlist[MCL_MAXTYPES];
-extern nfs_export * exportlist[MCL_MAXTYPES];
nfs_client * client_lookup(char *hname, int canonical);
nfs_client * client_find(struct hostent *);
int client_member(char *client, char *name);
int export_read(char *fname);
-void export_add(nfs_export *);
+void export_add(nfs_export *);
void export_reset(nfs_export *);
nfs_export * export_lookup(char *hname, char *path, int caconical);
nfs_export * export_find(struct hostent *, char *path);
return n;
}
-inline int hashint(unsigned int num)
+static inline int hashint(unsigned int num)
{
return num % HASH_TABLE_SIZE;
}
return 0;
}
}
-
if (f_export && ! f_ignore)
export_read(_PATH_EXPORTS);
if (f_export) {
{
nfs_export *exp;
- for (exp = exportlist[MCL_FQDN]; exp; exp=exp->m_next) {
+ for (exp = exportlist[MCL_FQDN].p_head; exp; exp=exp->m_next) {
exports_update_one(exp, verbose);
}
- for (exp = exportlist[MCL_GSS]; exp; exp=exp->m_next) {
+ for (exp = exportlist[MCL_GSS].p_head; exp; exp=exp->m_next) {
exports_update_one(exp, verbose);
}
}
int i;
for (i = 0; i < MCL_MAXTYPES; i++) {
- for (exp = exportlist[i]; exp; exp = exp->m_next) {
+ for (exp = exportlist[i].p_head; exp; exp = exp->m_next) {
if (verbose)
printf("exporting %s:%s\n",
exp->m_client->m_hostname,
}
}
- for (exp = exportlist[htype]; exp; exp = exp->m_next) {
+ for (exp = exportlist[htype].p_head; exp; exp = exp->m_next) {
if (path && strcmp(path, exp->m_export.e_path))
continue;
if (htype != exp->m_client->m_type)
char *hname, c;
for (htype = 0; htype < MCL_MAXTYPES; htype++) {
- for (exp = exportlist[htype]; exp; exp = exp->m_next) {
+ for (exp = exportlist[htype].p_head; exp; exp = exp->m_next) {
ep = &exp->m_export;
if (!exp->m_xtabent)
continue; /* neilb */
exp = NULL;
for (i = 0; !exp && i < MCL_MAXTYPES; i++)
- for (exp = exportlist[i]; exp; exp = exp->m_next) {
+ for (exp = exportlist[i].p_head; exp; exp = exp->m_next) {
if (strcmp(path, exp->m_export.e_path))
continue;
if (!use_ipaddr && !client_member(my_client.m_hostname, exp->m_client->m_hostname))
/* Now determine export point for this fsid/domain */
for (i=0 ; i < MCL_MAXTYPES; i++) {
nfs_export *next_exp;
- for (exp = exportlist[i]; exp; exp = next_exp) {
+ for (exp = exportlist[i].p_head; exp; exp = next_exp) {
struct stat stb;
char u[16];
char *path;
/* now find flags for this export point in this domain */
for (i=0 ; i < MCL_MAXTYPES; i++) {
- for (exp = exportlist[i]; exp; exp = exp->m_next) {
+ for (exp = exportlist[i].p_head; exp; exp = exp->m_next) {
if (!use_ipaddr && !client_member(dom, exp->m_client->m_hostname))
continue;
if (exp->m_export.e_flags & NFSEXP_CROSSMOUNT) {
elist = NULL;
for (i = 0; i < MCL_MAXTYPES; i++) {
- for (exp = exportlist[i]; exp; exp = exp->m_next) {
+ for (exp = exportlist[i].p_head; exp; exp = exp->m_next) {
for (e = elist; e != NULL; e = e->ex_next) {
if (!strcmp(exp->m_export.e_path, e->ex_dir))
break;