aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/alloc.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-06-16 15:11:57 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-16 15:11:57 -0400
commit300df7dc89cc276377fc020704e34875d5c473b6 (patch)
tree6b280000815b0562255cecf3da1a8c9597bce702 /fs/ocfs2/alloc.c
parent661adc423d70203a56723701aaf255e16950dfdb (diff)
parent9af0b38ff3f4f79c62dd909405b113bf7c1a23aa (diff)
Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jlbec/ocfs2
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jlbec/ocfs2: ocfs2/net: Use wait_event() in o2net_send_message_vec() ocfs2: Adjust rightmost path in ocfs2_add_branch. ocfs2: fdatasync should skip unimportant metadata writeout ocfs2: Remove redundant gotos in ocfs2_mount_volume() ocfs2: Add statistics for the checksum and ecc operations. ocfs2 patch to track delayed orphan scan timer statistics ocfs2: timer to queue scan of all orphan slots ocfs2: Correct ordering of ip_alloc_sem and localloc locks for directories ocfs2: Fix possible deadlock in quota recovery ocfs2: Fix possible deadlock with quotas in ocfs2_setattr() ocfs2: Fix lock inversion in ocfs2_local_read_info() ocfs2: Fix possible deadlock in ocfs2_global_read_dquot() ocfs2: update comments in masklog.h ocfs2: Don't printk the error when listing too many xattrs.
Diffstat (limited to 'fs/ocfs2/alloc.c')
-rw-r--r--fs/ocfs2/alloc.c80
1 files changed, 76 insertions, 4 deletions
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
index 678a067d9251..9edcde4974aa 100644
--- a/fs/ocfs2/alloc.c
+++ b/fs/ocfs2/alloc.c
@@ -475,6 +475,12 @@ struct ocfs2_path {
475#define path_leaf_el(_path) ((_path)->p_node[(_path)->p_tree_depth].el) 475#define path_leaf_el(_path) ((_path)->p_node[(_path)->p_tree_depth].el)
476#define path_num_items(_path) ((_path)->p_tree_depth + 1) 476#define path_num_items(_path) ((_path)->p_tree_depth + 1)
477 477
478static int ocfs2_find_path(struct inode *inode, struct ocfs2_path *path,
479 u32 cpos);
480static void ocfs2_adjust_rightmost_records(struct inode *inode,
481 handle_t *handle,
482 struct ocfs2_path *path,
483 struct ocfs2_extent_rec *insert_rec);
478/* 484/*
479 * Reset the actual path elements so that we can re-use the structure 485 * Reset the actual path elements so that we can re-use the structure
480 * to build another path. Generally, this involves freeing the buffer 486 * to build another path. Generally, this involves freeing the buffer
@@ -1013,6 +1019,54 @@ static inline u32 ocfs2_sum_rightmost_rec(struct ocfs2_extent_list *el)
1013} 1019}
1014 1020
1015/* 1021/*
1022 * Change range of the branches in the right most path according to the leaf
1023 * extent block's rightmost record.
1024 */
1025static int ocfs2_adjust_rightmost_branch(handle_t *handle,
1026 struct inode *inode,
1027 struct ocfs2_extent_tree *et)
1028{
1029 int status;
1030 struct ocfs2_path *path = NULL;
1031 struct ocfs2_extent_list *el;
1032 struct ocfs2_extent_rec *rec;
1033
1034 path = ocfs2_new_path_from_et(et);
1035 if (!path) {
1036 status = -ENOMEM;
1037 return status;
1038 }
1039
1040 status = ocfs2_find_path(inode, path, UINT_MAX);
1041 if (status < 0) {
1042 mlog_errno(status);
1043 goto out;
1044 }
1045
1046 status = ocfs2_extend_trans(handle, path_num_items(path) +
1047 handle->h_buffer_credits);
1048 if (status < 0) {
1049 mlog_errno(status);
1050 goto out;
1051 }
1052
1053 status = ocfs2_journal_access_path(inode, handle, path);
1054 if (status < 0) {
1055 mlog_errno(status);
1056 goto out;
1057 }
1058
1059 el = path_leaf_el(path);
1060 rec = &el->l_recs[le32_to_cpu(el->l_next_free_rec) - 1];
1061
1062 ocfs2_adjust_rightmost_records(inode, handle, path, rec);
1063
1064out:
1065 ocfs2_free_path(path);
1066 return status;
1067}
1068
1069/*
1016 * Add an entire tree branch to our inode. eb_bh is the extent block 1070 * Add an entire tree branch to our inode. eb_bh is the extent block
1017 * to start at, if we don't want to start the branch at the dinode 1071 * to start at, if we don't want to start the branch at the dinode
1018 * structure. 1072 * structure.
@@ -1038,7 +1092,7 @@ static int ocfs2_add_branch(struct ocfs2_super *osb,
1038 struct ocfs2_extent_block *eb; 1092 struct ocfs2_extent_block *eb;
1039 struct ocfs2_extent_list *eb_el; 1093 struct ocfs2_extent_list *eb_el;
1040 struct ocfs2_extent_list *el; 1094 struct ocfs2_extent_list *el;
1041 u32 new_cpos; 1095 u32 new_cpos, root_end;
1042 1096
1043 mlog_entry_void(); 1097 mlog_entry_void();
1044 1098
@@ -1055,6 +1109,27 @@ static int ocfs2_add_branch(struct ocfs2_super *osb,
1055 1109
1056 new_blocks = le16_to_cpu(el->l_tree_depth); 1110 new_blocks = le16_to_cpu(el->l_tree_depth);
1057 1111
1112 eb = (struct ocfs2_extent_block *)(*last_eb_bh)->b_data;
1113 new_cpos = ocfs2_sum_rightmost_rec(&eb->h_list);
1114 root_end = ocfs2_sum_rightmost_rec(et->et_root_el);
1115
1116 /*
1117 * If there is a gap before the root end and the real end
1118 * of the righmost leaf block, we need to remove the gap
1119 * between new_cpos and root_end first so that the tree
1120 * is consistent after we add a new branch(it will start
1121 * from new_cpos).
1122 */
1123 if (root_end > new_cpos) {
1124 mlog(0, "adjust the cluster end from %u to %u\n",
1125 root_end, new_cpos);
1126 status = ocfs2_adjust_rightmost_branch(handle, inode, et);
1127 if (status) {
1128 mlog_errno(status);
1129 goto bail;
1130 }
1131 }
1132
1058 /* allocate the number of new eb blocks we need */ 1133 /* allocate the number of new eb blocks we need */
1059 new_eb_bhs = kcalloc(new_blocks, sizeof(struct buffer_head *), 1134 new_eb_bhs = kcalloc(new_blocks, sizeof(struct buffer_head *),
1060 GFP_KERNEL); 1135 GFP_KERNEL);
@@ -1071,9 +1146,6 @@ static int ocfs2_add_branch(struct ocfs2_super *osb,
1071 goto bail; 1146 goto bail;
1072 } 1147 }
1073 1148
1074 eb = (struct ocfs2_extent_block *)(*last_eb_bh)->b_data;
1075 new_cpos = ocfs2_sum_rightmost_rec(&eb->h_list);
1076
1077 /* Note: new_eb_bhs[new_blocks - 1] is the guy which will be 1149 /* Note: new_eb_bhs[new_blocks - 1] is the guy which will be
1078 * linked with the rest of the tree. 1150 * linked with the rest of the tree.
1079 * conversly, new_eb_bhs[0] is the new bottommost leaf. 1151 * conversly, new_eb_bhs[0] is the new bottommost leaf.