From: David Howells <dhowells@redhat.com>

The attached patch provides a filesystem-specific page bit that a
filesystem can synchronise upon.  This can be used, for example, by a netfs
to synchronise with CacheFS writing its pages to disc.

Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 include/linux/page-flags.h |   10 ++++++++++
 include/linux/pagemap.h    |   11 +++++++++++
 mm/filemap.c               |   17 +++++++++++++++++
 3 files changed, 38 insertions(+)

diff -puN include/linux/page-flags.h~provide-a-filesystem-specific-syncable-page-bit include/linux/page-flags.h
--- devel/include/linux/page-flags.h~provide-a-filesystem-specific-syncable-page-bit	2005-09-07 20:11:10.000000000 -0700
+++ devel-akpm/include/linux/page-flags.h	2005-09-07 20:11:10.000000000 -0700
@@ -62,6 +62,7 @@
 #define PG_slab			 7	/* slab debug (Suparna wants this) */
 
 #define PG_checked		 8	/* kill me in 2.5.<early>. */
+#define PG_fs_misc		 8
 #define PG_arch_1		 9
 #define PG_reserved		10
 #define PG_private		11	/* Has something at ->private */
@@ -323,4 +324,13 @@ static inline void set_page_writeback(st
 	test_set_page_writeback(page);
 }
 
+/*
+ * Filesystem-specific page bit testing
+ */
+#define PageFsMisc(page)		test_bit(PG_fs_misc, &(page)->flags)
+#define SetPageFsMisc(page)		set_bit(PG_fs_misc, &(page)->flags)
+#define TestSetPageFsMisc(page)		test_and_set_bit(PG_fs_misc, &(page)->flags)
+#define ClearPageFsMisc(page)		clear_bit(PG_fs_misc, &(page)->flags)
+#define TestClearPageFsMisc(page)	test_and_clear_bit(PG_fs_misc, &(page)->flags)
+
 #endif	/* PAGE_FLAGS_H */
diff -puN include/linux/pagemap.h~provide-a-filesystem-specific-syncable-page-bit include/linux/pagemap.h
--- devel/include/linux/pagemap.h~provide-a-filesystem-specific-syncable-page-bit	2005-09-07 20:11:10.000000000 -0700
+++ devel-akpm/include/linux/pagemap.h	2005-09-07 20:11:10.000000000 -0700
@@ -200,6 +200,17 @@ static inline void wait_on_page_writebac
 extern void end_page_writeback(struct page *page);
 
 /*
+ * Wait for filesystem-specific page synchronisation to complete
+ */
+static inline void wait_on_page_fs_misc(struct page *page)
+{
+	if (PageFsMisc(page))
+		wait_on_page_bit(page, PG_fs_misc);
+}
+
+extern void fastcall end_page_fs_misc(struct page *page);
+
+/*
  * Fault a userspace page into pagetables.  Return non-zero on a fault.
  *
  * This assumes that two userspace pages are always sufficient.  That's
diff -puN mm/filemap.c~provide-a-filesystem-specific-syncable-page-bit mm/filemap.c
--- devel/mm/filemap.c~provide-a-filesystem-specific-syncable-page-bit	2005-09-07 20:11:10.000000000 -0700
+++ devel-akpm/mm/filemap.c	2005-09-07 20:11:10.000000000 -0700
@@ -494,6 +494,23 @@ void fastcall __lock_page(struct page *p
 EXPORT_SYMBOL(__lock_page);
 
 /*
+ * Note completion of filesystem specific page synchronisation
+ *
+ * This is used to allow a page to be written to a filesystem cache in the
+ * background without holding up the completion of readpage
+ */
+void fastcall end_page_fs_misc(struct page *page)
+{
+	smp_mb__before_clear_bit();
+	if (!TestClearPageFsMisc(page))
+		BUG();
+	smp_mb__after_clear_bit();
+	__wake_up_bit(page_waitqueue(page), &page->flags, PG_fs_misc);
+}
+
+EXPORT_SYMBOL(end_page_fs_misc);
+
+/*
  * a rather lightweight function, finding and getting a reference to a
  * hashed page atomically.
  */
_