Commit 07ba8063 authored by Olaf Kirch's avatar Olaf Kirch Committed by Linus Torvalds

[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: default avatarOlaf Kirch <okir@suse.de>
Signed-off-by: default avatarNeil Brown <neilb@suse.de>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 68a2d76c
...@@ -25,9 +25,9 @@ ...@@ -25,9 +25,9 @@
/* /*
* Global file hash table * Global file hash table
*/ */
#define FILE_HASH_BITS 5 #define FILE_HASH_BITS 7
#define FILE_NRHASH (1<<FILE_HASH_BITS) #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); static DEFINE_MUTEX(nlm_file_mutex);
#ifdef NFSD_DEBUG #ifdef NFSD_DEBUG
...@@ -82,6 +82,7 @@ u32 ...@@ -82,6 +82,7 @@ u32
nlm_lookup_file(struct svc_rqst *rqstp, struct nlm_file **result, nlm_lookup_file(struct svc_rqst *rqstp, struct nlm_file **result,
struct nfs_fh *f) struct nfs_fh *f)
{ {
struct hlist_node *pos;
struct nlm_file *file; struct nlm_file *file;
unsigned int hash; unsigned int hash;
u32 nfserr; u32 nfserr;
...@@ -93,7 +94,7 @@ nlm_lookup_file(struct svc_rqst *rqstp, struct nlm_file **result, ...@@ -93,7 +94,7 @@ nlm_lookup_file(struct svc_rqst *rqstp, struct nlm_file **result,
/* Lock file table */ /* Lock file table */
mutex_lock(&nlm_file_mutex); 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)) if (!nfs_compare_fh(&file->f_handle, f))
goto found; goto found;
...@@ -105,8 +106,8 @@ nlm_lookup_file(struct svc_rqst *rqstp, struct nlm_file **result, ...@@ -105,8 +106,8 @@ nlm_lookup_file(struct svc_rqst *rqstp, struct nlm_file **result,
goto out_unlock; goto out_unlock;
memcpy(&file->f_handle, f, sizeof(struct nfs_fh)); memcpy(&file->f_handle, f, sizeof(struct nfs_fh));
file->f_hash = hash;
init_MUTEX(&file->f_sema); init_MUTEX(&file->f_sema);
INIT_HLIST_NODE(&file->f_list);
INIT_LIST_HEAD(&file->f_blocks); INIT_LIST_HEAD(&file->f_blocks);
/* Open the file. Note that this must not sleep for too long, else /* 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, ...@@ -120,8 +121,7 @@ nlm_lookup_file(struct svc_rqst *rqstp, struct nlm_file **result,
goto out_free; goto out_free;
} }
file->f_next = nlm_files[hash]; hlist_add_head(&file->f_list, &nlm_files[hash]);
nlm_files[hash] = file;
found: found:
dprintk("lockd: found file %p (count %d)\n", file, file->f_count); dprintk("lockd: found file %p (count %d)\n", file, file->f_count);
...@@ -150,22 +150,14 @@ out_free: ...@@ -150,22 +150,14 @@ out_free:
static inline void static inline void
nlm_delete_file(struct nlm_file *file) nlm_delete_file(struct nlm_file *file)
{ {
struct nlm_file **fp, *f;
nlm_debug_print_file("closing file", file); nlm_debug_print_file("closing file", file);
if (!hlist_unhashed(&file->f_list)) {
fp = nlm_files + file->f_hash; hlist_del(&file->f_list);
while ((f = *fp) != NULL) { nlmsvc_ops->fclose(file->f_file);
if (f == file) { kfree(file);
*fp = file->f_next; } else {
nlmsvc_ops->fclose(file->f_file); printk(KERN_WARNING "lockd: attempt to release unknown file!\n");
kfree(file);
return;
}
fp = &f->f_next;
} }
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) ...@@ -236,13 +228,13 @@ nlm_inspect_file(struct nlm_host *host, struct nlm_file *file, int action)
static int static int
nlm_traverse_files(struct nlm_host *host, int action) 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; int i, ret = 0;
mutex_lock(&nlm_file_mutex); mutex_lock(&nlm_file_mutex);
for (i = 0; i < FILE_NRHASH; i++) { for (i = 0; i < FILE_NRHASH; i++) {
fp = nlm_files + i; hlist_for_each_entry_safe(file, pos, next, &nlm_files[i], f_list) {
while ((file = *fp) != NULL) {
file->f_count++; file->f_count++;
mutex_unlock(&nlm_file_mutex); mutex_unlock(&nlm_file_mutex);
...@@ -256,11 +248,9 @@ nlm_traverse_files(struct nlm_host *host, int action) ...@@ -256,11 +248,9 @@ nlm_traverse_files(struct nlm_host *host, int action)
/* No more references to this file. Let go of it. */ /* No more references to this file. Let go of it. */
if (list_empty(&file->f_blocks) && !file->f_locks if (list_empty(&file->f_blocks) && !file->f_locks
&& !file->f_shares && !file->f_count) { && !file->f_shares && !file->f_count) {
*fp = file->f_next; hlist_del(&file->f_list);
nlmsvc_ops->fclose(file->f_file); nlmsvc_ops->fclose(file->f_file);
kfree(file); kfree(file);
} else {
fp = &file->f_next;
} }
} }
} }
......
...@@ -105,7 +105,7 @@ struct nlm_rqst { ...@@ -105,7 +105,7 @@ struct nlm_rqst {
* an NFS client. * an NFS client.
*/ */
struct nlm_file { 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 nfs_fh f_handle; /* NFS file handle */
struct file * f_file; /* VFS file pointer */ struct file * f_file; /* VFS file pointer */
struct nlm_share * f_shares; /* DOS shares */ struct nlm_share * f_shares; /* DOS shares */
...@@ -113,7 +113,6 @@ struct nlm_file { ...@@ -113,7 +113,6 @@ struct nlm_file {
unsigned int f_locks; /* guesstimate # of locks */ unsigned int f_locks; /* guesstimate # of locks */
unsigned int f_count; /* reference count */ unsigned int f_count; /* reference count */
struct semaphore f_sema; /* avoid concurrent access */ struct semaphore f_sema; /* avoid concurrent access */
int f_hash; /* hash of f_handle */
}; };
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment