diff options
author | Jeff Mahoney <jeffm@suse.com> | 2014-04-23 10:00:52 -0400 |
---|---|---|
committer | Jan Kara <jack@suse.cz> | 2014-05-07 13:01:02 -0400 |
commit | 9d496552b95e957b919f9934672ea1af6c0f3c6d (patch) | |
tree | 973a128da3b45360c965744bf9035f9a961989fd | |
parent | 65ab18cb735e828199ce331c6eda7fb0904048e1 (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.c | 306 |
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 | ||
807 | static 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", |