aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2012-06-22 04:50:11 -0400
committerBen Myers <bpm@sgi.com>2012-07-01 15:50:06 -0400
commitde2a4f59190303ff5b82ead2969968a325e61230 (patch)
tree90a719a20401085dbb0e4848a49a0862f85059c9 /fs/xfs
parent6dde27077eaf590eac279627f74b7e4e40b864b2 (diff)
xfs: add discontiguous buffer support to transactions
Now that the buffer cache supports discontiguous buffers, add support to the transaction buffer interface for getting and reading buffers. Note that this patch does not convert the buffer item logging to support discontiguous buffers. That will be done as a separate commit. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/xfs_trans.h50
-rw-r--r--fs/xfs/xfs_trans_buf.c68
2 files changed, 79 insertions, 39 deletions
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
index 7c37b533aa8e..bc2afd52a0b7 100644
--- a/fs/xfs/xfs_trans.h
+++ b/fs/xfs/xfs_trans.h
@@ -448,11 +448,51 @@ xfs_trans_t *xfs_trans_dup(xfs_trans_t *);
448int xfs_trans_reserve(xfs_trans_t *, uint, uint, uint, 448int xfs_trans_reserve(xfs_trans_t *, uint, uint, uint,
449 uint, uint); 449 uint, uint);
450void xfs_trans_mod_sb(xfs_trans_t *, uint, int64_t); 450void xfs_trans_mod_sb(xfs_trans_t *, uint, int64_t);
451struct xfs_buf *xfs_trans_get_buf(xfs_trans_t *, struct xfs_buftarg *, xfs_daddr_t, 451
452 int, uint); 452struct xfs_buf *xfs_trans_get_buf_map(struct xfs_trans *tp,
453int xfs_trans_read_buf(struct xfs_mount *, xfs_trans_t *, 453 struct xfs_buftarg *target,
454 struct xfs_buftarg *, xfs_daddr_t, int, uint, 454 struct xfs_buf_map *map, int nmaps,
455 struct xfs_buf **); 455 uint flags);
456
457static inline struct xfs_buf *
458xfs_trans_get_buf(
459 struct xfs_trans *tp,
460 struct xfs_buftarg *target,
461 xfs_daddr_t blkno,
462 int numblks,
463 uint flags)
464{
465 struct xfs_buf_map map = {
466 .bm_bn = blkno,
467 .bm_len = numblks,
468 };
469 return xfs_trans_get_buf_map(tp, target, &map, 1, flags);
470}
471
472int xfs_trans_read_buf_map(struct xfs_mount *mp,
473 struct xfs_trans *tp,
474 struct xfs_buftarg *target,
475 struct xfs_buf_map *map, int nmaps,
476 xfs_buf_flags_t flags,
477 struct xfs_buf **bpp);
478
479static inline int
480xfs_trans_read_buf(
481 struct xfs_mount *mp,
482 struct xfs_trans *tp,
483 struct xfs_buftarg *target,
484 xfs_daddr_t blkno,
485 int numblks,
486 xfs_buf_flags_t flags,
487 struct xfs_buf **bpp)
488{
489 struct xfs_buf_map map = {
490 .bm_bn = blkno,
491 .bm_len = numblks,
492 };
493 return xfs_trans_read_buf_map(mp, tp, target, &map, 1, flags, bpp);
494}
495
456struct xfs_buf *xfs_trans_getsb(xfs_trans_t *, struct xfs_mount *, int); 496struct xfs_buf *xfs_trans_getsb(xfs_trans_t *, struct xfs_mount *, int);
457 497
458void xfs_trans_brelse(xfs_trans_t *, struct xfs_buf *); 498void xfs_trans_brelse(xfs_trans_t *, struct xfs_buf *);
diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c
index 21c5a5e3700d..6311b99c267f 100644
--- a/fs/xfs/xfs_trans_buf.c
+++ b/fs/xfs/xfs_trans_buf.c
@@ -41,20 +41,26 @@ STATIC struct xfs_buf *
41xfs_trans_buf_item_match( 41xfs_trans_buf_item_match(
42 struct xfs_trans *tp, 42 struct xfs_trans *tp,
43 struct xfs_buftarg *target, 43 struct xfs_buftarg *target,
44 xfs_daddr_t blkno, 44 struct xfs_buf_map *map,
45 int len) 45 int nmaps)
46{ 46{
47 struct xfs_log_item_desc *lidp; 47 struct xfs_log_item_desc *lidp;
48 struct xfs_buf_log_item *blip; 48 struct xfs_buf_log_item *blip;
49 int len = 0;
50 int i;
51
52 for (i = 0; i < nmaps; i++)
53 len += map[i].bm_len;
49 54
50 len = BBTOB(len);
51 list_for_each_entry(lidp, &tp->t_items, lid_trans) { 55 list_for_each_entry(lidp, &tp->t_items, lid_trans) {
52 blip = (struct xfs_buf_log_item *)lidp->lid_item; 56 blip = (struct xfs_buf_log_item *)lidp->lid_item;
53 if (blip->bli_item.li_type == XFS_LI_BUF && 57 if (blip->bli_item.li_type == XFS_LI_BUF &&
54 blip->bli_buf->b_target == target && 58 blip->bli_buf->b_target == target &&
55 XFS_BUF_ADDR(blip->bli_buf) == blkno && 59 XFS_BUF_ADDR(blip->bli_buf) == map[0].bm_bn &&
56 BBTOB(blip->bli_buf->b_length) == len) 60 blip->bli_buf->b_length == len) {
61 ASSERT(blip->bli_buf->b_map_count == nmaps);
57 return blip->bli_buf; 62 return blip->bli_buf;
63 }
58 } 64 }
59 65
60 return NULL; 66 return NULL;
@@ -128,21 +134,19 @@ xfs_trans_bjoin(
128 * If the transaction pointer is NULL, make this just a normal 134 * If the transaction pointer is NULL, make this just a normal
129 * get_buf() call. 135 * get_buf() call.
130 */ 136 */
131xfs_buf_t * 137struct xfs_buf *
132xfs_trans_get_buf(xfs_trans_t *tp, 138xfs_trans_get_buf_map(
133 xfs_buftarg_t *target_dev, 139 struct xfs_trans *tp,
134 xfs_daddr_t blkno, 140 struct xfs_buftarg *target,
135 int len, 141 struct xfs_buf_map *map,
136 uint flags) 142 int nmaps,
143 xfs_buf_flags_t flags)
137{ 144{
138 xfs_buf_t *bp; 145 xfs_buf_t *bp;
139 xfs_buf_log_item_t *bip; 146 xfs_buf_log_item_t *bip;
140 147
141 /* 148 if (!tp)
142 * Default to a normal get_buf() call if the tp is NULL. 149 return xfs_buf_get_map(target, map, nmaps, flags);
143 */
144 if (tp == NULL)
145 return xfs_buf_get(target_dev, blkno, len, flags);
146 150
147 /* 151 /*
148 * If we find the buffer in the cache with this transaction 152 * If we find the buffer in the cache with this transaction
@@ -150,7 +154,7 @@ xfs_trans_get_buf(xfs_trans_t *tp,
150 * have it locked. In this case we just increment the lock 154 * have it locked. In this case we just increment the lock
151 * recursion count and return the buffer to the caller. 155 * recursion count and return the buffer to the caller.
152 */ 156 */
153 bp = xfs_trans_buf_item_match(tp, target_dev, blkno, len); 157 bp = xfs_trans_buf_item_match(tp, target, map, nmaps);
154 if (bp != NULL) { 158 if (bp != NULL) {
155 ASSERT(xfs_buf_islocked(bp)); 159 ASSERT(xfs_buf_islocked(bp));
156 if (XFS_FORCED_SHUTDOWN(tp->t_mountp)) { 160 if (XFS_FORCED_SHUTDOWN(tp->t_mountp)) {
@@ -167,7 +171,7 @@ xfs_trans_get_buf(xfs_trans_t *tp,
167 return (bp); 171 return (bp);
168 } 172 }
169 173
170 bp = xfs_buf_get(target_dev, blkno, len, flags); 174 bp = xfs_buf_get_map(target, map, nmaps, flags);
171 if (bp == NULL) { 175 if (bp == NULL) {
172 return NULL; 176 return NULL;
173 } 177 }
@@ -246,26 +250,22 @@ int xfs_error_mod = 33;
246 * read_buf() call. 250 * read_buf() call.
247 */ 251 */
248int 252int
249xfs_trans_read_buf( 253xfs_trans_read_buf_map(
250 xfs_mount_t *mp, 254 struct xfs_mount *mp,
251 xfs_trans_t *tp, 255 struct xfs_trans *tp,
252 xfs_buftarg_t *target, 256 struct xfs_buftarg *target,
253 xfs_daddr_t blkno, 257 struct xfs_buf_map *map,
254 int len, 258 int nmaps,
255 uint flags, 259 xfs_buf_flags_t flags,
256 xfs_buf_t **bpp) 260 struct xfs_buf **bpp)
257{ 261{
258 xfs_buf_t *bp; 262 xfs_buf_t *bp;
259 xfs_buf_log_item_t *bip; 263 xfs_buf_log_item_t *bip;
260 int error; 264 int error;
261 265
262 *bpp = NULL; 266 *bpp = NULL;
263 267 if (!tp) {
264 /* 268 bp = xfs_buf_read_map(target, map, nmaps, flags);
265 * Default to a normal get_buf() call if the tp is NULL.
266 */
267 if (tp == NULL) {
268 bp = xfs_buf_read(target, blkno, len, flags);
269 if (!bp) 269 if (!bp)
270 return (flags & XBF_TRYLOCK) ? 270 return (flags & XBF_TRYLOCK) ?
271 EAGAIN : XFS_ERROR(ENOMEM); 271 EAGAIN : XFS_ERROR(ENOMEM);
@@ -303,7 +303,7 @@ xfs_trans_read_buf(
303 * If the buffer is not yet read in, then we read it in, increment 303 * If the buffer is not yet read in, then we read it in, increment
304 * the lock recursion count, and return it to the caller. 304 * the lock recursion count, and return it to the caller.
305 */ 305 */
306 bp = xfs_trans_buf_item_match(tp, target, blkno, len); 306 bp = xfs_trans_buf_item_match(tp, target, map, nmaps);
307 if (bp != NULL) { 307 if (bp != NULL) {
308 ASSERT(xfs_buf_islocked(bp)); 308 ASSERT(xfs_buf_islocked(bp));
309 ASSERT(bp->b_transp == tp); 309 ASSERT(bp->b_transp == tp);
@@ -349,7 +349,7 @@ xfs_trans_read_buf(
349 return 0; 349 return 0;
350 } 350 }
351 351
352 bp = xfs_buf_read(target, blkno, len, flags); 352 bp = xfs_buf_read_map(target, map, nmaps, flags);
353 if (bp == NULL) { 353 if (bp == NULL) {
354 *bpp = NULL; 354 *bpp = NULL;
355 return (flags & XBF_TRYLOCK) ? 355 return (flags & XBF_TRYLOCK) ?