diff options
Diffstat (limited to 'fs/coda/psdev.c')
-rw-r--r-- | fs/coda/psdev.c | 36 |
1 files changed, 23 insertions, 13 deletions
diff --git a/fs/coda/psdev.c b/fs/coda/psdev.c index 0ceef32e6fae..240669f51eac 100644 --- a/fs/coda/psdev.c +++ b/fs/coda/psdev.c | |||
@@ -38,8 +38,7 @@ | |||
38 | #include <linux/uaccess.h> | 38 | #include <linux/uaccess.h> |
39 | 39 | ||
40 | #include <linux/coda.h> | 40 | #include <linux/coda.h> |
41 | #include <linux/coda_psdev.h> | 41 | #include "coda_psdev.h" |
42 | |||
43 | #include "coda_linux.h" | 42 | #include "coda_linux.h" |
44 | 43 | ||
45 | #include "coda_int.h" | 44 | #include "coda_int.h" |
@@ -100,8 +99,12 @@ static ssize_t coda_psdev_write(struct file *file, const char __user *buf, | |||
100 | ssize_t retval = 0, count = 0; | 99 | ssize_t retval = 0, count = 0; |
101 | int error; | 100 | int error; |
102 | 101 | ||
102 | /* make sure there is enough to copy out the (opcode, unique) values */ | ||
103 | if (nbytes < (2 * sizeof(u_int32_t))) | ||
104 | return -EINVAL; | ||
105 | |||
103 | /* Peek at the opcode, uniquefier */ | 106 | /* Peek at the opcode, uniquefier */ |
104 | if (copy_from_user(&hdr, buf, 2 * sizeof(u_long))) | 107 | if (copy_from_user(&hdr, buf, 2 * sizeof(u_int32_t))) |
105 | return -EFAULT; | 108 | return -EFAULT; |
106 | 109 | ||
107 | if (DOWNCALL(hdr.opcode)) { | 110 | if (DOWNCALL(hdr.opcode)) { |
@@ -119,17 +122,21 @@ static ssize_t coda_psdev_write(struct file *file, const char __user *buf, | |||
119 | hdr.opcode, hdr.unique); | 122 | hdr.opcode, hdr.unique); |
120 | nbytes = size; | 123 | nbytes = size; |
121 | } | 124 | } |
122 | CODA_ALLOC(dcbuf, union outputArgs *, nbytes); | 125 | dcbuf = kvmalloc(nbytes, GFP_KERNEL); |
126 | if (!dcbuf) { | ||
127 | retval = -ENOMEM; | ||
128 | goto out; | ||
129 | } | ||
123 | if (copy_from_user(dcbuf, buf, nbytes)) { | 130 | if (copy_from_user(dcbuf, buf, nbytes)) { |
124 | CODA_FREE(dcbuf, nbytes); | 131 | kvfree(dcbuf); |
125 | retval = -EFAULT; | 132 | retval = -EFAULT; |
126 | goto out; | 133 | goto out; |
127 | } | 134 | } |
128 | 135 | ||
129 | /* what downcall errors does Venus handle ? */ | 136 | /* what downcall errors does Venus handle ? */ |
130 | error = coda_downcall(vcp, hdr.opcode, dcbuf); | 137 | error = coda_downcall(vcp, hdr.opcode, dcbuf, nbytes); |
131 | 138 | ||
132 | CODA_FREE(dcbuf, nbytes); | 139 | kvfree(dcbuf); |
133 | if (error) { | 140 | if (error) { |
134 | pr_warn("%s: coda_downcall error: %d\n", | 141 | pr_warn("%s: coda_downcall error: %d\n", |
135 | __func__, error); | 142 | __func__, error); |
@@ -182,8 +189,11 @@ static ssize_t coda_psdev_write(struct file *file, const char __user *buf, | |||
182 | if (req->uc_opcode == CODA_OPEN_BY_FD) { | 189 | if (req->uc_opcode == CODA_OPEN_BY_FD) { |
183 | struct coda_open_by_fd_out *outp = | 190 | struct coda_open_by_fd_out *outp = |
184 | (struct coda_open_by_fd_out *)req->uc_data; | 191 | (struct coda_open_by_fd_out *)req->uc_data; |
185 | if (!outp->oh.result) | 192 | if (!outp->oh.result) { |
186 | outp->fh = fget(outp->fd); | 193 | outp->fh = fget(outp->fd); |
194 | if (!outp->fh) | ||
195 | return -EBADF; | ||
196 | } | ||
187 | } | 197 | } |
188 | 198 | ||
189 | wake_up(&req->uc_sleep); | 199 | wake_up(&req->uc_sleep); |
@@ -252,7 +262,7 @@ static ssize_t coda_psdev_read(struct file * file, char __user * buf, | |||
252 | goto out; | 262 | goto out; |
253 | } | 263 | } |
254 | 264 | ||
255 | CODA_FREE(req->uc_data, sizeof(struct coda_in_hdr)); | 265 | kvfree(req->uc_data); |
256 | kfree(req); | 266 | kfree(req); |
257 | out: | 267 | out: |
258 | mutex_unlock(&vcp->vc_mutex); | 268 | mutex_unlock(&vcp->vc_mutex); |
@@ -314,7 +324,7 @@ static int coda_psdev_release(struct inode * inode, struct file * file) | |||
314 | 324 | ||
315 | /* Async requests need to be freed here */ | 325 | /* Async requests need to be freed here */ |
316 | if (req->uc_flags & CODA_REQ_ASYNC) { | 326 | if (req->uc_flags & CODA_REQ_ASYNC) { |
317 | CODA_FREE(req->uc_data, sizeof(struct coda_in_hdr)); | 327 | kvfree(req->uc_data); |
318 | kfree(req); | 328 | kfree(req); |
319 | continue; | 329 | continue; |
320 | } | 330 | } |
@@ -347,13 +357,13 @@ static const struct file_operations coda_psdev_fops = { | |||
347 | .llseek = noop_llseek, | 357 | .llseek = noop_llseek, |
348 | }; | 358 | }; |
349 | 359 | ||
350 | static int init_coda_psdev(void) | 360 | static int __init init_coda_psdev(void) |
351 | { | 361 | { |
352 | int i, err = 0; | 362 | int i, err = 0; |
353 | if (register_chrdev(CODA_PSDEV_MAJOR, "coda", &coda_psdev_fops)) { | 363 | if (register_chrdev(CODA_PSDEV_MAJOR, "coda", &coda_psdev_fops)) { |
354 | pr_err("%s: unable to get major %d\n", | 364 | pr_err("%s: unable to get major %d\n", |
355 | __func__, CODA_PSDEV_MAJOR); | 365 | __func__, CODA_PSDEV_MAJOR); |
356 | return -EIO; | 366 | return -EIO; |
357 | } | 367 | } |
358 | coda_psdev_class = class_create(THIS_MODULE, "coda"); | 368 | coda_psdev_class = class_create(THIS_MODULE, "coda"); |
359 | if (IS_ERR(coda_psdev_class)) { | 369 | if (IS_ERR(coda_psdev_class)) { |
@@ -378,7 +388,7 @@ MODULE_AUTHOR("Jan Harkes, Peter J. Braam"); | |||
378 | MODULE_DESCRIPTION("Coda Distributed File System VFS interface"); | 388 | MODULE_DESCRIPTION("Coda Distributed File System VFS interface"); |
379 | MODULE_ALIAS_CHARDEV_MAJOR(CODA_PSDEV_MAJOR); | 389 | MODULE_ALIAS_CHARDEV_MAJOR(CODA_PSDEV_MAJOR); |
380 | MODULE_LICENSE("GPL"); | 390 | MODULE_LICENSE("GPL"); |
381 | MODULE_VERSION("6.6"); | 391 | MODULE_VERSION("7.0"); |
382 | 392 | ||
383 | static int __init init_coda(void) | 393 | static int __init init_coda(void) |
384 | { | 394 | { |