diff options
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) ? |