diff options
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_buf.h')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_buf.h | 149 |
1 files changed, 54 insertions, 95 deletions
diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/linux-2.6/xfs_buf.h index 2a05614f0b92..50a7d5fb3b73 100644 --- a/fs/xfs/linux-2.6/xfs_buf.h +++ b/fs/xfs/linux-2.6/xfs_buf.h | |||
@@ -51,7 +51,6 @@ typedef enum { | |||
51 | #define XBF_DONE (1 << 5) /* all pages in the buffer uptodate */ | 51 | #define XBF_DONE (1 << 5) /* all pages in the buffer uptodate */ |
52 | #define XBF_DELWRI (1 << 6) /* buffer has dirty pages */ | 52 | #define XBF_DELWRI (1 << 6) /* buffer has dirty pages */ |
53 | #define XBF_STALE (1 << 7) /* buffer has been staled, do not find it */ | 53 | #define XBF_STALE (1 << 7) /* buffer has been staled, do not find it */ |
54 | #define XBF_FS_MANAGED (1 << 8) /* filesystem controls freeing memory */ | ||
55 | #define XBF_ORDERED (1 << 11)/* use ordered writes */ | 54 | #define XBF_ORDERED (1 << 11)/* use ordered writes */ |
56 | #define XBF_READ_AHEAD (1 << 12)/* asynchronous read-ahead */ | 55 | #define XBF_READ_AHEAD (1 << 12)/* asynchronous read-ahead */ |
57 | #define XBF_LOG_BUFFER (1 << 13)/* this is a buffer used for the log */ | 56 | #define XBF_LOG_BUFFER (1 << 13)/* this is a buffer used for the log */ |
@@ -62,38 +61,11 @@ typedef enum { | |||
62 | #define XBF_DONT_BLOCK (1 << 16)/* do not block in current thread */ | 61 | #define XBF_DONT_BLOCK (1 << 16)/* do not block in current thread */ |
63 | 62 | ||
64 | /* flags used only internally */ | 63 | /* flags used only internally */ |
65 | #define _XBF_PAGE_CACHE (1 << 17)/* backed by pagecache */ | ||
66 | #define _XBF_PAGES (1 << 18)/* backed by refcounted pages */ | 64 | #define _XBF_PAGES (1 << 18)/* backed by refcounted pages */ |
67 | #define _XBF_RUN_QUEUES (1 << 19)/* run block device task queue */ | 65 | #define _XBF_RUN_QUEUES (1 << 19)/* run block device task queue */ |
66 | #define _XBF_KMEM (1 << 20)/* backed by heap memory */ | ||
68 | #define _XBF_DELWRI_Q (1 << 21)/* buffer on delwri queue */ | 67 | #define _XBF_DELWRI_Q (1 << 21)/* buffer on delwri queue */ |
69 | 68 | ||
70 | /* | ||
71 | * Special flag for supporting metadata blocks smaller than a FSB. | ||
72 | * | ||
73 | * In this case we can have multiple xfs_buf_t on a single page and | ||
74 | * need to lock out concurrent xfs_buf_t readers as they only | ||
75 | * serialise access to the buffer. | ||
76 | * | ||
77 | * If the FSB size >= PAGE_CACHE_SIZE case, we have no serialisation | ||
78 | * between reads of the page. Hence we can have one thread read the | ||
79 | * page and modify it, but then race with another thread that thinks | ||
80 | * the page is not up-to-date and hence reads it again. | ||
81 | * | ||
82 | * The result is that the first modifcation to the page is lost. | ||
83 | * This sort of AGF/AGI reading race can happen when unlinking inodes | ||
84 | * that require truncation and results in the AGI unlinked list | ||
85 | * modifications being lost. | ||
86 | */ | ||
87 | #define _XBF_PAGE_LOCKED (1 << 22) | ||
88 | |||
89 | /* | ||
90 | * If we try a barrier write, but it fails we have to communicate | ||
91 | * this to the upper layers. Unfortunately b_error gets overwritten | ||
92 | * when the buffer is re-issued so we have to add another flag to | ||
93 | * keep this information. | ||
94 | */ | ||
95 | #define _XFS_BARRIER_FAILED (1 << 23) | ||
96 | |||
97 | typedef unsigned int xfs_buf_flags_t; | 69 | typedef unsigned int xfs_buf_flags_t; |
98 | 70 | ||
99 | #define XFS_BUF_FLAGS \ | 71 | #define XFS_BUF_FLAGS \ |
@@ -104,19 +76,15 @@ typedef unsigned int xfs_buf_flags_t; | |||
104 | { XBF_DONE, "DONE" }, \ | 76 | { XBF_DONE, "DONE" }, \ |
105 | { XBF_DELWRI, "DELWRI" }, \ | 77 | { XBF_DELWRI, "DELWRI" }, \ |
106 | { XBF_STALE, "STALE" }, \ | 78 | { XBF_STALE, "STALE" }, \ |
107 | { XBF_FS_MANAGED, "FS_MANAGED" }, \ | ||
108 | { XBF_ORDERED, "ORDERED" }, \ | 79 | { XBF_ORDERED, "ORDERED" }, \ |
109 | { XBF_READ_AHEAD, "READ_AHEAD" }, \ | 80 | { XBF_READ_AHEAD, "READ_AHEAD" }, \ |
110 | { XBF_LOCK, "LOCK" }, /* should never be set */\ | 81 | { XBF_LOCK, "LOCK" }, /* should never be set */\ |
111 | { XBF_TRYLOCK, "TRYLOCK" }, /* ditto */\ | 82 | { XBF_TRYLOCK, "TRYLOCK" }, /* ditto */\ |
112 | { XBF_DONT_BLOCK, "DONT_BLOCK" }, /* ditto */\ | 83 | { XBF_DONT_BLOCK, "DONT_BLOCK" }, /* ditto */\ |
113 | { _XBF_PAGE_CACHE, "PAGE_CACHE" }, \ | ||
114 | { _XBF_PAGES, "PAGES" }, \ | 84 | { _XBF_PAGES, "PAGES" }, \ |
115 | { _XBF_RUN_QUEUES, "RUN_QUEUES" }, \ | 85 | { _XBF_RUN_QUEUES, "RUN_QUEUES" }, \ |
116 | { _XBF_DELWRI_Q, "DELWRI_Q" }, \ | 86 | { _XBF_KMEM, "KMEM" }, \ |
117 | { _XBF_PAGE_LOCKED, "PAGE_LOCKED" }, \ | 87 | { _XBF_DELWRI_Q, "DELWRI_Q" } |
118 | { _XFS_BARRIER_FAILED, "BARRIER_FAILED" } | ||
119 | |||
120 | 88 | ||
121 | typedef enum { | 89 | typedef enum { |
122 | XBT_FORCE_SLEEP = 0, | 90 | XBT_FORCE_SLEEP = 0, |
@@ -131,70 +99,67 @@ typedef struct xfs_bufhash { | |||
131 | typedef struct xfs_buftarg { | 99 | typedef struct xfs_buftarg { |
132 | dev_t bt_dev; | 100 | dev_t bt_dev; |
133 | struct block_device *bt_bdev; | 101 | struct block_device *bt_bdev; |
134 | struct address_space *bt_mapping; | 102 | struct backing_dev_info *bt_bdi; |
103 | struct xfs_mount *bt_mount; | ||
135 | unsigned int bt_bsize; | 104 | unsigned int bt_bsize; |
136 | unsigned int bt_sshift; | 105 | unsigned int bt_sshift; |
137 | size_t bt_smask; | 106 | size_t bt_smask; |
138 | 107 | ||
139 | /* per device buffer hash table */ | ||
140 | uint bt_hashshift; | ||
141 | xfs_bufhash_t *bt_hash; | ||
142 | |||
143 | /* per device delwri queue */ | 108 | /* per device delwri queue */ |
144 | struct task_struct *bt_task; | 109 | struct task_struct *bt_task; |
145 | struct list_head bt_list; | ||
146 | struct list_head bt_delwrite_queue; | 110 | struct list_head bt_delwrite_queue; |
147 | spinlock_t bt_delwrite_lock; | 111 | spinlock_t bt_delwrite_lock; |
148 | unsigned long bt_flags; | 112 | unsigned long bt_flags; |
149 | } xfs_buftarg_t; | ||
150 | 113 | ||
151 | /* | 114 | /* LRU control structures */ |
152 | * xfs_buf_t: Buffer structure for pagecache-based buffers | 115 | struct shrinker bt_shrinker; |
153 | * | 116 | struct list_head bt_lru; |
154 | * This buffer structure is used by the pagecache buffer management routines | 117 | spinlock_t bt_lru_lock; |
155 | * to refer to an assembly of pages forming a logical buffer. | 118 | unsigned int bt_lru_nr; |
156 | * | 119 | } xfs_buftarg_t; |
157 | * The buffer structure is used on a temporary basis only, and discarded when | ||
158 | * released. The real data storage is recorded in the pagecache. Buffers are | ||
159 | * hashed to the block device on which the file system resides. | ||
160 | */ | ||
161 | 120 | ||
162 | struct xfs_buf; | 121 | struct xfs_buf; |
163 | typedef void (*xfs_buf_iodone_t)(struct xfs_buf *); | 122 | typedef void (*xfs_buf_iodone_t)(struct xfs_buf *); |
164 | typedef void (*xfs_buf_relse_t)(struct xfs_buf *); | ||
165 | typedef int (*xfs_buf_bdstrat_t)(struct xfs_buf *); | ||
166 | 123 | ||
167 | #define XB_PAGES 2 | 124 | #define XB_PAGES 2 |
168 | 125 | ||
169 | typedef struct xfs_buf { | 126 | typedef struct xfs_buf { |
127 | /* | ||
128 | * first cacheline holds all the fields needed for an uncontended cache | ||
129 | * hit to be fully processed. The semaphore straddles the cacheline | ||
130 | * boundary, but the counter and lock sits on the first cacheline, | ||
131 | * which is the only bit that is touched if we hit the semaphore | ||
132 | * fast-path on locking. | ||
133 | */ | ||
134 | struct rb_node b_rbnode; /* rbtree node */ | ||
135 | xfs_off_t b_file_offset; /* offset in file */ | ||
136 | size_t b_buffer_length;/* size of buffer in bytes */ | ||
137 | atomic_t b_hold; /* reference count */ | ||
138 | atomic_t b_lru_ref; /* lru reclaim ref count */ | ||
139 | xfs_buf_flags_t b_flags; /* status flags */ | ||
170 | struct semaphore b_sema; /* semaphore for lockables */ | 140 | struct semaphore b_sema; /* semaphore for lockables */ |
171 | unsigned long b_queuetime; /* time buffer was queued */ | 141 | |
172 | atomic_t b_pin_count; /* pin count */ | 142 | struct list_head b_lru; /* lru list */ |
173 | wait_queue_head_t b_waiters; /* unpin waiters */ | 143 | wait_queue_head_t b_waiters; /* unpin waiters */ |
174 | struct list_head b_list; | 144 | struct list_head b_list; |
175 | xfs_buf_flags_t b_flags; /* status flags */ | 145 | struct xfs_perag *b_pag; /* contains rbtree root */ |
176 | struct list_head b_hash_list; /* hash table list */ | ||
177 | xfs_bufhash_t *b_hash; /* hash table list start */ | ||
178 | xfs_buftarg_t *b_target; /* buffer target (device) */ | 146 | xfs_buftarg_t *b_target; /* buffer target (device) */ |
179 | atomic_t b_hold; /* reference count */ | ||
180 | xfs_daddr_t b_bn; /* block number for I/O */ | 147 | xfs_daddr_t b_bn; /* block number for I/O */ |
181 | xfs_off_t b_file_offset; /* offset in file */ | ||
182 | size_t b_buffer_length;/* size of buffer in bytes */ | ||
183 | size_t b_count_desired;/* desired transfer size */ | 148 | size_t b_count_desired;/* desired transfer size */ |
184 | void *b_addr; /* virtual address of buffer */ | 149 | void *b_addr; /* virtual address of buffer */ |
185 | struct work_struct b_iodone_work; | 150 | struct work_struct b_iodone_work; |
186 | atomic_t b_io_remaining; /* #outstanding I/O requests */ | ||
187 | xfs_buf_iodone_t b_iodone; /* I/O completion function */ | 151 | xfs_buf_iodone_t b_iodone; /* I/O completion function */ |
188 | xfs_buf_relse_t b_relse; /* releasing function */ | ||
189 | struct completion b_iowait; /* queue for I/O waiters */ | 152 | struct completion b_iowait; /* queue for I/O waiters */ |
190 | void *b_fspriv; | 153 | void *b_fspriv; |
191 | void *b_fspriv2; | 154 | void *b_fspriv2; |
192 | struct xfs_mount *b_mount; | ||
193 | unsigned short b_error; /* error code on I/O */ | ||
194 | unsigned int b_page_count; /* size of page array */ | ||
195 | unsigned int b_offset; /* page offset in first page */ | ||
196 | struct page **b_pages; /* array of page pointers */ | 155 | struct page **b_pages; /* array of page pointers */ |
197 | struct page *b_page_array[XB_PAGES]; /* inline pages */ | 156 | struct page *b_page_array[XB_PAGES]; /* inline pages */ |
157 | unsigned long b_queuetime; /* time buffer was queued */ | ||
158 | atomic_t b_pin_count; /* pin count */ | ||
159 | atomic_t b_io_remaining; /* #outstanding I/O requests */ | ||
160 | unsigned int b_page_count; /* size of page array */ | ||
161 | unsigned int b_offset; /* page offset in first page */ | ||
162 | unsigned short b_error; /* error code on I/O */ | ||
198 | #ifdef XFS_BUF_LOCK_TRACKING | 163 | #ifdef XFS_BUF_LOCK_TRACKING |
199 | int b_last_holder; | 164 | int b_last_holder; |
200 | #endif | 165 | #endif |
@@ -213,11 +178,14 @@ extern xfs_buf_t *xfs_buf_read(xfs_buftarg_t *, xfs_off_t, size_t, | |||
213 | xfs_buf_flags_t); | 178 | xfs_buf_flags_t); |
214 | 179 | ||
215 | extern xfs_buf_t *xfs_buf_get_empty(size_t, xfs_buftarg_t *); | 180 | extern xfs_buf_t *xfs_buf_get_empty(size_t, xfs_buftarg_t *); |
216 | extern xfs_buf_t *xfs_buf_get_noaddr(size_t, xfs_buftarg_t *); | 181 | extern void xfs_buf_set_empty(struct xfs_buf *bp, size_t len); |
182 | extern xfs_buf_t *xfs_buf_get_uncached(struct xfs_buftarg *, size_t, int); | ||
217 | extern int xfs_buf_associate_memory(xfs_buf_t *, void *, size_t); | 183 | extern int xfs_buf_associate_memory(xfs_buf_t *, void *, size_t); |
218 | extern void xfs_buf_hold(xfs_buf_t *); | 184 | extern void xfs_buf_hold(xfs_buf_t *); |
219 | extern void xfs_buf_readahead(xfs_buftarg_t *, xfs_off_t, size_t, | 185 | extern void xfs_buf_readahead(xfs_buftarg_t *, xfs_off_t, size_t); |
220 | xfs_buf_flags_t); | 186 | struct xfs_buf *xfs_buf_read_uncached(struct xfs_mount *mp, |
187 | struct xfs_buftarg *target, | ||
188 | xfs_daddr_t daddr, size_t length, int flags); | ||
221 | 189 | ||
222 | /* Releasing Buffers */ | 190 | /* Releasing Buffers */ |
223 | extern void xfs_buf_free(xfs_buf_t *); | 191 | extern void xfs_buf_free(xfs_buf_t *); |
@@ -242,6 +210,8 @@ extern int xfs_buf_iorequest(xfs_buf_t *); | |||
242 | extern int xfs_buf_iowait(xfs_buf_t *); | 210 | extern int xfs_buf_iowait(xfs_buf_t *); |
243 | extern void xfs_buf_iomove(xfs_buf_t *, size_t, size_t, void *, | 211 | extern void xfs_buf_iomove(xfs_buf_t *, size_t, size_t, void *, |
244 | xfs_buf_rw_t); | 212 | xfs_buf_rw_t); |
213 | #define xfs_buf_zero(bp, off, len) \ | ||
214 | xfs_buf_iomove((bp), (off), (len), NULL, XBRW_ZERO) | ||
245 | 215 | ||
246 | static inline int xfs_buf_geterror(xfs_buf_t *bp) | 216 | static inline int xfs_buf_geterror(xfs_buf_t *bp) |
247 | { | 217 | { |
@@ -267,7 +237,8 @@ extern void xfs_buf_terminate(void); | |||
267 | #define XFS_BUF_ZEROFLAGS(bp) ((bp)->b_flags &= \ | 237 | #define XFS_BUF_ZEROFLAGS(bp) ((bp)->b_flags &= \ |
268 | ~(XBF_READ|XBF_WRITE|XBF_ASYNC|XBF_DELWRI|XBF_ORDERED)) | 238 | ~(XBF_READ|XBF_WRITE|XBF_ASYNC|XBF_DELWRI|XBF_ORDERED)) |
269 | 239 | ||
270 | #define XFS_BUF_STALE(bp) ((bp)->b_flags |= XBF_STALE) | 240 | void xfs_buf_stale(struct xfs_buf *bp); |
241 | #define XFS_BUF_STALE(bp) xfs_buf_stale(bp); | ||
271 | #define XFS_BUF_UNSTALE(bp) ((bp)->b_flags &= ~XBF_STALE) | 242 | #define XFS_BUF_UNSTALE(bp) ((bp)->b_flags &= ~XBF_STALE) |
272 | #define XFS_BUF_ISSTALE(bp) ((bp)->b_flags & XBF_STALE) | 243 | #define XFS_BUF_ISSTALE(bp) ((bp)->b_flags & XBF_STALE) |
273 | #define XFS_BUF_SUPER_STALE(bp) do { \ | 244 | #define XFS_BUF_SUPER_STALE(bp) do { \ |
@@ -276,8 +247,6 @@ extern void xfs_buf_terminate(void); | |||
276 | XFS_BUF_DONE(bp); \ | 247 | XFS_BUF_DONE(bp); \ |
277 | } while (0) | 248 | } while (0) |
278 | 249 | ||
279 | #define XFS_BUF_UNMANAGE(bp) ((bp)->b_flags &= ~XBF_FS_MANAGED) | ||
280 | |||
281 | #define XFS_BUF_DELAYWRITE(bp) ((bp)->b_flags |= XBF_DELWRI) | 250 | #define XFS_BUF_DELAYWRITE(bp) ((bp)->b_flags |= XBF_DELWRI) |
282 | #define XFS_BUF_UNDELAYWRITE(bp) xfs_buf_delwri_dequeue(bp) | 251 | #define XFS_BUF_UNDELAYWRITE(bp) xfs_buf_delwri_dequeue(bp) |
283 | #define XFS_BUF_ISDELAYWRITE(bp) ((bp)->b_flags & XBF_DELWRI) | 252 | #define XFS_BUF_ISDELAYWRITE(bp) ((bp)->b_flags & XBF_DELWRI) |
@@ -320,7 +289,6 @@ extern void xfs_buf_terminate(void); | |||
320 | #define XFS_BUF_FSPRIVATE2(bp, type) ((type)(bp)->b_fspriv2) | 289 | #define XFS_BUF_FSPRIVATE2(bp, type) ((type)(bp)->b_fspriv2) |
321 | #define XFS_BUF_SET_FSPRIVATE2(bp, val) ((bp)->b_fspriv2 = (void*)(val)) | 290 | #define XFS_BUF_SET_FSPRIVATE2(bp, val) ((bp)->b_fspriv2 = (void*)(val)) |
322 | #define XFS_BUF_SET_START(bp) do { } while (0) | 291 | #define XFS_BUF_SET_START(bp) do { } while (0) |
323 | #define XFS_BUF_SET_BRELSE_FUNC(bp, func) ((bp)->b_relse = (func)) | ||
324 | 292 | ||
325 | #define XFS_BUF_PTR(bp) (xfs_caddr_t)((bp)->b_addr) | 293 | #define XFS_BUF_PTR(bp) (xfs_caddr_t)((bp)->b_addr) |
326 | #define XFS_BUF_SET_PTR(bp, val, cnt) xfs_buf_associate_memory(bp, val, cnt) | 294 | #define XFS_BUF_SET_PTR(bp, val, cnt) xfs_buf_associate_memory(bp, val, cnt) |
@@ -333,9 +301,15 @@ extern void xfs_buf_terminate(void); | |||
333 | #define XFS_BUF_SIZE(bp) ((bp)->b_buffer_length) | 301 | #define XFS_BUF_SIZE(bp) ((bp)->b_buffer_length) |
334 | #define XFS_BUF_SET_SIZE(bp, cnt) ((bp)->b_buffer_length = (cnt)) | 302 | #define XFS_BUF_SET_SIZE(bp, cnt) ((bp)->b_buffer_length = (cnt)) |
335 | 303 | ||
336 | #define XFS_BUF_SET_VTYPE_REF(bp, type, ref) do { } while (0) | 304 | static inline void |
305 | xfs_buf_set_ref( | ||
306 | struct xfs_buf *bp, | ||
307 | int lru_ref) | ||
308 | { | ||
309 | atomic_set(&bp->b_lru_ref, lru_ref); | ||
310 | } | ||
311 | #define XFS_BUF_SET_VTYPE_REF(bp, type, ref) xfs_buf_set_ref(bp, ref) | ||
337 | #define XFS_BUF_SET_VTYPE(bp, type) do { } while (0) | 312 | #define XFS_BUF_SET_VTYPE(bp, type) do { } while (0) |
338 | #define XFS_BUF_SET_REF(bp, ref) do { } while (0) | ||
339 | 313 | ||
340 | #define XFS_BUF_ISPINNED(bp) atomic_read(&((bp)->b_pin_count)) | 314 | #define XFS_BUF_ISPINNED(bp) atomic_read(&((bp)->b_pin_count)) |
341 | 315 | ||
@@ -351,30 +325,15 @@ extern void xfs_buf_terminate(void); | |||
351 | 325 | ||
352 | static inline void xfs_buf_relse(xfs_buf_t *bp) | 326 | static inline void xfs_buf_relse(xfs_buf_t *bp) |
353 | { | 327 | { |
354 | if (!bp->b_relse) | 328 | xfs_buf_unlock(bp); |
355 | xfs_buf_unlock(bp); | ||
356 | xfs_buf_rele(bp); | 329 | xfs_buf_rele(bp); |
357 | } | 330 | } |
358 | 331 | ||
359 | #define xfs_biodone(bp) xfs_buf_ioend(bp, 0) | ||
360 | |||
361 | #define xfs_biomove(bp, off, len, data, rw) \ | ||
362 | xfs_buf_iomove((bp), (off), (len), (data), \ | ||
363 | ((rw) == XBF_WRITE) ? XBRW_WRITE : XBRW_READ) | ||
364 | |||
365 | #define xfs_biozero(bp, off, len) \ | ||
366 | xfs_buf_iomove((bp), (off), (len), NULL, XBRW_ZERO) | ||
367 | |||
368 | #define xfs_iowait(bp) xfs_buf_iowait(bp) | ||
369 | |||
370 | #define xfs_baread(target, rablkno, ralen) \ | ||
371 | xfs_buf_readahead((target), (rablkno), (ralen), XBF_DONT_BLOCK) | ||
372 | |||
373 | |||
374 | /* | 332 | /* |
375 | * Handling of buftargs. | 333 | * Handling of buftargs. |
376 | */ | 334 | */ |
377 | extern xfs_buftarg_t *xfs_alloc_buftarg(struct block_device *, int, const char *); | 335 | extern xfs_buftarg_t *xfs_alloc_buftarg(struct xfs_mount *, |
336 | struct block_device *, int, const char *); | ||
378 | extern void xfs_free_buftarg(struct xfs_mount *, struct xfs_buftarg *); | 337 | extern void xfs_free_buftarg(struct xfs_mount *, struct xfs_buftarg *); |
379 | extern void xfs_wait_buftarg(xfs_buftarg_t *); | 338 | extern void xfs_wait_buftarg(xfs_buftarg_t *); |
380 | extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int, unsigned int); | 339 | extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int, unsigned int); |