
Defines the layout driver I/O, Policy operations interface.
This interface will evolve as we add additional layout drivers.
Also specifies layout driver register and unregister opreations.

---

 linux-2.6.14-pnfs-current-dhildebz/include/linux/nfs4_pnfs.h |  139 +++++++++++
 1 files changed, 139 insertions(+)

diff -puN /dev/null include/linux/nfs4_pnfs.h
--- /dev/null	2006-01-09 05:56:56.224752500 -0500
+++ linux-2.6.14-pnfs-current-dhildebz/include/linux/nfs4_pnfs.h	2006-01-11 14:21:28.426990000 -0500
@@ -0,0 +1,139 @@
+/*
+ *  include/linux/nfs4_pnfs.h
+ *
+ *  Common data structures needed by the pnfs client and pnfs layout driver.
+ *
+ *  Copyright (c) 2002 The Regents of the University of Michigan.
+ *  All rights reserved.
+ *
+ *  Dean Hildebrand   <dhildebz@eecs.umich.edu>
+ */
+
+#ifndef LINUX_NFS4_PNFS_H
+#define LINUX_NFS4_PNFS_H
+
+#define NFS4_PNFS_DEV_MAXCOUNT 16
+#define NFS4_PNFS_DEV_MAXSIZE 128
+
+/* Layout driver specific identifier for a mount point.  For each mountpoint
+ * a reference is stored in the nfs_server structure.
+ */
+struct pnfs_mount_type {
+	void* mountid;
+};
+
+/* Layout driver specific identifier for layout information for a file.
+ * Each inode has a specific layout type structure.
+ * A reference is stored in the nfs_inode structure.
+ */
+struct pnfs_layout_type {
+	struct pnfs_mount_type* mountid;
+	void* layoutid;
+};
+
+/* Layout driver I/O operations.
+ * Either the pagecache or non-pagecache read/write operations must be implemented
+ */
+struct layoutdriver_io_operations {
+	/* Functions that use the pagecache.
+	 * If use_pagecache == 1, then these functions must be implemented.
+	 */
+	ssize_t (*read_pagelist) (struct pnfs_layout_type * layoutid, struct inode *, struct page **pages, unsigned int pgbase, unsigned nr_pages, loff_t offset, size_t count, void* private);
+	ssize_t (*write_pagelist) (struct pnfs_layout_type * layoutid, struct inode *, struct page **pages, unsigned int pgbase, unsigned nr_pages, loff_t offset, size_t count, int sync, void* private);
+
+	/* Functions that do not use the pagecache.
+	 * If use_pagecache == 0, then these functions must be implemented.
+	 */
+	ssize_t (*read) (struct pnfs_layout_type * layoutid, struct file *, char __user *, size_t, loff_t *);
+	ssize_t (*write) (struct pnfs_layout_type * layoutid, struct file *, const char __user *, size_t, loff_t *);
+	ssize_t (*readv) (struct pnfs_layout_type * layoutid, struct file *, const struct iovec *, unsigned long, loff_t *);
+	ssize_t (*writev) (struct pnfs_layout_type * layoutid, struct file *, const struct iovec *, unsigned long, loff_t *);
+
+	/* Consistency ops */
+	int (*fsync) (struct pnfs_layout_type * layoutid, struct file *, struct dentry *, int);
+	/* 2 problems:
+	 * 1) the page list contains nfs_pages, NOT pages
+	 * 2) currently the NFS code doesn't create a page array (as it does with read/write)
+	 */
+	int (*commit) (struct pnfs_layout_type * layoutid, struct inode *, struct list_head *, int sync, void* private);
+
+	/* Layout information. For each inode, alloc_layout is executed once to retrieve an
+	 * inode specific layout structure.  Each subsequent layoutget operation results in
+	 * a set_layout call to set the opaque layout in the layout driver.*/
+	struct pnfs_layout_type* (*alloc_layout) (struct pnfs_mount_type * mountid, struct inode * inode);
+	void (*free_layout) (struct pnfs_layout_type * layoutid, struct inode * inode);
+	struct pnfs_layout_type* (*set_layout) (struct pnfs_layout_type * layoutid, struct inode * inode, void* layout);
+
+	/* Registration information for a new mounted file system
+	 */
+	struct pnfs_mount_type* (*initialize_mountpoint) (struct super_block *);
+	int (*uninitialize_mountpoint) (struct pnfs_mount_type* mountid);
+
+	/* Other ops... */
+	int (*ioctl) (struct pnfs_layout_type *, struct inode *, struct file *, unsigned int, unsigned long);
+};
+
+struct layoutdriver_policy_operations {
+	/* The stripe size of the file system */
+	ssize_t (*get_stripesize) (struct pnfs_layout_type * layoutid, struct inode *);
+
+	/* Should the NFS req. gather algorithm cross stripe boundaries? */
+	int (*gather_across_stripes) (struct pnfs_mount_type * mountid);
+
+	/* Retreive the block size of the file system.  If gather_across_stripes == 1,
+	 * then the file system will gather requests into the block size.
+	 * TODO: Where will the layout driver get this info?  It is hard coded in PVFS2.
+	 */
+	ssize_t (*get_blocksize) (struct pnfs_mount_type *);
+
+	/* I/O requests under this value are sent to the NFSv4 server */
+	int (*get_io_threshold) (struct pnfs_layout_type *, struct inode *);
+
+	/* Use the linux page cache prior to calling layout driver
+	 * read/write functions
+	 */
+	int (*use_pagecache) (struct pnfs_layout_type *, struct inode *);
+
+	/* Should the pNFS client issue a layoutget call in the
+	 * same compound as the OPEN operation?
+	 */
+	int (*layoutget_on_open) (struct pnfs_mount_type *);
+};
+
+/* Per-layout driver specific registration structure */
+struct pnfs_layoutdriver_type {
+	const int id;
+	const char *name;
+	struct layoutdriver_io_operations *ld_io_ops;
+	struct layoutdriver_policy_operations *ld_policy_ops;
+};
+
+struct pnfs_device
+{
+	unsigned int  layoutclass;
+	int           dev_id;
+	unsigned int  dev_addr_len;
+	char          dev_addr_buf[NFS4_PNFS_DEV_MAXSIZE];
+};
+
+struct pnfs_devicelist {
+	unsigned int        num_devs;
+	unsigned int        devs_len;
+	struct pnfs_device  devs[NFS4_PNFS_DEV_MAXCOUNT];
+};
+
+/* pNFS client callback functions.
+ * These operations allow the layout driver to access pNFS client
+ * specific information or call pNFS client->server operations.
+ * E.g., getdeviceinfo, I/O callbacks, etc
+ */
+struct pnfs_client_operations {
+	int (*nfs_fsync) (struct file * file, struct dentry * dentry, int datasync);
+	int (*nfs_getdevicelist) (struct super_block * sb, struct pnfs_devicelist* devlist);
+	int (*nfs_getdeviceinfo) (struct super_block * sb, u32 dev_id, struct pnfs_device * dev);
+};
+
+struct pnfs_client_operations* pnfs_register_layoutdriver(struct pnfs_layoutdriver_type *);
+void pnfs_unregister_layoutdriver(struct pnfs_layoutdriver_type *);
+
+#endif /* LINUX_NFS4_PNFS_H */
_
