From: "fs@ercist.iscas.ac.cn" <fs@ercist.iscas.ac.cn>
To: viro@parcelfarce.linux.theplanet.co.uk, akpm@osdl.org
Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org,
iscas-linaccident@intellilink.co.jp
Subject: [PATCH] VFS mpage.c:mpage_end_io_read wrong behavior when I/O failure occurs
Date: Thu, 02 Jun 2005 14:48:24 -0400 [thread overview]
Message-ID: <opsrraiyt18b2kfj@coolq> (raw)
In-Reply-To: <opsrq9wqlser1mdp@coolq>
Related FS:
JFS
Related files:
fs/mpage.c
Bug description:
Make a partition in USB storage HDD, create a test file with
any contents.
Write a program, do: open(O_RDWR) - write - fsync - close.
After each operation, pause for a while, such as 3 seconds. Between
open and fsync, unplug USB wire to force an I/O error. fsync will
return OK instead of EIO.
Bug analysis:
sys_fsync does 3 jobs:
1)submit all pages taged with PAGECACHE_TAG_DIRTY to disk I/O,
2)do file-system related fsync operations
3)wait all pages taged with PAGECACHE_TAG_WRITEBACK to complete.
Here, all disk I/O are asynchronous, when finished, mpage_end_io_write
will remove page from mapping's PAGECACHE_TAG_WRITEBACK tree. If I/O
fails, it will also set PG_error flag, but it FORGET to set the
mapping->flags AS_EIO flag. So in step 3, sys_fsync won't notice these
pages, then no error returns.
static int mpage_end_io_write(...)
{
...
if (!uptodate)
SetPageError(page);<-- Not set mapping->flags
...
}
static int wait_on_page_writeback_range(struct address_space *mapping,
pgoff_t start, pgoff_t end)
{
...
int ret = 0;
...
while ((index <= end) && <-- For I/O error page, no loop here
(nr_pages = pagevec_lookup_tag(&pvec, mapping, &index,
PAGECACHE_TAG_WRITEBACK,
min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1)) != 0) {
...
}
if (test_and_clear_bit(AS_ENOSPC, &mapping->flags))
ret = -ENOSPC;
if (test_and_clear_bit(AS_EIO, &mapping->flags)) <-- Not set
ret = -EIO;
return ret; <-- return 0
}
Way around:
Set AS_EIO to mapping->flags if I/O error happens.
Patch:
diff -uNp linux-2.6.11.11-orig/fs/mpage.c linux-2.6.11.11-new/fs/mpage.c
--- linux-2.6.11.11-orig/fs/mpage.c 2005-05-27 01:06:46.000000000 -0400
+++ linux-2.6.11.11-new/fs/mpage.c 2005-06-02 14:29:42.264334920 -0400
@@ -79,8 +79,11 @@ static int mpage_end_io_write(struct bio
if (--bvec >= bio->bi_io_vec)
prefetchw(&bvec->bv_page->flags);
- if (!uptodate)
+ if (!uptodate){
SetPageError(page);
+ if(page->mapping)
+ set_bit(AS_EIO, &page->mapping->flags);
+ }
end_page_writeback(page);
} while (bvec >= bio->bi_io_vec);
bio_put(bio);
Signed-off-by: Qu Fuping<fs@ercist.iscas.ac.cn>
parent reply other threads:[~2005-06-02 7:49 UTC|newest]
Thread overview: expand[flat|nested] mbox.gz Atom feed
[parent not found: <opsrq9wqlser1mdp@coolq>]
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=opsrraiyt18b2kfj@coolq \
--to=fs@ercist.iscas.ac.cn \
--cc=akpm@osdl.org \
--cc=iscas-linaccident@intellilink.co.jp \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=viro@parcelfarce.linux.theplanet.co.uk \
/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.