aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/lockd/svcsubs.c42
-rw-r--r--include/linux/lockd/lockd.h3
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)
30static struct nlm_file * nlm_files[FILE_NRHASH]; 30static struct hlist_head nlm_files[FILE_NRHASH];
31static DEFINE_MUTEX(nlm_file_mutex); 31static DEFINE_MUTEX(nlm_file_mutex);
32 32
33#ifdef NFSD_DEBUG 33#ifdef NFSD_DEBUG
@@ -82,6 +82,7 @@ u32
82nlm_lookup_file(struct svc_rqst *rqstp, struct nlm_file **result, 82nlm_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
126found: 126found:
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:
150static inline void 150static inline void
151nlm_delete_file(struct nlm_file *file) 151nlm_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)
236static int 228static int
237nlm_traverse_files(struct nlm_host *host, int action) 229nlm_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 */
107struct nlm_file { 107struct 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/*