Skip to content

Commit

Permalink
fuse: trust kernel i_ctime only
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Maxim Patlasov authored and Miklos Szeredi committed Apr 28, 2014
1 parent 8b47e73 commit 31f3267
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 4 deletions.
22 changes: 20 additions & 2 deletions fs/fuse/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -679,6 +679,14 @@ static int fuse_symlink(struct inode *dir, struct dentry *entry,
return create_new_entry(fc, req, dir, entry, S_IFLNK);
}

static inline void fuse_update_ctime(struct inode *inode)
{
if (!IS_NOCMTIME(inode)) {
inode->i_ctime = current_fs_time(inode->i_sb);
mark_inode_dirty_sync(inode);
}
}

static int fuse_unlink(struct inode *dir, struct dentry *entry)
{
int err;
Expand Down Expand Up @@ -713,6 +721,7 @@ static int fuse_unlink(struct inode *dir, struct dentry *entry)
fuse_invalidate_attr(inode);
fuse_invalidate_attr(dir);
fuse_invalidate_entry_cache(entry);
fuse_update_ctime(inode);
} else if (err == -EINTR)
fuse_invalidate_entry(entry);
return err;
Expand Down Expand Up @@ -771,6 +780,7 @@ static int fuse_rename(struct inode *olddir, struct dentry *oldent,
if (!err) {
/* ctime changes */
fuse_invalidate_attr(oldent->d_inode);
fuse_update_ctime(oldent->d_inode);

fuse_invalidate_attr(olddir);
if (olddir != newdir)
Expand All @@ -780,6 +790,7 @@ static int fuse_rename(struct inode *olddir, struct dentry *oldent,
if (newent->d_inode) {
fuse_invalidate_attr(newent->d_inode);
fuse_invalidate_entry_cache(newent);
fuse_update_ctime(newent->d_inode);
}
} else if (err == -EINTR) {
/* If request was interrupted, DEITY only knows if the
Expand Down Expand Up @@ -829,6 +840,7 @@ static int fuse_link(struct dentry *entry, struct inode *newdir,
inc_nlink(inode);
spin_unlock(&fc->lock);
fuse_invalidate_attr(inode);
fuse_update_ctime(inode);
} else if (err == -EINTR) {
fuse_invalidate_attr(inode);
}
Expand All @@ -846,6 +858,8 @@ static void fuse_fillattr(struct inode *inode, struct fuse_attr *attr,
attr->size = i_size_read(inode);
attr->mtime = inode->i_mtime.tv_sec;
attr->mtimensec = inode->i_mtime.tv_nsec;
attr->ctime = inode->i_ctime.tv_sec;
attr->ctimensec = inode->i_ctime.tv_nsec;
}

stat->dev = inode->i_sb->s_dev;
Expand Down Expand Up @@ -1811,8 +1825,10 @@ static int fuse_setxattr(struct dentry *entry, const char *name,
fc->no_setxattr = 1;
err = -EOPNOTSUPP;
}
if (!err)
if (!err) {
fuse_invalidate_attr(inode);
fuse_update_ctime(inode);
}
return err;
}

Expand Down Expand Up @@ -1942,8 +1958,10 @@ static int fuse_removexattr(struct dentry *entry, const char *name)
fc->no_removexattr = 1;
err = -EOPNOTSUPP;
}
if (!err)
if (!err) {
fuse_invalidate_attr(inode);
fuse_update_ctime(inode);
}
return err;
}

Expand Down
6 changes: 4 additions & 2 deletions fs/fuse/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,9 +175,9 @@ void fuse_change_attributes_common(struct inode *inode, struct fuse_attr *attr,
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;
}
inode->i_ctime.tv_sec = attr->ctime;
inode->i_ctime.tv_nsec = attr->ctimensec;

if (attr->blksize != 0)
inode->i_blkbits = ilog2(attr->blksize);
Expand Down Expand Up @@ -256,6 +256,8 @@ static void fuse_init_inode(struct inode *inode, struct fuse_attr *attr)
inode->i_size = attr->size;
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;
if (S_ISREG(inode->i_mode)) {
fuse_init_common(inode);
fuse_init_file_inode(inode);
Expand Down

0 comments on commit 31f3267

Please sign in to comment.