diff options
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_buf.c | 21 | ||||
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_buf.h | 1 | ||||
| -rw-r--r-- | fs/xfs/xfs_log.c | 8 | ||||
| -rw-r--r-- | fs/xfs/xfs_log_recover.c | 75 |
4 files changed, 67 insertions, 38 deletions
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index 09889035765..52b2b5da566 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c | |||
| @@ -708,6 +708,27 @@ xfs_buf_get_empty( | |||
| 708 | return bp; | 708 | return bp; |
| 709 | } | 709 | } |
| 710 | 710 | ||
| 711 | /* | ||
| 712 | * Return a buffer allocated as an empty buffer and associated to external | ||
| 713 | * memory via xfs_buf_associate_memory() back to it's empty state. | ||
| 714 | */ | ||
| 715 | void | ||
| 716 | xfs_buf_set_empty( | ||
| 717 | struct xfs_buf *bp, | ||
| 718 | size_t len) | ||
| 719 | { | ||
| 720 | if (bp->b_pages) | ||
| 721 | _xfs_buf_free_pages(bp); | ||
| 722 | |||
| 723 | bp->b_pages = NULL; | ||
| 724 | bp->b_page_count = 0; | ||
| 725 | bp->b_addr = NULL; | ||
| 726 | bp->b_file_offset = 0; | ||
| 727 | bp->b_buffer_length = bp->b_count_desired = len; | ||
| 728 | bp->b_bn = XFS_BUF_DADDR_NULL; | ||
| 729 | bp->b_flags &= ~XBF_MAPPED; | ||
| 730 | } | ||
| 731 | |||
| 711 | static inline struct page * | 732 | static inline struct page * |
| 712 | mem_to_page( | 733 | mem_to_page( |
| 713 | void *addr) | 734 | void *addr) |
diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/linux-2.6/xfs_buf.h index a9a1c451264..50a7d5fb3b7 100644 --- a/fs/xfs/linux-2.6/xfs_buf.h +++ b/fs/xfs/linux-2.6/xfs_buf.h | |||
| @@ -178,6 +178,7 @@ extern xfs_buf_t *xfs_buf_read(xfs_buftarg_t *, xfs_off_t, size_t, | |||
| 178 | xfs_buf_flags_t); | 178 | xfs_buf_flags_t); |
| 179 | 179 | ||
| 180 | 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 *); |
| 181 | extern void xfs_buf_set_empty(struct xfs_buf *bp, size_t len); | ||
| 181 | extern xfs_buf_t *xfs_buf_get_uncached(struct xfs_buftarg *, size_t, int); | 182 | extern xfs_buf_t *xfs_buf_get_uncached(struct xfs_buftarg *, size_t, int); |
| 182 | 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); |
| 183 | extern void xfs_buf_hold(xfs_buf_t *); | 184 | extern void xfs_buf_hold(xfs_buf_t *); |
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 18fd4beffcc..211930246f2 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c | |||
| @@ -1449,6 +1449,13 @@ xlog_dealloc_log(xlog_t *log) | |||
| 1449 | 1449 | ||
| 1450 | xlog_cil_destroy(log); | 1450 | xlog_cil_destroy(log); |
| 1451 | 1451 | ||
| 1452 | /* | ||
| 1453 | * always need to ensure that the extra buffer does not point to memory | ||
| 1454 | * owned by another log buffer before we free it. | ||
| 1455 | */ | ||
| 1456 | xfs_buf_set_empty(log->l_xbuf, log->l_iclog_size); | ||
| 1457 | xfs_buf_free(log->l_xbuf); | ||
| 1458 | |||
| 1452 | iclog = log->l_iclog; | 1459 | iclog = log->l_iclog; |
| 1453 | for (i=0; i<log->l_iclog_bufs; i++) { | 1460 | for (i=0; i<log->l_iclog_bufs; i++) { |
| 1454 | xfs_buf_free(iclog->ic_bp); | 1461 | xfs_buf_free(iclog->ic_bp); |
| @@ -1458,7 +1465,6 @@ xlog_dealloc_log(xlog_t *log) | |||
| 1458 | } | 1465 | } |
| 1459 | spinlock_destroy(&log->l_icloglock); | 1466 | spinlock_destroy(&log->l_icloglock); |
| 1460 | 1467 | ||
| 1461 | xfs_buf_free(log->l_xbuf); | ||
| 1462 | log->l_mp->m_log = NULL; | 1468 | log->l_mp->m_log = NULL; |
| 1463 | kmem_free(log); | 1469 | kmem_free(log); |
| 1464 | } /* xlog_dealloc_log */ | 1470 | } /* xlog_dealloc_log */ |
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 5cc464a17c9..04142caedb2 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c | |||
| @@ -205,6 +205,35 @@ xlog_bread( | |||
| 205 | } | 205 | } |
| 206 | 206 | ||
| 207 | /* | 207 | /* |
| 208 | * Read at an offset into the buffer. Returns with the buffer in it's original | ||
| 209 | * state regardless of the result of the read. | ||
| 210 | */ | ||
| 211 | STATIC int | ||
| 212 | xlog_bread_offset( | ||
| 213 | xlog_t *log, | ||
| 214 | xfs_daddr_t blk_no, /* block to read from */ | ||
| 215 | int nbblks, /* blocks to read */ | ||
| 216 | xfs_buf_t *bp, | ||
| 217 | xfs_caddr_t offset) | ||
| 218 | { | ||
| 219 | xfs_caddr_t orig_offset = XFS_BUF_PTR(bp); | ||
| 220 | int orig_len = bp->b_buffer_length; | ||
| 221 | int error, error2; | ||
| 222 | |||
| 223 | error = XFS_BUF_SET_PTR(bp, offset, BBTOB(nbblks)); | ||
| 224 | if (error) | ||
| 225 | return error; | ||
| 226 | |||
| 227 | error = xlog_bread_noalign(log, blk_no, nbblks, bp); | ||
| 228 | |||
| 229 | /* must reset buffer pointer even on error */ | ||
| 230 | error2 = XFS_BUF_SET_PTR(bp, orig_offset, orig_len); | ||
| 231 | if (error) | ||
| 232 | return error; | ||
| 233 | return error2; | ||
| 234 | } | ||
| 235 | |||
| 236 | /* | ||
| 208 | * Write out the buffer at the given block for the given number of blocks. | 237 | * Write out the buffer at the given block for the given number of blocks. |
| 209 | * The buffer is kept locked across the write and is returned locked. | 238 | * The buffer is kept locked across the write and is returned locked. |
| 210 | * This can only be used for synchronous log writes. | 239 | * This can only be used for synchronous log writes. |
| @@ -1229,20 +1258,12 @@ xlog_write_log_records( | |||
| 1229 | */ | 1258 | */ |
| 1230 | ealign = round_down(end_block, sectbb); | 1259 | ealign = round_down(end_block, sectbb); |
| 1231 | if (j == 0 && (start_block + endcount > ealign)) { | 1260 | if (j == 0 && (start_block + endcount > ealign)) { |
| 1232 | offset = XFS_BUF_PTR(bp); | 1261 | offset = XFS_BUF_PTR(bp) + BBTOB(ealign - start_block); |
| 1233 | balign = BBTOB(ealign - start_block); | 1262 | error = xlog_bread_offset(log, ealign, sectbb, |
| 1234 | error = XFS_BUF_SET_PTR(bp, offset + balign, | 1263 | bp, offset); |
| 1235 | BBTOB(sectbb)); | ||
| 1236 | if (error) | 1264 | if (error) |
| 1237 | break; | 1265 | break; |
| 1238 | 1266 | ||
| 1239 | error = xlog_bread_noalign(log, ealign, sectbb, bp); | ||
| 1240 | if (error) | ||
| 1241 | break; | ||
| 1242 | |||
| 1243 | error = XFS_BUF_SET_PTR(bp, offset, bufblks); | ||
| 1244 | if (error) | ||
| 1245 | break; | ||
| 1246 | } | 1267 | } |
| 1247 | 1268 | ||
| 1248 | offset = xlog_align(log, start_block, endcount, bp); | 1269 | offset = xlog_align(log, start_block, endcount, bp); |
| @@ -3448,19 +3469,9 @@ xlog_do_recovery_pass( | |||
| 3448 | * - order is important. | 3469 | * - order is important. |
| 3449 | */ | 3470 | */ |
| 3450 | wrapped_hblks = hblks - split_hblks; | 3471 | wrapped_hblks = hblks - split_hblks; |
| 3451 | error = XFS_BUF_SET_PTR(hbp, | 3472 | error = xlog_bread_offset(log, 0, |
| 3452 | offset + BBTOB(split_hblks), | 3473 | wrapped_hblks, hbp, |
| 3453 | BBTOB(hblks - split_hblks)); | 3474 | offset + BBTOB(split_hblks)); |
| 3454 | if (error) | ||
| 3455 | goto bread_err2; | ||
| 3456 | |||
| 3457 | error = xlog_bread_noalign(log, 0, | ||
| 3458 | wrapped_hblks, hbp); | ||
| 3459 | if (error) | ||
| 3460 | goto bread_err2; | ||
| 3461 | |||
| 3462 | error = XFS_BUF_SET_PTR(hbp, offset, | ||
| 3463 | BBTOB(hblks)); | ||
| 3464 | if (error) | 3475 | if (error) |
| 3465 | goto bread_err2; | 3476 | goto bread_err2; |
| 3466 | } | 3477 | } |
| @@ -3511,19 +3522,9 @@ xlog_do_recovery_pass( | |||
| 3511 | * _first_, then the log start (LR header end) | 3522 | * _first_, then the log start (LR header end) |
| 3512 | * - order is important. | 3523 | * - order is important. |
| 3513 | */ | 3524 | */ |
| 3514 | error = XFS_BUF_SET_PTR(dbp, | 3525 | error = xlog_bread_offset(log, 0, |
| 3515 | offset + BBTOB(split_bblks), | 3526 | bblks - split_bblks, hbp, |
| 3516 | BBTOB(bblks - split_bblks)); | 3527 | offset + BBTOB(split_bblks)); |
| 3517 | if (error) | ||
| 3518 | goto bread_err2; | ||
| 3519 | |||
| 3520 | error = xlog_bread_noalign(log, wrapped_hblks, | ||
| 3521 | bblks - split_bblks, | ||
| 3522 | dbp); | ||
| 3523 | if (error) | ||
| 3524 | goto bread_err2; | ||
| 3525 | |||
| 3526 | error = XFS_BUF_SET_PTR(dbp, offset, h_size); | ||
| 3527 | if (error) | 3528 | if (error) |
| 3528 | goto bread_err2; | 3529 | goto bread_err2; |
| 3529 | } | 3530 | } |
