

- 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);

_
