diff options
-rw-r--r-- | fs/ocfs2/alloc.c | 119 |
1 files changed, 74 insertions, 45 deletions
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index b5327b4cdb34..a02d026cb0e4 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c | |||
@@ -825,6 +825,74 @@ bail: | |||
825 | } | 825 | } |
826 | 826 | ||
827 | /* | 827 | /* |
828 | * Grow a b-tree so that it has more records. | ||
829 | * | ||
830 | * We might shift the tree depth in which case existing paths should | ||
831 | * be considered invalid. | ||
832 | * | ||
833 | * Tree depth after the grow is returned via *final_depth. | ||
834 | */ | ||
835 | static int ocfs2_grow_tree(struct inode *inode, handle_t *handle, | ||
836 | struct buffer_head *di_bh, int *final_depth, | ||
837 | struct buffer_head *last_eb_bh, | ||
838 | struct ocfs2_alloc_context *meta_ac) | ||
839 | { | ||
840 | int ret, shift; | ||
841 | struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data; | ||
842 | int depth = le16_to_cpu(di->id2.i_list.l_tree_depth); | ||
843 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
844 | struct buffer_head *bh = NULL; | ||
845 | |||
846 | BUG_ON(meta_ac == NULL); | ||
847 | |||
848 | shift = ocfs2_find_branch_target(osb, inode, di_bh, &bh); | ||
849 | if (shift < 0) { | ||
850 | ret = shift; | ||
851 | mlog_errno(ret); | ||
852 | goto out; | ||
853 | } | ||
854 | |||
855 | /* We traveled all the way to the bottom of the allocation tree | ||
856 | * and didn't find room for any more extents - we need to add | ||
857 | * another tree level */ | ||
858 | if (shift) { | ||
859 | BUG_ON(bh); | ||
860 | mlog(0, "need to shift tree depth (current = %d)\n", depth); | ||
861 | |||
862 | /* ocfs2_shift_tree_depth will return us a buffer with | ||
863 | * the new extent block (so we can pass that to | ||
864 | * ocfs2_add_branch). */ | ||
865 | ret = ocfs2_shift_tree_depth(osb, handle, inode, di_bh, | ||
866 | meta_ac, &bh); | ||
867 | if (ret < 0) { | ||
868 | mlog_errno(ret); | ||
869 | goto out; | ||
870 | } | ||
871 | depth++; | ||
872 | /* Special case: we have room now if we shifted from | ||
873 | * tree_depth 0 */ | ||
874 | if (depth == 1) | ||
875 | goto out; | ||
876 | } | ||
877 | |||
878 | /* call ocfs2_add_branch to add the final part of the tree with | ||
879 | * the new data. */ | ||
880 | mlog(0, "add branch. bh = %p\n", bh); | ||
881 | ret = ocfs2_add_branch(osb, handle, inode, di_bh, bh, last_eb_bh, | ||
882 | meta_ac); | ||
883 | if (ret < 0) { | ||
884 | mlog_errno(ret); | ||
885 | goto out; | ||
886 | } | ||
887 | |||
888 | out: | ||
889 | if (final_depth) | ||
890 | *final_depth = depth; | ||
891 | brelse(bh); | ||
892 | return ret; | ||
893 | } | ||
894 | |||
895 | /* | ||
828 | * This is only valid for leaf nodes, which are the only ones that can | 896 | * This is only valid for leaf nodes, which are the only ones that can |
829 | * have empty extents anyway. | 897 | * have empty extents anyway. |
830 | */ | 898 | */ |
@@ -2325,7 +2393,7 @@ int ocfs2_insert_extent(struct ocfs2_super *osb, | |||
2325 | u32 new_clusters, | 2393 | u32 new_clusters, |
2326 | struct ocfs2_alloc_context *meta_ac) | 2394 | struct ocfs2_alloc_context *meta_ac) |
2327 | { | 2395 | { |
2328 | int status, shift; | 2396 | int status; |
2329 | struct buffer_head *last_eb_bh = NULL; | 2397 | struct buffer_head *last_eb_bh = NULL; |
2330 | struct buffer_head *bh = NULL; | 2398 | struct buffer_head *bh = NULL; |
2331 | struct ocfs2_insert_type insert = {0, }; | 2399 | struct ocfs2_insert_type insert = {0, }; |
@@ -2360,55 +2428,16 @@ int ocfs2_insert_extent(struct ocfs2_super *osb, | |||
2360 | insert.ins_appending, insert.ins_contig, insert.ins_contig_index, | 2428 | insert.ins_appending, insert.ins_contig, insert.ins_contig_index, |
2361 | insert.ins_free_records, insert.ins_tree_depth); | 2429 | insert.ins_free_records, insert.ins_tree_depth); |
2362 | 2430 | ||
2363 | /* | 2431 | if (insert.ins_contig == CONTIG_NONE && insert.ins_free_records == 0) { |
2364 | * Avoid growing the tree unless we're out of records and the | 2432 | status = ocfs2_grow_tree(inode, handle, fe_bh, |
2365 | * insert type requres one. | 2433 | &insert.ins_tree_depth, last_eb_bh, |
2366 | */ | 2434 | meta_ac); |
2367 | if (insert.ins_contig != CONTIG_NONE || insert.ins_free_records) | 2435 | if (status) { |
2368 | goto out_add; | ||
2369 | |||
2370 | shift = ocfs2_find_branch_target(osb, inode, fe_bh, &bh); | ||
2371 | if (shift < 0) { | ||
2372 | status = shift; | ||
2373 | mlog_errno(status); | ||
2374 | goto bail; | ||
2375 | } | ||
2376 | |||
2377 | /* We traveled all the way to the bottom of the allocation tree | ||
2378 | * and didn't find room for any more extents - we need to add | ||
2379 | * another tree level */ | ||
2380 | if (shift) { | ||
2381 | BUG_ON(bh); | ||
2382 | mlog(0, "need to shift tree depth " | ||
2383 | "(current = %d)\n", insert.ins_tree_depth); | ||
2384 | |||
2385 | /* ocfs2_shift_tree_depth will return us a buffer with | ||
2386 | * the new extent block (so we can pass that to | ||
2387 | * ocfs2_add_branch). */ | ||
2388 | status = ocfs2_shift_tree_depth(osb, handle, inode, fe_bh, | ||
2389 | meta_ac, &bh); | ||
2390 | if (status < 0) { | ||
2391 | mlog_errno(status); | 2436 | mlog_errno(status); |
2392 | goto bail; | 2437 | goto bail; |
2393 | } | 2438 | } |
2394 | insert.ins_tree_depth++; | ||
2395 | /* Special case: we have room now if we shifted from | ||
2396 | * tree_depth 0 */ | ||
2397 | if (insert.ins_tree_depth == 1) | ||
2398 | goto out_add; | ||
2399 | } | ||
2400 | |||
2401 | /* call ocfs2_add_branch to add the final part of the tree with | ||
2402 | * the new data. */ | ||
2403 | mlog(0, "add branch. bh = %p\n", bh); | ||
2404 | status = ocfs2_add_branch(osb, handle, inode, fe_bh, bh, last_eb_bh, | ||
2405 | meta_ac); | ||
2406 | if (status < 0) { | ||
2407 | mlog_errno(status); | ||
2408 | goto bail; | ||
2409 | } | 2439 | } |
2410 | 2440 | ||
2411 | out_add: | ||
2412 | /* Finally, we can add clusters. This might rotate the tree for us. */ | 2441 | /* Finally, we can add clusters. This might rotate the tree for us. */ |
2413 | status = ocfs2_do_insert_extent(inode, handle, fe_bh, &rec, &insert); | 2442 | status = ocfs2_do_insert_extent(inode, handle, fe_bh, &rec, &insert); |
2414 | if (status < 0) | 2443 | if (status < 0) |