Linux NFS development
 help / color / mirror / Atom feed
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

  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