aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Mahoney <jeffm@suse.com>2014-04-23 10:00:52 -0400
committerJan Kara <jack@suse.cz>2014-05-07 13:01:02 -0400
commit9d496552b95e957b919f9934672ea1af6c0f3c6d (patch)
tree973a128da3b45360c965744bf9035f9a961989fd
parent65ab18cb735e828199ce331c6eda7fb0904048e1 (diff)
reiserfs: balance_leaf refactor, pull out balance_leaf_new_nodes_paste
This patch factors out a new balance_leaf_new_nodes_insert from the code in balance_leaf responsible for pasting new content into existing items that may have been shifted into new nodes in the tree. It has not been reformatted yet. Signed-off-by: Jeff Mahoney <jeffm@suse.com> Signed-off-by: Jan Kara <jack@suse.cz>
-rw-r--r--fs/reiserfs/do_balan.c306
1 files changed, 160 insertions, 146 deletions
diff --git a/fs/reiserfs/do_balan.c b/fs/reiserfs/do_balan.c
index c2c5ba77cfe0..db189cbfdaba 100644
--- a/fs/reiserfs/do_balan.c
+++ b/fs/reiserfs/do_balan.c
@@ -804,6 +804,164 @@ static void balance_leaf_new_nodes_insert(struct tree_balance *tb,
804 } 804 }
805} 805}
806 806
807static void balance_leaf_new_nodes_paste(struct tree_balance *tb,
808 struct item_head *ih,
809 const char *body,
810 struct item_head *insert_key,
811 struct buffer_head **insert_ptr,
812 int i)
813{
814 struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
815 int n = B_NR_ITEMS(tbS0);
816 struct buffer_info bi;
817 if (n - tb->snum[i] <= tb->item_pos) { /* pasted item or part if it falls to S_new[i] */
818 if (tb->item_pos == n - tb->snum[i] && tb->sbytes[i] != -1) { /* we must shift part of the appended item */
819 struct item_head *aux_ih;
820
821 RFALSE(ih, "PAP-12210: ih must be 0");
822
823 aux_ih = item_head(tbS0, tb->item_pos);
824 if (is_direntry_le_ih(aux_ih)) {
825 /* we append to directory item */
826
827 int entry_count;
828
829 entry_count = ih_entry_count(aux_ih);
830
831 if (entry_count - tb->sbytes[i] < tb->pos_in_item && tb->pos_in_item <= entry_count) {
832 /* new directory entry falls into S_new[i] */
833
834 RFALSE(!tb->insert_size[0], "PAP-12215: insert_size is already 0");
835 RFALSE(tb->sbytes[i] - 1 >= entry_count,
836 "PAP-12220: there are no so much entries (%d), only %d",
837 tb->sbytes[i] - 1, entry_count);
838
839 /* Shift snum[i]-1 items in whole. Shift sbytes[i] directory entries from directory item number snum[i] */
840 leaf_move_items(LEAF_FROM_S_TO_SNEW, tb, tb->snum[i], tb->sbytes[i] - 1, tb->S_new[i]);
841 /* Paste given directory entry to directory item */
842 buffer_info_init_bh(tb, &bi, tb->S_new[i]);
843 leaf_paste_in_buffer(&bi, 0, tb->pos_in_item - entry_count + tb->sbytes[i] - 1,
844 tb->insert_size[0], body, tb->zeroes_num);
845 /* paste new directory entry */
846 leaf_paste_entries(&bi, 0, tb->pos_in_item - entry_count + tb->sbytes[i] - 1, 1,
847 (struct reiserfs_de_head *) body,
848 body + DEH_SIZE, tb->insert_size[0]);
849 tb->insert_size[0] = 0;
850 tb->pos_in_item++;
851 } else { /* new directory entry doesn't fall into S_new[i] */
852 leaf_move_items(LEAF_FROM_S_TO_SNEW, tb, tb->snum[i], tb->sbytes[i], tb->S_new[i]);
853 }
854 } else { /* regular object */
855
856 int n_shift, n_rem, r_zeroes_number;
857 const char *r_body;
858
859 RFALSE(tb->pos_in_item != ih_item_len(item_head(tbS0, tb->item_pos)) || tb->insert_size[0] <= 0,
860 "PAP-12225: item too short or insert_size <= 0");
861
862 /* Calculate number of bytes which must be shifted from appended item */
863 n_shift = tb->sbytes[i] - tb->insert_size[0];
864 if (n_shift < 0)
865 n_shift = 0;
866 leaf_move_items(LEAF_FROM_S_TO_SNEW, tb, tb->snum[i], n_shift, tb->S_new[i]);
867
868 /* Calculate number of bytes which must remain in body after append to S_new[i] */
869 n_rem = tb->insert_size[0] - tb->sbytes[i];
870 if (n_rem < 0)
871 n_rem = 0;
872 /* Append part of body into S_new[0] */
873 buffer_info_init_bh(tb, &bi, tb->S_new[i]);
874 if (n_rem > tb->zeroes_num) {
875 r_zeroes_number = 0;
876 r_body = body + n_rem - tb->zeroes_num;
877 } else {
878 r_body = body;
879 r_zeroes_number = tb->zeroes_num - n_rem;
880 tb->zeroes_num -= r_zeroes_number;
881 }
882
883 leaf_paste_in_buffer(&bi, 0, n_shift,
884 tb->insert_size[0] - n_rem,
885 r_body, r_zeroes_number);
886 {
887 struct item_head *tmp;
888
889 tmp = item_head(tb->S_new[i], 0);
890 if (is_indirect_le_ih
891 (tmp)) {
892 set_ih_free_space(tmp, 0);
893 set_le_ih_k_offset(tmp, le_ih_k_offset(tmp) + (n_rem << (tb->tb_sb->s_blocksize_bits - UNFM_P_SHIFT)));
894 } else {
895 set_le_ih_k_offset(tmp, le_ih_k_offset(tmp) + n_rem);
896 }
897 }
898
899 tb->insert_size[0] = n_rem;
900 if (!n_rem)
901 tb->pos_in_item++;
902 }
903 } else
904 /* item falls wholly into S_new[i] */
905 {
906 int leaf_mi;
907 struct item_head *pasted;
908
909#ifdef CONFIG_REISERFS_CHECK
910 struct item_head *ih_check = item_head(tbS0, tb->item_pos);
911
912 if (!is_direntry_le_ih(ih_check)
913 && (tb->pos_in_item != ih_item_len(ih_check)
914 || tb->insert_size[0] <= 0))
915 reiserfs_panic(tb->tb_sb,
916 "PAP-12235",
917 "pos_in_item "
918 "must be equal "
919 "to ih_item_len");
920#endif /* CONFIG_REISERFS_CHECK */
921
922 leaf_mi = leaf_move_items(LEAF_FROM_S_TO_SNEW,
923 tb, tb->snum[i],
924 tb->sbytes[i],
925 tb->S_new[i]);
926
927 RFALSE(leaf_mi,
928 "PAP-12240: unexpected value returned by leaf_move_items (%d)",
929 leaf_mi);
930
931 /* paste into item */
932 buffer_info_init_bh(tb, &bi, tb->S_new[i]);
933 leaf_paste_in_buffer(&bi,
934 tb->item_pos - n + tb->snum[i],
935 tb->pos_in_item,
936 tb->insert_size[0],
937 body, tb->zeroes_num);
938
939 pasted = item_head(tb->S_new[i], tb->item_pos - n + tb->snum[i]);
940 if (is_direntry_le_ih(pasted)) {
941 leaf_paste_entries(&bi,
942 tb->item_pos - n + tb->snum[i],
943 tb->pos_in_item, 1,
944 (struct reiserfs_de_head *)body,
945 body + DEH_SIZE,
946 tb->insert_size[0]
947 );
948 }
949
950 /* if we paste to indirect item update ih_free_space */
951 if (is_indirect_le_ih(pasted))
952 set_ih_free_space(pasted, 0);
953 tb->zeroes_num = tb->insert_size[0] = 0;
954 }
955 }
956
957 else { /* pasted item doesn't fall into S_new[i] */
958
959 leaf_move_items(LEAF_FROM_S_TO_SNEW, tb,
960 tb->snum[i], tb->sbytes[i], tb->S_new[i]);
961 }
962
963}
964
807/** 965/**
808 * balance_leaf - reiserfs tree balancing algorithm 966 * balance_leaf - reiserfs tree balancing algorithm
809 * @tb: tree balance state 967 * @tb: tree balance state
@@ -953,152 +1111,8 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih,
953 break; 1111 break;
954 1112
955 case M_PASTE: /* append item */ 1113 case M_PASTE: /* append item */
956 1114 balance_leaf_new_nodes_paste(tb, ih, body, insert_key,
957 if (n - tb->snum[i] <= tb->item_pos) { /* pasted item or part if it falls to S_new[i] */ 1115 insert_ptr, i);
958 if (tb->item_pos == n - tb->snum[i] && tb->sbytes[i] != -1) { /* we must shift part of the appended item */
959 struct item_head *aux_ih;
960
961 RFALSE(ih, "PAP-12210: ih must be 0");
962
963 aux_ih = item_head(tbS0, tb->item_pos);
964 if (is_direntry_le_ih(aux_ih)) {
965 /* we append to directory item */
966
967 int entry_count;
968
969 entry_count = ih_entry_count(aux_ih);
970
971 if (entry_count - tb->sbytes[i] < tb->pos_in_item && tb->pos_in_item <= entry_count) {
972 /* new directory entry falls into S_new[i] */
973
974 RFALSE(!tb->insert_size[0], "PAP-12215: insert_size is already 0");
975 RFALSE(tb->sbytes[i] - 1 >= entry_count,
976 "PAP-12220: there are no so much entries (%d), only %d",
977 tb->sbytes[i] - 1, entry_count);
978
979 /* Shift snum[i]-1 items in whole. Shift sbytes[i] directory entries from directory item number snum[i] */
980 leaf_move_items(LEAF_FROM_S_TO_SNEW, tb, tb->snum[i], tb->sbytes[i] - 1, tb->S_new[i]);
981 /* Paste given directory entry to directory item */
982 buffer_info_init_bh(tb, &bi, tb->S_new[i]);
983 leaf_paste_in_buffer(&bi, 0, tb->pos_in_item - entry_count + tb->sbytes[i] - 1,
984 tb->insert_size[0], body, tb->zeroes_num);
985 /* paste new directory entry */
986 leaf_paste_entries(&bi, 0, tb->pos_in_item - entry_count + tb->sbytes[i] - 1, 1,
987 (struct reiserfs_de_head *) body,
988 body + DEH_SIZE, tb->insert_size[0]);
989 tb->insert_size[0] = 0;
990 tb->pos_in_item++;
991 } else { /* new directory entry doesn't fall into S_new[i] */
992 leaf_move_items(LEAF_FROM_S_TO_SNEW, tb, tb->snum[i], tb->sbytes[i], tb->S_new[i]);
993 }
994 } else { /* regular object */
995
996 int n_shift, n_rem, r_zeroes_number;
997 const char *r_body;
998
999 RFALSE(tb->pos_in_item != ih_item_len(item_head(tbS0, tb->item_pos)) || tb->insert_size[0] <= 0,
1000 "PAP-12225: item too short or insert_size <= 0");
1001
1002 /* Calculate number of bytes which must be shifted from appended item */
1003 n_shift = tb->sbytes[i] - tb->insert_size[0];
1004 if (n_shift < 0)
1005 n_shift = 0;
1006 leaf_move_items(LEAF_FROM_S_TO_SNEW, tb, tb->snum[i], n_shift, tb->S_new[i]);
1007
1008 /* Calculate number of bytes which must remain in body after append to S_new[i] */
1009 n_rem = tb->insert_size[0] - tb->sbytes[i];
1010 if (n_rem < 0)
1011 n_rem = 0;
1012 /* Append part of body into S_new[0] */
1013 buffer_info_init_bh(tb, &bi, tb->S_new[i]);
1014 if (n_rem > tb->zeroes_num) {
1015 r_zeroes_number = 0;
1016 r_body = body + n_rem - tb->zeroes_num;
1017 } else {
1018 r_body = body;
1019 r_zeroes_number = tb->zeroes_num - n_rem;
1020 tb->zeroes_num -= r_zeroes_number;
1021 }
1022
1023 leaf_paste_in_buffer(&bi, 0, n_shift,
1024 tb->insert_size[0] - n_rem,
1025 r_body, r_zeroes_number);
1026 {
1027 struct item_head *tmp;
1028
1029 tmp = item_head(tb->S_new[i], 0);
1030 if (is_indirect_le_ih
1031 (tmp)) {
1032 set_ih_free_space(tmp, 0);
1033 set_le_ih_k_offset(tmp, le_ih_k_offset(tmp) + (n_rem << (tb->tb_sb->s_blocksize_bits - UNFM_P_SHIFT)));
1034 } else {
1035 set_le_ih_k_offset(tmp, le_ih_k_offset(tmp) + n_rem);
1036 }
1037 }
1038
1039 tb->insert_size[0] = n_rem;
1040 if (!n_rem)
1041 tb->pos_in_item++;
1042 }
1043 } else
1044 /* item falls wholly into S_new[i] */
1045 {
1046 int leaf_mi;
1047 struct item_head *pasted;
1048
1049#ifdef CONFIG_REISERFS_CHECK
1050 struct item_head *ih_check = item_head(tbS0, tb->item_pos);
1051
1052 if (!is_direntry_le_ih(ih_check)
1053 && (tb->pos_in_item != ih_item_len(ih_check)
1054 || tb->insert_size[0] <= 0))
1055 reiserfs_panic(tb->tb_sb,
1056 "PAP-12235",
1057 "pos_in_item "
1058 "must be equal "
1059 "to ih_item_len");
1060#endif /* CONFIG_REISERFS_CHECK */
1061
1062 leaf_mi = leaf_move_items(LEAF_FROM_S_TO_SNEW,
1063 tb, tb->snum[i],
1064 tb->sbytes[i],
1065 tb->S_new[i]);
1066
1067 RFALSE(leaf_mi,
1068 "PAP-12240: unexpected value returned by leaf_move_items (%d)",
1069 leaf_mi);
1070
1071 /* paste into item */
1072 buffer_info_init_bh(tb, &bi, tb->S_new[i]);
1073 leaf_paste_in_buffer(&bi,
1074 tb->item_pos - n + tb->snum[i],
1075 tb->pos_in_item,
1076 tb->insert_size[0],
1077 body, tb->zeroes_num);
1078
1079 pasted = item_head(tb->S_new[i], tb->item_pos - n + tb->snum[i]);
1080 if (is_direntry_le_ih(pasted)) {
1081 leaf_paste_entries(&bi,
1082 tb->item_pos - n + tb->snum[i],
1083 tb->pos_in_item, 1,
1084 (struct reiserfs_de_head *)body,
1085 body + DEH_SIZE,
1086 tb->insert_size[0]
1087 );
1088 }
1089
1090 /* if we paste to indirect item update ih_free_space */
1091 if (is_indirect_le_ih(pasted))
1092 set_ih_free_space(pasted, 0);
1093 tb->zeroes_num = tb->insert_size[0] = 0;
1094 }
1095 }
1096
1097 else { /* pasted item doesn't fall into S_new[i] */
1098
1099 leaf_move_items(LEAF_FROM_S_TO_SNEW, tb,
1100 tb->snum[i], tb->sbytes[i], tb->S_new[i]);
1101 }
1102 break; 1116 break;
1103 default: /* cases d and t */ 1117 default: /* cases d and t */
1104 reiserfs_panic(tb->tb_sb, "PAP-12245", 1118 reiserfs_panic(tb->tb_sb, "PAP-12245",