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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.