From: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
To: Andrew Morton <akpm@osdl.org>
Cc: linux-kernel@vger.kernel.org
Subject: [PATCH] Fix !mapping_cap_writeback_dirty(inode->i_mapping)
Date: Sat, 29 Oct 2005 17:42:09 +0900 [thread overview]
Message-ID: <87vezgd89q.fsf_-_@devron.myhome.or.jp> (raw)
In-Reply-To: <20051011211601.72a0f91c.akpm@osdl.org> (Andrew Morton's message of "Tue, 11 Oct 2005 21:16:01 -0700")
Andrew Morton <akpm@osdl.org> writes:
> 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
> --- devel/fs/fs-writeback.c~write_inode_now-write-inode-if-not-bdi_cap_no_writeback 2005-10-11 21:13:25.000000000 -0700
> +++ devel-akpm/fs/fs-writeback.c 2005-10-11 21:13:40.000000000 -0700
> @@ -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.
--
OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
---
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;
}
_
next prev parent reply other threads:[~2005-10-29 8:42 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-09-14 20:39 [PATCH 2/2][FAT] miss-sync issues on sync mount (miss-sync on utime) Machida, Hiroyuki
2005-09-15 13:15 ` OGAWA Hirofumi
2005-09-15 13:58 ` Machida, Hiroyuki
2005-09-29 17:35 ` [PATCH 1/2] miss-sync changes on attributes (Re: [PATCH 2/2][FAT] miss-sync issues on sync mount (miss-sync on utime)) Machida, Hiroyuki
2005-09-29 17:49 ` [PATCH 2/2] replace ext2_sync_inode() with sync_inode_wodata( " Machida, Hiroyuki
2005-09-29 19:20 ` [PATCH 1/2] miss-sync changes on attributes " Machida, Hiroyuki
2005-10-11 21:26 ` Andrew Morton
2005-10-12 4:02 ` OGAWA Hirofumi
2005-10-12 4:16 ` Andrew Morton
2005-10-12 4:58 ` OGAWA Hirofumi
2005-10-12 5:47 ` OGAWA Hirofumi
2005-10-12 5:54 ` Machida, Hiroyuki
2005-10-12 6:10 ` Andrew Morton
2005-10-12 9:04 ` Machida, Hiroyuki
2005-10-12 6:21 ` OGAWA Hirofumi
2005-10-12 9:15 ` Machida, Hiroyuki
2005-10-14 13:01 ` [PATCH] generic_osync_inode() with OSYNC_INODE only passed (Re: [PATCH 1/2] miss-sync changes on attributes) Machida, Hiroyuki
2005-10-14 13:02 ` Machida, Hiroyuki
2005-10-29 8:42 ` OGAWA Hirofumi [this message]
2005-10-29 8:58 ` [PATCH] Don't use pdflush for filesystems has BDI_CAP_NO_WRITEBACK OGAWA Hirofumi
2005-10-30 17:15 ` OGAWA Hirofumi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87vezgd89q.fsf_-_@devron.myhome.or.jp \
--to=hirofumi@mail.parknet.co.jp \
--cc=akpm@osdl.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox