Merge tag 'v3.10.103' into update
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / fs / fuse / inode.c
index 9a0cdde14a088c43e12e5d5fc4ba84257ca98b46..505fd73886fa107b09e7a76d755cf749fa8ae9dd 100644 (file)
@@ -7,7 +7,7 @@
 */
 
 #include "fuse_i.h"
-
+#include "fuse.h"
 #include <linux/pagemap.h>
 #include <linux/slab.h>
 #include <linux/file.h>
@@ -201,7 +201,8 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr,
        struct timespec old_mtime;
 
        spin_lock(&fc->lock);
-       if (attr_version != 0 && fi->attr_version > attr_version) {
+       if ((attr_version != 0 && fi->attr_version > attr_version) ||
+           test_bit(FUSE_I_SIZE_UNSTABLE, &fi->state)) {
                spin_unlock(&fc->lock);
                return;
        }
@@ -460,6 +461,17 @@ static const match_table_t tokens = {
        {OPT_ERR,                       NULL}
 };
 
+static int fuse_match_uint(substring_t *s, unsigned int *res)
+{
+       int err = -ENOMEM;
+       char *buf = match_strdup(s);
+       if (buf) {
+               err = kstrtouint(buf, 10, res);
+               kfree(buf);
+       }
+       return err;
+}
+
 static int parse_fuse_opt(char *opt, struct fuse_mount_data *d, int is_bdev)
 {
        char *p;
@@ -470,6 +482,7 @@ static int parse_fuse_opt(char *opt, struct fuse_mount_data *d, int is_bdev)
        while ((p = strsep(&opt, ",")) != NULL) {
                int token;
                int value;
+               unsigned uv;
                substring_t args[MAX_OPT_ARGS];
                if (!*p)
                        continue;
@@ -493,18 +506,18 @@ static int parse_fuse_opt(char *opt, struct fuse_mount_data *d, int is_bdev)
                        break;
 
                case OPT_USER_ID:
-                       if (match_int(&args[0], &value))
+                       if (fuse_match_uint(&args[0], &uv))
                                return 0;
-                       d->user_id = make_kuid(current_user_ns(), value);
+                       d->user_id = make_kuid(current_user_ns(), uv);
                        if (!uid_valid(d->user_id))
                                return 0;
                        d->user_id_present = 1;
                        break;
 
                case OPT_GROUP_ID:
-                       if (match_int(&args[0], &value))
+                       if (fuse_match_uint(&args[0], &uv))
                                return 0;
-                       d->group_id = make_kgid(current_user_ns(), value);
+                       d->group_id = make_kgid(current_user_ns(), uv);
                        if (!gid_valid(d->group_id))
                                return 0;
                        d->group_id_present = 1;
@@ -900,7 +913,7 @@ static void fuse_send_init(struct fuse_conn *fc, struct fuse_req *req)
        arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_ATOMIC_O_TRUNC |
                FUSE_EXPORT_SUPPORT | FUSE_BIG_WRITES | FUSE_DONT_MASK |
                FUSE_SPLICE_WRITE | FUSE_SPLICE_MOVE | FUSE_SPLICE_READ |
-               FUSE_FLOCK_LOCKS | FUSE_IOCTL_DIR | FUSE_AUTO_INVAL_DATA |
+               FUSE_FLOCK_LOCKS | FUSE_HAS_IOCTL_DIR | FUSE_AUTO_INVAL_DATA |
                FUSE_DO_READDIRPLUS | FUSE_READDIRPLUS_AUTO | FUSE_ASYNC_DIO;
        req->in.h.opcode = FUSE_INIT;
        req->in.numargs = 1;
@@ -1015,6 +1028,7 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
                goto err_fput;
 
        fuse_conn_init(fc);
+       fc->release = fuse_free_conn;
 
        fc->dev = sb->s_dev;
        fc->sb = sb;
@@ -1029,7 +1043,6 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
                fc->dont_mask = 1;
        sb->s_flags |= MS_POSIXACL;
 
-       fc->release = fuse_free_conn;
        fc->flags = d.flags;
        fc->user_id = d.user_id;
        fc->group_id = d.group_id;
@@ -1285,7 +1298,7 @@ static int __init fuse_init(void)
 
        sanitize_global_limit(&max_user_bgreq);
        sanitize_global_limit(&max_user_congthresh);
-
+       fuse_iolog_init();
        return 0;
 
  err_sysfs_cleanup:
@@ -1306,6 +1319,7 @@ static void __exit fuse_exit(void)
        fuse_sysfs_cleanup();
        fuse_fs_cleanup();
        fuse_dev_cleanup();
+       fuse_iolog_exit();
 }
 
 module_init(fuse_init);