Exportfs and rpc.mountd optimalization (bz 76643)
This commit is contained in:
parent
3de3019b29
commit
0e25fb5be3
357
nfs-utils-1.1.4-export-hash.patch
Normal file
357
nfs-utils-1.1.4-export-hash.patch
Normal file
@ -0,0 +1,357 @@
|
||||
commit 4cacc965afc4fb03a465ffcc6cb3078aeadc3818
|
||||
Author: Tomas Richter <krik3t@gmail.com>
|
||||
Date: Wed Feb 18 13:33:27 2009 -0500
|
||||
|
||||
Exportfs and rpc.mountd optimalization
|
||||
|
||||
There were some problems with exportfs and rpc.mountd for long export
|
||||
lists - see https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=76643
|
||||
I do optimalization as my bachelors thesis (Facuulty of informatics,
|
||||
Masaryk's university Brno, Czech Republic), under lead of Yenya
|
||||
Kasprzak.
|
||||
|
||||
Both exportfs and rpc.mount build linked list of exports (shared
|
||||
functions in export.c). Every time they are inserting new export into
|
||||
list, they search for same export in list.
|
||||
I replaced linked list by hash table and functions export_add and
|
||||
export_lookup by functions hash_export_add and hash_export_lookup
|
||||
(export.c).
|
||||
|
||||
Because some other functions required exportlist as linked list, hash
|
||||
table has some implementation modification im comparison with ordinary
|
||||
hash table. It also keeps exports in linked list and has pointer to
|
||||
head of the list. So there's no need of implementation function
|
||||
<for_all_in_hash_table>.
|
||||
|
||||
Signed-off-by: Tomas Richter <krik3t@gmail.com>
|
||||
Signed-off-by: Steve Dickson <steved@redhat.com>
|
||||
|
||||
diff -up nfs-utils-1.1.4/support/export/export.c.orig nfs-utils-1.1.4/support/export/export.c
|
||||
--- nfs-utils-1.1.4/support/export/export.c.orig 2008-10-17 10:20:09.000000000 -0400
|
||||
+++ nfs-utils-1.1.4/support/export/export.c 2009-02-18 19:42:13.000000000 -0500
|
||||
@@ -19,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);
|
||||
@@ -125,22 +126,35 @@ export_dup(nfs_export *exp, struct hoste
|
||||
|
||||
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 *
|
||||
@@ -150,7 +164,7 @@ export_find(struct hostent *hp, char *pa
|
||||
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)
|
||||
@@ -169,7 +183,7 @@ export_allowed_internal (struct hostent
|
||||
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;
|
||||
@@ -207,17 +221,30 @@ export_allowed(struct hostent *hp, char
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -234,10 +261,10 @@ 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)
|
||||
@@ -251,7 +278,40 @@ export_freeall(void)
|
||||
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;
|
||||
+}
|
||||
diff -up nfs-utils-1.1.4/support/export/xtab.c.orig nfs-utils-1.1.4/support/export/xtab.c
|
||||
--- nfs-utils-1.1.4/support/export/xtab.c.orig 2008-10-17 10:20:09.000000000 -0400
|
||||
+++ nfs-utils-1.1.4/support/export/xtab.c 2009-02-18 19:42:13.000000000 -0500
|
||||
@@ -100,7 +100,7 @@ xtab_write(char *xtab, char *xtabtmp, in
|
||||
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)
|
||||
diff -up nfs-utils-1.1.4/support/include/exportfs.h.orig nfs-utils-1.1.4/support/include/exportfs.h
|
||||
--- nfs-utils-1.1.4/support/include/exportfs.h.orig 2008-10-17 10:20:09.000000000 -0400
|
||||
+++ nfs-utils-1.1.4/support/include/exportfs.h 2009-02-18 19:42:13.000000000 -0500
|
||||
@@ -52,8 +52,21 @@ typedef struct mexport {
|
||||
* 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 *);
|
||||
@@ -69,7 +82,7 @@ struct hostent * client_resolve(struct
|
||||
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);
|
||||
diff -up nfs-utils-1.1.4/support/misc/tcpwrapper.c.orig nfs-utils-1.1.4/support/misc/tcpwrapper.c
|
||||
--- nfs-utils-1.1.4/support/misc/tcpwrapper.c.orig 2009-02-17 16:45:04.000000000 -0500
|
||||
+++ nfs-utils-1.1.4/support/misc/tcpwrapper.c 2009-02-18 19:42:13.000000000 -0500
|
||||
@@ -91,7 +91,7 @@ inline unsigned int strtoint(char *str)
|
||||
|
||||
return n;
|
||||
}
|
||||
-inline int hashint(unsigned int num)
|
||||
+static inline int hashint(unsigned int num)
|
||||
{
|
||||
return num % HASH_TABLE_SIZE;
|
||||
}
|
||||
diff -up nfs-utils-1.1.4/utils/exportfs/exportfs.c.orig nfs-utils-1.1.4/utils/exportfs/exportfs.c
|
||||
--- nfs-utils-1.1.4/utils/exportfs/exportfs.c.orig 2008-10-17 10:20:09.000000000 -0400
|
||||
+++ nfs-utils-1.1.4/utils/exportfs/exportfs.c 2009-02-18 19:42:13.000000000 -0500
|
||||
@@ -111,7 +111,6 @@ main(int argc, char **argv)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
-
|
||||
if (f_export && ! f_ignore)
|
||||
export_read(_PATH_EXPORTS);
|
||||
if (f_export) {
|
||||
@@ -193,10 +192,10 @@ exports_update(int verbose)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -212,7 +211,7 @@ export_all(int 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,
|
||||
@@ -308,7 +307,7 @@ unexportfs(char *arg, int verbose)
|
||||
}
|
||||
}
|
||||
|
||||
- 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)
|
||||
@@ -453,7 +452,7 @@ dump(int verbose)
|
||||
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 */
|
||||
diff -up nfs-utils-1.1.4/utils/mountd/auth.c.orig nfs-utils-1.1.4/utils/mountd/auth.c
|
||||
--- nfs-utils-1.1.4/utils/mountd/auth.c.orig 2008-10-17 10:20:09.000000000 -0400
|
||||
+++ nfs-utils-1.1.4/utils/mountd/auth.c 2009-02-18 19:42:13.000000000 -0500
|
||||
@@ -142,7 +142,7 @@ auth_authenticate_internal(char *what, s
|
||||
|
||||
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))
|
||||
diff -up nfs-utils-1.1.4/utils/mountd/cache.c.orig nfs-utils-1.1.4/utils/mountd/cache.c
|
||||
--- nfs-utils-1.1.4/utils/mountd/cache.c.orig 2008-10-17 10:20:09.000000000 -0400
|
||||
+++ nfs-utils-1.1.4/utils/mountd/cache.c 2009-02-18 19:42:13.000000000 -0500
|
||||
@@ -394,7 +394,7 @@ void nfsd_fh(FILE *f)
|
||||
/* 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;
|
||||
@@ -654,7 +654,7 @@ void nfsd_export(FILE *f)
|
||||
|
||||
/* 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) {
|
||||
diff -up nfs-utils-1.1.4/utils/mountd/mountd.c.orig nfs-utils-1.1.4/utils/mountd/mountd.c
|
||||
--- nfs-utils-1.1.4/utils/mountd/mountd.c.orig 2008-10-17 10:20:09.000000000 -0400
|
||||
+++ nfs-utils-1.1.4/utils/mountd/mountd.c 2009-02-18 19:42:13.000000000 -0500
|
||||
@@ -521,7 +521,7 @@ get_exportlist(void)
|
||||
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;
|
@ -2,7 +2,7 @@ Summary: NFS utilities and supporting clients and daemons for the kernel NFS ser
|
||||
Name: nfs-utils
|
||||
URL: http://sourceforge.net/projects/nfs
|
||||
Version: 1.1.4
|
||||
Release: 18%{?dist}
|
||||
Release: 19%{?dist}
|
||||
Epoch: 1
|
||||
|
||||
# group all 32bit related archs
|
||||
@ -51,6 +51,7 @@ Patch121: nfs-utils-1.1.4-mount-textbased.patch
|
||||
Patch122: nfs-utils-1.1.4-mount-nolock.patch
|
||||
Patch123: nfs-utils-1.1.4-mount-udponly.patch
|
||||
Patch124: nfs-utils-1.1.4-umount-ipv6.patch
|
||||
Patch125: nfs-utils-1.1.4-export-hash.patch
|
||||
|
||||
%if %{enablefscache}
|
||||
Patch90: nfs-utils-1.1.0-mount-fsc.patch
|
||||
@ -130,6 +131,7 @@ This package also contains the mount.nfs and umount.nfs program.
|
||||
%patch122 -p1
|
||||
%patch123 -p1
|
||||
%patch124 -p1
|
||||
%patch125 -p1
|
||||
|
||||
%if %{enablefscache}
|
||||
%patch90 -p1
|
||||
@ -293,6 +295,9 @@ fi
|
||||
%attr(4755,root,root) /sbin/umount.nfs4
|
||||
|
||||
%changelog
|
||||
* Wed Feb 18 2009 Steve Dickson <steved@redhat.com> 1.1.4-19
|
||||
- Exportfs and rpc.mountd optimalization (bz 76643)
|
||||
|
||||
* Tue Feb 17 2009 Steve Dickson <steved@redhat.com> 1.1.4-18
|
||||
- umount.nfs command: Add an AF_INET6-capable version of nfs_call_unmount()
|
||||
- umount.nfs command: Support AF_INET6 server addresses
|
||||
|
Loading…
Reference in New Issue
Block a user