From: "Chen, Kenneth W" <kenneth.w.chen@intel.com>

Hit a kernel oops on 2.6.7 kernel when doing direct I/O to hugetlb page.

The destructor of compound page was moved into page->mapping since 2.6.6. 
It got interfered with set_page_dirty() for hugetlb page: an O_DIRECT read
into first tail page of the compound page will fool set_page_dirty() to
deference page->mapping->a_ops and then kernel oops.  Patch to fix the
oops.  We do just like what bio_set_pages_dirty() does.

Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/fs/direct-io.c |    2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)

diff -puN fs/direct-io.c~direct-i-o-stomp-over-page-mapping-for-hugetlb-page fs/direct-io.c
--- 25/fs/direct-io.c~direct-i-o-stomp-over-page-mapping-for-hugetlb-page	2004-06-24 18:33:23.162185184 -0700
+++ 25-akpm/fs/direct-io.c	2004-06-24 18:33:23.166184576 -0700
@@ -395,7 +395,7 @@ static int dio_bio_complete(struct dio *
 		for (page_no = 0; page_no < bio->bi_vcnt; page_no++) {
 			struct page *page = bvec[page_no].bv_page;
 
-			if (dio->rw == READ)
+			if (dio->rw == READ && !PageCompound(page))
 				set_page_dirty_lock(page);
 			page_cache_release(page);
 		}
_