diff options
Diffstat (limited to 'fs/xfs/xfs_buf.h')
-rw-r--r-- | fs/xfs/xfs_buf.h | 326 |
1 files changed, 326 insertions, 0 deletions
diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h new file mode 100644 index 000000000000..620972b8094d --- /dev/null +++ b/fs/xfs/xfs_buf.h | |||
@@ -0,0 +1,326 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2000-2005 Silicon Graphics, Inc. | ||
3 | * All Rights Reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it would be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write the Free Software Foundation, | ||
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
17 | */ | ||
18 | #ifndef __XFS_BUF_H__ | ||
19 | #define __XFS_BUF_H__ | ||
20 | |||
21 | #include <linux/list.h> | ||
22 | #include <linux/types.h> | ||
23 | #include <linux/spinlock.h> | ||
24 | #include <asm/system.h> | ||
25 | #include <linux/mm.h> | ||
26 | #include <linux/fs.h> | ||
27 | #include <linux/buffer_head.h> | ||
28 | #include <linux/uio.h> | ||
29 | |||
30 | /* | ||
31 | * Base types | ||
32 | */ | ||
33 | |||
34 | #define XFS_BUF_DADDR_NULL ((xfs_daddr_t) (-1LL)) | ||
35 | |||
36 | #define xfs_buf_ctob(pp) ((pp) * PAGE_CACHE_SIZE) | ||
37 | #define xfs_buf_btoc(dd) (((dd) + PAGE_CACHE_SIZE-1) >> PAGE_CACHE_SHIFT) | ||
38 | #define xfs_buf_btoct(dd) ((dd) >> PAGE_CACHE_SHIFT) | ||
39 | #define xfs_buf_poff(aa) ((aa) & ~PAGE_CACHE_MASK) | ||
40 | |||
41 | typedef enum { | ||
42 | XBRW_READ = 1, /* transfer into target memory */ | ||
43 | XBRW_WRITE = 2, /* transfer from target memory */ | ||
44 | XBRW_ZERO = 3, /* Zero target memory */ | ||
45 | } xfs_buf_rw_t; | ||
46 | |||
47 | #define XBF_READ (1 << 0) /* buffer intended for reading from device */ | ||
48 | #define XBF_WRITE (1 << 1) /* buffer intended for writing to device */ | ||
49 | #define XBF_READ_AHEAD (1 << 2) /* asynchronous read-ahead */ | ||
50 | #define XBF_MAPPED (1 << 3) /* buffer mapped (b_addr valid) */ | ||
51 | #define XBF_ASYNC (1 << 4) /* initiator will not wait for completion */ | ||
52 | #define XBF_DONE (1 << 5) /* all pages in the buffer uptodate */ | ||
53 | #define XBF_DELWRI (1 << 6) /* buffer has dirty pages */ | ||
54 | #define XBF_STALE (1 << 7) /* buffer has been staled, do not find it */ | ||
55 | |||
56 | /* I/O hints for the BIO layer */ | ||
57 | #define XBF_SYNCIO (1 << 10)/* treat this buffer as synchronous I/O */ | ||
58 | #define XBF_FUA (1 << 11)/* force cache write through mode */ | ||
59 | #define XBF_FLUSH (1 << 12)/* flush the disk cache before a write */ | ||
60 | |||
61 | /* flags used only as arguments to access routines */ | ||
62 | #define XBF_LOCK (1 << 15)/* lock requested */ | ||
63 | #define XBF_TRYLOCK (1 << 16)/* lock requested, but do not wait */ | ||
64 | #define XBF_DONT_BLOCK (1 << 17)/* do not block in current thread */ | ||
65 | |||
66 | /* flags used only internally */ | ||
67 | #define _XBF_PAGES (1 << 20)/* backed by refcounted pages */ | ||
68 | #define _XBF_KMEM (1 << 21)/* backed by heap memory */ | ||
69 | #define _XBF_DELWRI_Q (1 << 22)/* buffer on delwri queue */ | ||
70 | |||
71 | typedef unsigned int xfs_buf_flags_t; | ||
72 | |||
73 | #define XFS_BUF_FLAGS \ | ||
74 | { XBF_READ, "READ" }, \ | ||
75 | { XBF_WRITE, "WRITE" }, \ | ||
76 | { XBF_READ_AHEAD, "READ_AHEAD" }, \ | ||
77 | { XBF_MAPPED, "MAPPED" }, \ | ||
78 | { XBF_ASYNC, "ASYNC" }, \ | ||
79 | { XBF_DONE, "DONE" }, \ | ||
80 | { XBF_DELWRI, "DELWRI" }, \ | ||
81 | { XBF_STALE, "STALE" }, \ | ||
82 | { XBF_SYNCIO, "SYNCIO" }, \ | ||
83 | { XBF_FUA, "FUA" }, \ | ||
84 | { XBF_FLUSH, "FLUSH" }, \ | ||
85 | { XBF_LOCK, "LOCK" }, /* should never be set */\ | ||
86 | { XBF_TRYLOCK, "TRYLOCK" }, /* ditto */\ | ||
87 | { XBF_DONT_BLOCK, "DONT_BLOCK" }, /* ditto */\ | ||
88 | { _XBF_PAGES, "PAGES" }, \ | ||
89 | { _XBF_KMEM, "KMEM" }, \ | ||
90 | { _XBF_DELWRI_Q, "DELWRI_Q" } | ||
91 | |||
92 | typedef enum { | ||
93 | XBT_FORCE_SLEEP = 0, | ||
94 | XBT_FORCE_FLUSH = 1, | ||
95 | } xfs_buftarg_flags_t; | ||
96 | |||
97 | typedef struct xfs_buftarg { | ||
98 | dev_t bt_dev; | ||
99 | struct block_device *bt_bdev; | ||
100 | struct backing_dev_info *bt_bdi; | ||
101 | struct xfs_mount *bt_mount; | ||
102 | unsigned int bt_bsize; | ||
103 | unsigned int bt_sshift; | ||
104 | size_t bt_smask; | ||
105 | |||
106 | /* per device delwri queue */ | ||
107 | struct task_struct *bt_task; | ||
108 | struct list_head bt_delwrite_queue; | ||
109 | spinlock_t bt_delwrite_lock; | ||
110 | unsigned long bt_flags; | ||
111 | |||
112 | /* LRU control structures */ | ||
113 | struct shrinker bt_shrinker; | ||
114 | struct list_head bt_lru; | ||
115 | spinlock_t bt_lru_lock; | ||
116 | unsigned int bt_lru_nr; | ||
117 | } xfs_buftarg_t; | ||
118 | |||
119 | struct xfs_buf; | ||
120 | typedef void (*xfs_buf_iodone_t)(struct xfs_buf *); | ||
121 | |||
122 | #define XB_PAGES 2 | ||
123 | |||
124 | typedef struct xfs_buf { | ||
125 | /* | ||
126 | * first cacheline holds all the fields needed for an uncontended cache | ||
127 | * hit to be fully processed. The semaphore straddles the cacheline | ||
128 | * boundary, but the counter and lock sits on the first cacheline, | ||
129 | * which is the only bit that is touched if we hit the semaphore | ||
130 | * fast-path on locking. | ||
131 | */ | ||
132 | struct rb_node b_rbnode; /* rbtree node */ | ||
133 | xfs_off_t b_file_offset; /* offset in file */ | ||
134 | size_t b_buffer_length;/* size of buffer in bytes */ | ||
135 | atomic_t b_hold; /* reference count */ | ||
136 | atomic_t b_lru_ref; /* lru reclaim ref count */ | ||
137 | xfs_buf_flags_t b_flags; /* status flags */ | ||
138 | struct semaphore b_sema; /* semaphore for lockables */ | ||
139 | |||
140 | struct list_head b_lru; /* lru list */ | ||
141 | wait_queue_head_t b_waiters; /* unpin waiters */ | ||
142 | struct list_head b_list; | ||
143 | struct xfs_perag *b_pag; /* contains rbtree root */ | ||
144 | xfs_buftarg_t *b_target; /* buffer target (device) */ | ||
145 | xfs_daddr_t b_bn; /* block number for I/O */ | ||
146 | size_t b_count_desired;/* desired transfer size */ | ||
147 | void *b_addr; /* virtual address of buffer */ | ||
148 | struct work_struct b_iodone_work; | ||
149 | xfs_buf_iodone_t b_iodone; /* I/O completion function */ | ||
150 | struct completion b_iowait; /* queue for I/O waiters */ | ||
151 | void *b_fspriv; | ||
152 | struct xfs_trans *b_transp; | ||
153 | struct page **b_pages; /* array of page pointers */ | ||
154 | struct page *b_page_array[XB_PAGES]; /* inline pages */ | ||
155 | unsigned long b_queuetime; /* time buffer was queued */ | ||
156 | atomic_t b_pin_count; /* pin count */ | ||
157 | atomic_t b_io_remaining; /* #outstanding I/O requests */ | ||
158 | unsigned int b_page_count; /* size of page array */ | ||
159 | unsigned int b_offset; /* page offset in first page */ | ||
160 | unsigned short b_error; /* error code on I/O */ | ||
161 | #ifdef XFS_BUF_LOCK_TRACKING | ||
162 | int b_last_holder; | ||
163 | #endif | ||
164 | } xfs_buf_t; | ||
165 | |||
166 | |||
167 | /* Finding and Reading Buffers */ | ||
168 | extern xfs_buf_t *_xfs_buf_find(xfs_buftarg_t *, xfs_off_t, size_t, | ||
169 | xfs_buf_flags_t, xfs_buf_t *); | ||
170 | #define xfs_incore(buftarg,blkno,len,lockit) \ | ||
171 | _xfs_buf_find(buftarg, blkno ,len, lockit, NULL) | ||
172 | |||
173 | extern xfs_buf_t *xfs_buf_get(xfs_buftarg_t *, xfs_off_t, size_t, | ||
174 | xfs_buf_flags_t); | ||
175 | extern xfs_buf_t *xfs_buf_read(xfs_buftarg_t *, xfs_off_t, size_t, | ||
176 | xfs_buf_flags_t); | ||
177 | |||
178 | extern xfs_buf_t *xfs_buf_get_empty(size_t, xfs_buftarg_t *); | ||
179 | extern void xfs_buf_set_empty(struct xfs_buf *bp, size_t len); | ||
180 | extern xfs_buf_t *xfs_buf_get_uncached(struct xfs_buftarg *, size_t, int); | ||
181 | extern int xfs_buf_associate_memory(xfs_buf_t *, void *, size_t); | ||
182 | extern void xfs_buf_hold(xfs_buf_t *); | ||
183 | extern void xfs_buf_readahead(xfs_buftarg_t *, xfs_off_t, size_t); | ||
184 | struct xfs_buf *xfs_buf_read_uncached(struct xfs_mount *mp, | ||
185 | struct xfs_buftarg *target, | ||
186 | xfs_daddr_t daddr, size_t length, int flags); | ||
187 | |||
188 | /* Releasing Buffers */ | ||
189 | extern void xfs_buf_free(xfs_buf_t *); | ||
190 | extern void xfs_buf_rele(xfs_buf_t *); | ||
191 | |||
192 | /* Locking and Unlocking Buffers */ | ||
193 | extern int xfs_buf_trylock(xfs_buf_t *); | ||
194 | extern void xfs_buf_lock(xfs_buf_t *); | ||
195 | extern void xfs_buf_unlock(xfs_buf_t *); | ||
196 | #define xfs_buf_islocked(bp) \ | ||
197 | ((bp)->b_sema.count <= 0) | ||
198 | |||
199 | /* Buffer Read and Write Routines */ | ||
200 | extern int xfs_bwrite(struct xfs_mount *mp, struct xfs_buf *bp); | ||
201 | extern void xfs_bdwrite(void *mp, xfs_buf_t *bp); | ||
202 | |||
203 | extern void xfsbdstrat(struct xfs_mount *, struct xfs_buf *); | ||
204 | extern int xfs_bdstrat_cb(struct xfs_buf *); | ||
205 | |||
206 | extern void xfs_buf_ioend(xfs_buf_t *, int); | ||
207 | extern void xfs_buf_ioerror(xfs_buf_t *, int); | ||
208 | extern int xfs_buf_iorequest(xfs_buf_t *); | ||
209 | extern int xfs_buf_iowait(xfs_buf_t *); | ||
210 | extern void xfs_buf_iomove(xfs_buf_t *, size_t, size_t, void *, | ||
211 | xfs_buf_rw_t); | ||
212 | #define xfs_buf_zero(bp, off, len) \ | ||
213 | xfs_buf_iomove((bp), (off), (len), NULL, XBRW_ZERO) | ||
214 | |||
215 | static inline int xfs_buf_geterror(xfs_buf_t *bp) | ||
216 | { | ||
217 | return bp ? bp->b_error : ENOMEM; | ||
218 | } | ||
219 | |||
220 | /* Buffer Utility Routines */ | ||
221 | extern xfs_caddr_t xfs_buf_offset(xfs_buf_t *, size_t); | ||
222 | |||
223 | /* Delayed Write Buffer Routines */ | ||
224 | extern void xfs_buf_delwri_dequeue(xfs_buf_t *); | ||
225 | extern void xfs_buf_delwri_promote(xfs_buf_t *); | ||
226 | |||
227 | /* Buffer Daemon Setup Routines */ | ||
228 | extern int xfs_buf_init(void); | ||
229 | extern void xfs_buf_terminate(void); | ||
230 | |||
231 | static inline const char * | ||
232 | xfs_buf_target_name(struct xfs_buftarg *target) | ||
233 | { | ||
234 | static char __b[BDEVNAME_SIZE]; | ||
235 | |||
236 | return bdevname(target->bt_bdev, __b); | ||
237 | } | ||
238 | |||
239 | |||
240 | #define XFS_BUF_ZEROFLAGS(bp) \ | ||
241 | ((bp)->b_flags &= ~(XBF_READ|XBF_WRITE|XBF_ASYNC|XBF_DELWRI| \ | ||
242 | XBF_SYNCIO|XBF_FUA|XBF_FLUSH)) | ||
243 | |||
244 | void xfs_buf_stale(struct xfs_buf *bp); | ||
245 | #define XFS_BUF_STALE(bp) xfs_buf_stale(bp); | ||
246 | #define XFS_BUF_UNSTALE(bp) ((bp)->b_flags &= ~XBF_STALE) | ||
247 | #define XFS_BUF_ISSTALE(bp) ((bp)->b_flags & XBF_STALE) | ||
248 | #define XFS_BUF_SUPER_STALE(bp) do { \ | ||
249 | XFS_BUF_STALE(bp); \ | ||
250 | xfs_buf_delwri_dequeue(bp); \ | ||
251 | XFS_BUF_DONE(bp); \ | ||
252 | } while (0) | ||
253 | |||
254 | #define XFS_BUF_DELAYWRITE(bp) ((bp)->b_flags |= XBF_DELWRI) | ||
255 | #define XFS_BUF_UNDELAYWRITE(bp) xfs_buf_delwri_dequeue(bp) | ||
256 | #define XFS_BUF_ISDELAYWRITE(bp) ((bp)->b_flags & XBF_DELWRI) | ||
257 | |||
258 | #define XFS_BUF_DONE(bp) ((bp)->b_flags |= XBF_DONE) | ||
259 | #define XFS_BUF_UNDONE(bp) ((bp)->b_flags &= ~XBF_DONE) | ||
260 | #define XFS_BUF_ISDONE(bp) ((bp)->b_flags & XBF_DONE) | ||
261 | |||
262 | #define XFS_BUF_ASYNC(bp) ((bp)->b_flags |= XBF_ASYNC) | ||
263 | #define XFS_BUF_UNASYNC(bp) ((bp)->b_flags &= ~XBF_ASYNC) | ||
264 | #define XFS_BUF_ISASYNC(bp) ((bp)->b_flags & XBF_ASYNC) | ||
265 | |||
266 | #define XFS_BUF_READ(bp) ((bp)->b_flags |= XBF_READ) | ||
267 | #define XFS_BUF_UNREAD(bp) ((bp)->b_flags &= ~XBF_READ) | ||
268 | #define XFS_BUF_ISREAD(bp) ((bp)->b_flags & XBF_READ) | ||
269 | |||
270 | #define XFS_BUF_WRITE(bp) ((bp)->b_flags |= XBF_WRITE) | ||
271 | #define XFS_BUF_UNWRITE(bp) ((bp)->b_flags &= ~XBF_WRITE) | ||
272 | #define XFS_BUF_ISWRITE(bp) ((bp)->b_flags & XBF_WRITE) | ||
273 | |||
274 | #define XFS_BUF_ADDR(bp) ((bp)->b_bn) | ||
275 | #define XFS_BUF_SET_ADDR(bp, bno) ((bp)->b_bn = (xfs_daddr_t)(bno)) | ||
276 | #define XFS_BUF_OFFSET(bp) ((bp)->b_file_offset) | ||
277 | #define XFS_BUF_SET_OFFSET(bp, off) ((bp)->b_file_offset = (off)) | ||
278 | #define XFS_BUF_COUNT(bp) ((bp)->b_count_desired) | ||
279 | #define XFS_BUF_SET_COUNT(bp, cnt) ((bp)->b_count_desired = (cnt)) | ||
280 | #define XFS_BUF_SIZE(bp) ((bp)->b_buffer_length) | ||
281 | #define XFS_BUF_SET_SIZE(bp, cnt) ((bp)->b_buffer_length = (cnt)) | ||
282 | |||
283 | static inline void | ||
284 | xfs_buf_set_ref( | ||
285 | struct xfs_buf *bp, | ||
286 | int lru_ref) | ||
287 | { | ||
288 | atomic_set(&bp->b_lru_ref, lru_ref); | ||
289 | } | ||
290 | #define XFS_BUF_SET_VTYPE_REF(bp, type, ref) xfs_buf_set_ref(bp, ref) | ||
291 | #define XFS_BUF_SET_VTYPE(bp, type) do { } while (0) | ||
292 | |||
293 | static inline int xfs_buf_ispinned(struct xfs_buf *bp) | ||
294 | { | ||
295 | return atomic_read(&bp->b_pin_count); | ||
296 | } | ||
297 | |||
298 | #define XFS_BUF_FINISH_IOWAIT(bp) complete(&bp->b_iowait); | ||
299 | |||
300 | static inline void xfs_buf_relse(xfs_buf_t *bp) | ||
301 | { | ||
302 | xfs_buf_unlock(bp); | ||
303 | xfs_buf_rele(bp); | ||
304 | } | ||
305 | |||
306 | /* | ||
307 | * Handling of buftargs. | ||
308 | */ | ||
309 | extern xfs_buftarg_t *xfs_alloc_buftarg(struct xfs_mount *, | ||
310 | struct block_device *, int, const char *); | ||
311 | extern void xfs_free_buftarg(struct xfs_mount *, struct xfs_buftarg *); | ||
312 | extern void xfs_wait_buftarg(xfs_buftarg_t *); | ||
313 | extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int, unsigned int); | ||
314 | extern int xfs_flush_buftarg(xfs_buftarg_t *, int); | ||
315 | |||
316 | #ifdef CONFIG_KDB_MODULES | ||
317 | extern struct list_head *xfs_get_buftarg_list(void); | ||
318 | #endif | ||
319 | |||
320 | #define xfs_getsize_buftarg(buftarg) block_size((buftarg)->bt_bdev) | ||
321 | #define xfs_readonly_buftarg(buftarg) bdev_read_only((buftarg)->bt_bdev) | ||
322 | |||
323 | #define xfs_binval(buftarg) xfs_flush_buftarg(buftarg, 1) | ||
324 | #define XFS_bflush(buftarg) xfs_flush_buftarg(buftarg, 1) | ||
325 | |||
326 | #endif /* __XFS_BUF_H__ */ | ||