diff options
-rw-r--r-- | fs/xfs/xfs_bmap.c | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_bmap_btree.c | 113 | ||||
-rw-r--r-- | fs/xfs/xfs_bmap_btree.h | 6 | ||||
-rw-r--r-- | fs/xfs/xfs_btree.c | 101 | ||||
-rw-r--r-- | fs/xfs/xfs_btree.h | 1 |
5 files changed, 104 insertions, 119 deletions
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index 7d6c4ace8052..315bc2912682 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c | |||
@@ -476,7 +476,7 @@ xfs_bmap_add_attrfork_btree( | |||
476 | goto error0; | 476 | goto error0; |
477 | /* must be at least one entry */ | 477 | /* must be at least one entry */ |
478 | XFS_WANT_CORRUPTED_GOTO(stat == 1, error0); | 478 | XFS_WANT_CORRUPTED_GOTO(stat == 1, error0); |
479 | if ((error = xfs_bmbt_newroot(cur, flags, &stat))) | 479 | if ((error = xfs_btree_new_iroot(cur, flags, &stat))) |
480 | goto error0; | 480 | goto error0; |
481 | if (stat == 0) { | 481 | if (stat == 0) { |
482 | xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); | 482 | xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); |
diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c index e7539263457f..204f276aeaad 100644 --- a/fs/xfs/xfs_bmap_btree.c +++ b/fs/xfs/xfs_bmap_btree.c | |||
@@ -525,7 +525,7 @@ xfs_bmbt_insrec( | |||
525 | cur->bc_private.b.whichfork); | 525 | cur->bc_private.b.whichfork); |
526 | block = xfs_bmbt_get_block(cur, level, &bp); | 526 | block = xfs_bmbt_get_block(cur, level, &bp); |
527 | } else if (level == cur->bc_nlevels - 1) { | 527 | } else if (level == cur->bc_nlevels - 1) { |
528 | if ((error = xfs_bmbt_newroot(cur, &logflags, stat)) || | 528 | if ((error = xfs_btree_new_iroot(cur, &logflags, stat)) || |
529 | *stat == 0) { | 529 | *stat == 0) { |
530 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); | 530 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); |
531 | return error; | 531 | return error; |
@@ -1183,117 +1183,6 @@ xfs_bmbt_log_recs( | |||
1183 | } | 1183 | } |
1184 | 1184 | ||
1185 | /* | 1185 | /* |
1186 | * Give the bmap btree a new root block. Copy the old broot contents | ||
1187 | * down into a real block and make the broot point to it. | ||
1188 | */ | ||
1189 | int /* error */ | ||
1190 | xfs_bmbt_newroot( | ||
1191 | xfs_btree_cur_t *cur, /* btree cursor */ | ||
1192 | int *logflags, /* logging flags for inode */ | ||
1193 | int *stat) /* return status - 0 fail */ | ||
1194 | { | ||
1195 | xfs_alloc_arg_t args; /* allocation arguments */ | ||
1196 | xfs_bmbt_block_t *block; /* bmap btree block */ | ||
1197 | xfs_buf_t *bp; /* buffer for block */ | ||
1198 | xfs_bmbt_block_t *cblock; /* child btree block */ | ||
1199 | xfs_bmbt_key_t *ckp; /* child key pointer */ | ||
1200 | xfs_bmbt_ptr_t *cpp; /* child ptr pointer */ | ||
1201 | int error; /* error return code */ | ||
1202 | #ifdef DEBUG | ||
1203 | int i; /* loop counter */ | ||
1204 | #endif | ||
1205 | xfs_bmbt_key_t *kp; /* pointer to bmap btree key */ | ||
1206 | int level; /* btree level */ | ||
1207 | xfs_bmbt_ptr_t *pp; /* pointer to bmap block addr */ | ||
1208 | |||
1209 | XFS_BMBT_TRACE_CURSOR(cur, ENTRY); | ||
1210 | level = cur->bc_nlevels - 1; | ||
1211 | block = xfs_bmbt_get_block(cur, level, &bp); | ||
1212 | /* | ||
1213 | * Copy the root into a real block. | ||
1214 | */ | ||
1215 | args.mp = cur->bc_mp; | ||
1216 | pp = XFS_BMAP_PTR_IADDR(block, 1, cur); | ||
1217 | args.tp = cur->bc_tp; | ||
1218 | args.fsbno = cur->bc_private.b.firstblock; | ||
1219 | args.mod = args.minleft = args.alignment = args.total = args.isfl = | ||
1220 | args.userdata = args.minalignslop = 0; | ||
1221 | args.minlen = args.maxlen = args.prod = 1; | ||
1222 | args.wasdel = cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL; | ||
1223 | args.firstblock = args.fsbno; | ||
1224 | if (args.fsbno == NULLFSBLOCK) { | ||
1225 | #ifdef DEBUG | ||
1226 | if ((error = xfs_btree_check_lptr_disk(cur, *pp, level))) { | ||
1227 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); | ||
1228 | return error; | ||
1229 | } | ||
1230 | #endif | ||
1231 | args.fsbno = be64_to_cpu(*pp); | ||
1232 | args.type = XFS_ALLOCTYPE_START_BNO; | ||
1233 | } else if (cur->bc_private.b.flist->xbf_low) | ||
1234 | args.type = XFS_ALLOCTYPE_START_BNO; | ||
1235 | else | ||
1236 | args.type = XFS_ALLOCTYPE_NEAR_BNO; | ||
1237 | if ((error = xfs_alloc_vextent(&args))) { | ||
1238 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); | ||
1239 | return error; | ||
1240 | } | ||
1241 | if (args.fsbno == NULLFSBLOCK) { | ||
1242 | XFS_BMBT_TRACE_CURSOR(cur, EXIT); | ||
1243 | *stat = 0; | ||
1244 | return 0; | ||
1245 | } | ||
1246 | ASSERT(args.len == 1); | ||
1247 | cur->bc_private.b.firstblock = args.fsbno; | ||
1248 | cur->bc_private.b.allocated++; | ||
1249 | cur->bc_private.b.ip->i_d.di_nblocks++; | ||
1250 | XFS_TRANS_MOD_DQUOT_BYINO(args.mp, args.tp, cur->bc_private.b.ip, | ||
1251 | XFS_TRANS_DQ_BCOUNT, 1L); | ||
1252 | bp = xfs_btree_get_bufl(args.mp, cur->bc_tp, args.fsbno, 0); | ||
1253 | cblock = XFS_BUF_TO_BMBT_BLOCK(bp); | ||
1254 | *cblock = *block; | ||
1255 | be16_add_cpu(&block->bb_level, 1); | ||
1256 | block->bb_numrecs = cpu_to_be16(1); | ||
1257 | cur->bc_nlevels++; | ||
1258 | cur->bc_ptrs[level + 1] = 1; | ||
1259 | kp = XFS_BMAP_KEY_IADDR(block, 1, cur); | ||
1260 | ckp = XFS_BMAP_KEY_IADDR(cblock, 1, cur); | ||
1261 | memcpy(ckp, kp, be16_to_cpu(cblock->bb_numrecs) * sizeof(*kp)); | ||
1262 | cpp = XFS_BMAP_PTR_IADDR(cblock, 1, cur); | ||
1263 | #ifdef DEBUG | ||
1264 | for (i = 0; i < be16_to_cpu(cblock->bb_numrecs); i++) { | ||
1265 | if ((error = xfs_btree_check_lptr_disk(cur, pp[i], level))) { | ||
1266 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); | ||
1267 | return error; | ||
1268 | } | ||
1269 | } | ||
1270 | #endif | ||
1271 | memcpy(cpp, pp, be16_to_cpu(cblock->bb_numrecs) * sizeof(*pp)); | ||
1272 | #ifdef DEBUG | ||
1273 | if ((error = xfs_btree_check_lptr(cur, args.fsbno, level))) { | ||
1274 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); | ||
1275 | return error; | ||
1276 | } | ||
1277 | #endif | ||
1278 | *pp = cpu_to_be64(args.fsbno); | ||
1279 | xfs_iroot_realloc(cur->bc_private.b.ip, 1 - be16_to_cpu(cblock->bb_numrecs), | ||
1280 | cur->bc_private.b.whichfork); | ||
1281 | xfs_btree_setbuf(cur, level, bp); | ||
1282 | /* | ||
1283 | * Do all this logging at the end so that | ||
1284 | * the root is at the right level. | ||
1285 | */ | ||
1286 | xfs_bmbt_log_block(cur, bp, XFS_BB_ALL_BITS); | ||
1287 | xfs_bmbt_log_keys(cur, bp, 1, be16_to_cpu(cblock->bb_numrecs)); | ||
1288 | xfs_bmbt_log_ptrs(cur, bp, 1, be16_to_cpu(cblock->bb_numrecs)); | ||
1289 | XFS_BMBT_TRACE_CURSOR(cur, EXIT); | ||
1290 | *logflags |= | ||
1291 | XFS_ILOG_CORE | XFS_ILOG_FBROOT(cur->bc_private.b.whichfork); | ||
1292 | *stat = 1; | ||
1293 | return 0; | ||
1294 | } | ||
1295 | |||
1296 | /* | ||
1297 | * Set all the fields in a bmap extent record from the arguments. | 1186 | * Set all the fields in a bmap extent record from the arguments. |
1298 | */ | 1187 | */ |
1299 | void | 1188 | void |
diff --git a/fs/xfs/xfs_bmap_btree.h b/fs/xfs/xfs_bmap_btree.h index 6bfd62ec54fb..26fd8ace3e77 100644 --- a/fs/xfs/xfs_bmap_btree.h +++ b/fs/xfs/xfs_bmap_btree.h | |||
@@ -255,12 +255,6 @@ extern void xfs_bmbt_log_block(struct xfs_btree_cur *, struct xfs_buf *, int); | |||
255 | extern void xfs_bmbt_log_recs(struct xfs_btree_cur *, struct xfs_buf *, int, | 255 | extern void xfs_bmbt_log_recs(struct xfs_btree_cur *, struct xfs_buf *, int, |
256 | int); | 256 | int); |
257 | 257 | ||
258 | /* | ||
259 | * Give the bmap btree a new root block. Copy the old broot contents | ||
260 | * down into a real block and make the broot point to it. | ||
261 | */ | ||
262 | extern int xfs_bmbt_newroot(struct xfs_btree_cur *cur, int *lflags, int *stat); | ||
263 | |||
264 | extern void xfs_bmbt_set_all(xfs_bmbt_rec_host_t *r, xfs_bmbt_irec_t *s); | 258 | extern void xfs_bmbt_set_all(xfs_bmbt_rec_host_t *r, xfs_bmbt_irec_t *s); |
265 | extern void xfs_bmbt_set_allf(xfs_bmbt_rec_host_t *r, xfs_fileoff_t o, | 259 | extern void xfs_bmbt_set_allf(xfs_bmbt_rec_host_t *r, xfs_fileoff_t o, |
266 | xfs_fsblock_t b, xfs_filblks_t c, xfs_exntst_t v); | 260 | xfs_fsblock_t b, xfs_filblks_t c, xfs_exntst_t v); |
diff --git a/fs/xfs/xfs_btree.c b/fs/xfs/xfs_btree.c index 8de884c4dab7..3b6e01dea669 100644 --- a/fs/xfs/xfs_btree.c +++ b/fs/xfs/xfs_btree.c | |||
@@ -2469,6 +2469,107 @@ error0: | |||
2469 | } | 2469 | } |
2470 | 2470 | ||
2471 | /* | 2471 | /* |
2472 | * Copy the old inode root contents into a real block and make the | ||
2473 | * broot point to it. | ||
2474 | */ | ||
2475 | int /* error */ | ||
2476 | xfs_btree_new_iroot( | ||
2477 | struct xfs_btree_cur *cur, /* btree cursor */ | ||
2478 | int *logflags, /* logging flags for inode */ | ||
2479 | int *stat) /* return status - 0 fail */ | ||
2480 | { | ||
2481 | struct xfs_buf *cbp; /* buffer for cblock */ | ||
2482 | struct xfs_btree_block *block; /* btree block */ | ||
2483 | struct xfs_btree_block *cblock; /* child btree block */ | ||
2484 | union xfs_btree_key *ckp; /* child key pointer */ | ||
2485 | union xfs_btree_ptr *cpp; /* child ptr pointer */ | ||
2486 | union xfs_btree_key *kp; /* pointer to btree key */ | ||
2487 | union xfs_btree_ptr *pp; /* pointer to block addr */ | ||
2488 | union xfs_btree_ptr nptr; /* new block addr */ | ||
2489 | int level; /* btree level */ | ||
2490 | int error; /* error return code */ | ||
2491 | #ifdef DEBUG | ||
2492 | int i; /* loop counter */ | ||
2493 | #endif | ||
2494 | |||
2495 | XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY); | ||
2496 | XFS_BTREE_STATS_INC(cur, newroot); | ||
2497 | |||
2498 | ASSERT(cur->bc_flags & XFS_BTREE_ROOT_IN_INODE); | ||
2499 | |||
2500 | level = cur->bc_nlevels - 1; | ||
2501 | |||
2502 | block = xfs_btree_get_iroot(cur); | ||
2503 | pp = xfs_btree_ptr_addr(cur, 1, block); | ||
2504 | |||
2505 | /* Allocate the new block. If we can't do it, we're toast. Give up. */ | ||
2506 | error = cur->bc_ops->alloc_block(cur, pp, &nptr, 1, stat); | ||
2507 | if (error) | ||
2508 | goto error0; | ||
2509 | if (*stat == 0) { | ||
2510 | XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); | ||
2511 | return 0; | ||
2512 | } | ||
2513 | XFS_BTREE_STATS_INC(cur, alloc); | ||
2514 | |||
2515 | /* Copy the root into a real block. */ | ||
2516 | error = xfs_btree_get_buf_block(cur, &nptr, 0, &cblock, &cbp); | ||
2517 | if (error) | ||
2518 | goto error0; | ||
2519 | |||
2520 | memcpy(cblock, block, xfs_btree_block_len(cur)); | ||
2521 | |||
2522 | be16_add_cpu(&block->bb_level, 1); | ||
2523 | xfs_btree_set_numrecs(block, 1); | ||
2524 | cur->bc_nlevels++; | ||
2525 | cur->bc_ptrs[level + 1] = 1; | ||
2526 | |||
2527 | kp = xfs_btree_key_addr(cur, 1, block); | ||
2528 | ckp = xfs_btree_key_addr(cur, 1, cblock); | ||
2529 | xfs_btree_copy_keys(cur, ckp, kp, xfs_btree_get_numrecs(cblock)); | ||
2530 | |||
2531 | cpp = xfs_btree_ptr_addr(cur, 1, cblock); | ||
2532 | #ifdef DEBUG | ||
2533 | for (i = 0; i < be16_to_cpu(cblock->bb_numrecs); i++) { | ||
2534 | error = xfs_btree_check_ptr(cur, pp, i, level); | ||
2535 | if (error) | ||
2536 | goto error0; | ||
2537 | } | ||
2538 | #endif | ||
2539 | xfs_btree_copy_ptrs(cur, cpp, pp, xfs_btree_get_numrecs(cblock)); | ||
2540 | |||
2541 | #ifdef DEBUG | ||
2542 | error = xfs_btree_check_ptr(cur, &nptr, 0, level); | ||
2543 | if (error) | ||
2544 | goto error0; | ||
2545 | #endif | ||
2546 | xfs_btree_copy_ptrs(cur, pp, &nptr, 1); | ||
2547 | |||
2548 | xfs_iroot_realloc(cur->bc_private.b.ip, | ||
2549 | 1 - xfs_btree_get_numrecs(cblock), | ||
2550 | cur->bc_private.b.whichfork); | ||
2551 | |||
2552 | xfs_btree_setbuf(cur, level, cbp); | ||
2553 | |||
2554 | /* | ||
2555 | * Do all this logging at the end so that | ||
2556 | * the root is at the right level. | ||
2557 | */ | ||
2558 | xfs_btree_log_block(cur, cbp, XFS_BB_ALL_BITS); | ||
2559 | xfs_btree_log_keys(cur, cbp, 1, be16_to_cpu(cblock->bb_numrecs)); | ||
2560 | xfs_btree_log_ptrs(cur, cbp, 1, be16_to_cpu(cblock->bb_numrecs)); | ||
2561 | |||
2562 | *logflags |= | ||
2563 | XFS_ILOG_CORE | XFS_ILOG_FBROOT(cur->bc_private.b.whichfork); | ||
2564 | *stat = 1; | ||
2565 | XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); | ||
2566 | return 0; | ||
2567 | error0: | ||
2568 | XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR); | ||
2569 | return error; | ||
2570 | } | ||
2571 | |||
2572 | /* | ||
2472 | * Allocate a new root block, fill it in. | 2573 | * Allocate a new root block, fill it in. |
2473 | */ | 2574 | */ |
2474 | int /* error */ | 2575 | int /* error */ |
diff --git a/fs/xfs/xfs_btree.h b/fs/xfs/xfs_btree.h index 18015392feb0..21eec863f00f 100644 --- a/fs/xfs/xfs_btree.h +++ b/fs/xfs/xfs_btree.h | |||
@@ -548,6 +548,7 @@ int xfs_btree_rshift(struct xfs_btree_cur *, int, int *); | |||
548 | int xfs_btree_split(struct xfs_btree_cur *, int, union xfs_btree_ptr *, | 548 | int xfs_btree_split(struct xfs_btree_cur *, int, union xfs_btree_ptr *, |
549 | union xfs_btree_key *, struct xfs_btree_cur **, int *); | 549 | union xfs_btree_key *, struct xfs_btree_cur **, int *); |
550 | int xfs_btree_new_root(struct xfs_btree_cur *, int *); | 550 | int xfs_btree_new_root(struct xfs_btree_cur *, int *); |
551 | int xfs_btree_new_iroot(struct xfs_btree_cur *, int *, int *); | ||
551 | 552 | ||
552 | /* | 553 | /* |
553 | * Helpers. | 554 | * Helpers. |