]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - fs/fuse/inode.c
Merge tag 'llvmlinux-for-v3.15' of git://git.linuxfoundation.org/llvmlinux/kernel
[karo-tx-linux.git] / fs / fuse / inode.c
index c668c8436894f1eea526b0e4e63846a7c1deba6f..8d611696fcad303dfe4137a2ff9bc9e1d2a5b97d 100644 (file)
@@ -123,7 +123,7 @@ static void fuse_destroy_inode(struct inode *inode)
 
 static void fuse_evict_inode(struct inode *inode)
 {
-       truncate_inode_pages(&inode->i_data, 0);
+       truncate_inode_pages_final(&inode->i_data);
        clear_inode(inode);
        if (inode->i_sb->s_flags & MS_ACTIVE) {
                struct fuse_conn *fc = get_fuse_conn(inode);
@@ -135,6 +135,7 @@ static void fuse_evict_inode(struct inode *inode)
 
 static int fuse_remount_fs(struct super_block *sb, int *flags, char *data)
 {
+       sync_filesystem(sb);
        if (*flags & MS_MANDLOCK)
                return -EINVAL;
 
@@ -170,8 +171,11 @@ void fuse_change_attributes_common(struct inode *inode, struct fuse_attr *attr,
        inode->i_blocks  = attr->blocks;
        inode->i_atime.tv_sec   = attr->atime;
        inode->i_atime.tv_nsec  = attr->atimensec;
-       inode->i_mtime.tv_sec   = attr->mtime;
-       inode->i_mtime.tv_nsec  = attr->mtimensec;
+       /* mtime from server may be stale due to local buffered write */
+       if (!fc->writeback_cache || !S_ISREG(inode->i_mode)) {
+               inode->i_mtime.tv_sec   = attr->mtime;
+               inode->i_mtime.tv_nsec  = attr->mtimensec;
+       }
        inode->i_ctime.tv_sec   = attr->ctime;
        inode->i_ctime.tv_nsec  = attr->ctimensec;
 
@@ -250,6 +254,8 @@ static void fuse_init_inode(struct inode *inode, struct fuse_attr *attr)
 {
        inode->i_mode = attr->mode & S_IFMT;
        inode->i_size = attr->size;
+       inode->i_mtime.tv_sec  = attr->mtime;
+       inode->i_mtime.tv_nsec = attr->mtimensec;
        if (S_ISREG(inode->i_mode)) {
                fuse_init_common(inode);
                fuse_init_file_inode(inode);
@@ -296,7 +302,9 @@ struct inode *fuse_iget(struct super_block *sb, u64 nodeid,
                return NULL;
 
        if ((inode->i_state & I_NEW)) {
-               inode->i_flags |= S_NOATIME|S_NOCMTIME;
+               inode->i_flags |= S_NOATIME;
+               if (!fc->writeback_cache || !S_ISREG(inode->i_mode))
+                       inode->i_flags |= S_NOCMTIME;
                inode->i_generation = generation;
                inode->i_data.backing_dev_info = &fc->bdi;
                fuse_init_inode(inode, attr);
@@ -880,6 +888,8 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req)
                        }
                        if (arg->flags & FUSE_ASYNC_DIO)
                                fc->async_dio = 1;
+                       if (arg->flags & FUSE_WRITEBACK_CACHE)
+                               fc->writeback_cache = 1;
                } else {
                        ra_pages = fc->max_read / PAGE_CACHE_SIZE;
                        fc->no_lock = 1;
@@ -907,7 +917,8 @@ static void fuse_send_init(struct fuse_conn *fc, struct fuse_req *req)
                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_DO_READDIRPLUS | FUSE_READDIRPLUS_AUTO | FUSE_ASYNC_DIO;
+               FUSE_DO_READDIRPLUS | FUSE_READDIRPLUS_AUTO | FUSE_ASYNC_DIO |
+               FUSE_WRITEBACK_CACHE;
        req->in.h.opcode = FUSE_INIT;
        req->in.numargs = 1;
        req->in.args[0].size = sizeof(*arg);