patch for 2.0.30 mm/filemap.c

Bill Hawes (whawes@star.net)
Fri, 01 Aug 1997 08:33:23 -0400


This is a multi-part message in MIME format.
--------------0CD5516A3E82EE1D80904FBB
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

I'm working on back-porting some patches to 2.0.30, and have attached a
minor patch for mm/filemap.c. It fixes a memory leak in filemap_nopage
and a (very small) race that could result in "lost" pages.

Regards,
Bill
--------------0CD5516A3E82EE1D80904FBB
Content-Type: text/plain; charset=us-ascii; name="filemap_mem30-patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="filemap_mem30-patch"

--- mm/filemap.c.old Wed Sep 11 10:57:19 1996
+++ mm/filemap.c Mon Jul 28 20:08:27 1997
@@ -41,18 +41,7 @@
* Simple routines for both non-shared and shared mappings.
*/

-/*
- * This is a special fast page-free routine that _only_ works
- * on page-cache pages that we are currently using. We can
- * just decrement the page count, because we know that the page
- * has a count > 1 (the page cache itself counts as one, and
- * we're currently using it counts as one). So we don't need
- * the full free_page() stuff..
- */
-static inline void release_page(struct page * page)
-{
- atomic_dec(&page->count);
-}
+#define release_page(page) __free_page((page))

/*
* Invalidate the pages of an inode, removing all pages that aren't
@@ -784,8 +773,15 @@
found_page:
/*
* Ok, found a page in the page cache, now we need to check
- * that it's up-to-date
+ * that it's up-to-date. First check whether we'll need an
+ * extra page -- better to overlap the allocation with the I/O.
*/
+ if (no_share && !new_page) {
+ new_page = __get_free_page(GFP_KERNEL);
+ if (!new_page)
+ goto failure;
+ }
+
if (PageLocked(page))
goto page_locked_wait;
if (!PageUptodate(page))
@@ -810,13 +806,8 @@
}

/*
- * Check that we have another page to copy it over to..
+ * No sharing ... copy to the new page.
*/
- if (!new_page) {
- new_page = __get_free_page(GFP_KERNEL);
- if (!new_page)
- goto failure;
- }
memcpy((void *) new_page, (void *) old_page, PAGE_SIZE);
flush_page_to_ram(new_page);
release_page(page);
@@ -880,6 +871,8 @@
*/
failure:
release_page(page);
+ if (new_page)
+ free_page(new_page);
no_page:
return 0;
}

--------------0CD5516A3E82EE1D80904FBB--