diff options
Diffstat (limited to 'fs/lockd/svcsubs.c')
| -rw-r--r-- | fs/lockd/svcsubs.c | 42 |
1 files changed, 16 insertions, 26 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 | } |
