aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/linux-2.6/xfs_buf.h
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_buf.h')
-rw-r--r--fs/xfs/linux-2.6/xfs_buf.h149
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
97typedef unsigned int xfs_buf_flags_t; 69typedef 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
121typedef enum { 89typedef enum {
122 XBT_FORCE_SLEEP = 0, 90 XBT_FORCE_SLEEP = 0,
@@ -131,70 +99,67 @@ typedef struct xfs_bufhash {
131typedef struct xfs_buftarg { 99typedef 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
162struct xfs_buf; 121struct xfs_buf;
163typedef void (*xfs_buf_iodone_t)(struct xfs_buf *); 122typedef void (*xfs_buf_iodone_t)(struct xfs_buf *);
164typedef void (*xfs_buf_relse_t)(struct xfs_buf *);
165typedef int (*xfs_buf_bdstrat_t)(struct xfs_buf *);
166 123
167#define XB_PAGES 2 124#define XB_PAGES 2
168 125
169typedef struct xfs_buf { 126typedef 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
215extern xfs_buf_t *xfs_buf_get_empty(size_t, xfs_buftarg_t *); 180extern xfs_buf_t *xfs_buf_get_empty(size_t, xfs_buftarg_t *);
216extern xfs_buf_t *xfs_buf_get_noaddr(size_t, xfs_buftarg_t *); 181extern void xfs_buf_set_empty(struct xfs_buf *bp, size_t len);
182extern xfs_buf_t *xfs_buf_get_uncached(struct xfs_buftarg *, size_t, int);
217extern int xfs_buf_associate_memory(xfs_buf_t *, void *, size_t); 183extern int xfs_buf_associate_memory(xfs_buf_t *, void *, size_t);
218extern void xfs_buf_hold(xfs_buf_t *); 184extern void xfs_buf_hold(xfs_buf_t *);
219extern void xfs_buf_readahead(xfs_buftarg_t *, xfs_off_t, size_t, 185extern void xfs_buf_readahead(xfs_buftarg_t *, xfs_off_t, size_t);
220 xfs_buf_flags_t); 186struct 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 */
223extern void xfs_buf_free(xfs_buf_t *); 191extern void xfs_buf_free(xfs_buf_t *);
@@ -242,6 +210,8 @@ extern int xfs_buf_iorequest(xfs_buf_t *);
242extern int xfs_buf_iowait(xfs_buf_t *); 210extern int xfs_buf_iowait(xfs_buf_t *);
243extern void xfs_buf_iomove(xfs_buf_t *, size_t, size_t, void *, 211extern 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
246static inline int xfs_buf_geterror(xfs_buf_t *bp) 216static 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) 240void 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) 304static inline void
305xfs_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
352static inline void xfs_buf_relse(xfs_buf_t *bp) 326static 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 */
377extern xfs_buftarg_t *xfs_alloc_buftarg(struct block_device *, int, const char *); 335extern xfs_buftarg_t *xfs_alloc_buftarg(struct xfs_mount *,
336 struct block_device *, int, const char *);
378extern void xfs_free_buftarg(struct xfs_mount *, struct xfs_buftarg *); 337extern void xfs_free_buftarg(struct xfs_mount *, struct xfs_buftarg *);
379extern void xfs_wait_buftarg(xfs_buftarg_t *); 338extern void xfs_wait_buftarg(xfs_buftarg_t *);
380extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int, unsigned int); 339extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int, unsigned int);