limit checking
authorMiklos Szeredi <miklos@szeredi.hu>
Fri, 9 Apr 2004 17:48:32 +0000 (17:48 +0000)
committerMiklos Szeredi <miklos@szeredi.hu>
Fri, 9 Apr 2004 17:48:32 +0000 (17:48 +0000)
ChangeLog
include/linux/fuse.h
kernel/dev.c
kernel/dir.c
kernel/file.c
kernel/inode.c
kernel/util.c

index d0c7061ddc01eaa91be5556baa126bcc82906524..3d78ca5897530dfb36c5aa9c1d21b4fac203e09d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2004-04-09  Miklos Szeredi <mszeredi@inf.bme.hu>
+
+       * Check some limits so userspace won't get too big requests
+
 2004-04-05  Miklos Szeredi <mszeredi@inf.bme.hu>
 
        * Kill compile warning
index 8467ed6c24f8db48f84e17bb925c6cbe0354b33a..bee2930dc367b92b28b709800848d983f0e37752 100644 (file)
@@ -123,6 +123,10 @@ enum fuse_opcode {
 /* 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
+
 struct fuse_entry_out {
        unsigned long ino;         /* Inode number */
        unsigned long generation;  /* Inode generation: ino:gen must
index d8535e7e099b6346c1139365c5d9d7b0a26c55dc..afc9f4c97b2ae1169902fb6ef1b9f0d63e589c33 100644 (file)
@@ -24,7 +24,7 @@ static struct fuse_req *request_new(void)
        struct fuse_req *req;
 
        req = (struct fuse_req *) kmem_cache_alloc(fuse_req_cachep, SLAB_NOFS);
-       if(req) {
+       if (req) {
                INIT_LIST_HEAD(&req->list);
                req->issync = 0;
                req->locked = 0;
@@ -46,7 +46,7 @@ static void request_free(struct fuse_req *req)
 
 static int request_restartable(enum fuse_opcode opcode)
 {
-       switch(opcode) {
+       switch (opcode) {
        case FUSE_LOOKUP:
        case FUSE_GETATTR:
        case FUSE_READLINK:
@@ -69,11 +69,11 @@ static void request_wait_answer(struct fuse_req *req)
        spin_unlock(&fuse_lock);
        intr = wait_event_interruptible(req->waitq, req->finished);
        spin_lock(&fuse_lock);
-       if(!intr)
+       if (!intr)
                return;
 
        /* Request interrupted... Wait for it to be unlocked */
-       if(req->locked) {
+       if (req->locked) {
                req->interrupted = 1;
                spin_unlock(&fuse_lock);
                wait_event(req->waitq, !req->locked);
@@ -83,7 +83,7 @@ static void request_wait_answer(struct fuse_req *req)
        /* Operations which modify the filesystem cannot safely be
           restarted, because it is uncertain whether the operation has
           completed or not... */
-       if(req->sent && !request_restartable(req->in->h.opcode))
+       if (req->sent && !request_restartable(req->in->h.opcode))
                req->out->h.error = -EINTR;
        else
                req->out->h.error = -ERESTARTSYS;
@@ -92,7 +92,7 @@ static void request_wait_answer(struct fuse_req *req)
 static int get_unique(struct fuse_conn *fc)
 {
        do fc->reqctr++;
-       while(!fc->reqctr);
+       while (!fc->reqctr);
        return fc->reqctr;
 }
 
@@ -101,7 +101,7 @@ static void request_end(struct fuse_conn *fc, struct fuse_req *req)
 {
        fuse_reqend_t endfunc = req->end;
 
-       if(!endfunc) {
+       if (!endfunc) {
                wake_up(&req->waitq);
                spin_unlock(&fuse_lock);
        } else {
@@ -118,12 +118,12 @@ void request_send(struct fuse_conn *fc, struct fuse_in *in,
        struct fuse_req *req;
 
        out->h.error = -ERESTARTSYS;
-       if(down_interruptible(&fc->outstanding))
+       if (down_interruptible(&fc->outstanding))
                return;
 
        out->h.error = -ENOMEM;
        req = request_new();
-       if(req) {
+       if (req) {
                req->in = in;
                req->out = out;
                req->issync = 1;
@@ -131,7 +131,7 @@ void request_send(struct fuse_conn *fc, struct fuse_in *in,
                
                spin_lock(&fuse_lock);
                out->h.error = -ENOTCONN;
-               if(fc->file) {
+               if (fc->file) {
                        in->h.unique = get_unique(fc);          
                        list_add_tail(&req->list, &fc->pending);
                        wake_up(&fc->waitq);
@@ -148,7 +148,7 @@ void request_send(struct fuse_conn *fc, struct fuse_in *in,
 
 static inline void destroy_request(struct fuse_req *req)
 {
-       if(req) {
+       if (req) {
                kfree(req->in);
                request_free(req);
        }
@@ -162,14 +162,14 @@ int request_send_noreply(struct fuse_conn *fc, struct fuse_in *in)
        struct fuse_req *req;
 
        req = request_new();
-       if(!req)
+       if (!req)
                return -ENOMEM;
 
        req->in = in;
        req->issync = 0;
 
        spin_lock(&fuse_lock);
-       if(!fc->file) {
+       if (!fc->file) {
                spin_unlock(&fuse_lock);
                request_free(req);
                return -ENOTCONN;
@@ -189,12 +189,12 @@ int request_send_nonblock(struct fuse_conn *fc, struct fuse_in *in,
 
        BUG_ON(!end);
 
-       if(down_trylock(&fc->outstanding))
+       if (down_trylock(&fc->outstanding))
                return -EWOULDBLOCK;
 
        err = -ENOMEM;
        req = request_new();
-       if(req) {
+       if (req) {
                req->in = in;
                req->out = out;
                req->issync = 1;
@@ -203,7 +203,7 @@ int request_send_nonblock(struct fuse_conn *fc, struct fuse_in *in,
 
                spin_lock(&fuse_lock);
                err = -ENOTCONN;
-               if(fc->file) {
+               if (fc->file) {
                        in->h.unique = get_unique(fc);          
                        list_add_tail(&req->list, &fc->pending);
                        wake_up(&fc->waitq);
@@ -222,9 +222,9 @@ static void request_wait(struct fuse_conn *fc)
        DECLARE_WAITQUEUE(wait, current);
 
        add_wait_queue_exclusive(&fc->waitq, &wait);
-       while(fc->sb != NULL && list_empty(&fc->pending)) {
+       while (fc->sb != NULL && list_empty(&fc->pending)) {
                set_current_state(TASK_INTERRUPTIBLE);
-               if(signal_pending(current))
+               if (signal_pending(current))
                        break;
 
                spin_unlock(&fuse_lock);
@@ -238,12 +238,12 @@ static void request_wait(struct fuse_conn *fc)
 static inline int copy_in_one(const void *src, size_t srclen, char **dstp,
                              size_t *dstlenp)
 {
-       if(*dstlenp < srclen) {
+       if (*dstlenp < srclen) {
                printk("fuse_dev_read: buffer too small\n");
                return -EINVAL;
        }
                        
-       if(copy_to_user(*dstp, src, srclen))
+       if (srclen && copy_to_user(*dstp, src, srclen))
                return -EFAULT;
 
        *dstp += srclen;
@@ -259,13 +259,13 @@ static inline int copy_in_args(struct fuse_in *in, char *buf, size_t nbytes)
        size_t orignbytes = nbytes;
                
        err = copy_in_one(&in->h, sizeof(in->h), &buf, &nbytes);
-       if(err)
+       if (err)
                return err;
 
-       for(i = 0; i < in->numargs; i++) {
+       for (i = 0; i < in->numargs; i++) {
                struct fuse_in_arg *arg = &in->args[i];
                err = copy_in_one(arg->value, arg->size, &buf, &nbytes);
-               if(err)
+               if (err)
                        return err;
        }
 
@@ -281,21 +281,21 @@ static ssize_t fuse_dev_read(struct file *file, char *buf, size_t nbytes,
 
        spin_lock(&fuse_lock);
        request_wait(fc);
-       if(fc->sb != NULL && !list_empty(&fc->pending)) {
+       if (fc->sb != NULL && !list_empty(&fc->pending)) {
                req = list_entry(fc->pending.next, struct fuse_req, list);
                list_del_init(&req->list);
                req->locked = 1;
        }
        spin_unlock(&fuse_lock);
-       if(fc->sb == NULL)
+       if (fc->sb == NULL)
                return -ENODEV;
-       if(req == NULL)
+       if (req == NULL)
                return -EINTR;
 
        ret = copy_in_args(req->in, buf, nbytes);
        spin_lock(&fuse_lock);
-       if(req->issync) {
-               if(ret < 0) {
+       if (req->issync) {
+               if (ret < 0) {
                        req->out->h.error = -EPROTO;
                        req->finished = 1;
                } else {
@@ -303,7 +303,7 @@ static ssize_t fuse_dev_read(struct file *file, char *buf, size_t nbytes,
                        req->sent = 1;
                }
                req->locked = 0;
-               if(ret < 0 || req->interrupted)
+               if (ret < 0 || req->interrupted)
                        /* Unlocks fuse_lock: */
                        request_end(fc, req);
                else
@@ -323,7 +323,7 @@ static struct fuse_req *request_find(struct fuse_conn *fc, unsigned int unique)
        list_for_each(entry, &fc->processing) {
                struct fuse_req *tmp;
                tmp = list_entry(entry, struct fuse_req, list);
-               if(tmp->in->h.unique == unique) {
+               if (tmp->in->h.unique == unique) {
                        req = tmp;
                        break;
                }
@@ -343,18 +343,16 @@ static inline int copy_out_one(struct fuse_out_arg *arg, const char **srcp,
                               size_t *srclenp, int allowvar)
 {
        size_t dstlen = arg->size;
-       if(*srclenp < dstlen) {
-               if(!allowvar) {
+       if (*srclenp < dstlen) {
+               if (!allowvar) {
                        printk("fuse_dev_write: write is short\n");
                        return -EINVAL;
                }
                dstlen = *srclenp;
        }
 
-       if(dstlen) {
-               if(copy_from_user(arg->value, *srcp, dstlen))
-                       return -EFAULT;
-       }
+       if (dstlen && copy_from_user(arg->value, *srcp, dstlen))
+               return -EFAULT;
 
        *srcp += dstlen;
        *srclenp -= dstlen;
@@ -372,23 +370,23 @@ static inline int copy_out_args(struct fuse_out *out, const char *buf,
        buf += sizeof(struct fuse_out_header);
        nbytes -= sizeof(struct fuse_out_header);
                
-       if(!out->h.error) {
-               for(i = 0; i < out->numargs; i++) {
+       if (!out->h.error) {
+               for (i = 0; i < out->numargs; i++) {
                        struct fuse_out_arg *arg = &out->args[i];
                        int allowvar;
 
-                       if(out->argvar && i == out->numargs - 1)
+                       if (out->argvar && i == out->numargs - 1)
                                allowvar = 1;
                        else
                                allowvar = 0;
 
                        err = copy_out_one(arg, &buf, &nbytes, allowvar);
-                       if(err)
+                       if (err)
                                return err;
                }
        }
 
-       if(nbytes != 0) {
+       if (nbytes != 0) {
                printk("fuse_dev_write: write is long\n");
                return -EINVAL;
        }
@@ -399,12 +397,12 @@ static inline int copy_out_args(struct fuse_out *out, const char *buf,
 static inline int copy_out_header(struct fuse_out_header *oh, const char *buf,
                                  size_t nbytes)
 {
-       if(nbytes < sizeof(struct fuse_out_header)) {
+       if (nbytes < sizeof(struct fuse_out_header)) {
                printk("fuse_dev_write: write is short\n");
                return -EINVAL;
        }
        
-       if(copy_from_user(oh, buf, sizeof(struct fuse_out_header)))
+       if (copy_from_user(oh, buf, sizeof(struct fuse_out_header)))
                return -EFAULT;
 
        return 0;
@@ -425,8 +423,8 @@ static int fuse_invalidate(struct fuse_conn *fc, struct fuse_user_header *uh)
 {
        struct inode *inode = iget(fc->sb, uh->ino);
        int err = -ENOENT;
-       if(inode) {
-               if(inode->u.generic_ip) {
+       if (inode) {
+               if (inode->u.generic_ip) {
                        invalidate_inode_pages(inode);
                        err = 0;
                }
@@ -447,10 +445,10 @@ static int fuse_user_request(struct fuse_conn *fc, const char *buf,
                return -EINVAL;
        }
 
-       if(copy_from_user(&uh, buf, sizeof(struct fuse_out_header)))
+       if (copy_from_user(&uh, buf, sizeof(struct fuse_out_header)))
                return -EFAULT;
        
-       switch(uh.opcode) {
+       switch (uh.opcode) {
        case FUSE_INVALIDATE:
                err = fuse_invalidate(fc, &uh);
                break;
@@ -470,11 +468,11 @@ static ssize_t fuse_dev_write(struct file *file, const char *buf,
        struct fuse_req *req;
        struct fuse_out_header oh;
 
-       if(!fc->sb)
+       if (!fc->sb)
                return -EPERM;
 
        err = copy_out_header(&oh, buf, nbytes);
-       if(err)
+       if (err)
                return err;
 
        if (!oh.unique) {
@@ -489,23 +487,23 @@ static ssize_t fuse_dev_write(struct file *file, const char *buf,
 
        spin_lock(&fuse_lock);
        req = request_find(fc, oh.unique);
-       if(req != NULL) {
+       if (req != NULL) {
                list_del_init(&req->list);
                req->locked = 1;
        }
        spin_unlock(&fuse_lock);
-       if(!req)
+       if (!req)
                return -ENOENT;
 
        req->out->h = oh;
        err = copy_out_args(req->out, buf, nbytes);
 
        spin_lock(&fuse_lock);
-       if(err)
+       if (err)
                req->out->h.error = -EPROTO;
        else {
                /* fget() needs to be done in this context */
-               if(req->in->h.opcode == FUSE_GETDIR && !oh.error)
+               if (req->in->h.opcode == FUSE_GETDIR && !oh.error)
                        process_getdir(req);
        }       
        req->finished = 1;
@@ -514,7 +512,7 @@ static ssize_t fuse_dev_write(struct file *file, const char *buf,
        request_end(fc, req);
 
   out:
-       if(!err)
+       if (!err)
                return nbytes;
        else
                return err;
@@ -526,7 +524,7 @@ static unsigned int fuse_dev_poll(struct file *file, poll_table *wait)
        struct fuse_conn *fc = DEV_FC(file);
        unsigned int mask = POLLOUT | POLLWRNORM;
 
-       if(!fc->sb)
+       if (!fc->sb)
                return -EPERM;
 
        poll_wait(file, &fc->waitq, wait);
@@ -544,7 +542,7 @@ static struct fuse_conn *new_conn(void)
        struct fuse_conn *fc;
 
        fc = kmalloc(sizeof(*fc), GFP_KERNEL);
-       if(fc != NULL) {
+       if (fc != NULL) {
                fc->sb = NULL;
                fc->file = NULL;
                fc->flags = 0;
@@ -563,7 +561,7 @@ static int fuse_dev_open(struct inode *inode, struct file *file)
        struct fuse_conn *fc;
 
        fc = new_conn();
-       if(!fc)
+       if (!fc)
                return -ENOMEM;
 
        fc->file = file;
@@ -574,11 +572,11 @@ static int fuse_dev_open(struct inode *inode, struct file *file)
 
 static void end_requests(struct fuse_conn *fc, struct list_head *head)
 {
-       while(!list_empty(head)) {
+       while (!list_empty(head)) {
                struct fuse_req *req;
                req = list_entry(head->next, struct fuse_req, list);
                list_del_init(&req->list);
-               if(req->issync) {
+               if (req->issync) {
                        req->out->h.error = -ECONNABORTED;
                        req->finished = 1;
                        /* Unlocks fuse_lock: */
@@ -628,17 +626,17 @@ int fuse_dev_init()
        fuse_req_cachep = kmem_cache_create("fuser_request",
                                             sizeof(struct fuse_req),
                                             0, 0, NULL, NULL);
-       if(!fuse_req_cachep)
+       if (!fuse_req_cachep)
                return -ENOMEM;
 
        proc_fs_fuse = proc_mkdir("fuse", proc_root_fs);
-       if(proc_fs_fuse) {
+       if (proc_fs_fuse) {
                struct proc_dir_entry *de;
 
                proc_fs_fuse->owner = THIS_MODULE;
                proc_fuse_dev = create_proc_entry("dev", S_IFSOCK | 0666,
                                                  proc_fs_fuse);
-               if(proc_fuse_dev) {
+               if (proc_fuse_dev) {
                        proc_fuse_dev->owner = THIS_MODULE;
                        proc_fuse_dev->proc_fops = &fuse_dev_operations;
                }
@@ -653,7 +651,7 @@ int fuse_dev_init()
 
 void fuse_dev_cleanup()
 {
-       if(proc_fs_fuse) {
+       if (proc_fs_fuse) {
                remove_proc_entry("dev", proc_fs_fuse);
                remove_proc_entry("version", proc_fs_fuse);
                remove_proc_entry("fuse", proc_root_fs);
index d5d79b169490fb6c42abe6266778a628ad185b51..73f804382dd2e656cf711045e2be6d5bdf0a170a 100644 (file)
@@ -27,7 +27,7 @@ static struct dentry_operations fuse_dentry_operations;
 
 static void change_attributes(struct inode *inode, struct fuse_attr *attr)
 {
-       if(S_ISREG(inode->i_mode) && i_size_read(inode) != attr->size) {
+       if (S_ISREG(inode->i_mode) && i_size_read(inode) != attr->size) {
 #ifdef KERNEL_2_6
                invalidate_inode_pages(inode->i_mapping);
 #else
@@ -60,19 +60,19 @@ static void fuse_init_inode(struct inode *inode, struct fuse_attr *attr)
 {
        inode->i_mode = attr->mode & S_IFMT;
        i_size_write(inode, attr->size);
-       if(S_ISREG(inode->i_mode)) {
+       if (S_ISREG(inode->i_mode)) {
                inode->i_op = &fuse_file_inode_operations;
                fuse_init_file_inode(inode);
        }
-       else if(S_ISDIR(inode->i_mode)) {
+       else if (S_ISDIR(inode->i_mode)) {
                inode->i_op = &fuse_dir_inode_operations;
                inode->i_fop = &fuse_dir_operations;
        }
-       else if(S_ISLNK(inode->i_mode)) {
+       else if (S_ISLNK(inode->i_mode)) {
                inode->i_op = &fuse_symlink_inode_operations;
        }
-       else if(S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) || 
-               S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)){
+       else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) || 
+                S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)){
                inode->i_op = &fuse_file_inode_operations;
                init_special_inode(inode, inode->i_mode,
                                   new_decode_dev(attr->rdev));
@@ -88,11 +88,11 @@ struct inode *fuse_iget(struct super_block *sb, ino_t ino, int generation,
        struct inode *inode;
 
        inode = iget(sb, ino);
-       if(inode) {
-               if(!inode->u.generic_ip) {
+       if (inode) {
+               if (!inode->u.generic_ip) {
                        inode->i_generation = generation;
                        fuse_init_inode(inode, attr);
-               } else if(inode->i_generation != generation)
+               } else if (inode->i_generation != generation)
                        printk("fuse_iget: bad generation for ino %lu\n", ino);
 
                change_attributes(inode, attr);
@@ -109,6 +109,10 @@ static int fuse_do_lookup(struct inode *dir, struct dentry *entry,
        struct fuse_in in = FUSE_IN_INIT;
        struct fuse_out out = FUSE_OUT_INIT;
 
+
+       if (entry->d_name.len > FUSE_NAME_MAX)
+               return -ENAMETOOLONG;
+
        in.h.opcode = FUSE_LOOKUP;
        in.h.ino = dir->i_ino;
        in.numargs = 1;
@@ -127,7 +131,7 @@ static inline unsigned long time_to_jiffies(unsigned long sec,
                                            unsigned long nsec)
 {
        /* prevent wrapping of jiffies */
-       if(sec + 1 >= LONG_MAX / HZ)
+       if (sec + 1 >= LONG_MAX / HZ)
                return 0;
        
        return jiffies + sec * HZ + nsec / (1000000000 / HZ);
@@ -142,12 +146,12 @@ static int fuse_lookup_iget(struct inode *dir, struct dentry *entry,
        struct inode *inode = NULL;
 
        err = fuse_do_lookup(dir, entry, &outarg, &version);
-       if(!err) {
+       if (!err) {
                inode = fuse_iget(dir->i_sb, outarg.ino, outarg.generation,
                                  &outarg.attr, version);
-               if(!inode)
+               if (!inode)
                        return -ENOMEM;
-       } else if(err != -ENOENT)
+       } else if (err != -ENOENT)
                return err;
 
        entry->d_time = time_to_jiffies(outarg.entry_valid,
@@ -164,11 +168,11 @@ static int lookup_new_entry(struct inode *dir, struct dentry *entry,
        struct inode *inode;
        inode = fuse_iget(dir->i_sb, outarg->ino, outarg->generation, 
                          &outarg->attr, version);
-       if(!inode) 
+       if (!inode) 
                return -ENOMEM;
 
        /* Don't allow userspace to do really stupid things... */
-       if((inode->i_mode ^ mode) & S_IFMT) {
+       if ((inode->i_mode ^ mode) & S_IFMT) {
                iput(inode);
                printk("fuse_mknod: inode has wrong type\n");
                return -EINVAL;
@@ -204,7 +208,7 @@ static int _fuse_mknod(struct inode *dir, struct dentry *entry, int mode,
        out.args[0].value = &outarg;
        request_send(fc, &in, &out);
 
-       if(out.h.error) 
+       if (out.h.error) 
                return out.h.error;
 
        return lookup_new_entry(dir, entry, &outarg, out.h.unique, mode);
@@ -238,7 +242,7 @@ static int fuse_mkdir(struct inode *dir, struct dentry *entry, int mode)
        out.args[0].size = sizeof(outarg);
        out.args[0].value = &outarg;
        request_send(fc, &in, &out);
-       if(out.h.error)
+       if (out.h.error)
                return out.h.error;
 
        return lookup_new_entry(dir, entry, &outarg, out.h.unique, S_IFDIR);
@@ -251,19 +255,23 @@ static int fuse_symlink(struct inode *dir, struct dentry *entry,
        struct fuse_in in = FUSE_IN_INIT;
        struct fuse_out out = FUSE_OUT_INIT;
        struct fuse_entry_out outarg;
+       unsigned int len = strlen(link) + 1;
+       
+       if (len > FUSE_SYMLINK_MAX)
+               return -ENAMETOOLONG;
 
        in.h.opcode = FUSE_SYMLINK;
        in.h.ino = dir->i_ino;
        in.numargs = 2;
        in.args[0].size = entry->d_name.len + 1;
        in.args[0].value = entry->d_name.name;
-       in.args[1].size = strlen(link) + 1;
+       in.args[1].size = len;
        in.args[1].value = link;
        out.numargs = 1;
        out.args[0].size = sizeof(outarg);
        out.args[0].value = &outarg;
        request_send(fc, &in, &out);
-       if(out.h.error)
+       if (out.h.error)
                return out.h.error;
 
        return lookup_new_entry(dir, entry, &outarg, out.h.unique, S_IFLNK);
@@ -282,7 +290,7 @@ static int fuse_unlink(struct inode *dir, struct dentry *entry)
        in.args[0].value = entry->d_name.name;
        request_send(fc, &in, &out);
 
-       if(!out.h.error) {
+       if (!out.h.error) {
                /* Set nlink to zero so the inode can be cleared, if
                    the inode does have more links this will be
                    discovered at the next lookup/getattr */
@@ -305,7 +313,7 @@ static int fuse_rmdir(struct inode *dir, struct dentry *entry)
        in.args[0].size = entry->d_name.len + 1;
        in.args[0].value = entry->d_name.name;
        request_send(fc, &in, &out);
-       if(!out.h.error)
+       if (!out.h.error)
                entry->d_inode->i_nlink = 0;
 
        return out.h.error;
@@ -360,7 +368,7 @@ static int fuse_link(struct dentry *entry, struct inode *newdir,
        out.args[0].size = sizeof(outarg);
        out.args[0].value = &outarg;
        request_send(fc, &in, &out);
-       if(out.h.error)
+       if (out.h.error)
                return out.h.error;
 
        /* Invalidate old entry, so attributes are refreshed */
@@ -383,7 +391,7 @@ int fuse_do_getattr(struct inode *inode)
        out.args[0].value = &arg;
        request_send(fc, &in, &out);
        
-       if(!out.h.error)
+       if (!out.h.error)
                change_attributes(inode, &arg.attr);
        
        return out.h.error;
@@ -394,11 +402,11 @@ static int fuse_revalidate(struct dentry *entry)
        struct inode *inode = entry->d_inode;
        struct fuse_conn *fc = INO_FC(inode);
 
-       if(inode->i_ino == FUSE_ROOT_INO) {
-               if(!(fc->flags & FUSE_ALLOW_OTHER) &&
-                  current->fsuid != fc->uid)
+       if (inode->i_ino == FUSE_ROOT_INO) {
+               if (!(fc->flags & FUSE_ALLOW_OTHER) &&
+                   current->fsuid != fc->uid)
                        return -EACCES;
-       } else if(!entry->d_time || time_before_eq(jiffies, entry->d_time))
+       } else if (!entry->d_time || time_before_eq(jiffies, entry->d_time))
                return 0;
 
        return fuse_do_getattr(inode);
@@ -408,18 +416,18 @@ static int _fuse_permission(struct inode *inode, int mask)
 {
        struct fuse_conn *fc = INO_FC(inode);
 
-       if(!(fc->flags & FUSE_ALLOW_OTHER) && current->fsuid != fc->uid)
+       if (!(fc->flags & FUSE_ALLOW_OTHER) && current->fsuid != fc->uid)
                return -EACCES;
-       else if(fc->flags & FUSE_DEFAULT_PERMISSIONS) {
+       else if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
                int err = vfs_permission(inode, mask);
 
                /* If permission is denied, try to refresh file
                   attributes.  This is also needed, because the root
                   node will at first have no permissions */
 
-               if(err == -EACCES) {
+               if (err == -EACCES) {
                        err = fuse_do_getattr(inode);
-                       if(!err)
+                       if (!err)
                                err = vfs_permission(inode, mask);
                }
 
@@ -440,20 +448,20 @@ static int _fuse_permission(struct inode *inode, int mask)
 static int parse_dirfile(char *buf, size_t nbytes, struct file *file,
                         void *dstbuf, filldir_t filldir)
 {
-       while(nbytes >= FUSE_NAME_OFFSET) {
+       while (nbytes >= FUSE_NAME_OFFSET) {
                struct fuse_dirent *dirent = (struct fuse_dirent *) buf;
                size_t reclen = FUSE_DIRENT_SIZE(dirent);
                int over;
-               if(dirent->namelen > NAME_MAX) {
+               if (dirent->namelen > NAME_MAX) {
                        printk("fuse_readdir: name too long\n");
                        return -EPROTO;
                }
-               if(reclen > nbytes)
+               if (reclen > nbytes)
                        break;
 
                over = filldir(dstbuf, dirent->name, dirent->namelen,
                              file->f_pos, dirent->ino, dirent->type);
-               if(over)
+               if (over)
                        break;
 
                buf += reclen;
@@ -471,15 +479,15 @@ static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
        char *buf;
        int ret;
 
-       if(!cfile)
+       if (!cfile)
                return -EISDIR;
 
        buf = kmalloc(DIR_BUFSIZE, GFP_KERNEL);
-       if(!buf)
+       if (!buf)
                return -ENOMEM;
        
        ret = kernel_read(cfile, file->f_pos, buf, DIR_BUFSIZE);
-       if(ret < 0)
+       if (ret < 0)
                printk("fuse_readdir: failed to read container file\n");
        else 
                ret = parse_dirfile(buf, ret, file, dstbuf, filldir);
@@ -497,7 +505,7 @@ static char *read_link(struct dentry *dentry)
        char *link;
 
        link = (char *) __get_free_page(GFP_KERNEL);
-       if(!link)
+       if (!link)
                return ERR_PTR(-ENOMEM);
 
        in.h.opcode = FUSE_READLINK;
@@ -507,7 +515,7 @@ static char *read_link(struct dentry *dentry)
        out.args[0].size = PAGE_SIZE - 1;
        out.args[0].value = link;
        request_send(fc, &in, &out);
-       if(out.h.error) {
+       if (out.h.error) {
                free_page((unsigned long) link);
                return ERR_PTR(out.h.error);
        }
@@ -518,7 +526,7 @@ static char *read_link(struct dentry *dentry)
 
 static void free_link(char *link)
 {
-       if(!IS_ERR(link))
+       if (!IS_ERR(link))
                free_page((unsigned long) link);
 }
 
@@ -557,15 +565,15 @@ static int fuse_dir_open(struct inode *inode, struct file *file)
        out.args[0].size = sizeof(struct fuse_getdir_out);
        out.args[0].value = &outarg;
        request_send(fc, &in, &out);
-       if(!out.h.error) {
+       if (!out.h.error) {
                struct file *cfile = outarg.file;
                struct inode *inode;
-               if(!cfile) {
+               if (!cfile) {
                        printk("fuse_getdir: invalid file\n");
                        return -EPROTO;
                }
                inode = cfile->f_dentry->d_inode;
-               if(!S_ISREG(inode->i_mode)) {
+               if (!S_ISREG(inode->i_mode)) {
                        printk("fuse_getdir: not a regular file\n");
                        fput(cfile);
                        return -EPROTO;
@@ -581,7 +589,7 @@ static int fuse_dir_release(struct inode *inode, struct file *file)
 {
        struct file *cfile = file->private_data;
 
-       if(cfile)
+       if (cfile)
                fput(cfile);
 
        return 0;
@@ -595,16 +603,16 @@ static unsigned int iattr_to_fattr(struct iattr *iattr,
        
        memset(fattr, 0, sizeof(*fattr));
        
-       if(ivalid & ATTR_MODE)
+       if (ivalid & ATTR_MODE)
                fvalid |= FATTR_MODE,   fattr->mode = iattr->ia_mode;
-       if(ivalid & ATTR_UID)
+       if (ivalid & ATTR_UID)
                fvalid |= FATTR_UID,    fattr->uid = iattr->ia_uid;
-       if(ivalid & ATTR_GID)
+       if (ivalid & ATTR_GID)
                fvalid |= FATTR_GID,    fattr->gid = iattr->ia_gid;
-       if(ivalid & ATTR_SIZE)
+       if (ivalid & ATTR_SIZE)
                fvalid |= FATTR_SIZE,   fattr->size = iattr->ia_size;
        /* You can only _set_ these together (they may change by themselves) */
-       if((ivalid & (ATTR_ATIME | ATTR_MTIME)) == (ATTR_ATIME | ATTR_MTIME)) {
+       if ((ivalid & (ATTR_ATIME | ATTR_MTIME)) == (ATTR_ATIME | ATTR_MTIME)) {
                fvalid |= FATTR_ATIME | FATTR_MTIME;
 #ifdef KERNEL_2_6
                fattr->atime = iattr->ia_atime.tv_sec;
@@ -640,9 +648,9 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr)
        out.args[0].value = &outarg;
        request_send(fc, &in, &out);
 
-       if(!out.h.error) {
-               if(attr->ia_valid & ATTR_SIZE &&
-                  outarg.attr.size < i_size_read(inode))
+       if (!out.h.error) {
+               if (attr->ia_valid & ATTR_SIZE &&
+                   outarg.attr.size < i_size_read(inode))
                        vmtruncate(inode, outarg.attr.size);
 
                change_attributes(inode, &outarg.attr);
@@ -652,9 +660,9 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr)
 
 static int _fuse_dentry_revalidate(struct dentry *entry)
 {
-       if(!entry->d_inode)
+       if (!entry->d_inode)
                return 0;
-       else if(entry->d_time && time_after(jiffies, entry->d_time)) {
+       else if (entry->d_time && time_after(jiffies, entry->d_time)) {
                struct inode *inode = entry->d_inode;
                struct fuse_entry_out outarg;
                int version;
@@ -662,10 +670,10 @@ static int _fuse_dentry_revalidate(struct dentry *entry)
                
                ret = fuse_do_lookup(entry->d_parent->d_inode, entry, &outarg,
                                     &version);
-               if(ret)
+               if (ret)
                        return 0;
                
-               if(outarg.ino != inode->i_ino)
+               if (outarg.ino != inode->i_ino)
                        return 0;
                
                change_attributes(inode, &outarg.attr);
@@ -685,7 +693,7 @@ static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
 {
        struct inode *inode = entry->d_inode;
        int err = fuse_revalidate(entry);
-       if(!err)
+       if (!err)
                generic_fillattr(inode, stat);
        
        return err;
@@ -727,6 +735,9 @@ static int fuse_setxattr(struct dentry *entry, const char *name,
        struct fuse_out out = FUSE_OUT_INIT;
        struct fuse_setxattr_in inarg;
 
+       if (size > FUSE_XATTR_SIZE_MAX)
+               return -E2BIG;
+
        memset(&inarg, 0, sizeof(inarg));
        inarg.size = size;
        inarg.flags = flags;
@@ -766,7 +777,7 @@ static ssize_t fuse_getxattr(struct dentry *entry, const char *name,
        in.args[1].value = name;
        /* This is really two different operations rolled into one */
        out.numargs = 1;
-       if(size) {
+       if (size) {
                out.argvar = 1;
                out.args[0].size = size;
                out.args[0].value = value;
@@ -775,7 +786,7 @@ static ssize_t fuse_getxattr(struct dentry *entry, const char *name,
                out.args[0].value = &outarg;
        }
        request_send(fc, &in, &out);
-       if(!out.h.error)
+       if (!out.h.error)
                return size ? out.args[0].size : outarg.size;
        else
                return out.h.error;
@@ -800,7 +811,7 @@ static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size)
        in.args[0].value = &inarg;
        /* This is really two different operations rolled into one */
        out.numargs = 1;
-       if(size) {
+       if (size) {
                out.argvar = 1;
                out.args[0].size = size;
                out.args[0].value = list;
@@ -809,7 +820,7 @@ static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size)
                out.args[0].value = &outarg;
        }
        request_send(fc, &in, &out);
-       if(!out.h.error)
+       if (!out.h.error)
                return size ? out.args[0].size : outarg.size;
        else
                return out.h.error;
@@ -843,11 +854,11 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry)
        struct dentry *alias;
 
        int err = fuse_lookup_iget(dir, entry, &inode);
-       if(err)
+       if (err)
                return ERR_PTR(err);
 
-       if(inode && S_ISDIR(inode->i_mode) &&
-          (alias = d_find_alias(inode)) != NULL) {
+       if (inode && S_ISDIR(inode->i_mode) &&
+           (alias = d_find_alias(inode)) != NULL) {
                dput(alias);
                iput(inode);
                printk("fuse: cannot assign an existing directory\n");
index 8e24a0147bc89b83beeab30568a562042a577f1f..2c9473f3873d3cf936208184a7419ee53b91a35c 100644 (file)
@@ -19,7 +19,7 @@
 #ifndef NO_MM
 #define filemap_fdatawrite filemap_fdatasync
 #else
-#define filemap_fdatawrite do {} while(0)
+#define filemap_fdatawrite do {} while (0)
 #endif
 #endif
 
@@ -32,14 +32,14 @@ static int fuse_open(struct inode *inode, struct file *file)
        int err;
 
        err = generic_file_open(inode, file);
-       if(err)
+       if (err)
                return err;
 
        /* If opening the root node, no lookup has been performed on
           it, so the attributes must be refreshed */
-       if(inode->i_ino == FUSE_ROOT_INO) {
+       if (inode->i_ino == FUSE_ROOT_INO) {
                int err = fuse_do_getattr(inode);
-               if(err)
+               if (err)
                        return err;
        }
 
@@ -52,7 +52,7 @@ static int fuse_open(struct inode *inode, struct file *file)
        in.args[0].size = sizeof(inarg);
        in.args[0].value = &inarg;
        request_send(fc, &in, &out);
-       if(!out.h.error && !(fc->flags & FUSE_KERNEL_CACHE)) {
+       if (!out.h.error && !(fc->flags & FUSE_KERNEL_CACHE)) {
 #ifdef KERNEL_2_6
                invalidate_inode_pages(inode->i_mapping);
 #else
@@ -70,11 +70,11 @@ static int fuse_release(struct inode *inode, struct file *file)
        struct fuse_open_in *inarg = NULL;
        unsigned int s = sizeof(struct fuse_in) + sizeof(struct fuse_open_in);
 
-       if(file->f_mode & FMODE_WRITE)
+       if (file->f_mode & FMODE_WRITE)
                filemap_fdatawrite(inode->i_mapping);
 
        in = kmalloc(s, GFP_NOFS);
-       if(!in)
+       if (!in)
                return -ENOMEM;
        memset(in, 0, s);
        inarg = (struct fuse_open_in *) (in + 1);
@@ -85,7 +85,7 @@ static int fuse_release(struct inode *inode, struct file *file)
        in->numargs = 1;
        in->args[0].size = sizeof(struct fuse_open_in);
        in->args[0].value = inarg;
-       if(!request_send_noreply(fc, in))
+       if (!request_send_noreply(fc, in))
                return 0;
 
        kfree(in);
@@ -142,9 +142,9 @@ static int fuse_readpage(struct file *file, struct page *page)
        out.args[0].value = buffer;
 
        request_send(fc, &in, &out);
-       if(!out.h.error) {
+       if (!out.h.error) {
                size_t outsize = out.args[0].size;
-               if(outsize < PAGE_CACHE_SIZE) 
+               if (outsize < PAGE_CACHE_SIZE) 
                        memset(buffer + outsize, 0, PAGE_CACHE_SIZE - outsize);
                flush_dcache_page(page);
                SetPageUptodate(page);
@@ -287,7 +287,7 @@ static ssize_t fuse_file_read(struct file *filp, char *buf,
        struct inode *inode = mapping->host;
        struct fuse_conn *fc = INO_FC(inode);
 
-       if(fc->flags & FUSE_LARGE_READ)
+       if (fc->flags & FUSE_LARGE_READ)
                fuse_file_bigread(mapping, inode, *ppos, count);
 
        return generic_file_read(filp, buf, count, ppos);
@@ -318,7 +318,7 @@ static int write_buffer(struct inode *inode, struct page *page,
        in.args[1].value = buffer + offset;
        request_send(fc, &in, &out);
        kunmap(page);
-       if(out.h.error)
+       if (out.h.error)
                SetPageError(page);
 
        return out.h.error;
@@ -331,11 +331,11 @@ static int get_write_count(struct inode *inode, struct page *page)
        int count;
        
        end_index = size >> PAGE_CACHE_SHIFT;
-       if(page->index < end_index)
+       if (page->index < end_index)
                count = PAGE_CACHE_SIZE;
        else {
                count = size & (PAGE_CACHE_SIZE - 1);
-               if(page->index > end_index || count == 0)
+               if (page->index > end_index || count == 0)
                        return 0;
        }
        return count;
@@ -349,9 +349,9 @@ static void write_buffer_end(struct fuse_conn *fc, struct fuse_in *in,
        struct page *page = (struct page *) _page;
        
        lock_page(page);
-       if(out->h.error) {
+       if (out->h.error) {
                SetPageError(page);
-               if(out->h.error == -ENOSPC)
+               if (out->h.error == -ENOSPC)
                        set_bit(AS_ENOSPC, &page->mapping->flags);
                else
                        set_bit(AS_EIO, &page->mapping->flags);
@@ -375,7 +375,7 @@ static int write_buffer_nonblock(struct inode *inode, struct page *page,
                sizeof(struct fuse_write_in);
 
        in = kmalloc(s, GFP_NOFS);
-       if(!in)
+       if (!in)
                return -ENOMEM;
        memset(in, 0, s);
        out = (struct fuse_out *)(in + 1);
@@ -394,8 +394,8 @@ static int write_buffer_nonblock(struct inode *inode, struct page *page,
        in->args[1].size = count;
        in->args[1].value = buffer + offset;
        err = request_send_nonblock(fc, in, out, write_buffer_end, page);
-       if(err) {
-               if(err != -EWOULDBLOCK)
+       if (err) {
+               if (err != -EWOULDBLOCK)
                        SetPageError(page);
                kunmap(page);
                kfree(in);
@@ -410,14 +410,14 @@ static int fuse_writepage(struct page *page, struct writeback_control *wbc)
        unsigned count = get_write_count(inode, page);
 
        err = -EINVAL;
-       if(count) {
+       if (count) {
                /* FIXME: check sync_mode, and wait for previous writes (or
                   signal userspace to do this) */
-               if(wbc->nonblocking) {
+               if (wbc->nonblocking) {
                        err = write_buffer_nonblock(inode, page, 0, count);
-                       if(!err)
+                       if (!err)
                                SetPageWriteback(page);
-                       else if(err == -EWOULDBLOCK) {
+                       else if (err == -EWOULDBLOCK) {
                                __set_page_dirty_nobuffers(page);
                                err = 0;
                        }
@@ -435,7 +435,7 @@ static int fuse_writepage(struct page *page)
        struct inode *inode = page->mapping->host;
        int count = get_write_count(inode, page);
        err = -EINVAL;
-       if(count)
+       if (count)
                err = write_buffer(inode, page, 0, count);
 
        unlock_page(page);
@@ -457,9 +457,9 @@ static int fuse_commit_write(struct file *file, struct page *page,
        struct inode *inode = page->mapping->host;
 
        err = write_buffer(inode, page, offset, to - offset);
-       if(!err) {
+       if (!err) {
                loff_t pos = (page->index << PAGE_CACHE_SHIFT) + to;
-               if(pos > i_size_read(inode))
+               if (pos > i_size_read(inode))
                        i_size_write(inode, pos);
        }
        return err;
@@ -490,7 +490,7 @@ void fuse_init_file_inode(struct inode *inode)
        struct fuse_conn *fc = INO_FC(inode);
        /* Readahead somehow defeats big reads on 2.6 (says Michael
            Grigoriev) */
-       if(fc->flags & FUSE_LARGE_READ)
+       if (fc->flags & FUSE_LARGE_READ)
                inode->i_mapping->backing_dev_info->ra_pages = 0;
 #endif
        inode->i_fop = &fuse_file_operations;
index 22b424a5d15a5ca2d1be20d45d4465248597b9a9..17c0f6062ffac35e8b1aa6354d3b9877a02b9107 100644 (file)
@@ -42,11 +42,11 @@ static void fuse_clear_inode(struct inode *inode)
        struct fuse_forget_in *inarg = NULL;
        unsigned int s = sizeof(struct fuse_in) + sizeof(struct fuse_forget_in);
        
-       if(fc == NULL)
+       if (fc == NULL)
                return;
 
        in = kmalloc(s, GFP_NOFS);
-       if(!in)
+       if (!in)
                return;
        memset(in, 0, s);
        inarg = (struct fuse_forget_in *) (in + 1);
@@ -58,7 +58,7 @@ static void fuse_clear_inode(struct inode *inode)
        in->args[0].size = sizeof(struct fuse_forget_in);
        in->args[0].value = inarg;
                
-       if(!request_send_noreply(fc, in))
+       if (!request_send_noreply(fc, in))
                return;
 
        kfree(in);
@@ -105,7 +105,7 @@ static int fuse_statfs(struct super_block *sb, struct kstatfs *buf)
        out.args[0].size = sizeof(outarg);
        out.args[0].value = &outarg;
        request_send(fc, &in, &out);
-       if(!out.h.error)
+       if (!out.h.error)
                convert_fuse_statfs(buf, &outarg.st);
        
        return out.h.error;
@@ -117,17 +117,17 @@ static struct fuse_conn *get_conn(struct fuse_mount_data *d)
        struct file *file;
        struct inode *ino;
 
-       if(d == NULL) {
+       if (d == NULL) {
                printk("fuse_read_super: Bad mount data\n");
                return NULL;
        }
 
        file = fget(d->fd);
        ino = NULL;
-       if(file)
+       if (file)
                ino = file->f_dentry->d_inode;
        
-       if(!ino || !proc_fuse_dev || proc_fuse_dev->low_ino != ino->i_ino) {
+       if (!ino || !proc_fuse_dev || proc_fuse_dev->low_ino != ino->i_ino) {
                printk("fuse_read_super: Bad file: %i\n", d->fd);
                goto out;
        }
@@ -160,15 +160,15 @@ static struct dentry *fuse_get_dentry(struct super_block *sb, void *vobjp)
        struct inode *inode;
        struct dentry *entry;
 
-       if(ino == 0)
+       if (ino == 0)
                return ERR_PTR(-ESTALE);
 
        inode = ilookup(sb, ino);
-       if(!inode || inode->i_generation != generation)
+       if (!inode || inode->i_generation != generation)
                return ERR_PTR(-ESTALE);
 
        entry = d_alloc_anon(inode);
-       if(!entry) {
+       if (!entry) {
                iput(inode);
                return ERR_PTR(-ENOMEM);
        }
@@ -194,8 +194,8 @@ static int fuse_read_super(struct super_block *sb, void *data, int silent)
        struct inode *root;
        struct fuse_mount_data *d = data;
 
-       if(!capable(CAP_SYS_ADMIN)) {
-               if(d->flags & FUSE_ALLOW_OTHER)
+       if (!capable(CAP_SYS_ADMIN)) {
+               if (d->flags & FUSE_ALLOW_OTHER)
                        return -EPERM;
        }
 
@@ -209,10 +209,10 @@ static int fuse_read_super(struct super_block *sb, void *data, int silent)
 #endif
 
        fc = get_conn(d);
-       if(fc == NULL)
+       if (fc == NULL)
                return -EINVAL;
        spin_lock(&fuse_lock);
-       if(fc->sb != NULL) {
+       if (fc->sb != NULL) {
                printk("fuse_read_super: connection already mounted\n");
                spin_unlock(&fuse_lock);
                return -EINVAL;
@@ -227,13 +227,13 @@ static int fuse_read_super(struct super_block *sb, void *data, int silent)
        SB_FC(sb) = fc;
 
        root = get_root_inode(sb, d->rootmode);
-       if(root == NULL) {
+       if (root == NULL) {
                printk("fuse_read_super: failed to get root inode\n");
                return -EINVAL;
        }
 
        sb->s_root = d_alloc_root(root);
-       if(!sb->s_root)
+       if (!sb->s_root)
                return -EINVAL;
 
        return 0;
@@ -259,7 +259,7 @@ static struct super_block *fuse_read_super_compat(struct super_block *sb,
                                                  void *data, int silent)
 {
        int err = fuse_read_super(sb, data, silent);
-       if(err)
+       if (err)
                return NULL;
        else
                return sb;
@@ -273,7 +273,7 @@ int fuse_fs_init()
        int res;
 
        res = register_filesystem(&fuse_fs_type);
-       if(res)
+       if (res)
                printk("fuse: failed to register filesystem\n");
 
        return res;
index 67641576fd86886f3c43bb827aa306ad76bb60f5..faffb083dfb58bc821e9d29ac63a3a8b7f9d0760 100644 (file)
@@ -22,7 +22,7 @@ spinlock_t fuse_lock = SPIN_LOCK_UNLOCKED;
 /* Must be called with the fuse lock held */
 void fuse_release_conn(struct fuse_conn *fc)
 {
-       if(fc->sb == NULL && fc->file == NULL) {
+       if (fc->sb == NULL && fc->file == NULL) {
                kfree(fc);
        }
 }
@@ -36,11 +36,11 @@ int __init fuse_init(void)
               FUSE_KERNEL_VERSION, FUSE_KERNEL_MINOR_VERSION);
 
        res = fuse_fs_init();
-       if(res)
+       if (res)
                goto err;
        
        res = fuse_dev_init();
-       if(res)
+       if (res)
                goto err_fs_cleanup;
        
        return 0;