diff options
author | Olaf Kirch <okir@suse.de> | 2006-10-04 02:15:58 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-04 07:55:17 -0700 |
commit | 07ba80635117c136714084e019375aa508365375 (patch) | |
tree | 06160152e4b9c137669a5c833366858f72601895 | |
parent | 68a2d76cea4234bc027df23085d9df4f2171f7fc (diff) | |
download | linux-3.10-07ba80635117c136714084e019375aa508365375.tar.gz linux-3.10-07ba80635117c136714084e019375aa508365375.tar.bz2 linux-3.10-07ba80635117c136714084e019375aa508365375.zip |
[PATCH] knfsd: change nlm_file to use a hlist
This changes struct nlm_file and the nlm_files hash table to use a hlist
instead of the home-grown lists.
This allows us to remove f_hash which was only used to find the right hash
chain to delete an entry from.
It also increases the size of the nlm_files hash table from 32 to 128.
Signed-off-by: Olaf Kirch <okir@suse.de>
Signed-off-by: Neil Brown <neilb@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | fs/lockd/svcsubs.c | 42 | ||||
-rw-r--r-- | include/linux/lockd/lockd.h | 3 |
2 files changed, 17 insertions, 28 deletions
diff --git a/fs/lockd/svcsubs.c b/fs/lockd/svcsubs.c index a92fc581314..91731353dfa 100644 --- a/fs/lockd/svcsubs.c +++ b/fs/lockd/svcsubs.c @@ -25,9 +25,9 @@ /* * Global file hash table */ -#define FILE_HASH_BITS 5 +#define FILE_HASH_BITS 7 #define FILE_NRHASH (1<<FILE_HASH_BITS) -static struct nlm_file * nlm_files[FILE_NRHASH]; +static struct hlist_head nlm_files[FILE_NRHASH]; static DEFINE_MUTEX(nlm_file_mutex); #ifdef NFSD_DEBUG @@ -82,6 +82,7 @@ u32 nlm_lookup_file(struct svc_rqst *rqstp, struct nlm_file **result, struct nfs_fh *f) { + struct hlist_node *pos; struct nlm_file *file; unsigned int hash; u32 nfserr; @@ -93,7 +94,7 @@ nlm_lookup_file(struct svc_rqst *rqstp, struct nlm_file **result, /* Lock file table */ mutex_lock(&nlm_file_mutex); - for (file = nlm_files[hash]; file; file = file->f_next) + hlist_for_each_entry(file, pos, &nlm_files[hash], f_list) if (!nfs_compare_fh(&file->f_handle, f)) goto found; @@ -105,8 +106,8 @@ nlm_lookup_file(struct svc_rqst *rqstp, struct nlm_file **result, goto out_unlock; memcpy(&file->f_handle, f, sizeof(struct nfs_fh)); - file->f_hash = hash; init_MUTEX(&file->f_sema); + INIT_HLIST_NODE(&file->f_list); INIT_LIST_HEAD(&file->f_blocks); /* Open the file. Note that this must not sleep for too long, else @@ -120,8 +121,7 @@ nlm_lookup_file(struct svc_rqst *rqstp, struct nlm_file **result, goto out_free; } - file->f_next = nlm_files[hash]; - nlm_files[hash] = file; + hlist_add_head(&file->f_list, &nlm_files[hash]); found: dprintk("lockd: found file %p (count %d)\n", file, file->f_count); @@ -150,22 +150,14 @@ out_free: static inline void nlm_delete_file(struct nlm_file *file) { - struct nlm_file **fp, *f; - nlm_debug_print_file("closing file", file); - - fp = nlm_files + file->f_hash; - while ((f = *fp) != NULL) { - if (f == file) { - *fp = file->f_next; - nlmsvc_ops->fclose(file->f_file); - kfree(file); - return; - } - fp = &f->f_next; + if (!hlist_unhashed(&file->f_list)) { + hlist_del(&file->f_list); + nlmsvc_ops->fclose(file->f_file); + kfree(file); + } else { + printk(KERN_WARNING "lockd: attempt to release unknown file!\n"); } - - printk(KERN_WARNING "lockd: attempt to release unknown file!\n"); } /* @@ -236,13 +228,13 @@ nlm_inspect_file(struct nlm_host *host, struct nlm_file *file, int action) static int nlm_traverse_files(struct nlm_host *host, int action) { - struct nlm_file *file, **fp; + struct hlist_node *pos, *next; + struct nlm_file *file; int i, ret = 0; mutex_lock(&nlm_file_mutex); for (i = 0; i < FILE_NRHASH; i++) { - fp = nlm_files + i; - while ((file = *fp) != NULL) { + hlist_for_each_entry_safe(file, pos, next, &nlm_files[i], f_list) { file->f_count++; mutex_unlock(&nlm_file_mutex); @@ -256,11 +248,9 @@ nlm_traverse_files(struct nlm_host *host, int action) /* No more references to this file. Let go of it. */ if (list_empty(&file->f_blocks) && !file->f_locks && !file->f_shares && !file->f_count) { - *fp = file->f_next; + hlist_del(&file->f_list); nlmsvc_ops->fclose(file->f_file); kfree(file); - } else { - fp = &file->f_next; } } } diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h index 2e740f6a2f7..777a91e1ac8 100644 --- a/include/linux/lockd/lockd.h +++ b/include/linux/lockd/lockd.h @@ -105,7 +105,7 @@ struct nlm_rqst { * an NFS client. */ struct nlm_file { - struct nlm_file * f_next; /* linked list */ + struct hlist_node f_list; /* linked list */ struct nfs_fh f_handle; /* NFS file handle */ struct file * f_file; /* VFS file pointer */ struct nlm_share * f_shares; /* DOS shares */ @@ -113,7 +113,6 @@ struct nlm_file { unsigned int f_locks; /* guesstimate # of locks */ unsigned int f_count; /* reference count */ struct semaphore f_sema; /* avoid concurrent access */ - int f_hash; /* hash of f_handle */ }; /* |