Subject: afs/include/linux cachefs.h,1.11,1.12

From: [email-masked]
Date: Fri, 23 May 2003 13:59:23 +0100

Update of /home/cvs/afs/include/linux
In directory phoenix.infradead.org:/tmp/cvs-serv27749/include/linux

Modified Files:
	cachefs.h 
Log Message:
added a validity journal to keep track of data cache blocks which are
allocated but not yet written

Index: cachefs.h
===================================================================
RCS file: /home/cvs/afs/include/linux/cachefs.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- cachefs.h	25 Apr 2003 16:04:09 -0000	1.11
+++ cachefs.h	23 May 2003 12:59:21 -0000	1.12
@@ -15,6 +15,7 @@
 #include <linux/fs.h>
 #include <linux/list.h>
 #include <linux/pagemap.h>
+#include <linux/bio.h>
 
 struct cachefs_cookie;
 struct cachefs_netfs;
@@ -28,6 +29,8 @@
 	CACHEFS_MATCH_SUCCESS_DELETE,	/* successful match, entry requires deletion */
 } cachefs_match_val_t;
 
+typedef void (*cachefs_rw_complete_t)(void *cookie_data, struct page *page, void *data);
+
 /*****************************************************************************/
 /*
  * cachefs index definition
@@ -82,8 +85,8 @@
 {
 	const char			*name;		/* filesystem def name */
 	unsigned			version;	/* index layout version */
-	struct cachefs_cookie		*primary_index;	/* primary index */
-	struct cachefs_netfs_operations	*ops;		/* operations table */
+	struct cachefs_cookie		*primary_index;
+	struct cachefs_netfs_operations	*ops;
 	struct list_head		link;		/* internal cachefs list link */
 };
 
@@ -95,19 +98,20 @@
 {
 	/* get page-to-block mapping cookie for a page
 	 * - one should be allocated if it doesn't exist
-	 * - returning -ENODATA will make this page be ignored
+	 * - returning -ENODATA will cause this page to be ignored
 	 * - typically, the struct will be attached to page->private
 	 */
-	int (*get_page_cookie)(struct page *page, struct cachefs_page **_cookie);
+	int (*get_page_cookie)(struct page *page, struct cachefs_page **_page_cookie);
 
 	/* handle journal replaying indicating writeback needed */
 	int (*replay)(struct cachefs_cookie *cookie, unsigned page_number);
-	
+
 };
 
 /*****************************************************************************/
 /*
- * page mapping and journalling structure for pages that belong to or are mirrored in the cache
+ * page mapping cookie
+ * - stores the mapping of a page to a block in the cache (may also be null)
  * - note that the mapping may be removed without notice if a cache is removed
  */
 struct cachefs_page
@@ -119,19 +123,122 @@
 #define CACHEFS_PAGE_NEW	1		/* this is a newly allocated block */
 };
 
