diff options
author | Dave Chinner <dchinner@redhat.com> | 2012-06-22 04:50:11 -0400 |
---|---|---|
committer | Ben Myers <bpm@sgi.com> | 2012-07-01 15:50:06 -0400 |
commit | de2a4f59190303ff5b82ead2969968a325e61230 (patch) | |
tree | 90a719a20401085dbb0e4848a49a0862f85059c9 /fs/xfs | |
parent | 6dde27077eaf590eac279627f74b7e4e40b864b2 (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.h | 50 | ||||
-rw-r--r-- | fs/xfs/xfs_trans_buf.c | 68 |
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 *); | |||
448 | int xfs_trans_reserve(xfs_trans_t *, uint, uint, uint, | 448 | int xfs_trans_reserve(xfs_trans_t *, uint, uint, uint, |
449 | uint, uint); | 449 | uint, uint); |
450 | void xfs_trans_mod_sb(xfs_trans_t *, uint, int64_t); | 450 | void xfs_trans_mod_sb(xfs_trans_t *, uint, int64_t); |
451 | struct xfs_buf *xfs_trans_get_buf(xfs_trans_t *, struct xfs_buftarg *, xfs_daddr_t, | 451 | |
452 | int, uint); | 452 | struct xfs_buf *xfs_trans_get_buf_map(struct xfs_trans *tp, |
453 | int 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 | |||
457 | static inline struct xfs_buf * | ||
458 | xfs_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 | |||
472 | int 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 | |||
479 | static inline int | ||
480 | xfs_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 | |||
456 | struct xfs_buf *xfs_trans_getsb(xfs_trans_t *, struct xfs_mount *, int); | 496 | struct xfs_buf *xfs_trans_getsb(xfs_trans_t *, struct xfs_mount *, int); |
457 | 497 | ||
458 | void xfs_trans_brelse(xfs_trans_t *, struct xfs_buf *); | 498 | void 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 * | |||
41 | xfs_trans_buf_item_match( | 41 | xfs_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 | */ |
131 | xfs_buf_t * | 137 | struct xfs_buf * |
132 | xfs_trans_get_buf(xfs_trans_t *tp, | 138 | xfs_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 | */ |
248 | int | 252 | int |
249 | xfs_trans_read_buf( | 253 | xfs_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) ? |