pull kernel module fixes from mainline
authorMiklos Szeredi <miklos@szeredi.hu>
Tue, 16 Oct 2007 16:11:01 +0000 (16:11 +0000)
committerMiklos Szeredi <miklos@szeredi.hu>
Tue, 16 Oct 2007 16:11:01 +0000 (16:11 +0000)
ChangeLog
kernel/dev.c
kernel/dir.c
kernel/fuse_i.h
kernel/inode.c

index e8252b752b900be55dfe7c50bec66f2d0e1b4c8a..0c006743d941c619853b2bd27339f52649428b2b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,14 @@
 
        * Clarify licence version to be "LGPLv2" for the library
 
+       * kernel fixes:
+
+       * After mount set nlink attribute for the root inode to 1
+
+       * Fix wake up of task waiting for a reserved request
+
+       * Fix allowing setattr, listxattr and statfs for other users
+
 2007-09-18  Miklos Szeredi <miklos@szeredi.hu>
 
        * Add missing context initialization in fuse_fs_chmod().  Bug
index 60a6bbf5b3fe813041981e6fd4f48b897e6878e6..f8b7f3a9d84d5365c861aa6f6312bab237b7a1f5 100644 (file)
@@ -131,7 +131,7 @@ static struct fuse_req *get_reserved_req(struct fuse_conn *fc,
        struct fuse_file *ff = file->private_data;
 
        do {
-               wait_event(fc->blocked_waitq, ff->reserved_req);
+               wait_event(fc->reserved_req_waitq, ff->reserved_req);
                spin_lock(&fc->lock);
                if (ff->reserved_req) {
                        req = ff->reserved_req;
@@ -157,7 +157,7 @@ static void put_reserved_req(struct fuse_conn *fc, struct fuse_req *req)
        fuse_request_init(req);
        BUG_ON(ff->reserved_req);
        ff->reserved_req = req;
-       wake_up(&fc->blocked_waitq);
+       wake_up_all(&fc->reserved_req_waitq);
        spin_unlock(&fc->lock);
        fput(file);
 }
index b493e4e29f11aca820332f19835245c90630efc9..c5316d9c1f09f725b214461878539591bb349931 100644 (file)
@@ -720,7 +720,7 @@ int fuse_do_getattr(struct inode *inode)
  * for which the owner of the mount has ptrace privilege.  This
  * excludes processes started by other users, suid or sgid processes.
  */
-static int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task)
+int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task)
 {
        if (fc->flags & FUSE_ALLOW_OTHER)
                return 1;
@@ -1059,6 +1059,9 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr)
        int err;
        int is_truncate = 0;
 
+       if (!fuse_allow_task(fc, current))
+               return -EACCES;
+
        if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
                err = inode_change_ok(inode, attr);
                if (err)
@@ -1233,6 +1236,9 @@ static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size)
        struct fuse_getxattr_out outarg;
        ssize_t ret;
 
+       if (!fuse_allow_task(fc, current))
+               return -EACCES;
+
        if (fc->no_listxattr)
                return -EOPNOTSUPP;
 
index f9803b4e009df886bd47ea92b144f507e12b106c..3ea9a57f94b15bb1192ebff5ad06f22633ec1de7 100644 (file)
@@ -368,6 +368,9 @@ struct fuse_conn {
        /** waitq for blocked connection */
        wait_queue_head_t blocked_waitq;
 
+       /** waitq for reserved requests */
+       wait_queue_head_t reserved_req_waitq;
+
        /** The next unique request id */
        u64 reqctr;
 
@@ -639,3 +642,8 @@ void fuse_ctl_remove_conn(struct fuse_conn *fc);
  * Is file type valid?
  */
 int fuse_valid_type(int m);
+
+/**
+ * Is task allowed to perform filesystem operation?
+ */
+int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task);
index f52ee8b15699708304dfcfe60e1025e4ca609a55..8195f6e9e486617d90e877432212203506aefcfc 100644 (file)
@@ -258,6 +258,7 @@ static void fuse_put_super(struct super_block *sb)
        kill_fasync(&fc->fasync, SIGIO, POLL_IN);
        wake_up_all(&fc->waitq);
        wake_up_all(&fc->blocked_waitq);
+       wake_up_all(&fc->reserved_req_waitq);
        mutex_lock(&fuse_mutex);
        list_del(&fc->entry);
        fuse_ctl_remove_conn(fc);
@@ -293,6 +294,11 @@ static int fuse_statfs(struct super_block *sb, struct kstatfs *buf)
        struct fuse_statfs_out outarg;
        int err;
 
+       if (!fuse_allow_task(fc, current)) {
+               buf->f_type = FUSE_SUPER_MAGIC;
+               return 0;
+       }
+
        req = fuse_get_req(fc);
        if (IS_ERR(req))
                return PTR_ERR(req);
@@ -469,6 +475,7 @@ static struct fuse_conn *new_conn(void)
                atomic_set(&fc->count, 1);
                init_waitqueue_head(&fc->waitq);
                init_waitqueue_head(&fc->blocked_waitq);
+               init_waitqueue_head(&fc->reserved_req_waitq);
                INIT_LIST_HEAD(&fc->pending);
                INIT_LIST_HEAD(&fc->processing);
                INIT_LIST_HEAD(&fc->io);
@@ -506,6 +513,7 @@ static struct inode *get_root_inode(struct super_block *sb, unsigned mode)
 
        attr.mode = mode;
        attr.ino = FUSE_ROOT_ID;
+       attr.nlink = 1;
        return fuse_iget(sb, 1, 0, &attr);
 }
 #ifndef FUSE_MAINLINE