lkml.org 
[lkml]   [2003]   [Oct]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[PATCH] page->flags corruption fix
In the "better safe than sorry" category. Thanks go out to
Matt Domsch and Robert Hentosh. A similar fix went into the
2.6 kernel. Please apply.

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
# ChangeSet 1.1192 -> 1.1193
# include/linux/mm.h 1.43 -> 1.44
# mm/page_alloc.c 1.63 -> 1.64
# mm/filemap.c 1.88 -> 1.89
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/10/07 riel@cessna.boston.redhat.com 1.1193
# fix page->flags corruption due to races between atomic and non-atomic
# accesses, originally found and fixed by Robert Hentosh and Matt Domsch
# --------------------------------------------
#
diff -Nru a/include/linux/mm.h b/include/linux/mm.h
--- a/include/linux/mm.h Tue Oct 7 12:19:34 2003
+++ b/include/linux/mm.h Tue Oct 7 12:19:34 2003
@@ -322,9 +322,11 @@
#define TryLockPage(page) test_and_set_bit(PG_locked, &(page)->flags)
#define PageChecked(page) test_bit(PG_checked, &(page)->flags)
#define SetPageChecked(page) set_bit(PG_checked, &(page)->flags)
+#define ClearPageChecked(page) clear_bit(PG_checked, &(page)->flags)
#define PageLaunder(page) test_bit(PG_launder, &(page)->flags)
#define SetPageLaunder(page) set_bit(PG_launder, &(page)->flags)
#define ClearPageLaunder(page) clear_bit(PG_launder, &(page)->flags)
+#define ClearPageArch1(page) clear_bit(PG_arch_1, &(page)->flags)

/*
* The zone field is never updated after free_area_init_core()
diff -Nru a/mm/filemap.c b/mm/filemap.c
--- a/mm/filemap.c Tue Oct 7 12:19:34 2003
+++ b/mm/filemap.c Tue Oct 7 12:19:34 2003
@@ -654,10 +654,13 @@
struct address_space *mapping, unsigned long offset,
struct page **hash)
{
- unsigned long flags;
-
- flags = page->flags & ~(1 << PG_uptodate | 1 << PG_error | 1 << PG_dirty | 1 << PG_referenced | 1 << PG_arch_1 | 1 << PG_checked);
- page->flags = flags | (1 << PG_locked);
+ ClearPageUptodate(page);
+ ClearPageError(page);
+ ClearPageDirty(page);
+ ClearPageReferenced(page);
+ ClearPageArch1(page);
+ ClearPageChecked(page);
+ LockPage(page);
page_cache_get(page);
page->index = offset;
add_page_to_inode_queue(mapping, page);
diff -Nru a/mm/page_alloc.c b/mm/page_alloc.c
--- a/mm/page_alloc.c Tue Oct 7 12:19:34 2003
+++ b/mm/page_alloc.c Tue Oct 7 12:19:34 2003
@@ -109,7 +109,8 @@
BUG();
if (PageActive(page))
BUG();
- page->flags &= ~((1<<PG_referenced) | (1<<PG_dirty));
+ ClearPageReferenced(page);
+ ClearPageDirty(page);

if (current->flags & PF_FREE_PAGES)
goto local_freelist;
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 13:49    [W:0.236 / U:0.048 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site