struct fuse_copy_state cs;
        unsigned reqsize;
 
+ restart:
        spin_lock(&fuse_lock);
        fc = file->private_data;
        err = -EPERM;
 
        req = list_entry(fc->pending.next, struct fuse_req, list);
        list_del_init(&req->list);
-       spin_unlock(&fuse_lock);
 
        in = &req->in;
-       reqsize = req->in.h.len;
-       fuse_copy_init(&cs, 1, req, iov, nr_segs);
-       err = -EINVAL;
-       if (iov_length(iov, nr_segs) >= reqsize) {
-               err = fuse_copy_one(&cs, &in->h, sizeof(in->h));
-               if (!err)
-                       err = fuse_copy_args(&cs, in->numargs, in->argpages,
-                                            (struct fuse_arg *) in->args, 0);
+       reqsize = in->h.len;
+       /* If request is too large, reply with an error and restart the read */
+       if (iov_length(iov, nr_segs) < reqsize) {
+               req->out.h.error = -EIO;
+               /* SETXATTR is special, since it may contain too large data */
+               if (in->h.opcode == FUSE_SETXATTR)
+                       req->out.h.error = -E2BIG;
+               request_end(fc, req);
+               goto restart;
        }
+       spin_unlock(&fuse_lock);
+       fuse_copy_init(&cs, 1, req, iov, nr_segs);
+       err = fuse_copy_one(&cs, &in->h, sizeof(in->h));
+       if (!err)
+               err = fuse_copy_args(&cs, in->numargs, in->argpages,
+                                    (struct fuse_arg *) in->args, 0);
        fuse_copy_finish(&cs);
-
        spin_lock(&fuse_lock);
        req->locked = 0;
        if (!err && req->interrupted)
 
        if (fc->no_create)
                goto out;
 
-       err = -ENAMETOOLONG;
-       if (entry->d_name.len > FUSE_NAME_MAX)
-               goto out;
-
        err = -EINTR;
        req = fuse_get_request(fc);
        if (!req)
 {
        struct fuse_conn *fc = get_fuse_conn(dir);
        unsigned len = strlen(link) + 1;
-       struct fuse_req *req;
-
-       if (len > FUSE_SYMLINK_MAX)
-               return -ENAMETOOLONG;
-
-       req = fuse_get_request(fc);
+       struct fuse_req *req = fuse_get_request(fc);
        if (!req)
                return -EINTR;
 
        struct fuse_setxattr_in inarg;
        int err;
 
-       if (size > FUSE_XATTR_SIZE_MAX)
-               return -E2BIG;
-
        if (fc->no_setxattr)
                return -EOPNOTSUPP;
 
 
 /** If more requests are outstanding, then the operation will block */
 #define FUSE_MAX_OUTSTANDING 10
 
+/** Maximum size of data in a write request */
+#define FUSE_MAX_WRITE 4096
+
+/** It could be as large as PATH_MAX, but would that have any uses? */
+#define FUSE_NAME_MAX 1024
+
 /** If the FUSE_DEFAULT_PERMISSIONS flag is given, the filesystem
     module will check permissions based on the file mode.  Otherwise no
     permission checking is done in the kernel */
        struct fuse_arg args[3];
 };
 
-struct fuse_req;
-struct fuse_conn;
-
 /**
  * A request to the client
  */
 
        fc->max_read = d.max_read;
        if (fc->max_read / PAGE_CACHE_SIZE < fc->bdi.ra_pages)
                fc->bdi.ra_pages = fc->max_read / PAGE_CACHE_SIZE;
-       fc->max_write = FUSE_MAX_IN / 2;
+       fc->max_write = FUSE_MAX_WRITE;
 
        err = -ENOMEM;
        root = get_root_inode(sb, d.rootmode);
 
        FUSE_CREATE        = 35
 };
 
-/* Conservative buffer size for the client */
-#define FUSE_MAX_IN 8192
-
-#define FUSE_NAME_MAX 1024
-#define FUSE_SYMLINK_MAX 4096
-#define FUSE_XATTR_SIZE_MAX 4096
+/* The read buffer is required to be at least 8k, but may be much larger */
+#define FUSE_MIN_READ_BUFFER 8192
 
 struct fuse_entry_out {
        __u64   nodeid;         /* Inode ID */