diff options
author | Olaf Kirch <okir@suse.de> | 2006-10-04 05:15:58 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-04 10:55:17 -0400 |
commit | 07ba80635117c136714084e019375aa508365375 (patch) | |
tree | 06160152e4b9c137669a5c833366858f72601895 | |
parent | 68a2d76cea4234bc027df23085d9df4f2171f7fc (diff) |
[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 a92fc5813144..91731353dfa4 100644 --- a/fs/lockd/svcsubs.c +++ b/fs/lockd/svcsubs.c | |||
@@ -25,9 +25,9 @@ | |||
25 | /* | 25 | /* |
26 | * Global file hash table | 26 | * Global file hash table |
27 | */ | 27 | */ |
28 | #define FILE_HASH_BITS 5 | 28 | #define FILE_HASH_BITS 7 |
29 | #define FILE_NRHASH (1<<FILE_HASH_BITS) | 29 | #define FILE_NRHASH (1<<FILE_HASH_BITS) |
30 | static struct nlm_file * nlm_files[FILE_NRHASH]; | 30 | static struct hlist_head nlm_files[FILE_NRHASH]; |
31 | static DEFINE_MUTEX(nlm_file_mutex); | 31 | static DEFINE_MUTEX(nlm_file_mutex); |
32 | 32 | ||
33 | #ifdef NFSD_DEBUG | 33 | #ifdef NFSD_DEBUG |
@@ -82,6 +82,7 @@ u32 | |||
82 | nlm_lookup_file(struct svc_rqst *rqstp, struct nlm_file **result, | 82 | nlm_lookup_file(struct svc_rqst *rqstp, struct nlm_file **result, |
83 | struct nfs_fh *f) | 83 | struct nfs_fh *f) |
84 | { | 84 | { |
85 | struct hlist_node *pos; | ||
85 | struct nlm_file *file; | 86 | struct nlm_file *file; |
86 | unsigned int hash; | 87 | unsigned int hash; |
87 | u32 nfserr; | 88 | u32 nfserr; |
@@ -93,7 +94,7 @@ nlm_lookup_file(struct svc_rqst *rqstp, struct nlm_file **result, | |||
93 | /* Lock file table */ | 94 | /* Lock file table */ |
94 | mutex_lock(&nlm_file_mutex); | 95 | mutex_lock(&nlm_file_mutex); |
95 | 96 | ||
96 | for (file = nlm_files[hash]; file; file = file->f_next) | 97 | hlist_for_each_entry(file, pos, &nlm_files[hash], f_list) |
97 | if (!nfs_compare_fh(&file->f_handle, f)) | 98 | if (!nfs_compare_fh(&file->f_handle, f)) |
98 | goto found; | 99 | goto found; |
99 | 100 | ||
@@ -105,8 +106,8 @@ nlm_lookup_file(struct svc_rqst *rqstp, struct nlm_file **result, | |||
105 | goto out_unlock; | 106 | goto out_unlock; |
106 | 107 | ||
107 | memcpy(&file->f_handle, f, sizeof(struct nfs_fh)); | 108 | memcpy(&file->f_handle, f, sizeof(struct nfs_fh)); |
108 | file->f_hash = hash; | ||
109 | init_MUTEX(&file->f_sema); | 109 | init_MUTEX(&file->f_sema); |
110 | INIT_HLIST_NODE(&file->f_list); | ||
110 | INIT_LIST_HEAD(&file->f_blocks); | 111 | INIT_LIST_HEAD(&file->f_blocks); |
111 | 112 | ||
112 | /* Open the file. Note that this must not sleep for too long, else | 113 | /* 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 | goto out_free; | 121 | goto out_free; |
121 | } | 122 | } |
122 | 123 | ||
123 | file->f_next = nlm_files[hash]; | 124 | hlist_add_head(&file->f_list, &nlm_files[hash]); |
124 | nlm_files[hash] = file; | ||
125 | 125 | ||
126 | found: | 126 | found: |
127 | dprintk("lockd: found file %p (count %d)\n", file, file->f_count); | 127 | dprintk("lockd: found file %p (count %d)\n", file, file->f_count); |
@@ -150,22 +150,14 @@ out_free: | |||
150 | static inline void | 150 | static inline void |
151 | nlm_delete_file(struct nlm_file *file) | 151 | nlm_delete_file(struct nlm_file *file) |
152 | { | 152 | { |
153 | struct nlm_file **fp, *f; | ||
154 | |||
155 | nlm_debug_print_file("closing file", file); | 153 | nlm_debug_print_file("closing file", file); |
156 | 154 | if (!hlist_unhashed(&file->f_list)) { | |
157 | fp = nlm_files + file->f_hash; | 155 | hlist_del(&file->f_list); |
158 | while ((f = *fp) != NULL) { | 156 | nlmsvc_ops->fclose(file->f_file); |
159 | if (f == file) { | 157 | kfree(file); |
160 | *fp = file->f_next; | 158 | } else { |
161 | nlmsvc_ops->fclose(file->f_file); | 159 | printk(KERN_WARNING "lockd: attempt to release unknown file!\n"); |
162 | kfree(file); | ||
163 | return; | ||
164 | } | ||
165 | fp = &f->f_next; | ||
166 | } | 160 | } |
167 | |||
168 | printk(KERN_WARNING "lockd: attempt to release unknown file!\n"); | ||
169 | } | 161 | } |
170 | 162 | ||
171 | /* | 163 | /* |
@@ -236,13 +228,13 @@ nlm_inspect_file(struct nlm_host *host, struct nlm_file *file, int action) | |||
236 | static int | 228 | static int |
237 | nlm_traverse_files(struct nlm_host *host, int action) | 229 | nlm_traverse_files(struct nlm_host *host, int action) |
238 | { | 230 | { |
239 | struct nlm_file *file, **fp; | 231 | struct hlist_node *pos, *next; |
232 | struct nlm_file *file; | ||
240 | int i, ret = 0; | 233 | int i, ret = 0; |
241 | 234 | ||
242 | mutex_lock(&nlm_file_mutex); | 235 | mutex_lock(&nlm_file_mutex); |
243 | for (i = 0; i < FILE_NRHASH; i++) { | 236 | for (i = 0; i < FILE_NRHASH; i++) { |
244 | fp = nlm_files + i; | 237 | hlist_for_each_entry_safe(file, pos, next, &nlm_files[i], f_list) { |
245 | while ((file = *fp) != NULL) { | ||
246 | file->f_count++; | 238 | file->f_count++; |
247 | mutex_unlock(&nlm_file_mutex); | 239 | mutex_unlock(&nlm_file_mutex); |
248 | 240 | ||
@@ -256,11 +248,9 @@ nlm_traverse_files(struct nlm_host *host, int action) | |||
256 | /* No more references to this file. Let go of it. */ | 248 | /* No more references to this file. Let go of it. */ |
257 | if (list_empty(&file->f_blocks) && !file->f_locks | 249 | if (list_empty(&file->f_blocks) && !file->f_locks |
258 | && !file->f_shares && !file->f_count) { | 250 | && !file->f_shares && !file->f_count) { |
259 | *fp = file->f_next; | 251 | hlist_del(&file->f_list); |
260 | nlmsvc_ops->fclose(file->f_file); | 252 | nlmsvc_ops->fclose(file->f_file); |
261 | kfree(file); | 253 | kfree(file); |
262 | } else { | ||
263 | fp = &file->f_next; | ||
264 | } | 254 | } |
265 | } | 255 | } |
266 | } | 256 | } |
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h index 2e740f6a2f77..777a91e1ac8f 100644 --- a/include/linux/lockd/lockd.h +++ b/include/linux/lockd/lockd.h | |||
@@ -105,7 +105,7 @@ struct nlm_rqst { | |||
105 | * an NFS client. | 105 | * an NFS client. |
106 | */ | 106 | */ |
107 | struct nlm_file { | 107 | struct nlm_file { |
108 | struct nlm_file * f_next; /* linked list */ | 108 | struct hlist_node f_list; /* linked list */ |
109 | struct nfs_fh f_handle; /* NFS file handle */ | 109 | struct nfs_fh f_handle; /* NFS file handle */ |
110 | struct file * f_file; /* VFS file pointer */ | 110 | struct file * f_file; /* VFS file pointer */ |
111 | struct nlm_share * f_shares; /* DOS shares */ | 111 | struct nlm_share * f_shares; /* DOS shares */ |
@@ -113,7 +113,6 @@ struct nlm_file { | |||
113 | unsigned int f_locks; /* guesstimate # of locks */ | 113 | unsigned int f_locks; /* guesstimate # of locks */ |
114 | unsigned int f_count; /* reference count */ | 114 | unsigned int f_count; /* reference count */ |
115 | struct semaphore f_sema; /* avoid concurrent access */ | 115 | struct semaphore f_sema; /* avoid concurrent access */ |
116 | int f_hash; /* hash of f_handle */ | ||
117 | }; | 116 | }; |
118 | 117 | ||
119 | /* | 118 | /* |