Branch data Line data Source code
1 : : /*
2 : : * linux/include/linux/nfs_page.h
3 : : *
4 : : * Copyright (C) 2000 Trond Myklebust
5 : : *
6 : : * NFS page cache wrapper.
7 : : */
8 : :
9 : : #ifndef _LINUX_NFS_PAGE_H
10 : : #define _LINUX_NFS_PAGE_H
11 : :
12 : :
13 : : #include <linux/list.h>
14 : : #include <linux/pagemap.h>
15 : : #include <linux/wait.h>
16 : : #include <linux/sunrpc/auth.h>
17 : : #include <linux/nfs_xdr.h>
18 : :
19 : : #include <linux/kref.h>
20 : :
21 : : /*
22 : : * Valid flags for a dirty buffer
23 : : */
24 : : enum {
25 : : PG_BUSY = 0,
26 : : PG_MAPPED,
27 : : PG_CLEAN,
28 : : PG_NEED_COMMIT,
29 : : PG_NEED_RESCHED,
30 : : PG_COMMIT_TO_DS,
31 : : };
32 : :
33 : : struct nfs_inode;
34 : : struct nfs_page {
35 : : struct list_head wb_list; /* Defines state of page: */
36 : : struct page *wb_page; /* page to read in/write out */
37 : : struct nfs_open_context *wb_context; /* File state context info */
38 : : struct nfs_lock_context *wb_lock_context; /* lock context info */
39 : : pgoff_t wb_index; /* Offset >> PAGE_CACHE_SHIFT */
40 : : unsigned int wb_offset, /* Offset & ~PAGE_CACHE_MASK */
41 : : wb_pgbase, /* Start of page data */
42 : : wb_bytes; /* Length of request */
43 : : struct kref wb_kref; /* reference count */
44 : : unsigned long wb_flags;
45 : : struct nfs_write_verifier wb_verf; /* Commit cookie */
46 : : };
47 : :
48 : : struct nfs_pageio_descriptor;
49 : : struct nfs_pageio_ops {
50 : : void (*pg_init)(struct nfs_pageio_descriptor *, struct nfs_page *);
51 : : bool (*pg_test)(struct nfs_pageio_descriptor *, struct nfs_page *, struct nfs_page *);
52 : : int (*pg_doio)(struct nfs_pageio_descriptor *);
53 : : };
54 : :
55 : : struct nfs_pageio_descriptor {
56 : : struct list_head pg_list;
57 : : unsigned long pg_bytes_written;
58 : : size_t pg_count;
59 : : size_t pg_bsize;
60 : : unsigned int pg_base;
61 : : unsigned char pg_moreio : 1,
62 : : pg_recoalesce : 1;
63 : :
64 : : struct inode *pg_inode;
65 : : const struct nfs_pageio_ops *pg_ops;
66 : : int pg_ioflags;
67 : : int pg_error;
68 : : const struct rpc_call_ops *pg_rpc_callops;
69 : : const struct nfs_pgio_completion_ops *pg_completion_ops;
70 : : struct pnfs_layout_segment *pg_lseg;
71 : : struct nfs_direct_req *pg_dreq;
72 : : void *pg_layout_private;
73 : : };
74 : :
75 : : #define NFS_WBACK_BUSY(req) (test_bit(PG_BUSY,&(req)->wb_flags))
76 : :
77 : : extern struct nfs_page *nfs_create_request(struct nfs_open_context *ctx,
78 : : struct inode *inode,
79 : : struct page *page,
80 : : unsigned int offset,
81 : : unsigned int count);
82 : : extern void nfs_release_request(struct nfs_page *req);
83 : :
84 : :
85 : : extern void nfs_pageio_init(struct nfs_pageio_descriptor *desc,
86 : : struct inode *inode,
87 : : const struct nfs_pageio_ops *pg_ops,
88 : : const struct nfs_pgio_completion_ops *compl_ops,
89 : : size_t bsize,
90 : : int how);
91 : : extern int nfs_pageio_add_request(struct nfs_pageio_descriptor *,
92 : : struct nfs_page *);
93 : : extern void nfs_pageio_complete(struct nfs_pageio_descriptor *desc);
94 : : extern void nfs_pageio_cond_complete(struct nfs_pageio_descriptor *, pgoff_t);
95 : : extern bool nfs_generic_pg_test(struct nfs_pageio_descriptor *desc,
96 : : struct nfs_page *prev,
97 : : struct nfs_page *req);
98 : : extern int nfs_wait_on_request(struct nfs_page *);
99 : : extern void nfs_unlock_request(struct nfs_page *req);
100 : : extern void nfs_unlock_and_release_request(struct nfs_page *req);
101 : :
102 : : /*
103 : : * Lock the page of an asynchronous request
104 : : */
105 : : static inline int
106 : : nfs_lock_request(struct nfs_page *req)
107 : : {
108 : 0 : return !test_and_set_bit(PG_BUSY, &req->wb_flags);
109 : : }
110 : :
111 : : /**
112 : : * nfs_list_add_request - Insert a request into a list
113 : : * @req: request
114 : : * @head: head of list into which to insert the request.
115 : : */
116 : : static inline void
117 : : nfs_list_add_request(struct nfs_page *req, struct list_head *head)
118 : : {
119 : 0 : list_add_tail(&req->wb_list, head);
120 : : }
121 : :
122 : :
123 : : /**
124 : : * nfs_list_remove_request - Remove a request from its wb_list
125 : : * @req: request
126 : : */
127 : : static inline void
128 : : nfs_list_remove_request(struct nfs_page *req)
129 : : {
130 [ # # ][ # # ]: 0 : if (list_empty(&req->wb_list))
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
131 : : return;
132 : : list_del_init(&req->wb_list);
133 : : }
134 : :
135 : : static inline struct nfs_page *
136 : : nfs_list_entry(struct list_head *head)
137 : : {
138 : : return list_entry(head, struct nfs_page, wb_list);
139 : : }
140 : :
141 : : static inline
142 : : loff_t req_offset(struct nfs_page *req)
143 : : {
144 : 0 : return (((loff_t)req->wb_index) << PAGE_CACHE_SHIFT) + req->wb_offset;
145 : : }
146 : :
147 : : #endif /* _LINUX_NFS_PAGE_H */
|