aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaxim Patlasov <MPatlasov@parallels.com>2014-04-28 08:19:24 -0400
committerMiklos Szeredi <mszeredi@suse.cz>2014-04-28 08:19:24 -0400
commit31f3267b4ba16b12fb9dd3b1953ea0f221cc2ab4 (patch)
tree415623b0ba1a63d0c9bc2fdf189bc66cd68a650c
parent8b47e73e91c064cd75e8bf458ce738e1bfe2e700 (diff)
fuse: trust kernel i_ctime only
Let the kernel maintain i_ctime locally: update i_ctime explicitly on truncate, fallocate, open(O_TRUNC), setxattr, removexattr, link, rename, unlink. The inode flag I_DIRTY_SYNC serves as indication that local i_ctime should be flushed to the server eventually. The patch sets the flag and updates i_ctime in course of operations listed above. Signed-off-by: Maxim Patlasov <MPatlasov@parallels.com> Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
-rw-r--r--fs/fuse/dir.c22
-rw-r--r--fs/fuse/inode.c6
2 files changed, 24 insertions, 4 deletions
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 65357bd1d17b..f62ab8eedb5f 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -679,6 +679,14 @@ static int fuse_symlink(struct inode *dir, struct dentry *entry,
679 return create_new_entry(fc, req, dir, entry, S_IFLNK); 679 return create_new_entry(fc, req, dir, entry, S_IFLNK);
680} 680}
681 681
682static inline void fuse_update_ctime(struct inode *inode)
683{
684 if (!IS_NOCMTIME(inode)) {
685 inode->i_ctime = current_fs_time(inode->i_sb);
686 mark_inode_dirty_sync(inode);
687 }
688}
689
682static int fuse_unlink(struct inode *dir, struct dentry *entry) 690static int fuse_unlink(struct inode *dir, struct dentry *entry)
683{ 691{
684 int err; 692 int err;
@@ -713,6 +721,7 @@ static int fuse_unlink(struct inode *dir, struct dentry *entry)
713 fuse_invalidate_attr(inode); 721 fuse_invalidate_attr(inode);
714 fuse_invalidate_attr(dir); 722 fuse_invalidate_attr(dir);
715 fuse_invalidate_entry_cache(entry); 723 fuse_invalidate_entry_cache(entry);
724 fuse_update_ctime(inode);
716 } else if (err == -EINTR) 725 } else if (err == -EINTR)
717 fuse_invalidate_entry(entry); 726 fuse_invalidate_entry(entry);
718 return err; 727 return err;
@@ -771,6 +780,7 @@ static int fuse_rename(struct inode *olddir, struct dentry *oldent,
771 if (!err) { 780 if (!err) {
772 /* ctime changes */ 781 /* ctime changes */
773 fuse_invalidate_attr(oldent->d_inode); 782 fuse_invalidate_attr(oldent->d_inode);
783 fuse_update_ctime(oldent->d_inode);
774 784
775 fuse_invalidate_attr(olddir); 785 fuse_invalidate_attr(olddir);
776 if (olddir != newdir) 786 if (olddir != newdir)
@@ -780,6 +790,7 @@ static int fuse_rename(struct inode *olddir, struct dentry *oldent,
780 if (newent->d_inode) { 790 if (newent->d_inode) {
781 fuse_invalidate_attr(newent->d_inode); 791 fuse_invalidate_attr(newent->d_inode);
782 fuse_invalidate_entry_cache(newent); 792 fuse_invalidate_entry_cache(newent);
793 fuse_update_ctime(newent->d_inode);
783 } 794 }
784 } else if (err == -EINTR) { 795 } else if (err == -EINTR) {
785 /* If request was interrupted, DEITY only knows if the 796 /* If request was interrupted, DEITY only knows if the
@@ -829,6 +840,7 @@ static int fuse_link(struct dentry *entry, struct inode *newdir,
829 inc_nlink(inode); 840 inc_nlink(inode);
830 spin_unlock(&fc->lock); 841 spin_unlock(&fc->lock);
831 fuse_invalidate_attr(inode); 842 fuse_invalidate_attr(inode);
843 fuse_update_ctime(inode);
832 } else if (err == -EINTR) { 844 } else if (err == -EINTR) {
833 fuse_invalidate_attr(inode); 845 fuse_invalidate_attr(inode);
834 } 846 }
@@ -846,6 +858,8 @@ static void fuse_fillattr(struct inode *inode, struct fuse_attr *attr,
846 attr->size = i_size_read(inode); 858 attr->size = i_size_read(inode);
847 attr->mtime = inode->i_mtime.tv_sec; 859 attr->mtime = inode->i_mtime.tv_sec;
848 attr->mtimensec = inode->i_mtime.tv_nsec; 860 attr->mtimensec = inode->i_mtime.tv_nsec;
861 attr->ctime = inode->i_ctime.tv_sec;
862 attr->ctimensec = inode->i_ctime.tv_nsec;
849 } 863 }
850 864
851 stat->dev = inode->i_sb->s_dev; 865 stat->dev = inode->i_sb->s_dev;
@@ -1811,8 +1825,10 @@ static int fuse_setxattr(struct dentry *entry, const char *name,
1811 fc->no_setxattr = 1; 1825 fc->no_setxattr = 1;
1812 err = -EOPNOTSUPP; 1826 err = -EOPNOTSUPP;
1813 } 1827 }
1814 if (!err) 1828 if (!err) {
1815 fuse_invalidate_attr(inode); 1829 fuse_invalidate_attr(inode);
1830 fuse_update_ctime(inode);
1831 }
1816 return err; 1832 return err;
1817} 1833}
1818 1834
@@ -1942,8 +1958,10 @@ static int fuse_removexattr(struct dentry *entry, const char *name)
1942 fc->no_removexattr = 1; 1958 fc->no_removexattr = 1;
1943 err = -EOPNOTSUPP; 1959 err = -EOPNOTSUPP;
1944 } 1960 }
1945 if (!err) 1961 if (!err) {
1946 fuse_invalidate_attr(inode); 1962 fuse_invalidate_attr(inode);
1963 fuse_update_ctime(inode);
1964 }
1947 return err; 1965 return err;
1948} 1966}
1949 1967
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 560eafcdd6a7..e9ecb1878109 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -175,9 +175,9 @@ void fuse_change_attributes_common(struct inode *inode, struct fuse_attr *attr,
175 if (!fc->writeback_cache || !S_ISREG(inode->i_mode)) { 175 if (!fc->writeback_cache || !S_ISREG(inode->i_mode)) {
176 inode->i_mtime.tv_sec = attr->mtime; 176 inode->i_mtime.tv_sec = attr->mtime;
177 inode->i_mtime.tv_nsec = attr->mtimensec; 177 inode->i_mtime.tv_nsec = attr->mtimensec;
178 inode->i_ctime.tv_sec = attr->ctime;
179 inode->i_ctime.tv_nsec = attr->ctimensec;
178 } 180 }
179 inode->i_ctime.tv_sec = attr->ctime;
180 inode->i_ctime.tv_nsec = attr->ctimensec;
181 181
182 if (attr->blksize != 0) 182 if (attr->blksize != 0)
183 inode->i_blkbits = ilog2(attr->blksize); 183 inode->i_blkbits = ilog2(attr->blksize);
@@ -256,6 +256,8 @@ static void fuse_init_inode(struct inode *inode, struct fuse_attr *attr)
256 inode->i_size = attr->size; 256 inode->i_size = attr->size;
257 inode->i_mtime.tv_sec = attr->mtime; 257 inode->i_mtime.tv_sec = attr->mtime;
258 inode->i_mtime.tv_nsec = attr->mtimensec; 258 inode->i_mtime.tv_nsec = attr->mtimensec;
259 inode->i_ctime.tv_sec = attr->ctime;
260 inode->i_ctime.tv_nsec = attr->ctimensec;
259 if (S_ISREG(inode->i_mode)) { 261 if (S_ISREG(inode->i_mode)) {
260 fuse_init_common(inode); 262 fuse_init_common(inode);
261 fuse_init_file_inode(inode); 263 fuse_init_file_inode(inode);