0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef _LINUX_NFS_PAGE_H
0011 #define _LINUX_NFS_PAGE_H
0012
0013
0014 #include <linux/list.h>
0015 #include <linux/pagemap.h>
0016 #include <linux/wait.h>
0017 #include <linux/sunrpc/auth.h>
0018 #include <linux/nfs_xdr.h>
0019
0020 #include <linux/kref.h>
0021
0022
0023
0024
0025 enum {
0026 PG_BUSY = 0,
0027 PG_MAPPED,
0028 PG_CLEAN,
0029 PG_COMMIT_TO_DS,
0030 PG_INODE_REF,
0031 PG_HEADLOCK,
0032 PG_TEARDOWN,
0033 PG_UNLOCKPAGE,
0034 PG_UPTODATE,
0035 PG_WB_END,
0036 PG_REMOVE,
0037 PG_CONTENDED1,
0038 PG_CONTENDED2,
0039 };
0040
0041 struct nfs_inode;
0042 struct nfs_page {
0043 struct list_head wb_list;
0044 struct page *wb_page;
0045 struct nfs_lock_context *wb_lock_context;
0046 pgoff_t wb_index;
0047 unsigned int wb_offset,
0048 wb_pgbase,
0049 wb_bytes;
0050 struct kref wb_kref;
0051 unsigned long wb_flags;
0052 struct nfs_write_verifier wb_verf;
0053 struct nfs_page *wb_this_page;
0054 struct nfs_page *wb_head;
0055 unsigned short wb_nio;
0056 };
0057
0058 struct nfs_pgio_mirror;
0059 struct nfs_pageio_descriptor;
0060 struct nfs_pageio_ops {
0061 void (*pg_init)(struct nfs_pageio_descriptor *, struct nfs_page *);
0062 size_t (*pg_test)(struct nfs_pageio_descriptor *, struct nfs_page *,
0063 struct nfs_page *);
0064 int (*pg_doio)(struct nfs_pageio_descriptor *);
0065 unsigned int (*pg_get_mirror_count)(struct nfs_pageio_descriptor *,
0066 struct nfs_page *);
0067 void (*pg_cleanup)(struct nfs_pageio_descriptor *);
0068 struct nfs_pgio_mirror *
0069 (*pg_get_mirror)(struct nfs_pageio_descriptor *, u32);
0070 u32 (*pg_set_mirror)(struct nfs_pageio_descriptor *, u32);
0071 };
0072
0073 struct nfs_rw_ops {
0074 struct nfs_pgio_header *(*rw_alloc_header)(void);
0075 void (*rw_free_header)(struct nfs_pgio_header *);
0076 int (*rw_done)(struct rpc_task *, struct nfs_pgio_header *,
0077 struct inode *);
0078 void (*rw_result)(struct rpc_task *, struct nfs_pgio_header *);
0079 void (*rw_initiate)(struct nfs_pgio_header *, struct rpc_message *,
0080 const struct nfs_rpc_ops *,
0081 struct rpc_task_setup *, int);
0082 };
0083
0084 struct nfs_pgio_mirror {
0085 struct list_head pg_list;
0086 unsigned long pg_bytes_written;
0087 size_t pg_count;
0088 size_t pg_bsize;
0089 unsigned int pg_base;
0090 unsigned char pg_recoalesce : 1;
0091 };
0092
0093 struct nfs_pageio_descriptor {
0094 struct inode *pg_inode;
0095 const struct nfs_pageio_ops *pg_ops;
0096 const struct nfs_rw_ops *pg_rw_ops;
0097 int pg_ioflags;
0098 int pg_error;
0099 const struct rpc_call_ops *pg_rpc_callops;
0100 const struct nfs_pgio_completion_ops *pg_completion_ops;
0101 struct pnfs_layout_segment *pg_lseg;
0102 struct nfs_io_completion *pg_io_completion;
0103 struct nfs_direct_req *pg_dreq;
0104 unsigned int pg_bsize;
0105
0106 u32 pg_mirror_count;
0107 struct nfs_pgio_mirror *pg_mirrors;
0108 struct nfs_pgio_mirror pg_mirrors_static[1];
0109 struct nfs_pgio_mirror *pg_mirrors_dynamic;
0110 u32 pg_mirror_idx;
0111 unsigned short pg_maxretrans;
0112 unsigned char pg_moreio : 1;
0113 };
0114
0115
0116 #define NFS_PAGEIO_DESCRIPTOR_MIRROR_MAX 16
0117
0118 #define NFS_WBACK_BUSY(req) (test_bit(PG_BUSY,&(req)->wb_flags))
0119
0120 extern struct nfs_page *nfs_create_request(struct nfs_open_context *ctx,
0121 struct page *page,
0122 unsigned int offset,
0123 unsigned int count);
0124 extern void nfs_release_request(struct nfs_page *);
0125
0126
0127 extern void nfs_pageio_init(struct nfs_pageio_descriptor *desc,
0128 struct inode *inode,
0129 const struct nfs_pageio_ops *pg_ops,
0130 const struct nfs_pgio_completion_ops *compl_ops,
0131 const struct nfs_rw_ops *rw_ops,
0132 size_t bsize,
0133 int how);
0134 extern int nfs_pageio_add_request(struct nfs_pageio_descriptor *,
0135 struct nfs_page *);
0136 extern int nfs_pageio_resend(struct nfs_pageio_descriptor *,
0137 struct nfs_pgio_header *);
0138 extern void nfs_pageio_complete(struct nfs_pageio_descriptor *desc);
0139 extern void nfs_pageio_cond_complete(struct nfs_pageio_descriptor *, pgoff_t);
0140 extern size_t nfs_generic_pg_test(struct nfs_pageio_descriptor *desc,
0141 struct nfs_page *prev,
0142 struct nfs_page *req);
0143 extern int nfs_wait_on_request(struct nfs_page *);
0144 extern void nfs_unlock_request(struct nfs_page *req);
0145 extern void nfs_unlock_and_release_request(struct nfs_page *);
0146 extern struct nfs_page *nfs_page_group_lock_head(struct nfs_page *req);
0147 extern int nfs_page_group_lock_subrequests(struct nfs_page *head);
0148 extern void nfs_join_page_group(struct nfs_page *head, struct inode *inode);
0149 extern int nfs_page_group_lock(struct nfs_page *);
0150 extern void nfs_page_group_unlock(struct nfs_page *);
0151 extern bool nfs_page_group_sync_on_bit(struct nfs_page *, unsigned int);
0152 extern int nfs_page_set_headlock(struct nfs_page *req);
0153 extern void nfs_page_clear_headlock(struct nfs_page *req);
0154 extern bool nfs_async_iocounter_wait(struct rpc_task *, struct nfs_lock_context *);
0155
0156
0157
0158
0159 static inline int
0160 nfs_lock_request(struct nfs_page *req)
0161 {
0162 return !test_and_set_bit(PG_BUSY, &req->wb_flags);
0163 }
0164
0165
0166
0167
0168
0169
0170 static inline void
0171 nfs_list_add_request(struct nfs_page *req, struct list_head *head)
0172 {
0173 list_add_tail(&req->wb_list, head);
0174 }
0175
0176
0177
0178
0179
0180
0181 static inline void
0182 nfs_list_move_request(struct nfs_page *req, struct list_head *head)
0183 {
0184 list_move_tail(&req->wb_list, head);
0185 }
0186
0187
0188
0189
0190
0191 static inline void
0192 nfs_list_remove_request(struct nfs_page *req)
0193 {
0194 if (list_empty(&req->wb_list))
0195 return;
0196 list_del_init(&req->wb_list);
0197 }
0198
0199 static inline struct nfs_page *
0200 nfs_list_entry(struct list_head *head)
0201 {
0202 return list_entry(head, struct nfs_page, wb_list);
0203 }
0204
0205 static inline loff_t req_offset(const struct nfs_page *req)
0206 {
0207 return (((loff_t)req->wb_index) << PAGE_SHIFT) + req->wb_offset;
0208 }
0209
0210 static inline struct nfs_open_context *
0211 nfs_req_openctx(struct nfs_page *req)
0212 {
0213 return req->wb_lock_context->open_context;
0214 }
0215
0216 #endif