From 07ba80635117c136714084e019375aa508365375 Mon Sep 17 00:00:00 2001 From: Olaf Kirch Date: Wed, 4 Oct 2006 02:15:58 -0700 Subject: [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 Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/lockd/svcsubs.c | 42 ++++++++++++++++-------------------------- 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<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 */ }; /* -- cgit v1.2.3-70-g09d2