diff options
Diffstat (limited to 'fs/nfs/idmap.c')
-rw-r--r-- | fs/nfs/idmap.c | 47 |
1 files changed, 24 insertions, 23 deletions
diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c index 821edd30333b..3fab5b0cfc5a 100644 --- a/fs/nfs/idmap.c +++ b/fs/nfs/idmap.c | |||
@@ -35,6 +35,7 @@ | |||
35 | */ | 35 | */ |
36 | 36 | ||
37 | #include <linux/module.h> | 37 | #include <linux/module.h> |
38 | #include <linux/mutex.h> | ||
38 | #include <linux/init.h> | 39 | #include <linux/init.h> |
39 | #include <linux/types.h> | 40 | #include <linux/types.h> |
40 | #include <linux/slab.h> | 41 | #include <linux/slab.h> |
@@ -74,8 +75,8 @@ struct idmap { | |||
74 | struct dentry *idmap_dentry; | 75 | struct dentry *idmap_dentry; |
75 | wait_queue_head_t idmap_wq; | 76 | wait_queue_head_t idmap_wq; |
76 | struct idmap_msg idmap_im; | 77 | struct idmap_msg idmap_im; |
77 | struct semaphore idmap_lock; /* Serializes upcalls */ | 78 | struct mutex idmap_lock; /* Serializes upcalls */ |
78 | struct semaphore idmap_im_lock; /* Protects the hashtable */ | 79 | struct mutex idmap_im_lock; /* Protects the hashtable */ |
79 | struct idmap_hashtable idmap_user_hash; | 80 | struct idmap_hashtable idmap_user_hash; |
80 | struct idmap_hashtable idmap_group_hash; | 81 | struct idmap_hashtable idmap_group_hash; |
81 | }; | 82 | }; |
@@ -101,11 +102,9 @@ nfs_idmap_new(struct nfs4_client *clp) | |||
101 | 102 | ||
102 | if (clp->cl_idmap != NULL) | 103 | if (clp->cl_idmap != NULL) |
103 | return; | 104 | return; |
104 | if ((idmap = kmalloc(sizeof(*idmap), GFP_KERNEL)) == NULL) | 105 | if ((idmap = kzalloc(sizeof(*idmap), GFP_KERNEL)) == NULL) |
105 | return; | 106 | return; |
106 | 107 | ||
107 | memset(idmap, 0, sizeof(*idmap)); | ||
108 | |||
109 | snprintf(idmap->idmap_path, sizeof(idmap->idmap_path), | 108 | snprintf(idmap->idmap_path, sizeof(idmap->idmap_path), |
110 | "%s/idmap", clp->cl_rpcclient->cl_pathname); | 109 | "%s/idmap", clp->cl_rpcclient->cl_pathname); |
111 | 110 | ||
@@ -116,8 +115,8 @@ nfs_idmap_new(struct nfs4_client *clp) | |||
116 | return; | 115 | return; |
117 | } | 116 | } |
118 | 117 | ||
119 | init_MUTEX(&idmap->idmap_lock); | 118 | mutex_init(&idmap->idmap_lock); |
120 | init_MUTEX(&idmap->idmap_im_lock); | 119 | mutex_init(&idmap->idmap_im_lock); |
121 | init_waitqueue_head(&idmap->idmap_wq); | 120 | init_waitqueue_head(&idmap->idmap_wq); |
122 | idmap->idmap_user_hash.h_type = IDMAP_TYPE_USER; | 121 | idmap->idmap_user_hash.h_type = IDMAP_TYPE_USER; |
123 | idmap->idmap_group_hash.h_type = IDMAP_TYPE_GROUP; | 122 | idmap->idmap_group_hash.h_type = IDMAP_TYPE_GROUP; |
@@ -132,6 +131,8 @@ nfs_idmap_delete(struct nfs4_client *clp) | |||
132 | 131 | ||
133 | if (!idmap) | 132 | if (!idmap) |
134 | return; | 133 | return; |
134 | dput(idmap->idmap_dentry); | ||
135 | idmap->idmap_dentry = NULL; | ||
135 | rpc_unlink(idmap->idmap_path); | 136 | rpc_unlink(idmap->idmap_path); |
136 | clp->cl_idmap = NULL; | 137 | clp->cl_idmap = NULL; |
137 | kfree(idmap); | 138 | kfree(idmap); |
@@ -232,8 +233,8 @@ nfs_idmap_id(struct idmap *idmap, struct idmap_hashtable *h, | |||
232 | if (namelen >= IDMAP_NAMESZ) | 233 | if (namelen >= IDMAP_NAMESZ) |
233 | return -EINVAL; | 234 | return -EINVAL; |
234 | 235 | ||
235 | down(&idmap->idmap_lock); | 236 | mutex_lock(&idmap->idmap_lock); |
236 | down(&idmap->idmap_im_lock); | 237 | mutex_lock(&idmap->idmap_im_lock); |
237 | 238 | ||
238 | he = idmap_lookup_name(h, name, namelen); | 239 | he = idmap_lookup_name(h, name, namelen); |
239 | if (he != NULL) { | 240 | if (he != NULL) { |
@@ -259,11 +260,11 @@ nfs_idmap_id(struct idmap *idmap, struct idmap_hashtable *h, | |||
259 | } | 260 | } |
260 | 261 | ||
261 | set_current_state(TASK_UNINTERRUPTIBLE); | 262 | set_current_state(TASK_UNINTERRUPTIBLE); |
262 | up(&idmap->idmap_im_lock); | 263 | mutex_unlock(&idmap->idmap_im_lock); |
263 | schedule(); | 264 | schedule(); |
264 | current->state = TASK_RUNNING; | 265 | current->state = TASK_RUNNING; |
265 | remove_wait_queue(&idmap->idmap_wq, &wq); | 266 | remove_wait_queue(&idmap->idmap_wq, &wq); |
266 | down(&idmap->idmap_im_lock); | 267 | mutex_lock(&idmap->idmap_im_lock); |
267 | 268 | ||
268 | if (im->im_status & IDMAP_STATUS_SUCCESS) { | 269 | if (im->im_status & IDMAP_STATUS_SUCCESS) { |
269 | *id = im->im_id; | 270 | *id = im->im_id; |
@@ -272,8 +273,8 @@ nfs_idmap_id(struct idmap *idmap, struct idmap_hashtable *h, | |||
272 | 273 | ||
273 | out: | 274 | out: |
274 | memset(im, 0, sizeof(*im)); | 275 | memset(im, 0, sizeof(*im)); |
275 | up(&idmap->idmap_im_lock); | 276 | mutex_unlock(&idmap->idmap_im_lock); |
276 | up(&idmap->idmap_lock); | 277 | mutex_unlock(&idmap->idmap_lock); |
277 | return (ret); | 278 | return (ret); |
278 | } | 279 | } |
279 | 280 | ||
@@ -293,8 +294,8 @@ nfs_idmap_name(struct idmap *idmap, struct idmap_hashtable *h, | |||
293 | 294 | ||
294 | im = &idmap->idmap_im; | 295 | im = &idmap->idmap_im; |
295 | 296 | ||
296 | down(&idmap->idmap_lock); | 297 | mutex_lock(&idmap->idmap_lock); |
297 | down(&idmap->idmap_im_lock); | 298 | mutex_lock(&idmap->idmap_im_lock); |
298 | 299 | ||
299 | he = idmap_lookup_id(h, id); | 300 | he = idmap_lookup_id(h, id); |
300 | if (he != 0) { | 301 | if (he != 0) { |
@@ -320,11 +321,11 @@ nfs_idmap_name(struct idmap *idmap, struct idmap_hashtable *h, | |||
320 | } | 321 | } |
321 | 322 | ||
322 | set_current_state(TASK_UNINTERRUPTIBLE); | 323 | set_current_state(TASK_UNINTERRUPTIBLE); |
323 | up(&idmap->idmap_im_lock); | 324 | mutex_unlock(&idmap->idmap_im_lock); |
324 | schedule(); | 325 | schedule(); |
325 | current->state = TASK_RUNNING; | 326 | current->state = TASK_RUNNING; |
326 | remove_wait_queue(&idmap->idmap_wq, &wq); | 327 | remove_wait_queue(&idmap->idmap_wq, &wq); |
327 | down(&idmap->idmap_im_lock); | 328 | mutex_lock(&idmap->idmap_im_lock); |
328 | 329 | ||
329 | if (im->im_status & IDMAP_STATUS_SUCCESS) { | 330 | if (im->im_status & IDMAP_STATUS_SUCCESS) { |
330 | if ((len = strnlen(im->im_name, IDMAP_NAMESZ)) == 0) | 331 | if ((len = strnlen(im->im_name, IDMAP_NAMESZ)) == 0) |
@@ -335,8 +336,8 @@ nfs_idmap_name(struct idmap *idmap, struct idmap_hashtable *h, | |||
335 | 336 | ||
336 | out: | 337 | out: |
337 | memset(im, 0, sizeof(*im)); | 338 | memset(im, 0, sizeof(*im)); |
338 | up(&idmap->idmap_im_lock); | 339 | mutex_unlock(&idmap->idmap_im_lock); |
339 | up(&idmap->idmap_lock); | 340 | mutex_unlock(&idmap->idmap_lock); |
340 | return ret; | 341 | return ret; |
341 | } | 342 | } |
342 | 343 | ||
@@ -380,7 +381,7 @@ idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) | |||
380 | if (copy_from_user(&im_in, src, mlen) != 0) | 381 | if (copy_from_user(&im_in, src, mlen) != 0) |
381 | return (-EFAULT); | 382 | return (-EFAULT); |
382 | 383 | ||
383 | down(&idmap->idmap_im_lock); | 384 | mutex_lock(&idmap->idmap_im_lock); |
384 | 385 | ||
385 | ret = mlen; | 386 | ret = mlen; |
386 | im->im_status = im_in.im_status; | 387 | im->im_status = im_in.im_status; |
@@ -440,7 +441,7 @@ idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) | |||
440 | idmap_update_entry(he, im_in.im_name, namelen_in, im_in.im_id); | 441 | idmap_update_entry(he, im_in.im_name, namelen_in, im_in.im_id); |
441 | ret = mlen; | 442 | ret = mlen; |
442 | out: | 443 | out: |
443 | up(&idmap->idmap_im_lock); | 444 | mutex_unlock(&idmap->idmap_im_lock); |
444 | return ret; | 445 | return ret; |
445 | } | 446 | } |
446 | 447 | ||
@@ -452,10 +453,10 @@ idmap_pipe_destroy_msg(struct rpc_pipe_msg *msg) | |||
452 | 453 | ||
453 | if (msg->errno >= 0) | 454 | if (msg->errno >= 0) |
454 | return; | 455 | return; |
455 | down(&idmap->idmap_im_lock); | 456 | mutex_lock(&idmap->idmap_im_lock); |
456 | im->im_status = IDMAP_STATUS_LOOKUPFAIL; | 457 | im->im_status = IDMAP_STATUS_LOOKUPFAIL; |
457 | wake_up(&idmap->idmap_wq); | 458 | wake_up(&idmap->idmap_wq); |
458 | up(&idmap->idmap_im_lock); | 459 | mutex_unlock(&idmap->idmap_im_lock); |
459 | } | 460 | } |
460 | 461 | ||
461 | /* | 462 | /* |