5 #include <asm/uaccess.h>
6 #include <linux/string.h>
7 #include <linux/time.h>
24 static void leaf_copy_dir_entries(
struct buffer_info *dest_bi,
25 struct buffer_head *
source,
int last_first,
26 int item_num,
int from,
int copy_count)
28 struct buffer_head *
dest = dest_bi->
bi_bh;
40 RFALSE(!is_direntry_le_ih(ih),
"vs-10000: item must be directory item");
45 copy_records_len = (from ?
deh_location(&(deh[from - 1])) :
47 deh_location(&(deh[from + copy_count - 1]));
63 if ((item_num_in_dest == -1) ||
78 DEH_SIZE * copy_count + copy_records_len);
84 set_le_ih_k_offset(&new_ih,
89 set_le_ih_k_offset(&new_ih,
U32_MAX);
107 DEH_SIZE * copy_count + copy_records_len,
118 : 0, copy_count, deh + from, records,
119 DEH_SIZE * copy_count + copy_records_len);
126 static int leaf_copy_boundary_item(
struct buffer_info *dest_bi,
127 struct buffer_head *
src,
int last_first,
128 int bytes_or_entries)
130 struct buffer_head *dest = dest_bi->
bi_bh;
131 int dest_nr_item, src_nr_item;
149 "vs-10010: item can not have empty length");
151 if (is_direntry_le_ih(ih)) {
152 if (bytes_or_entries == -1)
163 if (bytes_or_entries == -1)
166 #ifdef CONFIG_REISERFS_CHECK
169 && is_indirect_le_ih(ih))
173 "last unformatted node "
175 "entirely (%h)", ih);
183 bytes_or_entries,
B_I_PITEM(src, ih), 0);
185 if (is_indirect_le_ih(dih)) {
187 "vs-10030: merge to left: last unformatted node of non-last indirect item %h must have zerto free space",
208 if (is_direntry_le_ih(ih)) {
209 if (bytes_or_entries == -1)
226 "vs-10040: merge to right: last unformatted node of non-last indirect item must be filled entirely (%h)",
229 if (bytes_or_entries == -1) {
233 RFALSE(le_ih_k_offset(dih) !=
235 "vs-10050: items %h and %h do not match", ih, dih);
238 set_le_ih_k_offset(dih, le_ih_k_offset(ih));
242 set_le_ih_k_type(dih, le_ih_k_type(ih));
246 "vs-10060: no so much bytes %lu (needed %lu)",
248 (
unsigned long)bytes_or_entries);
251 if (is_direct_le_ih(dih)) {
252 RFALSE(le_ih_k_offset(dih) <=
253 (
unsigned long)bytes_or_entries,
254 "vs-10070: dih %h, bytes_or_entries(%d)", dih,
256 set_le_ih_k_offset(dih,
257 le_ih_k_offset(dih) -
260 RFALSE(le_ih_k_offset(dih) <=
262 "vs-10080: dih %h, bytes_or_entries(%d)",
265 set_le_ih_k_offset(dih,
266 le_ih_k_offset(dih) -
283 static void leaf_copy_items_entirely(
struct buffer_info *dest_bi,
284 struct buffer_head *src,
int last_first,
285 int first,
int cpy_num)
287 struct buffer_head *
dest;
290 int last_loc, last_inserted_loc,
location;
296 "vs-10090: bad last_first parameter %d", last_first);
298 "vs-10100: too few items in source %d, required %d from %d",
300 RFALSE(cpy_num < 0,
"vs-10110: can not copy negative amount of items");
301 RFALSE(!dest_bi,
"vs-10120: can not copy negative amount of items");
303 dest = dest_bi->
bi_bh;
305 RFALSE(!dest,
"vs-10130: can not copy negative amount of items");
321 "vs-10140: not enough free space for headers %d (needed %d)",
325 memmove(ih + cpy_num, ih, (nr - dest_before) * IH_SIZE);
330 free_space -= (IH_SIZE * cpy_num);
334 j = location = (dest_before == 0) ? dest->b_size :
ih_location(ih - 1);
335 for (i = dest_before; i < nr + cpy_num; i++) {
341 last_loc =
ih_location(&(ih[nr + cpy_num - 1 - dest_before]));
342 last_inserted_loc =
ih_location(&(ih[cpy_num - 1]));
345 RFALSE(free_space < j - last_inserted_loc,
346 "vs-10150: not enough free space for items %d (needed %d)",
347 free_space, j - last_inserted_loc);
349 memmove(dest->b_data + last_loc,
350 dest->b_data + last_loc + j - last_inserted_loc,
351 last_inserted_loc - last_loc);
354 memcpy(dest->b_data + last_inserted_loc,
355 B_N_PITEM(src, (first + cpy_num - 1)), j - last_inserted_loc);
367 "vs-10160: block number in bh does not match to field in disk_child structure %lu and %lu",
368 (
long unsigned)dest->b_blocknr,
371 dc_size(t_dc) + (j - last_inserted_loc +
381 static void leaf_item_bottle(
struct buffer_info *dest_bi,
382 struct buffer_head *src,
int last_first,
383 int item_num,
int cpy_bytes)
385 struct buffer_head *dest = dest_bi->
bi_bh;
389 "vs-10170: bytes == - 1 means: do not split item");
394 if (is_direntry_le_ih(ih))
396 item_num, 0, cpy_bytes);
404 memcpy(&n_ih, ih, IH_SIZE);
406 if (is_indirect_le_ih(ih)) {
409 "vs-10180: when whole indirect item is bottle to left neighbor, it must have free_space==0 (not %lu)",
415 "vs-10190: bad mergeability of item %h", ih);
423 if (is_direntry_le_ih(ih))
439 if (is_direct_le_ih(ih)) {
440 set_le_ih_k_offset(&n_ih,
448 "vs-10200: ih->ih_free_space must be 0 when indirect item will be appended");
449 set_le_ih_k_offset(&n_ih,
475 static int leaf_copy_items(
struct buffer_info *dest_bi,
struct buffer_head *src,
476 int last_first,
int cpy_num,
int cpy_bytes)
478 struct buffer_head *
dest;
481 dest = dest_bi->
bi_bh;
482 RFALSE(!dest || !src,
"vs-10210: !dest || !src");
484 "vs-10220:last_first != FIRST_TO_LAST && last_first != LAST_TO_FIRST");
486 "vs-10230: No enough items: %d, req. %d",
B_NR_ITEMS(src),
488 RFALSE(cpy_num < 0,
"vs-10240: cpy_num < 0 (%d)", cpy_num);
502 i = leaf_copy_boundary_item(dest_bi, src,
FIRST_TO_LAST, bytes);
518 cpy_num + pos - 1, cpy_bytes);
529 i = leaf_copy_boundary_item(dest_bi, src,
LAST_TO_FIRST, bytes);
535 pos = src_nr_item - cpy_num -
i;
536 if (cpy_bytes == -1) {
543 pos + 1, cpy_num - 1);
556 static void leaf_define_dest_src_infos(
int shift_mode,
struct tree_balance *
tb,
560 struct buffer_head *Snew)
566 switch (shift_mode) {
573 dest_bi->
bi_bh = tb->
L[0];
585 dest_bi->
bi_bh = tb->
R[0];
597 dest_bi->
bi_bh = tb->
L[0];
609 dest_bi->
bi_bh = tb->
R[0];
621 dest_bi->
bi_bh = Snew;
629 "shift type is unknown (%d)", shift_mode);
632 "vs-10260: mode==%d, source (%p) or dest (%p) buffer is initialized incorrectly",
639 int mov_bytes,
struct buffer_head *Snew)
645 leaf_define_dest_src_infos(shift_mode, tb, &dest_bi, &src_bi,
649 leaf_copy_items(&dest_bi, src_bi.
bi_bh, first_last, mov_num,
655 mov_num), mov_num, mov_bytes);
674 "vs-10270: S0 is empty now, but shift_bytes != -1 (%d)",
676 #ifdef CONFIG_REISERFS_CHECK
680 "balance condition corrupted "
693 RFALSE((shift_bytes != -1 &&
698 "vs-10280: item must be mergeable");
726 static void leaf_delete_items_entirely(
struct buffer_info *
bi,
727 int first,
int del_num);
736 int first,
int del_num,
int del_bytes)
738 struct buffer_head *bh;
741 RFALSE(!bh,
"10155: bh is not defined");
742 RFALSE(del_num < 0,
"10160: del_num can not be < 0. del_num==%d",
745 || first + del_num > item_amount,
746 "10165: invalid number of first item to be deleted (%d) or "
747 "no so much items (%d) to delete (only %d)", first,
748 first + del_num, item_amount);
753 if (first == 0 && del_num == item_amount && del_bytes == -1) {
761 leaf_delete_items_entirely(cur_bi, first, del_num);
765 leaf_delete_items_entirely(cur_bi, first, del_num - 1);
776 leaf_delete_items_entirely(cur_bi, first + 1,
780 if (is_direntry_le_ih(ih))
792 len - del_bytes, del_bytes);
800 const char *inserted_item_body,
int zeros_number)
802 struct buffer_head *bh = bi->
bi_bh;
807 int last_loc, unmoved_loc;
816 "vs-10170: not enough free space in block %z, new item %h",
817 bh, inserted_item_ih);
819 "vs-10172: zero number == %d, item length == %d",
826 last_loc = nr ?
ih_location(&(ih[nr - before - 1])) : bh->b_size;
827 unmoved_loc = before ?
ih_location(ih - 1) : bh->b_size;
830 bh->b_data + last_loc, unmoved_loc - last_loc);
832 to = bh->b_data + unmoved_loc -
ih_item_len(inserted_item_ih);
833 memset(to, 0, zeros_number);
837 if (inserted_item_body)
838 memmove(to, inserted_item_body,
844 memmove(ih + 1, ih, IH_SIZE * (nr - before));
845 memmove(ih, inserted_item_ih, IH_SIZE);
848 for (i = before; i < nr + 1; i++) {
856 free_space - (IH_SIZE +
874 const char *
body,
int zeros_number)
876 struct buffer_head *bh = bi->
bi_bh;
881 int last_loc, unmoved_loc;
888 RFALSE(free_space < paste_size,
889 "vs-10175: not enough free space: needed %d, available %d",
890 paste_size, free_space);
892 #ifdef CONFIG_REISERFS_CHECK
893 if (zeros_number > paste_size) {
899 "zeros_number == %d, paste_size == %d",
900 zeros_number, paste_size);
907 last_loc =
ih_location(&(ih[nr - affected_item_num - 1]));
908 unmoved_loc = affected_item_num ?
ih_location(ih - 1) : bh->b_size;
911 memmove(bh->b_data + last_loc - paste_size, bh->b_data + last_loc,
912 unmoved_loc - last_loc);
915 for (i = affected_item_num; i <
nr; i++)
921 if (!is_direntry_le_ih(ih)) {
924 memmove(bh->b_data + ih_location(ih) +
926 bh->b_data + ih_location(ih),
929 memset(bh->b_data + ih_location(ih), 0,
931 memcpy(bh->b_data + ih_location(ih) +
933 paste_size - zeros_number);
935 memset(bh->b_data + unmoved_loc - paste_size, 0,
937 memcpy(bh->b_data + unmoved_loc - paste_size +
939 paste_size - zeros_number);
943 memset(bh->b_data + unmoved_loc - paste_size,
'\0', paste_size);
964 static int leaf_cut_entries(
struct buffer_head *bh,
965 struct item_head *ih,
int from,
int del_count)
969 int prev_record_offset;
976 RFALSE(!is_direntry_le_ih(ih),
"10180: item is not directory item");
978 "10185: item contains not enough entries: entry_count = %d, from = %d, to delete = %d",
994 cut_records_len = prev_record_offset -
996 prev_record = item + prev_record_offset;
999 for (i =
I_ENTRY_COUNT(ih) - 1; i > from + del_count - 1; i--)
1004 for (i = 0; i <
from; i++)
1013 deh + from + del_count,
1014 prev_record - cut_records_len - (
char *)(deh + from +
1019 prev_record, item +
ih_item_len(ih) - prev_record);
1021 return DEH_SIZE * del_count + cut_records_len;
1036 struct buffer_head *bh = bi->
bi_bh;
1039 int last_loc, unmoved_loc;
1048 if (is_direntry_le_ih(ih)) {
1050 cut_size = leaf_cut_entries(bh, ih, pos_in_item, cut_size);
1051 if (pos_in_item == 0) {
1054 "when 0-th enrty of item is cut, that item must be first in the node, not %d-th",
1062 RFALSE(is_statdata_le_ih(ih),
"10195: item is stat data");
1064 "10200: invalid offset (%lu) or trunc_size (%lu) or ih_item_len (%lu)",
1065 (
long unsigned)pos_in_item, (
long unsigned)cut_size,
1069 if (pos_in_item == 0) {
1075 if (is_direct_le_ih(ih))
1076 set_le_ih_k_offset(ih,
1077 le_ih_k_offset(ih) +
1080 set_le_ih_k_offset(ih,
1081 le_ih_k_offset(ih) +
1086 "10205: invalid ih_free_space (%h)", ih);
1092 last_loc =
ih_location(&(ih[nr - cut_item_num - 1]));
1095 unmoved_loc = cut_item_num ?
ih_location(ih - 1) : bh->b_size;
1098 memmove(bh->b_data + last_loc + cut_size, bh->b_data + last_loc,
1099 unmoved_loc - last_loc - cut_size);
1104 if (is_indirect_le_ih(ih)) {
1110 for (i = cut_item_num; i <
nr; i++)
1128 static void leaf_delete_items_entirely(
struct buffer_info *
bi,
1129 int first,
int del_num)
1131 struct buffer_head *bh = bi->
bi_bh;
1134 int last_loc, last_removed_loc;
1139 RFALSE(del_num < 0,
"10215: del_num less than 0 (%d)", del_num);
1147 RFALSE(first < 0 || first + del_num > nr,
1148 "10220: first=%d, number=%d, there is %d items", first, del_num,
1151 if (first == 0 && del_num == nr) {
1162 j = (first == 0) ? bh->b_size :
ih_location(ih - 1);
1166 last_removed_loc =
ih_location(&(ih[del_num - 1]));
1168 memmove(bh->b_data + last_loc + j - last_removed_loc,
1169 bh->b_data + last_loc, last_removed_loc - last_loc);
1172 memmove(ih, ih + del_num, (nr - first - del_num) * IH_SIZE);
1175 for (i = first; i < nr - del_num; i++)
1184 IH_SIZE * del_num));
1192 dc_size(t_dc) - (j - last_removed_loc +
1193 IH_SIZE * del_num));
1202 int new_entry_count,
1204 const char *records,
int paste_size)
1210 int i, old_entry_num;
1211 struct buffer_head *bh = bi->
bi_bh;
1213 if (new_entry_count == 0)
1219 RFALSE(!is_direntry_le_ih(ih),
"10225: item is not directory item");
1221 "10230: there are no entry we paste entries before. entry_count = %d, before = %d",
1243 for (i = 0; i < before; i++)
1251 memmove(insert_point + paste_size, insert_point,
1252 item + (
ih_item_len(ih) - paste_size) - insert_point);
1256 paste_size -
DEH_SIZE * new_entry_count);
1260 memmove((
char *)(deh + new_entry_count), deh,
1261 insert_point - (
char *)deh);
1268 for (i = 0; i < new_entry_count; i++) {
1272 (&(new_dehs[new_entry_count - 1])) +
1273 insert_point +
DEH_SIZE * new_entry_count -
1279 set_le_ih_k_offset(ih,
deh_offset(new_dehs));
1283 #ifdef CONFIG_REISERFS_CHECK
1297 "directory item (%h) "
1298 "corrupted (prev %a, "
1300 ih, deh + i - 1, i, deh + i);
1303 "directory item (%h) "
1304 "corrupted (cur(%d) %a, "
1306 ih, i, deh + i, deh + i + 1);