tux3: Fix tux3_iattrdirty() usages

Now, on some paths, mark_inode_dirty() is not called after
tux3_iattrdirty() was called.

E.g. If inode->i_ctime is same with current time, file_update_time()
skips to dirty inode.

	tux3_iattrdirty()
	file_update_time() {
	    if (!timespec_equal(&inode->i_ctime, &now))
		sync_it |= S_CTIME;
	    if (sync_it)
	        mark_inode_dirty_sync()
	}

This is wrong as tux3_iattrdirty() usage. tux3_iattrdirty() was
called, the caller must call mark_inode_dirty() too.

Otherwise,

	delta = 1
	tux3_iattrdirty(inode)
	    iattr_delta = delta

        /* flush delta 1 */
	inode is not dirty, so iattr_delta == 1 is remaining

	/* flush delta 2 for data pages */
	read_idata_for_i_size()
	    if (iattr_delta != delta)
		/*
		 * iattr_delta is still 1, so read from idata[], but
		 * idata[] is invalid.
		 */

By remaining iattr_delta, future inode flush is confused, and hits to
assertion.

To fix this, this makes sure to call tux3_iattrdirty() only when we call
mark_inode_dirty().

[FIXME: file_update_time() of mmap and write can race.]

Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
diff --git a/fs/tux3/user/inode.c b/fs/tux3/user/inode.c
index acc815c..56df92d 100644
--- a/fs/tux3/user/inode.c
+++ b/fs/tux3/user/inode.c
@@ -351,7 +351,6 @@
 	int err;
 
 	change_begin(sb);
-	tux3_iattrdirty(inode);
 	err = __tuxtruncate(inode, size);
 	change_end(sb);
 
diff --git a/fs/tux3/user/tux3fuse.c b/fs/tux3/user/tux3fuse.c
index 8c17fbe..121d815 100644
--- a/fs/tux3/user/tux3fuse.c
+++ b/fs/tux3/user/tux3fuse.c
@@ -224,6 +224,10 @@
 static void tux3fuse_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr,
 			     int to_set, struct fuse_file_info *fi)
 {
+#define SET_ATTRS	(FUSE_SET_ATTR_MODE | FUSE_SET_ATTR_UID |	\
+			 FUSE_SET_ATTR_GID | FUSE_SET_ATTR_ATIME |	\
+			 FUSE_SET_ATTR_MTIME)
+
 	trace("(%lx)", ino);
 	struct sb *sb = tux3fuse_get_sb(req);
 	struct inode *inode;
@@ -235,23 +239,22 @@
 	}
 
 	change_begin(sb);
-
-	tux3_iattrdirty(inode);
-
 	if (to_set & FUSE_SET_ATTR_SIZE)
 		__tuxtruncate(inode, attr->st_size);
-	if (to_set & FUSE_SET_ATTR_MODE)
-		inode->i_mode = attr->st_mode;
-	if (to_set & FUSE_SET_ATTR_UID)
-		i_uid_write(inode, attr->st_uid);
-	if (to_set & FUSE_SET_ATTR_GID)
-		i_gid_write(inode, attr->st_gid);
-	if (to_set & FUSE_SET_ATTR_ATIME)
-		inode->i_atime = attr->st_atim;
-	if (to_set & FUSE_SET_ATTR_MTIME)
-		inode->i_mtime = attr->st_mtim;
-	if (to_set)
+	if (to_set & SET_ATTRS) {
+		tux3_iattrdirty(inode);
+		if (to_set & FUSE_SET_ATTR_MODE)
+			inode->i_mode = attr->st_mode;
+		if (to_set & FUSE_SET_ATTR_UID)
+			i_uid_write(inode, attr->st_uid);
+		if (to_set & FUSE_SET_ATTR_GID)
+			i_gid_write(inode, attr->st_gid);
+		if (to_set & FUSE_SET_ATTR_ATIME)
+			inode->i_atime = attr->st_atim;
+		if (to_set & FUSE_SET_ATTR_MTIME)
+			inode->i_mtime = attr->st_mtim;
 		tux3_mark_inode_dirty(inode);
+	}
 	change_end(sb);
 
 	struct stat stbuf;