X-Git-Url: https://git.decadent.org.uk/gitweb/?p=nfs-utils.git;a=blobdiff_plain;f=support%2Fexport%2Fexport.c;h=3e4da699091110645362457b3d2f3e264949233e;hp=ba0d095eba5d1bf0c94cb52e4fba85ee545a2253;hb=5d954d871fb265af584faef5df6e2e7e6ada7c3b;hpb=1898a9dc11a9834f557775a6b7d1ca7b1b6ca057 diff --git a/support/export/export.c b/support/export/export.c index ba0d095..3e4da69 100644 --- a/support/export/export.c +++ b/support/export/export.c @@ -6,7 +6,9 @@ * Copyright (C) 1995, 1996 Olaf Kirch */ -#include "config.h" +#ifdef HAVE_CONFIG_H +#include +#endif #include #include @@ -17,7 +19,8 @@ #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); @@ -25,6 +28,34 @@ static int export_check(nfs_export *, struct hostent *, char *); static nfs_export * export_allowed_internal(struct hostent *hp, char *path); +static void +export_free(nfs_export *exp) +{ + xfree(exp->m_export.e_squids); + xfree(exp->m_export.e_sqgids); + free(exp->m_export.e_mountpoint); + free(exp->m_export.e_fslocdata); + + xfree(exp->m_export.e_hostname); + xfree(exp); +} + +static void warn_duplicated_exports(nfs_export *exp, struct exportent *eep) +{ + if (exp->m_export.e_flags != eep->e_flags) { + xlog(L_ERROR, "incompatible duplicated export entries:"); + xlog(L_ERROR, "\t%s:%s (0x%x) [IGNORED]", eep->e_hostname, + eep->e_path, eep->e_flags); + xlog(L_ERROR, "\t%s:%s (0x%x)", exp->m_export.e_hostname, + exp->m_export.e_path, exp->m_export.e_flags); + } else { + xlog(L_ERROR, "duplicated export entries:"); + xlog(L_ERROR, "\t%s:%s", eep->e_hostname, eep->e_path); + xlog(L_ERROR, "\t%s:%s", exp->m_export.e_hostname, + exp->m_export.e_path); + } +} + int export_read(char *fname) { @@ -33,27 +64,13 @@ export_read(char *fname) setexportent(fname, "r"); while ((eep = getexportent(0,1)) != NULL) { - exp = export_lookup(eep->e_hostname, eep->e_path, 0); - if (!exp) - export_create(eep,0); - else { - if (exp->m_export.e_flags != eep->e_flags) { - xlog(L_ERROR, "incompatible duplicated export entries:"); - xlog(L_ERROR, "\t%s:%s (0x%x) [IGNORED]", eep->e_hostname, - eep->e_path, eep->e_flags); - xlog(L_ERROR, "\t%s:%s (0x%x)", exp->m_export.e_hostname, - exp->m_export.e_path, exp->m_export.e_flags); - } - else { - xlog(L_ERROR, "duplicated export entries:"); - xlog(L_ERROR, "\t%s:%s", eep->e_hostname, eep->e_path); - xlog(L_ERROR, "\t%s:%s", exp->m_export.e_hostname, - exp->m_export.e_path); - } - } + exp = export_lookup(eep->e_hostname, eep->e_path, 0); + if (!exp) + export_create(eep, 0); + else + warn_duplicated_exports(exp, eep); } endexportent(); - return 0; } @@ -83,11 +100,14 @@ export_init(nfs_export *exp, nfs_client *clp, struct exportent *nep) struct exportent *e = &exp->m_export; dupexportent(e, nep); + if (nep->e_hostname) + e->e_hostname = xstrdup(nep->e_hostname); exp->m_exported = 0; exp->m_xtabent = 0; exp->m_mayexport = 0; exp->m_changed = 0; + exp->m_warned = 0; exp->m_client = clp; clp->m_count++; } @@ -106,33 +126,54 @@ export_dup(nfs_export *exp, struct hostent *hp) new = (nfs_export *) xmalloc(sizeof(*new)); memcpy(new, exp, sizeof(*new)); dupexportent(&new->m_export, &exp->m_export); + if (exp->m_export.e_hostname) + new->m_export.e_hostname = xstrdup(exp->m_export.e_hostname); clp = client_dup(exp->m_client, hp); + if (clp == NULL) { + export_free(new); + return NULL; + } clp->m_count++; new->m_client = clp; new->m_mayexport = exp->m_mayexport; new->m_exported = 0; new->m_xtabent = 0; new->m_changed = 0; + new->m_warned = 0; export_add(new); 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 * @@ -142,7 +183,7 @@ export_find(struct hostent *hp, char *path) 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) @@ -161,7 +202,7 @@ export_allowed_internal (struct hostent *hp, char *path) 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; @@ -172,10 +213,9 @@ export_allowed_internal (struct hostent *hp, char *path) return NULL; } -struct exportent * +nfs_export * export_allowed(struct hostent *hp, char *path) { - static struct exportent ee; nfs_export *exp; char epath[MAXPATHLEN+1]; char *p = NULL; @@ -188,10 +228,8 @@ export_allowed(struct hostent *hp, char *path) /* Try the longest matching exported pathname. */ while (1) { exp = export_allowed_internal (hp, epath); - if (exp) { - dupexportent(&ee, &exp->m_export); - return ⅇ - } + if (exp) + return exp; /* We have to treat the root, "/", specially. */ if (p == &epath[1]) break; p = strrchr(epath, '/'); @@ -202,17 +240,30 @@ export_allowed(struct hostent *hp, char *path) 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; } @@ -225,35 +276,56 @@ export_check(nfs_export *exp, struct hostent *hp, char *path) return client_check(exp->m_client, hp); } +/** + * export_freeall - deallocate all nfs_export records + * + */ void 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_squids); - if (exp->m_export.e_sqgids) - xfree(exp->m_export.e_sqgids); - xfree(exp); + export_free(exp); + } + for (j = 0; j < HASH_TABLE_SIZE; j++) { + exportlist[i].entries[j].p_first = NULL; + exportlist[i].entries[j].p_last = NULL; } - exportlist[i] = NULL; + exportlist[i].p_head = NULL; } client_freeall(); } -void -export_reset(nfs_export *exp) +/* + * 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) { - if (!exp) - return; + int num = strtoint(str); - /* Restore m_path. */ - strncpy(exp->m_export.m_path, exp->m_export.e_path, - sizeof (exp->m_export.m_path) - 1); - exp->m_export.m_path[sizeof (exp->m_export.m_path) - 1] = '\0'; + return num % HASH_TABLE_SIZE; }