-extern int cachefs_file_mappage(struct page *page, unsigned gfp);
-extern int cachefs_file_readpage(struct cachefs_netfs *netfs, struct page *page);
-extern int cachefs_file_readpages(struct address_space *mapping,
-				  struct list_head *pages, unsigned nr_pages);
-extern int cachefs_file_writepage(struct page *page);
-extern int cachefs_file_writepages(struct page *page);
-extern int cachefs_file_unmappage(struct page *page);
-
-/* convenience routines for mapping page->private to a struct cachefs_page */
-extern int cachefs_get_page_private(struct page *page, struct cachefs_page **_page,
-				    unsigned gfp_flags);
+/*
+ * read a page from the cache or allocate a block in which to store it
+ * - if the cookie is not backed by a file:
+ *   - -ENOBUFS will be returned and nothing more will be done
+ * - else if the page is backed by a block in the cache:
+ *   - a read will be started which will call end_io_data on completion
+ *   - the wb-journal will be searched for an entry pertaining to this block
+ *     - if an entry is found:
+ *       - 1 will be returned
+ *       else
+ *       - 0 will be returned
+ * - else if the page is unbacked:
+ *   - a block will be allocated and attached
+ *   - the validity journal will be marked to note the block does not yet
+ *     contain valid data
+ *   - -ENODATA will be returned
+ */
+int cachefs_read_or_alloc_page(struct cachefs_cookie *cookie,
+			       struct page *page,
+			       cachefs_rw_complete_t end_io_func,
+			       void *end_io_data,
+			       unsigned long gfp);
+
+/*
+ * see if any of the list of pages are cached
+ * - for each cached page:
+ *   - the page cookie will have been changed to refer to the backing cache
+ *     block
+ *   - a BIO will have been dispatched to load the page with end_io as the
+ *     completion function
+ *     - end_io can be NULL, in which case a default function will just unlock
+ *       the page
+ *     - BIOs may be merged to serve multiple pages that are adjacent on disc
+ *   - they will be removed from the page list
+ * - all uncached pages will be left on the page list and will be otherwise
+ *   untouched
+ * - no cache space will be allocated
+ * - all pages must be locked before calling
+ */
+extern void cachefs_read_pages(struct cachefs_cookie *cookie,
+			       struct address_space *mapping,
+			       struct list_head *pages,
+			       unsigned nr_pages,
+			       bio_end_io_t end_io);
+
+/*
+ * request a page be stored in the cache
+ * - this request may be ignored if no cache block is currently attached, in which case it
+ *   - returns -ENOBUFS
+ * - if a cache block was already allocated:
+ *   - the page cookie will be updated to reflect the block selected
+ *   - a BIO will have been dispatched to write the page with end_io as the completion func
+ *     - end_io can be NULL, in which case a default function will just clear the writeback bit
+ *   - if a page is associated with a v-journal entry, that entry will be erased
+ *   - returns 0
+ */
+extern int cachefs_write_page(struct cachefs_cookie *cookie,
+			      struct page *page,
+			      cachefs_rw_complete_t end_io_func,
+			      void *end_io_data,
+			      unsigned long gfp);
+
+/*
+ * request a list of pages be stored/updated in the cache
+ * - this request may be ignored for any page that has no cache block currently attached, in which
+ *   case, that page remains on the list
+ * - for any page that has a cache block allocated:
+ *   - the page cookie will be updated to reflect the block selected
+ *   - the page will be removed from the list
+ *   - a BIO will have been dispatched to write the page with end_io as the completion func
+ *     - end_io can be NULL, in which case a default function will just clear the writeback bit
+ *     - BIOs may be merged to serve multiple pages that are adjacent on disc
+ */
+extern void cachefs_write_pages(struct cachefs_cookie *cookie,
+				struct list_head *pages,
+				bio_end_io_t end_io);
+
+/*
+ * indicate that caching is no longer required on a page
+ * - cannot cancel any outstanding BIOs between this page and the cache
+ */
+extern void __cachefs_uncache_page(struct cachefs_cookie *cookie,
+				   struct page *page);
+
+static inline void cachefs_uncache_page(struct cachefs_cookie *cookie,
+					struct page *page,
+					struct cachefs_page *pageio)
+{
+	if (__builtin_constant_p(pageio) && !pageio || pageio->mapped_block)
+		__cachefs_uncache_page(cookie,page);
+}
+
+/*
+ * keep track of pages changed locally but not yet committed
+ */
+extern void cachefs_writeback_prepare(struct cachefs_cookie *cookie,
+				      struct page *page,
+				      unsigned short from,
+				      unsigned short to);
+
+extern void cachefs_writeback_committed(struct cachefs_cookie *cookie,
+					struct page *page,
+					unsigned short from,
+					unsigned short to);
+
+extern void cachefs_writeback_aborted(struct cachefs_cookie *cookie,
+				      struct page *page,
+				      unsigned short from,
+				      unsigned short to);
+
+/*
+ * convenience routines for mapping page->private directly to a struct cachefs_page
+ */
+extern int cachefs_page_get_private(struct page *page, struct cachefs_page **_page, unsigned gfp);
 
-static inline struct cachefs_page *__cachefs_get_page_private(struct page *page)
+static inline struct cachefs_page *__cachefs_page_get_private(struct page *page)
 {
 	BUG_ON(!PagePrivate(page));
 	return (struct cachefs_page *) page->private;