diff options
Diffstat (limited to 'fs/nfs/idmap.c')
-rw-r--r-- | fs/nfs/idmap.c | 87 |
1 files changed, 44 insertions, 43 deletions
diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c index d11eb055265c..c56fc7d5a46e 100644 --- a/fs/nfs/idmap.c +++ b/fs/nfs/idmap.c | |||
@@ -72,39 +72,39 @@ module_param_call(idmap_cache_timeout, param_set_idmap_timeout, param_get_int, | |||
72 | &nfs_idmap_cache_timeout, 0644); | 72 | &nfs_idmap_cache_timeout, 0644); |
73 | 73 | ||
74 | struct idmap_hashent { | 74 | struct idmap_hashent { |
75 | unsigned long ih_expires; | 75 | unsigned long ih_expires; |
76 | __u32 ih_id; | 76 | __u32 ih_id; |
77 | int ih_namelen; | 77 | int ih_namelen; |
78 | char ih_name[IDMAP_NAMESZ]; | 78 | char ih_name[IDMAP_NAMESZ]; |
79 | }; | 79 | }; |
80 | 80 | ||
81 | struct idmap_hashtable { | 81 | struct idmap_hashtable { |
82 | __u8 h_type; | 82 | __u8 h_type; |
83 | struct idmap_hashent h_entries[IDMAP_HASH_SZ]; | 83 | struct idmap_hashent h_entries[IDMAP_HASH_SZ]; |
84 | }; | 84 | }; |
85 | 85 | ||
86 | struct idmap { | 86 | struct idmap { |
87 | struct dentry *idmap_dentry; | 87 | struct dentry *idmap_dentry; |
88 | wait_queue_head_t idmap_wq; | 88 | wait_queue_head_t idmap_wq; |
89 | struct idmap_msg idmap_im; | 89 | struct idmap_msg idmap_im; |
90 | struct mutex idmap_lock; /* Serializes upcalls */ | 90 | struct mutex idmap_lock; /* Serializes upcalls */ |
91 | struct mutex idmap_im_lock; /* Protects the hashtable */ | 91 | struct mutex idmap_im_lock; /* Protects the hashtable */ |
92 | struct idmap_hashtable idmap_user_hash; | 92 | struct idmap_hashtable idmap_user_hash; |
93 | struct idmap_hashtable idmap_group_hash; | 93 | struct idmap_hashtable idmap_group_hash; |
94 | }; | 94 | }; |
95 | 95 | ||
96 | static ssize_t idmap_pipe_upcall(struct file *, struct rpc_pipe_msg *, | 96 | static ssize_t idmap_pipe_upcall(struct file *, struct rpc_pipe_msg *, |
97 | char __user *, size_t); | 97 | char __user *, size_t); |
98 | static ssize_t idmap_pipe_downcall(struct file *, const char __user *, | 98 | static ssize_t idmap_pipe_downcall(struct file *, const char __user *, |
99 | size_t); | 99 | size_t); |
100 | static void idmap_pipe_destroy_msg(struct rpc_pipe_msg *); | 100 | static void idmap_pipe_destroy_msg(struct rpc_pipe_msg *); |
101 | 101 | ||
102 | static unsigned int fnvhash32(const void *, size_t); | 102 | static unsigned int fnvhash32(const void *, size_t); |
103 | 103 | ||
104 | static struct rpc_pipe_ops idmap_upcall_ops = { | 104 | static struct rpc_pipe_ops idmap_upcall_ops = { |
105 | .upcall = idmap_pipe_upcall, | 105 | .upcall = idmap_pipe_upcall, |
106 | .downcall = idmap_pipe_downcall, | 106 | .downcall = idmap_pipe_downcall, |
107 | .destroy_msg = idmap_pipe_destroy_msg, | 107 | .destroy_msg = idmap_pipe_destroy_msg, |
108 | }; | 108 | }; |
109 | 109 | ||
110 | int | 110 | int |
@@ -115,19 +115,20 @@ nfs_idmap_new(struct nfs_client *clp) | |||
115 | 115 | ||
116 | BUG_ON(clp->cl_idmap != NULL); | 116 | BUG_ON(clp->cl_idmap != NULL); |
117 | 117 | ||
118 | if ((idmap = kzalloc(sizeof(*idmap), GFP_KERNEL)) == NULL) | 118 | idmap = kzalloc(sizeof(*idmap), GFP_KERNEL); |
119 | return -ENOMEM; | 119 | if (idmap == NULL) |
120 | return -ENOMEM; | ||
120 | 121 | ||
121 | idmap->idmap_dentry = rpc_mkpipe(clp->cl_rpcclient->cl_dentry, "idmap", | 122 | idmap->idmap_dentry = rpc_mkpipe(clp->cl_rpcclient->cl_dentry, "idmap", |
122 | idmap, &idmap_upcall_ops, 0); | 123 | idmap, &idmap_upcall_ops, 0); |
123 | if (IS_ERR(idmap->idmap_dentry)) { | 124 | if (IS_ERR(idmap->idmap_dentry)) { |
124 | error = PTR_ERR(idmap->idmap_dentry); | 125 | error = PTR_ERR(idmap->idmap_dentry); |
125 | kfree(idmap); | 126 | kfree(idmap); |
126 | return error; | 127 | return error; |
127 | } | 128 | } |
128 | 129 | ||
129 | mutex_init(&idmap->idmap_lock); | 130 | mutex_init(&idmap->idmap_lock); |
130 | mutex_init(&idmap->idmap_im_lock); | 131 | mutex_init(&idmap->idmap_im_lock); |
131 | init_waitqueue_head(&idmap->idmap_wq); | 132 | init_waitqueue_head(&idmap->idmap_wq); |
132 | idmap->idmap_user_hash.h_type = IDMAP_TYPE_USER; | 133 | idmap->idmap_user_hash.h_type = IDMAP_TYPE_USER; |
133 | idmap->idmap_group_hash.h_type = IDMAP_TYPE_GROUP; | 134 | idmap->idmap_group_hash.h_type = IDMAP_TYPE_GROUP; |
@@ -285,7 +286,7 @@ nfs_idmap_id(struct idmap *idmap, struct idmap_hashtable *h, | |||
285 | memset(im, 0, sizeof(*im)); | 286 | memset(im, 0, sizeof(*im)); |
286 | mutex_unlock(&idmap->idmap_im_lock); | 287 | mutex_unlock(&idmap->idmap_im_lock); |
287 | mutex_unlock(&idmap->idmap_lock); | 288 | mutex_unlock(&idmap->idmap_lock); |
288 | return (ret); | 289 | return ret; |
289 | } | 290 | } |
290 | 291 | ||
291 | /* | 292 | /* |
@@ -354,16 +355,16 @@ nfs_idmap_name(struct idmap *idmap, struct idmap_hashtable *h, | |||
354 | /* RPC pipefs upcall/downcall routines */ | 355 | /* RPC pipefs upcall/downcall routines */ |
355 | static ssize_t | 356 | static ssize_t |
356 | idmap_pipe_upcall(struct file *filp, struct rpc_pipe_msg *msg, | 357 | idmap_pipe_upcall(struct file *filp, struct rpc_pipe_msg *msg, |
357 | char __user *dst, size_t buflen) | 358 | char __user *dst, size_t buflen) |
358 | { | 359 | { |
359 | char *data = (char *)msg->data + msg->copied; | 360 | char *data = (char *)msg->data + msg->copied; |
360 | ssize_t mlen = msg->len - msg->copied; | 361 | ssize_t mlen = msg->len - msg->copied; |
361 | ssize_t left; | 362 | ssize_t left; |
362 | 363 | ||
363 | if (mlen > buflen) | 364 | if (mlen > buflen) |
364 | mlen = buflen; | 365 | mlen = buflen; |
365 | 366 | ||
366 | left = copy_to_user(dst, data, mlen); | 367 | left = copy_to_user(dst, data, mlen); |
367 | if (left < 0) { | 368 | if (left < 0) { |
368 | msg->errno = left; | 369 | msg->errno = left; |
369 | return left; | 370 | return left; |
@@ -371,13 +372,13 @@ idmap_pipe_upcall(struct file *filp, struct rpc_pipe_msg *msg, | |||
371 | mlen -= left; | 372 | mlen -= left; |
372 | msg->copied += mlen; | 373 | msg->copied += mlen; |
373 | msg->errno = 0; | 374 | msg->errno = 0; |
374 | return mlen; | 375 | return mlen; |
375 | } | 376 | } |
376 | 377 | ||
377 | static ssize_t | 378 | static ssize_t |
378 | idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) | 379 | idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) |
379 | { | 380 | { |
380 | struct rpc_inode *rpci = RPC_I(filp->f_path.dentry->d_inode); | 381 | struct rpc_inode *rpci = RPC_I(filp->f_path.dentry->d_inode); |
381 | struct idmap *idmap = (struct idmap *)rpci->private; | 382 | struct idmap *idmap = (struct idmap *)rpci->private; |
382 | struct idmap_msg im_in, *im = &idmap->idmap_im; | 383 | struct idmap_msg im_in, *im = &idmap->idmap_im; |
383 | struct idmap_hashtable *h; | 384 | struct idmap_hashtable *h; |
@@ -385,11 +386,11 @@ idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) | |||
385 | int namelen_in; | 386 | int namelen_in; |
386 | int ret; | 387 | int ret; |
387 | 388 | ||
388 | if (mlen != sizeof(im_in)) | 389 | if (mlen != sizeof(im_in)) |
389 | return (-ENOSPC); | 390 | return -ENOSPC; |
390 | 391 | ||
391 | if (copy_from_user(&im_in, src, mlen) != 0) | 392 | if (copy_from_user(&im_in, src, mlen) != 0) |
392 | return (-EFAULT); | 393 | return -EFAULT; |
393 | 394 | ||
394 | mutex_lock(&idmap->idmap_im_lock); | 395 | mutex_lock(&idmap->idmap_im_lock); |
395 | 396 | ||
@@ -487,7 +488,7 @@ static unsigned int fnvhash32(const void *buf, size_t buflen) | |||
487 | hash ^= (unsigned int)*p; | 488 | hash ^= (unsigned int)*p; |
488 | } | 489 | } |
489 | 490 | ||
490 | return (hash); | 491 | return hash; |
491 | } | 492 | } |
492 | 493 | ||
493 | int nfs_map_name_to_uid(struct nfs_client *clp, const char *name, size_t namelen, __u32 *uid) | 494 | int nfs_map_name_to_uid(struct nfs_client *clp, const char *name, size_t namelen, __u32 *uid) |