Subject: afs/include/linux cachefs.h,1.8,1.9

From: [email-masked]
Date: Thu, 17 Apr 2003 12:59:06 +0100

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

Modified Files:
	cachefs.h 
Log Message:
wrote first part of proper netfs interface... netfs, index and files can now
be registered with the cache

Index: cachefs.h
===================================================================
RCS file: /home/cvs/afs/include/linux/cachefs.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- cachefs.h	7 Mar 2003 19:16:28 -0000	1.8
+++ cachefs.h	17 Apr 2003 11:59:03 -0000	1.9
@@ -16,29 +16,28 @@
 #include <linux/list.h>
 #include <linux/pagemap.h>
 
-struct cachefs_file;
 struct cachefs_netfs;
 struct cachefs_netfs_operations;
-struct cachefs_index;
+struct cachefs_object;
+struct cachefs_page;
 
-/* see if entry matches the specified key
- * - return:
- *	0 - no match
- *	1 - match
- *	2 - matched, but out of date
- * - entries that aren't in use will not be presented for matching
- */
-typedef int (*cachefs_index_match_t)(const void *entry, const void *data);
+typedef enum {
+	CACHEFS_MATCH_FAILED,		/* no match */
+	CACHEFS_MATCH_SUCCESS,		/* successful match */
+	CACHEFS_MATCH_SUCCESS_UPDATE,	/* successful match, entry requires update */
+	CACHEFS_MATCH_SUCCESS_DELETE,	/* successful match, entry requires deletion */
+} cachefs_match_val_t;
 
 /*****************************************************************************/
 /*
- * cachefs catalogue/index
+ * cachefs index definition
  * - each index file contains a number of fixed size entries
  *   - they don't have to fit exactly into a page, but if they don't, the gap at the end of the
  *     page will not be used
  * - if the first 4 bytes of the entry are all zero, then the entry is taken as not being in use
  */
-struct cachefs_index {
+struct cachefs_index_def
+{
 	u_int8_t			name[8];	/* name of index */
 	u_int16_t			data_size;	/* index entry data size */
 
@@ -53,57 +52,97 @@
 #define CACHEFS_INDEX_KEYS_ASCIIZ	2
 #define CACHEFS_INDEX_KEYS_IPV4ADDR	3
 #define CACHEFS_INDEX_KEYS_IPV6ADDR	4
+
+	/* see if entry matches the specified key
+	 * - container_of(target,...) should be used to find the key data
+	 * - entries that aren't in use will not be presented for matching
+	 */
+	cachefs_match_val_t (*match)(struct cachefs_object *target, const void *entry);
+
+	/* update entry from key 
+	 * - container_of(source,...) should be used to find the key data
+	 */
+	void (*update)(struct cachefs_object *source, void *entry);
+};
+
+/*****************************************************************************/
+/*
+ * data file or index object
+ * - before registration:
+ *   - iparent must be filled
+ *   - def must be filled in for an index and set to NULL for a file
+ * - a file will only appear in one cache
+ * - a request to cache a file may or may not be honoured, subject to constraints such as disc
+ *   space
+ * - indexes files are created on disc just-in-time
+ */
+struct cachefs_object
+{
+	struct cachefs_index_def	*idef;		/* index definition */
+	struct cachefs_object		*iparent;	/* index holding this entry */
+	struct list_head		active_inodes;	/* inode(s) backing this file/index */
+	struct rw_semaphore		sem;
 };
 
+extern int cachefs_register_object(struct cachefs_object *object);
+extern void cachefs_unregister_object(struct cachefs_object *object, int retire);
+
 /*****************************************************************************/
 /*
  * cachefs cached network filesystem type
- * - each type is recorded in every mounted cache
+ * - name, version, ops and primary_index.def must be filled in before registration
+ * - all other fields will be set during registration
  */
-struct cachefs_netfs {
+struct cachefs_netfs
+{
 	const char			*name;		/* filesystem def name */
 	unsigned			version;	/* index layout version */
-	const struct cachefs_index	*primary;	/* primary index definition */
+	struct cachefs_object		primary_index;	/* primary index */
 	struct cachefs_netfs_operations	*ops;		/* operations table */
-	struct list_head		link;		/* internal cachefs link */
-	struct list_head		cross_indexes;	/* internal cross-index list */
+	struct list_head		link;		/* internal cachefs list link */
 };
 
 extern int cachefs_register_netfs(struct cachefs_netfs *netfs);
 extern void cachefs_unregister_netfs(struct cachefs_netfs *netfs);
 
-struct cachefs_netfs_operations {
+struct cachefs_netfs_operations
+{
+	/* 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
+	 * - typically, the struct will be attached to page->private
+	 */
+	int (*get_page_cookie)(struct page *page, struct cachefs_page **_cookie);
+
 	/* handle journal replaying indicating writeback needed */
-	int (*replay)(struct cachefs_file *file, unsigned page_number);
+	int (*replay)(struct cachefs_object *object, unsigned page_number);
 	
 };
 
 /*****************************************************************************/
 /*
- * cachefs data file
- * - each file can only appear in one cache
- */
-struct cachefs_file {
-	struct cachefs_index		*container;	/* index holding this entry */
-	struct list_head		link;		/* link in parent index's list */
-	unsigned			catalogue_ix;	/* catalogue index */
-	unsigned			storage_ix;	/* data storage record index */
-	struct page			*storage_page;	/* page containing data storage record */
-};
-
-/*****************************************************************************/
-/*
  * page mapping and journalling structure for pages that belong to or are mirrored in the cache
+ * - note that the mapping may be removed without notice if a cache is removed
  */
-struct cachefs_page {
-	struct cachefs_super	*mapped_sb;	/* superblock holding mapped_block */
+struct cachefs_page
+{
 	struct cachefs_block	*mapped_block;	/* block mirroring this page */
+	rwlock_t		lock;
 	unsigned		flags;
 #define CACHEFS_PAGE_BOUNDARY	0x00000001	/* next block has a different indirection chain */
 #define CACHEFS_PAGE_NEW	0x00000002	/* this is a newly allocated block */
 #define CACHEFS_PAGE_BYSECTORS	0x00000004	/* this page is dealt with in sector granularity */
 };
 
+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);