aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaxim Patlasov <MPatlasov@parallels.com>2014-04-28 08:19:25 -0400
committerMiklos Szeredi <mszeredi@suse.cz>2014-04-28 08:19:25 -0400
commit3ad22c62dd23ad26c8737c300f455de60ba01f40 (patch)
treefb861c617f46885bb29a21ba8e50eebd27ed4968
parent31f3267b4ba16b12fb9dd3b1953ea0f221cc2ab4 (diff)
fuse: clear FUSE_I_CTIME_DIRTY flag on setattr
The patch addresses two use-cases when the flag may be safely cleared: 1. fuse_do_setattr() is called with ATTR_CTIME flag set in attr->ia_valid. In this case attr->ia_ctime bears actual value. In-kernel fuse must send it to the userspace server and then assign the value to inode->i_ctime. 2. fuse_do_setattr() is called with ATTR_SIZE flag set in attr->ia_valid, whereas ATTR_CTIME is not set (truncate(2)). In this case in-kernel fuse must sent "now" to the userspace server and then assign the value to inode->i_ctime. In both cases we could clear I_DIRTY_SYNC, but that needs more thought. Signed-off-by: Maxim Patlasov <MPatlasov@parallels.com> Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
-rw-r--r--fs/fuse/dir.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index f62ab8eedb5f..843dcf1222eb 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -1518,7 +1518,7 @@ static bool update_mtime(unsigned ivalid, bool trust_local_mtime)
1518} 1518}
1519 1519
1520static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg, 1520static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg,
1521 bool trust_local_mtime) 1521 bool trust_local_cmtime)
1522{ 1522{
1523 unsigned ivalid = iattr->ia_valid; 1523 unsigned ivalid = iattr->ia_valid;
1524 1524
@@ -1537,13 +1537,18 @@ static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg,
1537 if (!(ivalid & ATTR_ATIME_SET)) 1537 if (!(ivalid & ATTR_ATIME_SET))
1538 arg->valid |= FATTR_ATIME_NOW; 1538 arg->valid |= FATTR_ATIME_NOW;
1539 } 1539 }
1540 if ((ivalid & ATTR_MTIME) && update_mtime(ivalid, trust_local_mtime)) { 1540 if ((ivalid & ATTR_MTIME) && update_mtime(ivalid, trust_local_cmtime)) {
1541 arg->valid |= FATTR_MTIME; 1541 arg->valid |= FATTR_MTIME;
1542 arg->mtime = iattr->ia_mtime.tv_sec; 1542 arg->mtime = iattr->ia_mtime.tv_sec;
1543 arg->mtimensec = iattr->ia_mtime.tv_nsec; 1543 arg->mtimensec = iattr->ia_mtime.tv_nsec;
1544 if (!(ivalid & ATTR_MTIME_SET) && !trust_local_mtime) 1544 if (!(ivalid & ATTR_MTIME_SET) && !trust_local_cmtime)
1545 arg->valid |= FATTR_MTIME_NOW; 1545 arg->valid |= FATTR_MTIME_NOW;
1546 } 1546 }
1547 if ((ivalid & ATTR_CTIME) && trust_local_cmtime) {
1548 arg->valid |= FATTR_CTIME;
1549 arg->ctime = iattr->ia_ctime.tv_sec;
1550 arg->ctimensec = iattr->ia_ctime.tv_nsec;
1551 }
1547} 1552}
1548 1553
1549/* 1554/*
@@ -1666,7 +1671,7 @@ int fuse_do_setattr(struct inode *inode, struct iattr *attr,
1666 bool is_wb = fc->writeback_cache; 1671 bool is_wb = fc->writeback_cache;
1667 loff_t oldsize; 1672 loff_t oldsize;
1668 int err; 1673 int err;
1669 bool trust_local_mtime = is_wb && S_ISREG(inode->i_mode); 1674 bool trust_local_cmtime = is_wb && S_ISREG(inode->i_mode);
1670 1675
1671 if (!(fc->flags & FUSE_DEFAULT_PERMISSIONS)) 1676 if (!(fc->flags & FUSE_DEFAULT_PERMISSIONS))
1672 attr->ia_valid |= ATTR_FORCE; 1677 attr->ia_valid |= ATTR_FORCE;
@@ -1691,13 +1696,13 @@ int fuse_do_setattr(struct inode *inode, struct iattr *attr,
1691 if (is_truncate) { 1696 if (is_truncate) {
1692 fuse_set_nowrite(inode); 1697 fuse_set_nowrite(inode);
1693 set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state); 1698 set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
1694 if (trust_local_mtime && attr->ia_size != inode->i_size) 1699 if (trust_local_cmtime && attr->ia_size != inode->i_size)
1695 attr->ia_valid |= ATTR_MTIME; 1700 attr->ia_valid |= ATTR_MTIME | ATTR_CTIME;
1696 } 1701 }
1697 1702
1698 memset(&inarg, 0, sizeof(inarg)); 1703 memset(&inarg, 0, sizeof(inarg));
1699 memset(&outarg, 0, sizeof(outarg)); 1704 memset(&outarg, 0, sizeof(outarg));
1700 iattr_to_fattr(attr, &inarg, trust_local_mtime); 1705 iattr_to_fattr(attr, &inarg, trust_local_cmtime);
1701 if (file) { 1706 if (file) {
1702 struct fuse_file *ff = file->private_data; 1707 struct fuse_file *ff = file->private_data;
1703 inarg.valid |= FATTR_FH; 1708 inarg.valid |= FATTR_FH;
@@ -1726,8 +1731,11 @@ int fuse_do_setattr(struct inode *inode, struct iattr *attr,
1726 1731
1727 spin_lock(&fc->lock); 1732 spin_lock(&fc->lock);
1728 /* the kernel maintains i_mtime locally */ 1733 /* the kernel maintains i_mtime locally */
1729 if (trust_local_mtime && (attr->ia_valid & ATTR_MTIME)) { 1734 if (trust_local_cmtime) {
1730 inode->i_mtime = attr->ia_mtime; 1735 if (attr->ia_valid & ATTR_MTIME)
1736 inode->i_mtime = attr->ia_mtime;
1737 if (attr->ia_valid & ATTR_CTIME)
1738 inode->i_ctime = attr->ia_ctime;
1731 /* FIXME: clear I_DIRTY_SYNC? */ 1739 /* FIXME: clear I_DIRTY_SYNC? */
1732 } 1740 }
1733 1741