[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>
This commit is contained in:
parent
68a2d76cea
commit
07ba806351
|
@ -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
|
||||||
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,
|
||||||
/* 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,
|
||||||
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,
|
||||||
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:
|
||||||
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)
|
||||||
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)
|
||||||
/* 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 {
|
||||||
* 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 {
|
||||||
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 */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue