diff options
Diffstat (limited to 'fs/xfs/xfs_log_recover.c')
-rw-r--r-- | fs/xfs/xfs_log_recover.c | 75 |
1 files changed, 38 insertions, 37 deletions
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 5cc464a17c93..04142caedb2b 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 | } |