Skip to contentSkip to conversation

miss-sync issues on sync mount (miss-sync on utime)

PATCH In review Machida, Hiroyuki 3 participants 21 messages Sep 14, 2005 – Oct 30, 2005

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 2/2 miss-sync issues on sync mount (miss-sync on utime)

The 2nd patch fixes miss-sync issue on attribute operations, like utime.

---
Hiroyuki Machida

---
 file.c |    4 ++++
 1 files changed, 4 insertions(+)
fs/fat/file.c +4 -0
@@ -201,6 +183,10 @@ int fat_notify_change(struct dentry *den
 	else
 		mask = sbi->options.fs_fmask;
 	inode->i_mode &= S_IFMT | (S_IRWXUGO & ~mask);
+
+	if ( (!error) && IS_SYNC(inode)) {
+		error = write_inode_now(inode, 1);
+	}
 out:
 	unlock_kernel();
 	return error;
maintainer
#1 lore raw

fs/fat/file.c int fat_notify_change(struct dentry *den · line 189

Quoted 3 lines · Hiroyuki
fs/fat/file.c +3 -0
+	if ( (!error) && IS_SYNC(inode)) {
+		error = write_inode_now(inode, 1);
+	}

We don't need to sync the data pages at all here. And I think it is not right place for doing this. If we need this, since we need to see O_SYNC for fchxxx() VFS would be right place to do it.

But, personally, I'd like to kill the "-o sync" stuff for these independent meta data rather. Then...

Signature · 1 line
OGAWA Hirofumi <[email protected]>
#2 lore raw
Quoted 11 lines · OGAWA Hirofumi

fs/fat/file.c int fat_notify_change(struct dentry *den · line 189

Quoted 3 lines · Hiroyuki
fs/fat/file.c +3 -0
+	if ( (!error) && IS_SYNC(inode)) {
+		error = write_inode_now(inode, 1);
+	}

We don't need to sync the data pages at all here. And I think it is not right place for doing this. If we need this, since we need to see O_SYNC for fchxxx() VFS would be right place to do it.

I see, I'll look into those.

Quoted 2 lines

But, personally, I'd like to kill the "-o sync" stuff for these independent meta data rather. Then...

Signature · 2 lines
Hiroyuki Machida		[email protected]		
SSW Dept. HENC, Sony Corp.
#3 lore raw

PATCH 1/2 miss-sync changes on attributes (Re: [PATCH 2/2][FAT] miss-sync issues on sync mount (miss-sync on utime))

In reply to OGAWA Hirofumi

I revise a previous patch. Now checking dirty flag is done at vfs layer, as OGAWA-san said. I realized ext2_sync_inode() is good for syncing inode without it's data. I moved it to vfs layer and rename it to sync_inode_wodata().

The first patch attached here is changes on vfs layer. Second patch attached at the next mail is changes on ext2 fs.

Quoted 14 lines · OGAWA Hirofumi

Review

Quoted 3 lines · Hiroyuki
(quoted diff) +3 -0
+	if ( (!error) && IS_SYNC(inode)) {
+		error = write_inode_now(inode, 1);
+	}

We don't need to sync the data pages at all here. And I think it is not right place for doing this. If we need this, since we need to see O_SYNC for fchxxx() VFS would be right place to do it.

But, personally, I'd like to kill the "-o sync" stuff for these independent meta data rather. Then...

Signature · 1 line
Hiroyuki Machida		[email protected]		

This patch adds inode-sync after attribute changes, if needed.

* fs-sync-attr.patch for 2.6.13

 fs/fs-writeback.c      |   19 +++++++++++++++++++
 fs/open.c              |   12 ++++++++++++
 include/linux/fs.h     |    1 +
 4 files changed, 32 insertions(+)
fs/fs-writeback.c +19 -0
@@ -593,6 +593,25 @@ int sync_inode(struct inode *inode, stru
 EXPORT_SYMBOL(sync_inode);
 
 /**
+ * sync_inode_wodata - sync(write and wait) inode to disk, without it's data.
+ * @inode: the inode to sync
+ *
+ * sync_inode_wodata() will write an inode  then wait.  It will also
+ * correctly update the inode on its superblock's dirty inode lists 
+ * and will update inode->i_state.
+ *
+ * The caller must have a ref on the inode.
+ */
+int sync_inode_wodata(struct inode *inode)
+{
+	struct writeback_control wbc = {
+		.sync_mode = WB_SYNC_ALL, /* wait */
+		.nr_to_write = 0,/* no data to be written */
+	};
+	return sync_inode(inode, &wbc);
+}
+
+/**
  * generic_osync_inode - flush all dirty data for a given inode to disk
  * @inode: inode to write
  * @mapping: the address_space that should be flushed
fs/open.c +12 -0
diff -upr linux-2.6.13/fs/open.c linux-2.6.13-sync-attr/fs/open.c
@@ -207,6 +207,8 @@ int do_truncate(struct dentry *dentry, l
 
 	down(&dentry->d_inode->i_sem);
 	err = notify_change(dentry, &newattrs);
+	if (!err && IS_SYNC(dentry->d_inode))
+		sync_inode_wodata(dentry->d_inode);
 	up(&dentry->d_inode->i_sem);
 	return err;
 }
@@ -394,6 +396,8 @@ asmlinkage long sys_utime(char __user * 
 	}
 	down(&inode->i_sem);
 	error = notify_change(nd.dentry, &newattrs);
+	if (!error && IS_SYNC(inode))
+		sync_inode_wodata(inode);
 	up(&inode->i_sem);
 dput_and_out:
 	path_release(&nd);
@@ -447,6 +451,8 @@ long do_utimes(char __user * filename, s
 	}
 	down(&inode->i_sem);
 	error = notify_change(nd.dentry, &newattrs);
+	if (!error && IS_SYNC(inode))
+		sync_inode_wodata(inode);
 	up(&inode->i_sem);
 dput_and_out:
 	path_release(&nd);
@@ -620,6 +626,8 @@ asmlinkage long sys_fchmod(unsigned int 
 	newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
 	newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
 	err = notify_change(dentry, &newattrs);
+	if (!err && IS_SYNC(inode))
+		sync_inode_wodata(inode);
 	up(&inode->i_sem);
 
 out_putf:
@@ -654,6 +662,8 @@ asmlinkage long sys_chmod(const char __u
 	newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
 	newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
 	error = notify_change(nd.dentry, &newattrs);
+	if (!error && IS_SYNC(inode))
+		sync_inode_wodata(inode);
 	up(&inode->i_sem);
 
 dput_and_out:
@@ -692,6 +702,8 @@ static int chown_common(struct dentry * 
 		newattrs.ia_valid |= ATTR_KILL_SUID|ATTR_KILL_SGID;
 	down(&inode->i_sem);
 	error = notify_change(dentry, &newattrs);
+	if (!error && IS_SYNC(inode))
+		sync_inode_wodata(inode);
 	up(&inode->i_sem);
 out:
 	return error;
include/linux/fs.h +1 -0
diff -upr linux-2.6.13/include/linux/fs.h linux-2.6.13-sync-attr/include/linux/fs.h
@@ -1082,6 +1082,7 @@ static inline void file_accessed(struct 
 }
 
 int sync_inode(struct inode *inode, struct writeback_control *wbc);
+int sync_inode_wodata(struct inode *inode);
 
 /**
  * struct export_operations - for nfsd to communicate with file systems
#4 lore raw

PATCH 2/2 replace ext2_sync_inode() with sync_inode_wodata( (Re: [PATCH 2/2][FAT] miss-sync issues on sync mount (miss-sync on utime))

This patch replaces ext2_sync_inode() with sync_inode_wodata(), which is introduced by fs-sync-attr.patch attached at
"[PATCH 1/2] miss-sync changes on attributes"

Quoted 31 lines · Hiroyuki

I revise a previous patch. Now checking dirty flag is done at vfs layer, as OGAWA-san said. I realized ext2_sync_inode() is good for syncing inode without it's data. I moved it to vfs layer and rename it to sync_inode_wodata().

The first patch attached here is changes on vfs layer. Second patch attached at the next mail is changes on ext2 fs.

Quoted 9 lines · OGAWA Hirofumi

Review

Quoted 3 lines · Hiroyuki
(quoted diff) +3 -0
+    if ( (!error) && IS_SYNC(inode)) {
+        error = write_inode_now(inode, 1);
+    }
Quoted 6 lines

We don't need to sync the data pages at all here. And I think it is not right place for doing this. If we need this, since we need to see O_SYNC for fchxxx() VFS would be right place to do it.

But, personally, I'd like to kill the "-o sync" stuff for these independent meta data rather. Then...

------------------------------------------------------------------------

Signature · 1 line
Hiroyuki Machida		[email protected]		

This patch replaces ext2_sync_inode() with sync_inode_wodata().

* ext2-inode-sync.patch for 2.6.13

 ext2.h  |    1 -
 fsync.c |    2 +-
 inode.c |   11 +----------
 xattr.c |    2 +-
 4 files changed, 3 insertions(+), 13 deletions(-)
fs/ext2/ext2.h +0 -1
@@ -127,7 +127,6 @@ extern void ext2_read_inode (struct inod
 extern int ext2_write_inode (struct inode *, int);
 extern void ext2_put_inode (struct inode *);
 extern void ext2_delete_inode (struct inode *);
-extern int ext2_sync_inode (struct inode *);
 extern void ext2_discard_prealloc (struct inode *);
 extern int ext2_get_block(struct inode *, sector_t, struct buffer_head *, int);
 extern void ext2_truncate (struct inode *);
fs/ext2/fsync.c +1 -1
diff -upr linux-2.6.13/fs/ext2/fsync.c linux-2.6.13-sync-attr/fs/ext2/fsync.c
@@ -44,7 +44,7 @@ int ext2_sync_file(struct file *file, st
 	if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
 		return ret;
 
-	err = ext2_sync_inode(inode);
+	err = sync_inode_wodata(inode);
 	if (ret == 0)
 		ret = err;
 	return ret;
fs/ext2/inode.c +1 -10
diff -upr linux-2.6.13/fs/ext2/inode.c linux-2.6.13-sync-attr/fs/ext2/inode.c
@@ -993,7 +993,7 @@ do_indirects:
 	inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
 	if (inode_needs_sync(inode)) {
 		sync_mapping_buffers(inode->i_mapping);
-		ext2_sync_inode (inode);
+		sync_inode_wodata(inode);
 	} else {
 		mark_inode_dirty(inode);
 	}
@@ -1282,15 +1282,6 @@ int ext2_write_inode(struct inode *inode
 	return ext2_update_inode(inode, wait);
 }
 
-int ext2_sync_inode(struct inode *inode)
-{
-	struct writeback_control wbc = {
-		.sync_mode = WB_SYNC_ALL,
-		.nr_to_write = 0,	/* sys_fsync did this */
-	};
-	return sync_inode(inode, &wbc);
-}
-
 int ext2_setattr(struct dentry *dentry, struct iattr *iattr)
 {
 	struct inode *inode = dentry->d_inode;
fs/ext2/xattr.c +1 -1
diff -upr linux-2.6.13/fs/ext2/xattr.c linux-2.6.13-sync-attr/fs/ext2/xattr.c
@@ -705,7 +705,7 @@ ext2_xattr_set2(struct inode *inode, str
 	EXT2_I(inode)->i_file_acl = new_bh ? new_bh->b_blocknr : 0;
 	inode->i_ctime = CURRENT_TIME_SEC;
 	if (IS_SYNC(inode)) {
-		error = ext2_sync_inode (inode);
+		error = sync_inode_wodata(inode);
 		/* In case sync failed due to ENOSPC the inode was actually
 		 * written (only some dirty data were not) so we just proceed
 		 * as if nothing happened and cleanup the unused block */
#5 lore raw

Re: [PATCH 1/2] miss-sync changes on attributes (Re: [PATCH 2/2][FAT] miss-sync issues on sync mount (miss-sync on utime))

In reply to Machida, Hiroyuki

Previous patch didn't export sync_inode_wodata(), that had a problem with modula ext2 fs. Bug-fixed version is attached here.

Quoted 35 lines · Hiroyuki

I revise a previous patch. Now checking dirty flag is done at vfs layer, as OGAWA-san said. I realized ext2_sync_inode() is good for syncing inode without it's data. I moved it to vfs layer and rename it to sync_inode_wodata().

The first patch attached here is changes on vfs layer. Second patch attached at the next mail is changes on ext2 fs.

Quoted 9 lines · OGAWA Hirofumi

Review

Quoted 3 lines · Hiroyuki
(quoted diff) +3 -0
+    if ( (!error) && IS_SYNC(inode)) {
+        error = write_inode_now(inode, 1);
+    }
Quoted 6 lines

We don't need to sync the data pages at all here. And I think it is not right place for doing this. If we need this, since we need to see O_SYNC for fchxxx() VFS would be right place to do it.

But, personally, I'd like to kill the "-o sync" stuff for these independent meta data rather. Then...

------------------------------------------------------------------------

This patch adds inode-sync after attribute changes, if needed.

Quoted 8 lines

* fs-sync-attr.patch for 2.6.13

 fs/fs-writeback.c      |   19 +++++++++++++++++++
 fs/open.c              |   12 ++++++++++++
 include/linux/fs.h     |    1 +
 4 files changed, 32 insertions(+)
	:

This patch adds inode-sync after attribute changes, if needed.

* fs-sync-attr_2.patch for 2.6.13

 fs/fs-writeback.c  |   20 ++++++++++++++++++++
 fs/open.c          |   12 ++++++++++++
 include/linux/fs.h |    1 +
 3 files changed, 33 insertions(+)
fs/fs-writeback.c +20 -0
diff -upr linux-2.6.13/fs/fs-writeback.c linux-2.6.13-sync-attr/fs/fs-writeback.c
@@ -593,6 +593,26 @@ int sync_inode(struct inode *inode, stru
 EXPORT_SYMBOL(sync_inode);
 
 /**
+ * sync_inode_wodata - sync(write and wait) inode to disk, without it's data.
+ * @inode: the inode to sync
+ *
+ * sync_inode_wodata() will write an inode  then wait.  It will also
+ * correctly update the inode on its superblock's dirty inode lists 
+ * and will update inode->i_state.
+ *
+ * The caller must have a ref on the inode.
+ */
+int sync_inode_wodata(struct inode *inode)
+{
+	struct writeback_control wbc = {
+		.sync_mode = WB_SYNC_ALL, /* wait */
+		.nr_to_write = 0,/* no data to be written */
+	};
+	return sync_inode(inode, &wbc);
+}
+EXPORT_SYMBOL(sync_inode_wodata);
+
+/**
  * generic_osync_inode - flush all dirty data for a given inode to disk
  * @inode: inode to write
  * @mapping: the address_space that should be flushed
fs/open.c +12 -0
diff -upr linux-2.6.13/fs/open.c linux-2.6.13-sync-attr/fs/open.c
@@ -207,6 +207,8 @@ int do_truncate(struct dentry *dentry, l
 
 	down(&dentry->d_inode->i_sem);
 	err = notify_change(dentry, &newattrs);
+	if (!err && IS_SYNC(dentry->d_inode))
+		sync_inode_wodata(dentry->d_inode);
 	up(&dentry->d_inode->i_sem);
 	return err;
 }
@@ -394,6 +396,8 @@ asmlinkage long sys_utime(char __user * 
 	}
 	down(&inode->i_sem);
 	error = notify_change(nd.dentry, &newattrs);
+	if (!error && IS_SYNC(inode))
+		sync_inode_wodata(inode);
 	up(&inode->i_sem);
 dput_and_out:
 	path_release(&nd);
@@ -447,6 +451,8 @@ long do_utimes(char __user * filename, s
 	}
 	down(&inode->i_sem);
 	error = notify_change(nd.dentry, &newattrs);
+	if (!error && IS_SYNC(inode))
+		sync_inode_wodata(inode);
 	up(&inode->i_sem);
 dput_and_out:
 	path_release(&nd);
@@ -620,6 +626,8 @@ asmlinkage long sys_fchmod(unsigned int 
 	newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
 	newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
 	err = notify_change(dentry, &newattrs);
+	if (!err && IS_SYNC(inode))
+		sync_inode_wodata(inode);
 	up(&inode->i_sem);
 
 out_putf:
@@ -654,6 +662,8 @@ asmlinkage long sys_chmod(const char __u
 	newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
 	newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
 	error = notify_change(nd.dentry, &newattrs);
+	if (!error && IS_SYNC(inode))
+		sync_inode_wodata(inode);
 	up(&inode->i_sem);
 
 dput_and_out:
@@ -692,6 +702,8 @@ static int chown_common(struct dentry * 
 		newattrs.ia_valid |= ATTR_KILL_SUID|ATTR_KILL_SGID;
 	down(&inode->i_sem);
 	error = notify_change(dentry, &newattrs);
+	if (!error && IS_SYNC(inode))
+		sync_inode_wodata(inode);
 	up(&inode->i_sem);
 out:
 	return error;
include/linux/fs.h +1 -0
diff -upr linux-2.6.13/include/linux/fs.h linux-2.6.13-sync-attr/include/linux/fs.h
@@ -1082,6 +1082,7 @@ static inline void file_accessed(struct 
 }
 
 int sync_inode(struct inode *inode, struct writeback_control *wbc);
+int sync_inode_wodata(struct inode *inode);
 
 /**
  * struct export_operations - for nfsd to communicate with file systems
#6 lore raw

Re: [PATCH 1/2] miss-sync changes on attributes (Re: [PATCH 2/2][FAT] miss-sync issues on sync mount (miss-sync on utime))

In reply to Machida, Hiroyuki
Quoted 26 lines · Hiroyuki

This patch adds inode-sync after attribute changes, if needed.

* fs-sync-attr.patch for 2.6.13

 fs/fs-writeback.c      |   19 +++++++++++++++++++
 fs/open.c              |   12 ++++++++++++
 include/linux/fs.h     |    1 +
 4 files changed, 32 insertions(+)
fs/fs-writeback.c +8 -0
@@ -593,6 +593,25 @@ int sync_inode(struct inode *inode, stru
 EXPORT_SYMBOL(sync_inode);
 
 /**
+ * sync_inode_wodata - sync(write and wait) inode to disk, without it's data.
+ * @inode: the inode to sync
+ *
+ * sync_inode_wodata() will write an inode  then wait.  It will also
+ * correctly update the inode on its superblock's dirty inode lists 
+ * and will update inode->i_state.
+ *
+ * The caller must have a ref on the inode.

fs/fs-writeback.c int sync_inode(struct inode *inode, stru · line 613

Quoted 10 lines
fs/fs-writeback.c +10 -0
+ */
+int sync_inode_wodata(struct inode *inode)
+{
+	struct writeback_control wbc = {
+		.sync_mode = WB_SYNC_ALL, /* wait */
+		.nr_to_write = 0,/* no data to be written */
+	};
+	return sync_inode(inode, &wbc);
+}
+

I think this function duplicates write_inode_now()?

maintainer
#7 lore raw

Re: [PATCH 1/2] miss-sync changes on attributes (Re: [PATCH 2/2][FAT] miss-sync issues on sync mount (miss-sync on utime))

Quoted 13 lines · Andrew Morton
Quoted 13 lines

/**
+ * sync_inode_wodata - sync(write and wait) inode to disk, without it's data.
+ * @inode: the inode to sync
+ *
+ * sync_inode_wodata() will write an inode then wait. It will also
+ * correctly update the inode on its superblock's dirty inode lists
+ * and will update inode->i_state.
+ *
+ * The caller must have a ref on the inode.
+ */

fs/fs-writeback.c +3 -0
+int sync_inode_wodata(struct inode *inode)
+{
+	struct writeback_control wbc = {
Quoted 8 lines

fs/fs-writeback.c int sync_inode(struct inode *inode, stru · line 613

Quoted 6 lines
fs/fs-writeback.c +6 -0
+		.sync_mode = WB_SYNC_ALL, /* wait */
+		.nr_to_write = 0,/* no data to be written */
+	};
+	return sync_inode(inode, &wbc);
+}
+

I think this function duplicates write_inode_now()?

write_inode_now() seems to write data pages, but this doesn't write (.nr_to_write = 0).

Signature · 1 line
OGAWA Hirofumi <[email protected]>
#8 lore raw

Re: [PATCH 1/2] miss-sync changes on attributes (Re: [PATCH 2/2][FAT] miss-sync issues on sync mount (miss-sync on utime))

Quoted 25 lines · OGAWA Hirofumi
Quoted 13 lines · Andrew Morton
Quoted 13 lines

/**
+ * sync_inode_wodata - sync(write and wait) inode to disk, without it's data.
+ * @inode: the inode to sync
+ *
+ * sync_inode_wodata() will write an inode then wait. It will also
+ * correctly update the inode on its superblock's dirty inode lists
+ * and will update inode->i_state.
+ *
+ * The caller must have a ref on the inode.
+ */

(quoted diff) +3 -0
+int sync_inode_wodata(struct inode *inode)
+{
+	struct writeback_control wbc = {
Quoted 8 lines

Review

Quoted 6 lines
(quoted diff) +6 -0
+		.sync_mode = WB_SYNC_ALL, /* wait */
+		.nr_to_write = 0,/* no data to be written */
+	};
+	return sync_inode(inode, &wbc);
+}
+

I think this function duplicates write_inode_now()?

Quoted 2 lines

write_inode_now() seems to write data pages, but this doesn't write (.nr_to_write = 0).

hm, OK.

However there's not much point in writing a brand-new function when write_inode_now() almost does the right thing. We can share the implementation within fs-writeback.c.

<looks>

Isn't write_inode_now() buggy? If !mapping_cap_writeback_dirty() we should still write the inode itself?

fs/fs-writeback.c renamed from fs/fs-writeback.c~write_inode_now-write-inode-if-not-bdi_cap_no_writeback +1 -1
diff -puN fs/fs-writeback.c~write_inode_now-write-inode-if-not-bdi_cap_no_writeback fs/fs-writeback.c
@@ -558,7 +558,7 @@ int write_inode_now(struct inode *inode,
 	};
 
 	if (!mapping_cap_writeback_dirty(inode->i_mapping))
-		return 0;
+		wbc.nr_to_write = 0;
 
 	might_sleep();
 	spin_lock(&inode_lock);

_

maintainer
#9 lore raw

Re: [PATCH 1/2] miss-sync changes on attributes (Re: [PATCH 2/2][FAT] miss-sync issues on sync mount (miss-sync on utime))

Quoted 3 lines · Andrew Morton

However there's not much point in writing a brand-new function when write_inode_now() almost does the right thing. We can share the implementation within fs-writeback.c.

Indeed. We use the generic_osync_inode() for it?

Quoted 2 lines

Isn't write_inode_now() buggy? If !mapping_cap_writeback_dirty() we should still write the inode itself?

Indeed. It seems we should write the dirty inode to backing device's buffers. sync_sb_inodes() too? If so, really buggy.. I'll check it.

Signature · 1 line
OGAWA Hirofumi <[email protected]>
maintainer
#10 lore raw

Re: [PATCH 1/2] miss-sync changes on attributes (Re: [PATCH 2/2][FAT] miss-sync issues on sync mount (miss-sync on utime))

Quoted 5 lines · OGAWA Hirofumi
Quoted 2 lines

Isn't write_inode_now() buggy? If !mapping_cap_writeback_dirty() we should still write the inode itself?

Indeed. It seems we should write the dirty inode to backing device's buffers. sync_sb_inodes() too? If so, really buggy.. I'll check it.

write_inode_now() seems ok.

If !mapping_cap_writeback_dirty(), the inode is bdev_inode itself or ram-based fs's inode, so ->write_inode() is not needed. And if backing_dev is ramdisk, mapping->backing_dev_info was setted the following special bdi.

static struct backing_dev_info rd_file_backing_dev_info = {
.ra_pages = 0, /* No readahead */
.capabilities = BDI_CAP_MAP_COPY, /* Does contribute to dirty memory */
.unplug_io_fn = default_unplug_io_fn,
};

Signature · 1 line
OGAWA Hirofumi <[email protected]>
#11 lore raw

Re: [PATCH 1/2] miss-sync changes on attributes (Re: [PATCH 2/2][FAT] miss-sync issues on sync mount (miss-sync on utime))

In reply to OGAWA Hirofumi
Quoted 9 lines · OGAWA Hirofumi
Quoted 3 lines · Andrew Morton

However there's not much point in writing a brand-new function when write_inode_now() almost does the right thing. We can share the implementation within fs-writeback.c.

Indeed. We use the generic_osync_inode() for it?

Please let me confirm.
Using generic_osync_inode(inode, NULL, OSYNC_INODE) instaed of sync_inode_wodata(inode) is peferable for changes on fs/open.c, even it would write data. Is it correct?

Signature · 1 line
Hiroyuki Machida		[email protected]		
#12 lore raw

Re: [PATCH 1/2] miss-sync changes on attributes (Re: [PATCH 2/2][FAT] miss-sync issues on sync mount (miss-sync on utime))

Quoted 12 lines · Hiroyuki
Quoted 8 lines · OGAWA Hirofumi
Quoted 3 lines · Andrew Morton

However there's not much point in writing a brand-new function when write_inode_now() almost does the right thing. We can share the implementation within fs-writeback.c.

Quoted 7 lines
Quoted 1 line

Indeed. We use the generic_osync_inode() for it?

Please let me confirm.
Using generic_osync_inode(inode, NULL, OSYNC_INODE) instaed of sync_inode_wodata(inode) is peferable for changes on fs/open.c, even it would write data. Is it correct?

I don't know. It depends on what you're actually trying to do, and I don't recall anyone having described that!

#13 lore raw

Re: [PATCH 1/2] miss-sync changes on attributes (Re: [PATCH 2/2][FAT] miss-sync issues on sync mount (miss-sync on utime))

Quoted 24 lines · Andrew Morton
Quoted 13 lines · Hiroyuki
Quoted 9 lines · OGAWA Hirofumi
Quoted 3 lines · Andrew Morton

However there's not much point in writing a brand-new function when write_inode_now() almost does the right thing. We can share the implementation within fs-writeback.c.

Quoted 7 lines
Quoted 1 line

Indeed. We use the generic_osync_inode() for it?

Please let me confirm.
Using generic_osync_inode(inode, NULL, OSYNC_INODE) instaed of sync_inode_wodata(inode) is peferable for changes on fs/open.c, even it would write data. Is it correct?

Quoted 2 lines

I don't know. It depends on what you're actually trying to do, and I don't recall anyone having described that!

I'm just little confused, because I realized generic_osync_inode(,,OSYNC_INODE) calls sync_inode_now(), however Ogawasa-san pointed out sync_inode_now() which my first patch used is writing data page.

Signature · 2 lines
Hiroyuki Machida		[email protected]		
SSW Dept. HENC, Sony Corp.
maintainer
#14 lore raw

Re: [PATCH 1/2] miss-sync changes on attributes (Re: [PATCH 2/2][FAT] miss-sync issues on sync mount (miss-sync on utime))

In reply to Machida, Hiroyuki
Quoted 6 lines · Hiroyuki
Quoted 5 lines · OGAWA Hirofumi
Quoted 3 lines · Andrew Morton

However there's not much point in writing a brand-new function when write_inode_now() almost does the right thing. We can share the implementation within fs-writeback.c.

Quoted 6 lines
Quoted 1 line

Indeed. We use the generic_osync_inode() for it?

Please let me confirm.
Using generic_osync_inode(inode, NULL, OSYNC_INODE) instaed of sync_inode_wodata(inode) is peferable for changes on fs/open.c, even it would write data. Is it correct?

No, I only thought the interface is good. I don't know why it writes data pages even if OSYNC_INODE only.

Signature · 1 line
OGAWA Hirofumi <[email protected]>
#15 lore raw

Re: [PATCH 1/2] miss-sync changes on attributes (Re: [PATCH 2/2][FAT] miss-sync issues on sync mount (miss-sync on utime))

Quoted 14 lines · OGAWA Hirofumi
Quoted 11 lines · Hiroyuki
Quoted 8 lines · OGAWA Hirofumi
Quoted 3 lines · Andrew Morton

However there's not much point in writing a brand-new function when write_inode_now() almost does the right thing. We can share the implementation within fs-writeback.c.

Indeed. We use the generic_osync_inode() for it?

Quoted 8 lines
Quoted 4 lines

Please let me confirm.
Using generic_osync_inode(inode, NULL, OSYNC_INODE) instaed of sync_inode_wodata(inode) is peferable for changes on fs/open.c, even it would write data. Is it correct?

No, I only thought the interface is good. I don't know why it writes data pages even if OSYNC_INODE only.

I checked 2.6.13 tree, following functions call generic_osync_inode(). However noone calls it with OSYNC_INODE. SO I can't find intention of it's usage.

Does anyone know why generic_osync_inode() trys to write data page, even if OSYNC_INODE only passed ?

- fs/reiserfs/file.c
reiserfs_file_write() OSYNC_METADATA | OSYNC_DATA
- mm/filemap.c
sync_page_range() OSYNC_METADATA
sync_page_range_nolock() OSYNC_METADATA
generic_file_direct_write OSYNC_METADATA

Signature · 1 line
Hiroyuki Machida		[email protected]		
#16 lore raw

PATCH 1/1 generic_osync_inode() with OSYNC_INODE only passed (Re: [PATCH 1/2] miss-sync changes on attributes)

generic_osync_inode() seems to do over-writing, if OSYNC_INODE only passed. According comments of generic_osync_inode(), it is expected to write inode itself only. Current implementation trys to write data page, even if OSYNC_INODE only passed. This patch fixes it.

This patch is preparetion of other patch to fix "miss-sync changes on attributes".

Quoted 46 lines · Hiroyuki
Quoted 23 lines · OGAWA Hirofumi
Quoted 10 lines · Hiroyuki
Quoted 8 lines · OGAWA Hirofumi
Quoted 3 lines · Andrew Morton

However there's not much point in writing a brand-new function when write_inode_now() almost does the right thing. We can share the implementation within fs-writeback.c.

Quoted 7 lines
Quoted 1 line

Indeed. We use the generic_osync_inode() for it?

Please let me confirm.
Using generic_osync_inode(inode, NULL, OSYNC_INODE) instaed of sync_inode_wodata(inode) is peferable for changes on fs/open.c, even it would write data. Is it correct?

Quoted 2 lines

No, I only thought the interface is good. I don't know why it writes data pages even if OSYNC_INODE only.

I checked 2.6.13 tree, following functions call generic_osync_inode(). However noone calls it with OSYNC_INODE. SO I can't find intention of it's usage.

Does anyone know why generic_osync_inode() trys to write data page, even if OSYNC_INODE only passed ?

- fs/reiserfs/file.c
reiserfs_file_write() OSYNC_METADATA | OSYNC_DATA
- mm/filemap.c
sync_page_range() OSYNC_METADATA
sync_page_range_nolock() OSYNC_METADATA
generic_file_direct_write OSYNC_METADATA

Signature · 1 line
Hiroyuki Machida		[email protected]		
#17 lore raw

PATCH 1/1 generic_osync_inode() with OSYNC_INODE only passed (Re: [PATCH 1/2] miss-sync changes on attributes)

In reply to Machida, Hiroyuki

generic__inode() seems to do over-writing, if OSYNC_INODE only passed. According comments of generic_osync_inode(), it is expected to write inode itself only. Current implementation trys to write data page, even if OSYNC_INODE only passed. This patch fixes it.

This patch is preparetion of other patch to fix "miss-sync changes on attributes".

Quoted 46 lines · Hiroyuki
Quoted 23 lines · OGAWA Hirofumi
Quoted 10 lines · Hiroyuki
Quoted 8 lines · OGAWA Hirofumi
Quoted 3 lines · Andrew Morton

However there's not much point in writing a brand-new function when write_inode_now() almost does the right thing. We can share the implementation within fs-writeback.c.

Quoted 7 lines
Quoted 1 line

Indeed. We use the generic_osync_inode() for it?

Please let me confirm.
Using generic_osync_inode(inode, NULL, OSYNC_INODE) instaed of sync_inode_wodata(inode) is peferable for changes on fs/open.c, even it would write data. Is it correct?

Quoted 2 lines

No, I only thought the interface is good. I don't know why it writes data pages even if OSYNC_INODE only.

I checked 2.6.13 tree, following functions call generic_osync_inode(). However noone calls it with OSYNC_INODE. SO I can't find intention of it's usage.

Does anyone know why generic_osync_inode() trys to write data page, even if OSYNC_INODE only passed ?

- fs/reiserfs/file.c
reiserfs_file_write() OSYNC_METADATA | OSYNC_DATA
- mm/filemap.c
sync_page_range() OSYNC_METADATA
sync_page_range_nolock() OSYNC_METADATA
generic_file_direct_write OSYNC_METADATA

Signature · 1 line
Hiroyuki Machida		[email protected]		
fs-writeback.c renamed from fs-writeback.c.ORG +15 -4
@@ -614,6 +614,7 @@ int generic_osync_inode(struct inode *in
 	int err = 0;
 	int need_write_inode_now = 0;
 	int err2;
+	long nr_write;
 
 	current->flags |= PF_SYNCWRITE;
 	if (what & OSYNC_DATA)
@@ -632,13 +633,23 @@ int generic_osync_inode(struct inode *in
 
 	spin_lock(&inode_lock);
 	if ((inode->i_state & I_DIRTY) &&
-	    ((what & OSYNC_INODE) || (inode->i_state & I_DIRTY_DATASYNC)))
+	    ((what & OSYNC_INODE) || (inode->i_state & I_DIRTY_DATASYNC))) {
 		need_write_inode_now = 1;
+		nr_write = (what == OSYNC_INODE) ? 0 : LONG_MAX;
+	}
 	spin_unlock(&inode_lock);
 
-	if (need_write_inode_now) {
-		err2 = write_inode_now(inode, 1);
-		if (!err)
+	if (need_write_inode_now && 
+	    mapping_cap_writeback_dirty(inode->i_mapping)) {
+		struct writeback_control wbc = {
+			.sync_mode = WB_SYNC_ALL, 
+		};
+
+		wbc.nr_to_write = nr_write;
+		might_sleep();
+		err2 = sync_inode(inode, &wbc);
+		wait_on_inode(inode);
+		if (!err) 
 			err = err2;
 	}
 	else
maintainer
#18 lore raw

PATCH 1/1 Fix !mapping_cap_writeback_dirty(inode->i_mapping)

In reply to Andrew Morton
Quoted 7 lines · Andrew Morton

Isn't write_inode_now() buggy? If !mapping_cap_writeback_dirty() we should still write the inode itself?

diff -puN fs/fs-writeback.c~write_inode_now-write-inode-if-not-bdi_cap_no_writeback fs/fs-writeback.c

fs/fs-writeback.c int write_inode_now(struct inode *inode, · line 564

Quoted 8 lines
fs/fs-writeback.c renamed from fs/fs-writeback.c~write_inode_now-write-inode-if-not-bdi_cap_no_writeback +1 -1
@@ -558,7 +558,7 @@ int write_inode_now(struct inode *inode,
 	};
 
 	if (!mapping_cap_writeback_dirty(inode->i_mapping))
-		return 0;
+		wbc.nr_to_write = 0;
 
 	might_sleep();
 	spin_lock(&inode_lock);

You are right, and I was wrong.

Yes, if block device has BDI_CAP_NO_WRITEBACK and inode->i_mapping was changing to bd_inode->i_mapping,
the !mapping_cap_writeback_dirty(inode->i_mapping) is true, so we need to write the inode itself of block special file.

I think we need to fix sync_sb_inodes() too. What do you think?

Since wbc.nr_to_write includes the information on how many pages were written, we can't change wbc.nr_to_write in sync_sb_inodes().

This patch fixed the following case,

	# mke2fs -m0 -F file
	# mount -t ext2 file mnt -o loop
	# cd mnt
	# mknod ram b 1 0
	# cat ram
	# cd ..
	# umount mnt
	# e2fsck -f file
           "mnt/ram" wasn't flushed and it was corrupted

Thanks.

Signature · 134 lines
OGAWA Hirofumi <[email protected]>



Signed-off-by: OGAWA Hirofumi <[email protected]>
---

 fs/fs-writeback.c |   34 +++++++++++++++++-----------------
 1 file changed, 17 insertions(+), 17 deletions(-)

diff -puN fs/fs-writeback.c~device-inode-write-fix fs/fs-writeback.c
--- linux-2.6.14/fs/fs-writeback.c~device-inode-write-fix	2005-10-29 08:06:28.000000000 +0900
+++ linux-2.6.14-hirofumi/fs/fs-writeback.c	2005-10-29 08:06:28.000000000 +0900
@@ -151,7 +151,8 @@ static int write_inode(struct inode *ino
  * Called under inode_lock.
  */
 static int
-__sync_single_inode(struct inode *inode, struct writeback_control *wbc)
+__sync_single_inode(struct inode *inode, struct writeback_control *wbc,
+		    int inode_only)
 {
 	unsigned dirty;
 	struct address_space *mapping = inode->i_mapping;
@@ -168,7 +169,9 @@ __sync_single_inode(struct inode *inode,
 
 	spin_unlock(&inode_lock);
 
-	ret = do_writepages(mapping, wbc);
+	ret = 0;
+	if (!inode_only)
+		ret = do_writepages(mapping, wbc);
 
 	/* Don't write the inode if only I_DIRTY_PAGES was set */
 	if (dirty & (I_DIRTY_SYNC | I_DIRTY_DATASYNC)) {
@@ -177,7 +180,7 @@ __sync_single_inode(struct inode *inode,
 			ret = err;
 	}
 
-	if (wait) {
+	if (!inode_only && wait) {
 		int err = filemap_fdatawait(mapping);
 		if (ret == 0)
 			ret = err;
@@ -242,7 +245,7 @@ __sync_single_inode(struct inode *inode,
  */
 static int
 __writeback_single_inode(struct inode *inode,
-			struct writeback_control *wbc)
+			 struct writeback_control *wbc, int inode_only)
 {
 	wait_queue_head_t *wqh;
 
@@ -267,7 +270,7 @@ __writeback_single_inode(struct inode *i
 			spin_lock(&inode_lock);
 		} while (inode->i_state & I_LOCK);
 	}
-	return __sync_single_inode(inode, wbc);
+	return __sync_single_inode(inode, wbc, inode_only);
 }
 
 /*
@@ -304,6 +307,7 @@ static void
 sync_sb_inodes(struct super_block *sb, struct writeback_control *wbc)
 {
 	const unsigned long start = jiffies;	/* livelock avoidance */
+	int inode_only;
 
 	if (!wbc->for_kupdate || list_empty(&sb->s_io))
 		list_splice_init(&sb->s_dirty, &sb->s_io);
@@ -315,7 +319,8 @@ sync_sb_inodes(struct super_block *sb, s
 		struct backing_dev_info *bdi = mapping->backing_dev_info;
 		long pages_skipped;
 
-		if (!bdi_cap_writeback_dirty(bdi)) {
+		inode_only = 0;
+		if (!mapping_cap_writeback_dirty(mapping)) {
 			list_move(&inode->i_list, &sb->s_dirty);
 			if (sb == blockdev_superblock) {
 				/*
@@ -324,12 +329,7 @@ sync_sb_inodes(struct super_block *sb, s
 				 */
 				continue;
 			}
-			/*
-			 * Dirty memory-backed inode against a filesystem other
-			 * than the kernel-internal bdev filesystem.  Skip the
-			 * entire superblock.
-			 */
-			break;
+			inode_only = 1;
 		}
 
 		if (wbc->nonblocking && bdi_write_congested(bdi)) {
@@ -363,7 +363,7 @@ sync_sb_inodes(struct super_block *sb, s
 		BUG_ON(inode->i_state & I_FREEING);
 		__iget(inode);
 		pages_skipped = wbc->pages_skipped;
-		__writeback_single_inode(inode, wbc);
+		__writeback_single_inode(inode, wbc, inode_only);
 		if (wbc->sync_mode == WB_SYNC_HOLD) {
 			inode->dirtied_when = jiffies;
 			list_move(&inode->i_list, &sb->s_dirty);
@@ -551,18 +551,18 @@ void sync_inodes(int wait)
  
 int write_inode_now(struct inode *inode, int sync)
 {
-	int ret;
 	struct writeback_control wbc = {
 		.nr_to_write = LONG_MAX,
 		.sync_mode = WB_SYNC_ALL,
 	};
+	int ret, inode_only = 0;
 
 	if (!mapping_cap_writeback_dirty(inode->i_mapping))
-		return 0;
+		inode_only = 1;
 
 	might_sleep();
 	spin_lock(&inode_lock);
-	ret = __writeback_single_inode(inode, &wbc);
+	ret = __writeback_single_inode(inode, &wbc, inode_only);
 	spin_unlock(&inode_lock);
 	if (sync)
 		wait_on_inode(inode);
@@ -586,7 +586,7 @@ int sync_inode(struct inode *inode, stru
 	int ret;
 
 	spin_lock(&inode_lock);
-	ret = __writeback_single_inode(inode, wbc);
+	ret = __writeback_single_inode(inode, wbc, 0);
 	spin_unlock(&inode_lock);
 	return ret;
 }
_
maintainer
#19 lore raw

PATCH 1/1 Don't use pdflush for filesystems has BDI_CAP_NO_WRITEBACK

Hi,

If inodes of filesystem has BDI_CAP_NO_WRITEBACK, it shouldn't be needed to flush the inodes by pdflush at all. So, this patch stops puting the inode on the sb->s_dirty, by setting I_DIRTY as initial state.

With this patch, I think unnecessary flush is stopped.

BTW, probably all most of on memory filesystems also doesn't need to flush by pdflush...?

Thanks.

Signature · 121 lines
OGAWA Hirofumi <[email protected]>


Signed-off-by: OGAWA Hirofumi <[email protected]>
---

 fs/hugetlbfs/inode.c |    1 +
 fs/pipe.c            |    8 +-------
 fs/ramfs/inode.c     |    1 +
 fs/relayfs/inode.c   |    1 +
 fs/sysfs/inode.c     |    1 +
 include/linux/fs.h   |   10 ++++++++++
 kernel/cpuset.c      |    1 +
 mm/shmem.c           |    1 +
 8 files changed, 17 insertions(+), 7 deletions(-)

diff -puN fs/hugetlbfs/inode.c~add-set_inode_noflush fs/hugetlbfs/inode.c
--- linux-2.6.14/fs/hugetlbfs/inode.c~add-set_inode_noflush	2005-10-29 08:13:57.000000000 +0900
+++ linux-2.6.14-hirofumi/fs/hugetlbfs/inode.c	2005-10-29 08:13:57.000000000 +0900
@@ -394,6 +394,7 @@ static struct inode *hugetlbfs_get_inode
 	inode = new_inode(sb);
 	if (inode) {
 		struct hugetlbfs_inode_info *info;
+		set_inode_noflush(inode);
 		inode->i_mode = mode;
 		inode->i_uid = uid;
 		inode->i_gid = gid;
diff -puN fs/pipe.c~add-set_inode_noflush fs/pipe.c
--- linux-2.6.14/fs/pipe.c~add-set_inode_noflush	2005-10-29 08:13:57.000000000 +0900
+++ linux-2.6.14-hirofumi/fs/pipe.c	2005-10-29 08:13:57.000000000 +0900
@@ -697,13 +697,7 @@ static struct inode * get_pipe_inode(voi
 	PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 1;
 	inode->i_fop = &rdwr_pipe_fops;
 
-	/*
-	 * Mark the inode dirty from the very beginning,
-	 * that way it will never be moved to the dirty
-	 * list because "mark_inode_dirty()" will think
-	 * that it already _is_ on the dirty list.
-	 */
-	inode->i_state = I_DIRTY;
+	set_inode_noflush(inode);
 	inode->i_mode = S_IFIFO | S_IRUSR | S_IWUSR;
 	inode->i_uid = current->fsuid;
 	inode->i_gid = current->fsgid;
diff -puN fs/ramfs/inode.c~add-set_inode_noflush fs/ramfs/inode.c
--- linux-2.6.14/fs/ramfs/inode.c~add-set_inode_noflush	2005-10-29 08:13:57.000000000 +0900
+++ linux-2.6.14-hirofumi/fs/ramfs/inode.c	2005-10-29 08:13:57.000000000 +0900
@@ -55,6 +55,7 @@ struct inode *ramfs_get_inode(struct sup
 	struct inode * inode = new_inode(sb);
 
 	if (inode) {
+		set_inode_noflush(inode);
 		inode->i_mode = mode;
 		inode->i_uid = current->fsuid;
 		inode->i_gid = current->fsgid;
diff -puN fs/relayfs/inode.c~add-set_inode_noflush fs/relayfs/inode.c
--- linux-2.6.14/fs/relayfs/inode.c~add-set_inode_noflush	2005-10-29 08:13:57.000000000 +0900
+++ linux-2.6.14-hirofumi/fs/relayfs/inode.c	2005-10-29 08:13:57.000000000 +0900
@@ -52,6 +52,7 @@ static struct inode *relayfs_get_inode(s
 		return NULL;
 	}
 
+	set_inode_noflush(inode);
 	inode->i_mode = mode;
 	inode->i_uid = 0;
 	inode->i_gid = 0;
diff -puN fs/sysfs/inode.c~add-set_inode_noflush fs/sysfs/inode.c
--- linux-2.6.14/fs/sysfs/inode.c~add-set_inode_noflush	2005-10-29 08:13:57.000000000 +0900
+++ linux-2.6.14-hirofumi/fs/sysfs/inode.c	2005-10-29 08:13:57.000000000 +0900
@@ -113,6 +113,7 @@ struct inode * sysfs_new_inode(mode_t mo
 {
 	struct inode * inode = new_inode(sysfs_sb);
 	if (inode) {
+		set_inode_noflush(inode);
 		inode->i_blksize = PAGE_CACHE_SIZE;
 		inode->i_blocks = 0;
 		inode->i_mapping->a_ops = &sysfs_aops;
diff -puN include/linux/fs.h~add-set_inode_noflush include/linux/fs.h
--- linux-2.6.14/include/linux/fs.h~add-set_inode_noflush	2005-10-29 08:13:57.000000000 +0900
+++ linux-2.6.14-hirofumi/include/linux/fs.h	2005-10-29 08:13:57.000000000 +0900
@@ -1075,6 +1075,16 @@ static inline void file_accessed(struct 
 		touch_atime(file->f_vfsmnt, file->f_dentry);
 }
 
+static inline void set_inode_noflush(struct inode *inode)
+{
+	/*
+	 * Mark the inode dirty from the very beginning, that way it
+	 * will never be moved to the dirty list because "mark_inode_dirty()"
+	 * will think that it already _is_ on the dirty list.
+	 */
+	inode->i_state |= I_DIRTY;
+}
+
 int sync_inode(struct inode *inode, struct writeback_control *wbc);
 
 /**
diff -puN kernel/cpuset.c~add-set_inode_noflush kernel/cpuset.c
--- linux-2.6.14/kernel/cpuset.c~add-set_inode_noflush	2005-10-29 08:13:57.000000000 +0900
+++ linux-2.6.14-hirofumi/kernel/cpuset.c	2005-10-29 08:13:57.000000000 +0900
@@ -236,6 +236,7 @@ static struct inode *cpuset_new_inode(mo
 	struct inode *inode = new_inode(cpuset_sb);
 
 	if (inode) {
+		set_inode_noflush(inode);
 		inode->i_mode = mode;
 		inode->i_uid = current->fsuid;
 		inode->i_gid = current->fsgid;
diff -puN mm/shmem.c~add-set_inode_noflush mm/shmem.c
--- linux-2.6.14/mm/shmem.c~add-set_inode_noflush	2005-10-29 08:13:57.000000000 +0900
+++ linux-2.6.14-hirofumi/mm/shmem.c	2005-10-29 08:13:57.000000000 +0900
@@ -1283,6 +1283,7 @@ shmem_get_inode(struct super_block *sb, 
 
 	inode = new_inode(sb);
 	if (inode) {
+		set_inode_noflush(inode);
 		inode->i_mode = mode;
 		inode->i_uid = current->fsuid;
 		inode->i_gid = current->fsgid;
_
maintainer
#20 lore raw

Re: [PATCH] Don't use pdflush for filesystems has BDI_CAP_NO_WRITEBACK

fs/hugetlbfs/inode.c static struct inode *hugetlbfs_get_inode · line 400

Quoted 11 lines · OGAWA Hirofumi

diff -puN fs/hugetlbfs/inode.c~add-set_inode_noflush fs/hugetlbfs/inode.c

fs/hugetlbfs/inode.c renamed from fs/hugetlbfs/inode.c~add-set_inode_noflush +1 -0
@@ -394,6 +394,7 @@ static struct inode *hugetlbfs_get_inode
 	inode = new_inode(sb);
 	if (inode) {
 		struct hugetlbfs_inode_info *info;
+		set_inode_noflush(inode);
 		inode->i_mode = mode;
 		inode->i_uid = uid;
 		inode->i_gid = gid;

Sigh, I'm forgetting block special file again. Sorry for wrong patch.

Signature · 1 line
OGAWA Hirofumi <[email protected]>