linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Andrew Morton <akpm@osdl.org>
To: Oliver Xymoron <oxymoron@waste.org>
Cc: linux-kernel@vger.kernel.org
Subject: Re: [PATCH] [1/3] writes: report truncate and io errors on async writes
Date: Sat, 2 Aug 2003 03:47:56 -0700	[thread overview]
Message-ID: <20030802034756.11c7287c.akpm@osdl.org> (raw)
In-Reply-To: <20030802041731.GA22824@waste.org>

Oliver Xymoron <oxymoron@waste.org> wrote:
>
> These patches add the missing infrastructure for reporting
> asynchronous write errors to block devices to userspace. Errors are
> reported at the next fsync, fdatasync, or msync on the given file, and
> on close if the error occurs in time.

Thank you for persisting with this.  I won't lose the patches this time.

I made some adjustments...



- code simplifications

- No need to lock the page to stabilise ->mapping in mpage.c


 fs/mpage.c   |   29 +++++++----------------------
 fs/open.c    |   10 ++++------
 mm/filemap.c |    6 +++---
 mm/vmscan.c  |   38 +++++++++++++++++++++++---------------
 4 files changed, 37 insertions(+), 46 deletions(-)

diff -puN fs/open.c~awe-core-fixes fs/open.c
--- 25/fs/open.c~awe-core-fixes	2003-08-02 03:33:28.000000000 -0700
+++ 25-akpm/fs/open.c	2003-08-02 03:33:28.000000000 -0700
@@ -955,20 +955,18 @@ int filp_close(struct file *filp, fl_own
 	}
 
 	err = mapping->error;
-	if (err && !retval) {
-		mapping->error = 0;
+	if (!retval)
 		retval = err;
-	}
+	mapping->error = 0;
 
 	if (!file_count(filp)) {
 		printk(KERN_ERR "VFS: Close: file count is 0\n");
 		return retval;
 	}
 
-	if (filp->f_op && filp->f_op->flush)
-	{
+	if (filp->f_op && filp->f_op->flush) {
 		err = filp->f_op->flush(filp);
-		if (err && !retval)
+		if (!retval)
 			retval = err;
 	}
 
diff -puN mm/vmscan.c~awe-core-fixes mm/vmscan.c
--- 25/mm/vmscan.c~awe-core-fixes	2003-08-02 03:33:28.000000000 -0700
+++ 25-akpm/mm/vmscan.c	2003-08-02 03:33:37.000000000 -0700
@@ -236,6 +236,27 @@ static int may_write_to_queue(struct bac
 }
 
 /*
+ * We detected a synchronous write error writing a page out.  Probably
+ * -ENOSPC.  We need to propagate that into the address_space for a subsequent
+ * fsync(), msync() or close().
+ *
+ * The tricky part is that after writepage we cannot touch the mapping: nothing
+ * prevents it from being freed up.  But we have a ref on the page and once
+ * that page is locked, the mapping is pinned.
+ *
+ * We're allowed to run sleeping lock_page() here because we know the caller has
+ * __GFP_FS.
+ */
+static void handle_write_error(struct address_space *mapping,
+				struct page *page, int error)
+{
+	lock_page(page);
+	if (page->mapping == mapping)
+		mapping->error = error;
+	unlock_page(page);
+}
+
+/*
  * shrink_list returns the number of reclaimed pages
  */
 static int
@@ -362,21 +383,8 @@ shrink_list(struct list_head *page_list,
 
 				SetPageReclaim(page);
 				res = mapping->a_ops->writepage(page, &wbc);
-
-				if (res < 0) {
-					/*
-					 * lock the page to keep truncate away
-					 * then check that it is still on the
-					 * mapping.
-					 */
-					lock_page(page);
-					if (page->mapping == mapping)
-						mapping->error = res;
-					unlock_page(page);
-				}
-				if (res < 0) {
-					mapping->error = res;
-				}
+				if (res < 0)
+					handle_write_error(mapping, page, res);
 				if (res == WRITEPAGE_ACTIVATE) {
 					ClearPageReclaim(page);
 					goto activate_locked;
diff -puN mm/filemap.c~awe-core-fixes mm/filemap.c
--- 25/mm/filemap.c~awe-core-fixes	2003-08-02 03:33:28.000000000 -0700
+++ 25-akpm/mm/filemap.c	2003-08-02 03:33:28.000000000 -0700
@@ -199,9 +199,9 @@ restart:
 	spin_unlock(&mapping->page_lock);
 
 	/* Check for outstanding write errors */
-	if (mapping->error)
-	{
-		ret = mapping->error;
+	if (mapping->error) {
+		if (!ret)
+			ret = mapping->error;
 		mapping->error = 0;
 	}
 
diff -puN fs/mpage.c~awe-core-fixes fs/mpage.c
--- 25/fs/mpage.c~awe-core-fixes	2003-08-02 03:33:28.000000000 -0700
+++ 25-akpm/fs/mpage.c	2003-08-02 03:33:28.000000000 -0700
@@ -563,17 +563,11 @@ confused:
 	if (bio)
 		bio = mpage_bio_submit(WRITE, bio);
 	*ret = page->mapping->a_ops->writepage(page, wbc);
-	if (*ret < 0) {
-		/*
-		 * lock the page to keep truncate away
-		 * then check that it is still on the
-		 * mapping.
-		 */
-		lock_page(page);
-		if (page->mapping == mapping)
-			mapping->error = *ret;
-		unlock_page(page);
-	}
+	/*
+	 * The caller has a ref on the inode, so *mapping is stable
+	 */
+	if (*ret < 0)
+		mapping->error = *ret;
 out:
 	return bio;
 }
@@ -675,17 +669,8 @@ mpage_writepages(struct address_space *m
 					test_clear_page_dirty(page)) {
 			if (writepage) {
 				ret = (*writepage)(page, wbc);
-				if (ret < 0) {
-					/*
-					 * lock the page to keep truncate away
-					 * then check that it is still on the
-					 * mapping.
-					 */
-					lock_page(page);
-					if (page->mapping == mapping)
-						mapping->error = ret;
-					unlock_page(page);
-				}
+				if (ret < 0)
+					mapping->error = ret;
 			} else {
 				bio = mpage_writepage(bio, page, get_block,
 					&last_block_in_bio, &ret, wbc);

_


  reply	other threads:[~2003-08-02 10:47 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-08-02  4:17 [PATCH] [1/3] writes: report truncate and io errors on async writes Oliver Xymoron
2003-08-02 10:47 ` Andrew Morton [this message]
  -- strict thread matches above, loose matches on Subject: below --
2003-08-02  4:13 Oliver Xymoron

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=20030802034756.11c7287c.akpm@osdl.org \
    --to=akpm@osdl.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=oxymoron@waste.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;
as well as URLs for NNTP newsgroup(s).