From: "J. Bruce Fields" <bfields@fieldses.org>
To: vincent.roqueta@ext.bull.net
Cc: nfs@lists.sourceforge.net, Tomas Richter <krik3t@gmail.com>
Subject: Re: Exportfs and rpc.mountd optimalization - patch
Date: Mon, 22 Aug 2005 11:53:20 -0400 [thread overview]
Message-ID: <20050822155320.GC12618@fieldses.org> (raw)
In-Reply-To: <42B86FB9.6060102@gmail.com>
Vincent, have you tried rerunning your export-scalability test with this
patch applied to see if it helps?
--b.
On Tue, Jun 21, 2005 at 09:51:21PM +0200, Tomas Richter wrote:
> There's patch for my optimalization of exportfs and rpc.mountd (attachment).
>
> 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>.
>
> Tomas Richter
>
> diff -rbu nfs-utils/support/export/export.c nfs-utils-opt/support/export/export.c
> --- nfs-utils/support/export/export.c 2005-06-20 23:26:00.000000000 +0200
> +++ nfs-utils-opt/support/export/export.c 2005-05-05 16:15:45.000000000 +0200
> @@ -4,6 +4,8 @@
> * Maintain list of exported file systems.
> *
> * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
> + *
> + * 2005 Tomas Richter <krik3t@gmail.com> Added hashing for exportlist
> */
>
> #include "config.h"
> @@ -17,13 +19,15 @@
> #include "nfslib.h"
> #include "exportfs.h"
>
> -nfs_export *exportlist[MCL_MAXTYPES] = { NULL, };
> +hash_table exportlist[MCL_MAXTYPES] = {{NULL, {{NULL,NULL}, }}, };
>
> static void export_init(nfs_export *exp, nfs_client *clp,
> struct exportent *nep);
> static int export_check(nfs_export *, struct hostent *, char *);
> static nfs_export *
> export_allowed_internal(struct hostent *hp, char *path);
> +void hash_export_add(nfs_export*);
> +nfs_export * hash_export_lookup(char*, char*, int);
>
> int
> export_read(char *fname)
> @@ -33,7 +37,7 @@
>
> setexportent(fname, "r");
> while ((eep = getexportent(0,1)) != NULL) {
> - exp = export_lookup(eep->e_hostname, eep->e_path, 0);
> + exp = hash_export_lookup(eep->e_hostname, eep->e_path, 0);
> if (!exp)
> export_create(eep,0);
> else {
> @@ -72,7 +76,7 @@
> }
> exp = (nfs_export *) xmalloc(sizeof(*exp));
> export_init(exp, clp, xep);
> - export_add(exp);
> + hash_export_add(exp);
>
> return exp;
> }
> @@ -113,11 +117,12 @@
> new->m_exported = 0;
> new->m_xtabent = 0;
> new->m_changed = 0;
> - export_add(new);
> + hash_export_add(new);
>
> return new;
> }
>
> +/* This function was replaced by hash_export_add
> void
> export_add(nfs_export *exp)
> {
> @@ -134,6 +139,7 @@
> exp->m_next = *epp;
> *epp = exp;
> }
> +*/
>
> nfs_export *
> export_find(struct hostent *hp, char *path)
> @@ -142,7 +148,7 @@
> 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 +167,7 @@
> 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;
> @@ -199,6 +205,7 @@
> return NULL;
> }
>
> +/* This function was replace by hash_export_lookup
> nfs_export *
> export_lookup(char *hname, char *path, int canonical)
> {
> @@ -207,11 +214,12 @@
>
> if (!(clp = client_lookup(hname, canonical)))
> return NULL;
> - for (exp = exportlist[clp->m_type]; exp; exp = exp->m_next)
> + for (exp = exportlist[clp->m_type].p_head; exp; exp = exp->m_next)
> if (exp->m_client == clp && !strcmp(exp->m_export.e_path, path))
> return exp;
> return NULL;
> }
> +*/
>
> static int
> export_check(nfs_export *exp, struct hostent *hp, char *path)
> @@ -226,10 +234,10 @@
> 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)
> @@ -240,7 +248,11 @@
> free(exp->m_export.e_mountpoint);
> 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();
> }
> @@ -256,3 +268,90 @@
> sizeof (exp->m_export.m_path) - 1);
> exp->m_export.m_path[sizeof (exp->m_export.m_path) - 1] = '\0';
> }
> +
> +/*
> +* Functions for work with hash table.
> +*/
> +
> +/*
> +* compute and returns int from string
> +* int can be same for different strings, but in that case it doesn'n matter.
> +*/
> +unsigned int strtoint(char *str){
> + int i = 0;
> + unsigned int n = 0;
> + while ( str[i] != '\0') {
> + n+=((int)str[i])*i;
> + i++;
> + }
> + return n;
> +}
> +
> +/*
> +* represents hash function
> +*/
> +int hashint(unsigned int num){
> + return num % HASH_TABLE_SIZE;
> +}
> +
> +/*
> +* add nfs_export exp into hash table
> +*/
> +void hash_export_add(nfs_export *exp){
> + hash_table * p_tbl;
> + hash_entry * p_hen;
> + nfs_export * p_next;
> +
> + int type = exp->m_client->m_type;
> + /* hashing by m_hostname */
> + int pos = hashint(strtoint(exp->m_client->m_hostname));
> +
> + if (type < 0 || type >= MCL_MAXTYPES) {
> + xlog(L_FATAL, "unknown client type in hash_export_add");
> + }
> +
> + 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;
> + }
> +}
> +
> +/*
> +* search for export in hash table
> +* if it is present, returns pointer to export else returns NULL
> +*/
> +nfs_export * hash_export_lookup(char *hname, char*path, int canonical) {
> + nfs_client * clp;
> + nfs_export * exp;
> + hash_entry * p_hen;
> +
> + if(!(clp = client_lookup(hname, canonical))) {
> + return NULL;
> + }
> +
> + int pos = hashint( strtoint( clp->m_hostname ) );
> + p_hen = &(exportlist[clp->m_type].entries[pos]); /* pointer to hash entry */
> +
> + 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;
> +
> +}
> +
> diff -rbu nfs-utils/support/export/rmtab.c nfs-utils-opt/support/export/rmtab.c
> --- nfs-utils/support/export/rmtab.c 2005-06-20 23:26:00.000000000 +0200
> +++ nfs-utils-opt/support/export/rmtab.c 2005-04-24 15:31:35.000000000 +0200
> @@ -36,7 +36,7 @@
> /* see if the entry already exists, otherwise this was an instantiated
> * wild card, and we must add it
> */
> - nfs_export *exp2 = export_lookup(rep->r_client,
> + nfs_export *exp2 = hash_export_lookup(rep->r_client,
> exp->m_export.e_path, 0);
> if (!exp2) {
> struct exportent ee;
> diff -rbu nfs-utils/support/export/xtab.c nfs-utils-opt/support/export/xtab.c
> --- nfs-utils/support/export/xtab.c 2005-06-20 23:26:00.000000000 +0200
> +++ nfs-utils-opt/support/export/xtab.c 2005-04-24 15:31:04.000000000 +0200
> @@ -35,7 +35,7 @@
> return 0;
> setexportent(xtab, "r");
> while ((xp = getexportent(is_export==0, 0)) != NULL) {
> - if (!(exp = export_lookup(xp->e_hostname, xp->e_path, is_export != 1)) &&
> + if (!(exp = hash_export_lookup(xp->e_hostname, xp->e_path, is_export != 1)) &&
> !(exp = export_create(xp, is_export!=1))) {
> continue;
> }
> @@ -92,7 +92,7 @@
> 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 -rbu nfs-utils/support/include/exportfs.h nfs-utils-opt/support/include/exportfs.h
> --- nfs-utils/support/include/exportfs.h 2005-06-20 23:26:00.000000000 +0200
> +++ nfs-utils-opt/support/include/exportfs.h 2005-04-24 20:17:10.000000000 +0200
> @@ -9,6 +9,8 @@
> #ifndef EXPORTFS_H
> #define EXPORTFS_H
>
> +#define HASH_TABLE_SIZE 1021
> +
> #include <netdb.h>
> #include "nfslib.h"
>
> @@ -43,8 +45,18 @@
> m_changed : 1; /* options (may) have changed */
> } nfs_export;
>
> +typedef struct m_hash_entry {
> + nfs_export * p_first;
> + nfs_export * p_last;
> +} hash_entry;
> +
> +typedef struct m_hash_table {
> + nfs_export * p_head;
> + hash_entry entries[HASH_TABLE_SIZE];
> +} hash_table;
> +
> extern nfs_client * clientlist[MCL_MAXTYPES];
> -extern nfs_export * exportlist[MCL_MAXTYPES];
> +extern hash_table exportlist[MCL_MAXTYPES];
>
> nfs_client * client_lookup(char *hname, int canonical);
> nfs_client * client_find(struct hostent *);
> @@ -59,9 +71,11 @@
> int client_member(char *client, char *name);
>
> int export_read(char *fname);
> -void export_add(nfs_export *);
> +/* void export_add(nfs_export *);*/
> +void hash_export_add(nfs_export *exp);
> void export_reset(nfs_export *);
> -nfs_export * export_lookup(char *hname, char *path, int caconical);
> +/* nfs_export * export_lookup(char *hname, char *path, int caconical); */
> +nfs_export * hash_export_lookup(char *hname, char *path, int caconical);
> nfs_export * export_find(struct hostent *, char *path);
> nfs_export * export_allowed(struct hostent *, char *path);
> nfs_export * export_create(struct exportent *, int canonical);
> diff -rbu nfs-utils/utils/exportfs/exportfs.c nfs-utils-opt/utils/exportfs/exportfs.c
> --- nfs-utils/utils/exportfs/exportfs.c 2005-06-20 23:28:00.000000000 +0200
> +++ nfs-utils-opt/utils/exportfs/exportfs.c 2005-06-20 23:58:45.000000000 +0200
> @@ -189,10 +189,10 @@
> {
> 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);
> }
> }
> @@ -208,7 +208,7 @@
> 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,
> @@ -252,7 +252,7 @@
> exp = export_find(hp, path);
> hname = hp->h_name;
> } else {
> - exp = export_lookup(hname, path, 0);
> + exp = hash_export_lookup(hname, path, 0);
> }
>
> if (!exp) {
> @@ -300,7 +300,7 @@
> }
> }
>
> - 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)
> @@ -357,7 +357,7 @@
> 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 */
> Pouze v nfs-utils-opt/utils/exportfs: exportfs.c~
> diff -rbu nfs-utils/utils/mountd/auth.c nfs-utils-opt/utils/mountd/auth.c
> --- nfs-utils/utils/mountd/auth.c 2005-06-20 23:28:00.000000000 +0200
> +++ nfs-utils-opt/utils/mountd/auth.c 2005-04-24 15:23:14.000000000 +0200
> @@ -93,7 +93,7 @@
>
> 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 (!client_member(my_client.m_hostname, exp->m_client->m_hostname))
> continue;
> if (strcmp(path, exp->m_export.e_path))
> diff -rbu nfs-utils/utils/mountd/cache.c nfs-utils-opt/utils/mountd/cache.c
> --- nfs-utils/utils/mountd/cache.c 2005-06-20 23:28:00.000000000 +0200
> +++ nfs-utils-opt/utils/mountd/cache.c 2005-04-24 15:24:14.000000000 +0200
> @@ -144,7 +144,7 @@
>
> /* Now determine export point for this fsid/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 (!client_member(dom, exp->m_client->m_hostname))
> continue;
> if (fsidtype == 1 &&
> @@ -244,7 +244,7 @@
>
> /* 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 (!client_member(dom, exp->m_client->m_hostname))
> continue;
> if (strcmp(path, exp->m_export.e_path))
> diff -rbu nfs-utils/utils/mountd/mountd.c nfs-utils-opt/utils/mountd/mountd.c
> --- nfs-utils/utils/mountd/mountd.c 2005-06-20 23:28:00.000000000 +0200
> +++ nfs-utils-opt/utils/mountd/mountd.c 2005-06-20 23:53:01.000000000 +0200
> @@ -371,7 +371,7 @@
> 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.m_path, e->ex_dir))
> break;
-------------------------------------------------------
SF.Net email is Sponsored by the Better Software Conference & EXPO
September 19-22, 2005 * San Francisco, CA * Development Lifecycle Practices
Agile & Plan-Driven Development * Managing Projects & Teams * Testing & QA
Security * Process Improvement & Measurement * http://www.sqe.com/bsce5sf
_______________________________________________
NFS maillist - NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs
next prev parent reply other threads:[~2005-08-22 15:53 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-06-21 19:51 Exportfs and rpc.mountd optimalization - patch Tomas Richter
2005-08-22 15:53 ` J. Bruce Fields [this message]
2005-08-22 16:05 ` Vincent Roqueta
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20050822155320.GC12618@fieldses.org \
--to=bfields@fieldses.org \
--cc=krik3t@gmail.com \
--cc=nfs@lists.sourceforge.net \
--cc=vincent.roqueta@ext.bull.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox