From f0e8134cea99ab7944f24e212b876c36f4cb7c7b Mon Sep 17 00:00:00 2001 From: phil Date: Sat, 26 Mar 2005 04:13:11 +0000 Subject: [PATCH] b=5981 r=adilger SetPageDirty in 2.6 is a hangman's noose made of time bombs, with which to shoot yourself in the foot. It doesn't adjust page lists or counters, which we now believe was almost certainly responsible for the two weeks of mysterious "negative nr_dirty" hangs at NERSC and NOAA. As an extra precaution, I also move the clear_page_dirty_for_io compat function into the 2.4-only part. If configure happened to ever enable it in 2.6 somehow, it would be a similar disaster (assuming that the compile didn't fail). --- lustre/include/linux/lustre_compat25.h | 42 +++++++++++++++++----------------- lustre/llite/rw.c | 4 ++-- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/lustre/include/linux/lustre_compat25.h b/lustre/include/linux/lustre_compat25.h index b95f962..9b3a56d 100644 --- a/lustre/include/linux/lustre_compat25.h +++ b/lustre/include/linux/lustre_compat25.h @@ -130,12 +130,6 @@ static inline int cleanup_group_info(void) #define DCACHE_DISCONNECTED DCACHE_NFSD_DISCONNECTED #define ll_dev_t int -static inline void clear_page_dirty(struct page *page) -{ - if (PageDirty(page)) - ClearPageDirty(page); -} - /* 2.5 uses hlists for some things, like the d_hash. we'll treat them * as 2.5 and let macros drop back.. */ #ifndef HLIST_HEAD /* until we get a kernel newer than l28 */ @@ -176,6 +170,27 @@ typedef long sector_t; #define ll_invalidate_inode_pages(inode) invalidate_inode_pages(inode) #define ll_truncate_complete_page(page) truncate_complete_page(page) +static inline void clear_page_dirty(struct page *page) +{ + if (PageDirty(page)) + ClearPageDirty(page); +} + +static inline int clear_page_dirty_for_io(struct page *page) +{ + struct address_space *mapping = page->mapping; + + if (page->mapping && PageDirty(page)) { + ClearPageDirty(page); + ll_pgcache_lock(mapping); + list_del(&page->list); + list_add(&page->list, &mapping->locked_pages); + ll_pgcache_unlock(mapping); + return 1; + } + return 0; +} + static inline void __d_drop(struct dentry *dentry) { list_del(&dentry->d_hash); @@ -250,21 +265,6 @@ static inline int mapping_has_pages(struct address_space *mapping) return rc; } - -static inline int clear_page_dirty_for_io(struct page *page) -{ - struct address_space *mapping = page->mapping; - - if (page->mapping && PageDirty(page)) { - ClearPageDirty(page); - ll_pgcache_lock(mapping); - list_del(&page->list); - list_add(&page->list, &mapping->locked_pages); - ll_pgcache_unlock(mapping); - return 1; - } - return 0; -} #else static inline int mapping_has_pages(struct address_space *mapping) { diff --git a/lustre/llite/rw.c b/lustre/llite/rw.c index d88a5d5..6e379c8 100644 --- a/lustre/llite/rw.c +++ b/lustre/llite/rw.c @@ -732,7 +732,7 @@ void ll_ap_completion(void *data, int cmd, struct obdo *oa, int rc) if (cmd == OBD_BRW_READ) { llap->llap_defer_uptodate = 0; } else { - SetPageDirty(page); + set_page_dirty(page); ClearPageLaunder(page); } SetPageError(page); @@ -1135,7 +1135,7 @@ out: if (!lli->lli_async_rc) lli->lli_async_rc = rc; /* re-dirty page on error so it retries write */ - SetPageDirty(page); + set_page_dirty(page); ClearPageLaunder(page); unlock_page(page); } -- 1.8.3.1