Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 31f3267b authored by Maxim Patlasov's avatar Maxim Patlasov Committed by Miklos Szeredi
Browse files

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: default avatarMaxim Patlasov <MPatlasov@parallels.com>
Signed-off-by: default avatarMiklos Szeredi <mszeredi@suse.cz>
parent 8b47e73e
Loading
Loading
Loading
Loading
+20 −2
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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)
@@ -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
@@ -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);
	}
@@ -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;
@@ -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;
}

@@ -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;
}

+4 −2
Original line number Diff line number Diff line
@@ -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;
	}

	if (attr->blksize != 0)
		inode->i_blkbits = ilog2(attr->blksize);
@@ -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);