aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ocfs2/alloc.c3
-rw-r--r--fs/ocfs2/alloc.h12
-rw-r--r--fs/ocfs2/aops.c3
-rw-r--r--fs/ocfs2/dir.c5
-rw-r--r--fs/ocfs2/file.c9
-rw-r--r--fs/ocfs2/journal.h17
-rw-r--r--fs/ocfs2/suballoc.c4
-rw-r--r--fs/ocfs2/suballoc.h7
8 files changed, 40 insertions, 20 deletions
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
index 377acb24f67b..dc36cd140754 100644
--- a/fs/ocfs2/alloc.c
+++ b/fs/ocfs2/alloc.c
@@ -4527,7 +4527,8 @@ static int ocfs2_split_tree(struct inode *inode, struct buffer_head *di_bh,
4527 } else 4527 } else
4528 rightmost_el = path_leaf_el(path); 4528 rightmost_el = path_leaf_el(path);
4529 4529
4530 credits += path->p_tree_depth + ocfs2_extend_meta_needed(di); 4530 credits += path->p_tree_depth +
4531 ocfs2_extend_meta_needed(&di->id2.i_list);
4531 ret = ocfs2_extend_trans(handle, credits); 4532 ret = ocfs2_extend_trans(handle, credits);
4532 if (ret) { 4533 if (ret) {
4533 mlog_errno(ret); 4534 mlog_errno(ret);
diff --git a/fs/ocfs2/alloc.h b/fs/ocfs2/alloc.h
index 5c0f764b59ec..a0e334f10cd1 100644
--- a/fs/ocfs2/alloc.h
+++ b/fs/ocfs2/alloc.h
@@ -48,8 +48,14 @@ int ocfs2_remove_extent(struct inode *inode, struct buffer_head *di_bh,
48int ocfs2_num_free_extents(struct ocfs2_super *osb, 48int ocfs2_num_free_extents(struct ocfs2_super *osb,
49 struct inode *inode, 49 struct inode *inode,
50 struct buffer_head *bh); 50 struct buffer_head *bh);
51/* how many new metadata chunks would an allocation need at maximum? */ 51/*
52static inline int ocfs2_extend_meta_needed(struct ocfs2_dinode *fe) 52 * how many new metadata chunks would an allocation need at maximum?
53 *
54 * Please note that the caller must make sure that root_el is the root
55 * of extent tree. So for an inode, it should be &fe->id2.i_list. Otherwise
56 * the result may be wrong.
57 */
58static inline int ocfs2_extend_meta_needed(struct ocfs2_extent_list *root_el)
53{ 59{
54 /* 60 /*
55 * Rather than do all the work of determining how much we need 61 * Rather than do all the work of determining how much we need
@@ -59,7 +65,7 @@ static inline int ocfs2_extend_meta_needed(struct ocfs2_dinode *fe)
59 * new tree_depth==0 extent_block, and one block at the new 65 * new tree_depth==0 extent_block, and one block at the new
60 * top-of-the tree. 66 * top-of-the tree.
61 */ 67 */
62 return le16_to_cpu(fe->id2.i_list.l_tree_depth) + 2; 68 return le16_to_cpu(root_el->l_tree_depth) + 2;
63} 69}
64 70
65void ocfs2_dinode_new_extent_list(struct inode *inode, struct ocfs2_dinode *di); 71void ocfs2_dinode_new_extent_list(struct inode *inode, struct ocfs2_dinode *di);
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index e2008dcec753..bbe3f8b2d0e2 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -1720,7 +1720,8 @@ int ocfs2_write_begin_nolock(struct address_space *mapping,
1720 goto out; 1720 goto out;
1721 } 1721 }
1722 1722
1723 credits = ocfs2_calc_extend_credits(inode->i_sb, di, 1723 credits = ocfs2_calc_extend_credits(inode->i_sb,
1724 &di->id2.i_list,
1724 clusters_to_alloc); 1725 clusters_to_alloc);
1725 1726
1726 } 1727 }
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c
index fda09c32a5f2..126aa219c0c1 100644
--- a/fs/ocfs2/dir.c
+++ b/fs/ocfs2/dir.c
@@ -1430,6 +1430,7 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb,
1430 int credits, num_free_extents, drop_alloc_sem = 0; 1430 int credits, num_free_extents, drop_alloc_sem = 0;
1431 loff_t dir_i_size; 1431 loff_t dir_i_size;
1432 struct ocfs2_dinode *fe = (struct ocfs2_dinode *) parent_fe_bh->b_data; 1432 struct ocfs2_dinode *fe = (struct ocfs2_dinode *) parent_fe_bh->b_data;
1433 struct ocfs2_extent_list *el = &fe->id2.i_list;
1433 struct ocfs2_alloc_context *data_ac = NULL; 1434 struct ocfs2_alloc_context *data_ac = NULL;
1434 struct ocfs2_alloc_context *meta_ac = NULL; 1435 struct ocfs2_alloc_context *meta_ac = NULL;
1435 handle_t *handle = NULL; 1436 handle_t *handle = NULL;
@@ -1488,7 +1489,7 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb,
1488 } 1489 }
1489 1490
1490 if (!num_free_extents) { 1491 if (!num_free_extents) {
1491 status = ocfs2_reserve_new_metadata(osb, fe, &meta_ac); 1492 status = ocfs2_reserve_new_metadata(osb, el, &meta_ac);
1492 if (status < 0) { 1493 if (status < 0) {
1493 if (status != -ENOSPC) 1494 if (status != -ENOSPC)
1494 mlog_errno(status); 1495 mlog_errno(status);
@@ -1503,7 +1504,7 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb,
1503 goto bail; 1504 goto bail;
1504 } 1505 }
1505 1506
1506 credits = ocfs2_calc_extend_credits(sb, fe, 1); 1507 credits = ocfs2_calc_extend_credits(sb, el, 1);
1507 } else { 1508 } else {
1508 spin_unlock(&OCFS2_I(dir)->ip_lock); 1509 spin_unlock(&OCFS2_I(dir)->ip_lock);
1509 credits = OCFS2_SIMPLE_DIR_EXTEND_CREDITS; 1510 credits = OCFS2_SIMPLE_DIR_EXTEND_CREDITS;
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index b6c483dfe615..a31bba6c5575 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -540,7 +540,7 @@ int ocfs2_do_extend_allocation(struct ocfs2_super *osb,
540 goto leave; 540 goto leave;
541 } else if ((!free_extents) 541 } else if ((!free_extents)
542 && (ocfs2_alloc_context_bits_left(meta_ac) 542 && (ocfs2_alloc_context_bits_left(meta_ac)
543 < ocfs2_extend_meta_needed(fe))) { 543 < ocfs2_extend_meta_needed(&fe->id2.i_list))) {
544 mlog(0, "filesystem is really fragmented...\n"); 544 mlog(0, "filesystem is really fragmented...\n");
545 status = -EAGAIN; 545 status = -EAGAIN;
546 reason = RESTART_META; 546 reason = RESTART_META;
@@ -652,7 +652,7 @@ int ocfs2_lock_allocators(struct inode *inode, struct buffer_head *di_bh,
652 */ 652 */
653 if (!num_free_extents || 653 if (!num_free_extents ||
654 (ocfs2_sparse_alloc(osb) && num_free_extents < max_recs_needed)) { 654 (ocfs2_sparse_alloc(osb) && num_free_extents < max_recs_needed)) {
655 ret = ocfs2_reserve_new_metadata(osb, di, meta_ac); 655 ret = ocfs2_reserve_new_metadata(osb, &di->id2.i_list, meta_ac);
656 if (ret < 0) { 656 if (ret < 0) {
657 if (ret != -ENOSPC) 657 if (ret != -ENOSPC)
658 mlog_errno(ret); 658 mlog_errno(ret);
@@ -732,7 +732,8 @@ restart_all:
732 goto leave; 732 goto leave;
733 } 733 }
734 734
735 credits = ocfs2_calc_extend_credits(osb->sb, fe, clusters_to_add); 735 credits = ocfs2_calc_extend_credits(osb->sb, &fe->id2.i_list,
736 clusters_to_add);
736 handle = ocfs2_start_trans(osb, credits); 737 handle = ocfs2_start_trans(osb, credits);
737 if (IS_ERR(handle)) { 738 if (IS_ERR(handle)) {
738 status = PTR_ERR(handle); 739 status = PTR_ERR(handle);
@@ -790,7 +791,7 @@ restarted_transaction:
790 mlog(0, "restarting transaction.\n"); 791 mlog(0, "restarting transaction.\n");
791 /* TODO: This can be more intelligent. */ 792 /* TODO: This can be more intelligent. */
792 credits = ocfs2_calc_extend_credits(osb->sb, 793 credits = ocfs2_calc_extend_credits(osb->sb,
793 fe, 794 &fe->id2.i_list,
794 clusters_to_add); 795 clusters_to_add);
795 status = ocfs2_extend_trans(handle, credits); 796 status = ocfs2_extend_trans(handle, credits);
796 if (status < 0) { 797 if (status < 0) {
diff --git a/fs/ocfs2/journal.h b/fs/ocfs2/journal.h
index 2178ebffa05f..9485f8037d9b 100644
--- a/fs/ocfs2/journal.h
+++ b/fs/ocfs2/journal.h
@@ -340,11 +340,16 @@ int ocfs2_journal_dirty_data(handle_t *handle,
340#define OCFS2_RENAME_CREDITS (3 * OCFS2_INODE_UPDATE_CREDITS + 3 \ 340#define OCFS2_RENAME_CREDITS (3 * OCFS2_INODE_UPDATE_CREDITS + 3 \
341 + OCFS2_UNLINK_CREDITS) 341 + OCFS2_UNLINK_CREDITS)
342 342
343/*
344 * Please note that the caller must make sure that root_el is the root
345 * of extent tree. So for an inode, it should be &fe->id2.i_list. Otherwise
346 * the result may be wrong.
347 */
343static inline int ocfs2_calc_extend_credits(struct super_block *sb, 348static inline int ocfs2_calc_extend_credits(struct super_block *sb,
344 struct ocfs2_dinode *fe, 349 struct ocfs2_extent_list *root_el,
345 u32 bits_wanted) 350 u32 bits_wanted)
346{ 351{
347 int bitmap_blocks, sysfile_bitmap_blocks, dinode_blocks; 352 int bitmap_blocks, sysfile_bitmap_blocks, extent_blocks;
348 353
349 /* bitmap dinode, group desc. + relinked group. */ 354 /* bitmap dinode, group desc. + relinked group. */
350 bitmap_blocks = OCFS2_SUBALLOC_ALLOC; 355 bitmap_blocks = OCFS2_SUBALLOC_ALLOC;
@@ -355,16 +360,16 @@ static inline int ocfs2_calc_extend_credits(struct super_block *sb,
355 * however many metadata chunks needed * a remaining suballoc 360 * however many metadata chunks needed * a remaining suballoc
356 * alloc. */ 361 * alloc. */
357 sysfile_bitmap_blocks = 1 + 362 sysfile_bitmap_blocks = 1 +
358 (OCFS2_SUBALLOC_ALLOC - 1) * ocfs2_extend_meta_needed(fe); 363 (OCFS2_SUBALLOC_ALLOC - 1) * ocfs2_extend_meta_needed(root_el);
359 364
360 /* this does not include *new* metadata blocks, which are 365 /* this does not include *new* metadata blocks, which are
361 * accounted for in sysfile_bitmap_blocks. fe + 366 * accounted for in sysfile_bitmap_blocks. root_el +
362 * prev. last_eb_blk + blocks along edge of tree. 367 * prev. last_eb_blk + blocks along edge of tree.
363 * calc_symlink_credits passes because we just need 1 368 * calc_symlink_credits passes because we just need 1
364 * credit for the dinode there. */ 369 * credit for the dinode there. */
365 dinode_blocks = 1 + 1 + le16_to_cpu(fe->id2.i_list.l_tree_depth); 370 extent_blocks = 1 + 1 + le16_to_cpu(root_el->l_tree_depth);
366 371
367 return bitmap_blocks + sysfile_bitmap_blocks + dinode_blocks; 372 return bitmap_blocks + sysfile_bitmap_blocks + extent_blocks;
368} 373}
369 374
370static inline int ocfs2_calc_symlink_credits(struct super_block *sb) 375static inline int ocfs2_calc_symlink_credits(struct super_block *sb)
diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c
index de7b93d76d12..2a817bca1ddb 100644
--- a/fs/ocfs2/suballoc.c
+++ b/fs/ocfs2/suballoc.c
@@ -494,7 +494,7 @@ bail:
494} 494}
495 495
496int ocfs2_reserve_new_metadata(struct ocfs2_super *osb, 496int ocfs2_reserve_new_metadata(struct ocfs2_super *osb,
497 struct ocfs2_dinode *fe, 497 struct ocfs2_extent_list *root_el,
498 struct ocfs2_alloc_context **ac) 498 struct ocfs2_alloc_context **ac)
499{ 499{
500 int status; 500 int status;
@@ -507,7 +507,7 @@ int ocfs2_reserve_new_metadata(struct ocfs2_super *osb,
507 goto bail; 507 goto bail;
508 } 508 }
509 509
510 (*ac)->ac_bits_wanted = ocfs2_extend_meta_needed(fe); 510 (*ac)->ac_bits_wanted = ocfs2_extend_meta_needed(root_el);
511 (*ac)->ac_which = OCFS2_AC_USE_META; 511 (*ac)->ac_which = OCFS2_AC_USE_META;
512 slot = osb->slot_num; 512 slot = osb->slot_num;
513 (*ac)->ac_group_search = ocfs2_block_group_search; 513 (*ac)->ac_group_search = ocfs2_block_group_search;
diff --git a/fs/ocfs2/suballoc.h b/fs/ocfs2/suballoc.h
index 40d51daf5fbc..3f96c875bcf7 100644
--- a/fs/ocfs2/suballoc.h
+++ b/fs/ocfs2/suballoc.h
@@ -59,8 +59,13 @@ static inline int ocfs2_alloc_context_bits_left(struct ocfs2_alloc_context *ac)
59 return ac->ac_bits_wanted - ac->ac_bits_given; 59 return ac->ac_bits_wanted - ac->ac_bits_given;
60} 60}
61 61
62/*
63 * Please note that the caller must make sure that root_el is the root
64 * of extent tree. So for an inode, it should be &fe->id2.i_list. Otherwise
65 * the result may be wrong.
66 */
62int ocfs2_reserve_new_metadata(struct ocfs2_super *osb, 67int ocfs2_reserve_new_metadata(struct ocfs2_super *osb,
63 struct ocfs2_dinode *fe, 68 struct ocfs2_extent_list *root_el,
64 struct ocfs2_alloc_context **ac); 69 struct ocfs2_alloc_context **ac);
65int ocfs2_reserve_new_inode(struct ocfs2_super *osb, 70int ocfs2_reserve_new_inode(struct ocfs2_super *osb,
66 struct ocfs2_alloc_context **ac); 71 struct ocfs2_alloc_context **ac);