summaryrefslogtreecommitdiffstats
path: root/fs/coda/psdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/coda/psdev.c')
-rw-r--r--fs/coda/psdev.c36
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);
257out: 267out:
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
350static int init_coda_psdev(void) 360static 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");
378MODULE_DESCRIPTION("Coda Distributed File System VFS interface"); 388MODULE_DESCRIPTION("Coda Distributed File System VFS interface");
379MODULE_ALIAS_CHARDEV_MAJOR(CODA_PSDEV_MAJOR); 389MODULE_ALIAS_CHARDEV_MAJOR(CODA_PSDEV_MAJOR);
380MODULE_LICENSE("GPL"); 390MODULE_LICENSE("GPL");
381MODULE_VERSION("6.6"); 391MODULE_VERSION("7.0");
382 392
383static int __init init_coda(void) 393static int __init init_coda(void)
384{ 394{