aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/idmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/idmap.c')
-rw-r--r--fs/nfs/idmap.c99
1 files changed, 49 insertions, 50 deletions
diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c
index d11eb055265c..8ae5dba2d4e5 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
74struct idmap_hashent { 74struct 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 size_t ih_namelen;
78 char ih_name[IDMAP_NAMESZ]; 78 char ih_name[IDMAP_NAMESZ];
79}; 79};
80 80
81struct idmap_hashtable { 81struct 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
86struct idmap { 86struct 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
96static ssize_t idmap_pipe_upcall(struct file *, struct rpc_pipe_msg *, 96static ssize_t idmap_pipe_upcall(struct file *, struct rpc_pipe_msg *,
97 char __user *, size_t); 97 char __user *, size_t);
98static ssize_t idmap_pipe_downcall(struct file *, const char __user *, 98static ssize_t idmap_pipe_downcall(struct file *, const char __user *,
99 size_t); 99 size_t);
100static void idmap_pipe_destroy_msg(struct rpc_pipe_msg *); 100static void idmap_pipe_destroy_msg(struct rpc_pipe_msg *);
101 101
102static unsigned int fnvhash32(const void *, size_t); 102static unsigned int fnvhash32(const void *, size_t);
103 103
104static struct rpc_pipe_ops idmap_upcall_ops = { 104static 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
110int 110int
@@ -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;
@@ -192,7 +193,7 @@ idmap_lookup_id(struct idmap_hashtable *h, __u32 id)
192 * pretty trivial. 193 * pretty trivial.
193 */ 194 */
194static inline struct idmap_hashent * 195static inline struct idmap_hashent *
195idmap_alloc_name(struct idmap_hashtable *h, char *name, unsigned len) 196idmap_alloc_name(struct idmap_hashtable *h, char *name, size_t len)
196{ 197{
197 return idmap_name_hash(h, name, len); 198 return idmap_name_hash(h, name, len);
198} 199}
@@ -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,42 +355,40 @@ nfs_idmap_name(struct idmap *idmap, struct idmap_hashtable *h,
354/* RPC pipefs upcall/downcall routines */ 355/* RPC pipefs upcall/downcall routines */
355static ssize_t 356static ssize_t
356idmap_pipe_upcall(struct file *filp, struct rpc_pipe_msg *msg, 357idmap_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 size_t mlen = min(msg->len, buflen);
361 ssize_t left; 362 unsigned long left;
362 363
363 if (mlen > buflen) 364 left = copy_to_user(dst, data, mlen);
364 mlen = buflen; 365 if (left == mlen) {
365 366 msg->errno = -EFAULT;
366 left = copy_to_user(dst, data, mlen); 367 return -EFAULT;
367 if (left < 0) {
368 msg->errno = left;
369 return left;
370 } 368 }
369
371 mlen -= left; 370 mlen -= left;
372 msg->copied += mlen; 371 msg->copied += mlen;
373 msg->errno = 0; 372 msg->errno = 0;
374 return mlen; 373 return mlen;
375} 374}
376 375
377static ssize_t 376static ssize_t
378idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) 377idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
379{ 378{
380 struct rpc_inode *rpci = RPC_I(filp->f_path.dentry->d_inode); 379 struct rpc_inode *rpci = RPC_I(filp->f_path.dentry->d_inode);
381 struct idmap *idmap = (struct idmap *)rpci->private; 380 struct idmap *idmap = (struct idmap *)rpci->private;
382 struct idmap_msg im_in, *im = &idmap->idmap_im; 381 struct idmap_msg im_in, *im = &idmap->idmap_im;
383 struct idmap_hashtable *h; 382 struct idmap_hashtable *h;
384 struct idmap_hashent *he = NULL; 383 struct idmap_hashent *he = NULL;
385 int namelen_in; 384 size_t namelen_in;
386 int ret; 385 int ret;
387 386
388 if (mlen != sizeof(im_in)) 387 if (mlen != sizeof(im_in))
389 return (-ENOSPC); 388 return -ENOSPC;
390 389
391 if (copy_from_user(&im_in, src, mlen) != 0) 390 if (copy_from_user(&im_in, src, mlen) != 0)
392 return (-EFAULT); 391 return -EFAULT;
393 392
394 mutex_lock(&idmap->idmap_im_lock); 393 mutex_lock(&idmap->idmap_im_lock);
395 394
@@ -487,7 +486,7 @@ static unsigned int fnvhash32(const void *buf, size_t buflen)
487 hash ^= (unsigned int)*p; 486 hash ^= (unsigned int)*p;
488 } 487 }
489 488
490 return (hash); 489 return hash;
491} 490}
492 491
493int nfs_map_name_to_uid(struct nfs_client *clp, const char *name, size_t namelen, __u32 *uid) 492int nfs_map_name_to_uid(struct nfs_client *clp, const char *name, size_t namelen, __u32 *uid)