aboutsummaryrefslogtreecommitdiffstats
path: root/fs/reiserfs/lbalance.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/reiserfs/lbalance.c')
-rw-r--r--fs/reiserfs/lbalance.c2218
1 files changed, 1149 insertions, 1069 deletions
diff --git a/fs/reiserfs/lbalance.c b/fs/reiserfs/lbalance.c
index 2406608fc5cd..2533c1f64aba 100644
--- a/fs/reiserfs/lbalance.c
+++ b/fs/reiserfs/lbalance.c
@@ -21,648 +21,709 @@
21 leaf_paste_entries 21 leaf_paste_entries
22 */ 22 */
23 23
24
25/* copy copy_count entries from source directory item to dest buffer (creating new item if needed) */ 24/* copy copy_count entries from source directory item to dest buffer (creating new item if needed) */
26static void leaf_copy_dir_entries (struct buffer_info * dest_bi, struct buffer_head * source, 25static void leaf_copy_dir_entries(struct buffer_info *dest_bi,
27 int last_first, int item_num, int from, int copy_count) 26 struct buffer_head *source, int last_first,
27 int item_num, int from, int copy_count)
28{ 28{
29 struct buffer_head * dest = dest_bi->bi_bh; 29 struct buffer_head *dest = dest_bi->bi_bh;
30 int item_num_in_dest; /* either the number of target item, 30 int item_num_in_dest; /* either the number of target item,
31 or if we must create a new item, 31 or if we must create a new item,
32 the number of the item we will 32 the number of the item we will
33 create it next to */ 33 create it next to */
34 struct item_head * ih; 34 struct item_head *ih;
35 struct reiserfs_de_head * deh; 35 struct reiserfs_de_head *deh;
36 int copy_records_len; /* length of all records in item to be copied */ 36 int copy_records_len; /* length of all records in item to be copied */
37 char * records; 37 char *records;
38 38
39 ih = B_N_PITEM_HEAD (source, item_num); 39 ih = B_N_PITEM_HEAD(source, item_num);
40 40
41 RFALSE( !is_direntry_le_ih (ih), "vs-10000: item must be directory item"); 41 RFALSE(!is_direntry_le_ih(ih), "vs-10000: item must be directory item");
42 42
43 /* length of all record to be copied and first byte of the last of them */ 43 /* length of all record to be copied and first byte of the last of them */
44 deh = B_I_DEH (source, ih); 44 deh = B_I_DEH(source, ih);
45 if (copy_count) { 45 if (copy_count) {
46 copy_records_len = (from ? deh_location( &(deh[from - 1]) ) : 46 copy_records_len = (from ? deh_location(&(deh[from - 1])) :
47 ih_item_len(ih)) - deh_location( &(deh[from + copy_count - 1])); 47 ih_item_len(ih)) -
48 records = source->b_data + ih_location(ih) + 48 deh_location(&(deh[from + copy_count - 1]));
49 deh_location( &(deh[from + copy_count - 1])); 49 records =
50 } else { 50 source->b_data + ih_location(ih) +
51 copy_records_len = 0; 51 deh_location(&(deh[from + copy_count - 1]));
52 records = NULL; 52 } else {
53 } 53 copy_records_len = 0;
54 54 records = NULL;
55 /* when copy last to first, dest buffer can contain 0 items */ 55 }
56 item_num_in_dest = (last_first == LAST_TO_FIRST) ? (( B_NR_ITEMS(dest) ) ? 0 : -1) : (B_NR_ITEMS(dest) - 1); 56
57 57 /* when copy last to first, dest buffer can contain 0 items */
58 /* if there are no items in dest or the first/last item in dest is not item of the same directory */ 58 item_num_in_dest =
59 if ( (item_num_in_dest == - 1) || 59 (last_first ==
60 (last_first == FIRST_TO_LAST && le_ih_k_offset (ih) == DOT_OFFSET) || 60 LAST_TO_FIRST) ? ((B_NR_ITEMS(dest)) ? 0 : -1) : (B_NR_ITEMS(dest)
61 (last_first == LAST_TO_FIRST && comp_short_le_keys/*COMP_SHORT_KEYS*/ (&ih->ih_key, B_N_PKEY (dest, item_num_in_dest)))) { 61 - 1);
62 /* create new item in dest */ 62
63 struct item_head new_ih; 63 /* if there are no items in dest or the first/last item in dest is not item of the same directory */
64 64 if ((item_num_in_dest == -1) ||
65 /* form item header */ 65 (last_first == FIRST_TO_LAST && le_ih_k_offset(ih) == DOT_OFFSET) ||
66 memcpy (&new_ih.ih_key, &ih->ih_key, KEY_SIZE); 66 (last_first == LAST_TO_FIRST
67 put_ih_version( &new_ih, KEY_FORMAT_3_5 ); 67 && comp_short_le_keys /*COMP_SHORT_KEYS */ (&ih->ih_key,
68 /* calculate item len */ 68 B_N_PKEY(dest,
69 put_ih_item_len( &new_ih, DEH_SIZE * copy_count + copy_records_len ); 69 item_num_in_dest))))
70 put_ih_entry_count( &new_ih, 0 ); 70 {
71 71 /* create new item in dest */
72 if (last_first == LAST_TO_FIRST) { 72 struct item_head new_ih;
73 /* form key by the following way */ 73
74 if (from < I_ENTRY_COUNT(ih)) { 74 /* form item header */
75 set_le_ih_k_offset( &new_ih, deh_offset( &(deh[from]) ) ); 75 memcpy(&new_ih.ih_key, &ih->ih_key, KEY_SIZE);
76 /*memcpy (&new_ih.ih_key.k_offset, &deh[from].deh_offset, SHORT_KEY_SIZE);*/ 76 put_ih_version(&new_ih, KEY_FORMAT_3_5);
77 } else { 77 /* calculate item len */
78 /* no entries will be copied to this item in this function */ 78 put_ih_item_len(&new_ih,
79 set_le_ih_k_offset (&new_ih, U32_MAX); 79 DEH_SIZE * copy_count + copy_records_len);
80 /* this item is not yet valid, but we want I_IS_DIRECTORY_ITEM to return 1 for it, so we -1 */ 80 put_ih_entry_count(&new_ih, 0);
81 } 81
82 set_le_key_k_type (KEY_FORMAT_3_5, &(new_ih.ih_key), TYPE_DIRENTRY); 82 if (last_first == LAST_TO_FIRST) {
83 /* form key by the following way */
84 if (from < I_ENTRY_COUNT(ih)) {
85 set_le_ih_k_offset(&new_ih,
86 deh_offset(&(deh[from])));
87 /*memcpy (&new_ih.ih_key.k_offset, &deh[from].deh_offset, SHORT_KEY_SIZE); */
88 } else {
89 /* no entries will be copied to this item in this function */
90 set_le_ih_k_offset(&new_ih, U32_MAX);
91 /* this item is not yet valid, but we want I_IS_DIRECTORY_ITEM to return 1 for it, so we -1 */
92 }
93 set_le_key_k_type(KEY_FORMAT_3_5, &(new_ih.ih_key),
94 TYPE_DIRENTRY);
95 }
96
97 /* insert item into dest buffer */
98 leaf_insert_into_buf(dest_bi,
99 (last_first ==
100 LAST_TO_FIRST) ? 0 : B_NR_ITEMS(dest),
101 &new_ih, NULL, 0);
102 } else {
103 /* prepare space for entries */
104 leaf_paste_in_buffer(dest_bi,
105 (last_first ==
106 FIRST_TO_LAST) ? (B_NR_ITEMS(dest) -
107 1) : 0, MAX_US_INT,
108 DEH_SIZE * copy_count + copy_records_len,
109 records, 0);
83 } 110 }
84
85 /* insert item into dest buffer */
86 leaf_insert_into_buf (dest_bi, (last_first == LAST_TO_FIRST) ? 0 : B_NR_ITEMS(dest), &new_ih, NULL, 0);
87 } else {
88 /* prepare space for entries */
89 leaf_paste_in_buffer (dest_bi, (last_first==FIRST_TO_LAST) ? (B_NR_ITEMS(dest) - 1) : 0, MAX_US_INT,
90 DEH_SIZE * copy_count + copy_records_len, records, 0
91 );
92 }
93
94 item_num_in_dest = (last_first == FIRST_TO_LAST) ? (B_NR_ITEMS(dest)-1) : 0;
95
96 leaf_paste_entries (dest_bi->bi_bh, item_num_in_dest,
97 (last_first == FIRST_TO_LAST) ? I_ENTRY_COUNT(B_N_PITEM_HEAD (dest, item_num_in_dest)) : 0,
98 copy_count, deh + from, records,
99 DEH_SIZE * copy_count + copy_records_len
100 );
101}
102 111
112 item_num_in_dest =
113 (last_first == FIRST_TO_LAST) ? (B_NR_ITEMS(dest) - 1) : 0;
114
115 leaf_paste_entries(dest_bi->bi_bh, item_num_in_dest,
116 (last_first ==
117 FIRST_TO_LAST) ? I_ENTRY_COUNT(B_N_PITEM_HEAD(dest,
118 item_num_in_dest))
119 : 0, copy_count, deh + from, records,
120 DEH_SIZE * copy_count + copy_records_len);
121}
103 122
104/* Copy the first (if last_first == FIRST_TO_LAST) or last (last_first == LAST_TO_FIRST) item or 123/* Copy the first (if last_first == FIRST_TO_LAST) or last (last_first == LAST_TO_FIRST) item or
105 part of it or nothing (see the return 0 below) from SOURCE to the end 124 part of it or nothing (see the return 0 below) from SOURCE to the end
106 (if last_first) or beginning (!last_first) of the DEST */ 125 (if last_first) or beginning (!last_first) of the DEST */
107/* returns 1 if anything was copied, else 0 */ 126/* returns 1 if anything was copied, else 0 */
108static int leaf_copy_boundary_item (struct buffer_info * dest_bi, struct buffer_head * src, int last_first, 127static int leaf_copy_boundary_item(struct buffer_info *dest_bi,
109 int bytes_or_entries) 128 struct buffer_head *src, int last_first,
129 int bytes_or_entries)
110{ 130{
111 struct buffer_head * dest = dest_bi->bi_bh; 131 struct buffer_head *dest = dest_bi->bi_bh;
112 int dest_nr_item, src_nr_item; /* number of items in the source and destination buffers */ 132 int dest_nr_item, src_nr_item; /* number of items in the source and destination buffers */
113 struct item_head * ih; 133 struct item_head *ih;
114 struct item_head * dih; 134 struct item_head *dih;
115 135
116 dest_nr_item = B_NR_ITEMS(dest); 136 dest_nr_item = B_NR_ITEMS(dest);
117 137
118 if ( last_first == FIRST_TO_LAST ) { 138 if (last_first == FIRST_TO_LAST) {
119 /* if ( DEST is empty or first item of SOURCE and last item of DEST are the items of different objects 139 /* if ( DEST is empty or first item of SOURCE and last item of DEST are the items of different objects
120 or of different types ) then there is no need to treat this item differently from the other items 140 or of different types ) then there is no need to treat this item differently from the other items
121 that we copy, so we return */ 141 that we copy, so we return */
122 ih = B_N_PITEM_HEAD (src, 0); 142 ih = B_N_PITEM_HEAD(src, 0);
123 dih = B_N_PITEM_HEAD (dest, dest_nr_item - 1); 143 dih = B_N_PITEM_HEAD(dest, dest_nr_item - 1);
124 if (!dest_nr_item || (!op_is_left_mergeable (&(ih->ih_key), src->b_size))) 144 if (!dest_nr_item
125 /* there is nothing to merge */ 145 || (!op_is_left_mergeable(&(ih->ih_key), src->b_size)))
126 return 0; 146 /* there is nothing to merge */
127 147 return 0;
128 RFALSE( ! ih_item_len(ih), "vs-10010: item can not have empty length"); 148
129 149 RFALSE(!ih_item_len(ih),
130 if ( is_direntry_le_ih (ih) ) { 150 "vs-10010: item can not have empty length");
131 if ( bytes_or_entries == -1 ) 151
132 /* copy all entries to dest */ 152 if (is_direntry_le_ih(ih)) {
133 bytes_or_entries = ih_entry_count(ih); 153 if (bytes_or_entries == -1)
134 leaf_copy_dir_entries (dest_bi, src, FIRST_TO_LAST, 0, 0, bytes_or_entries); 154 /* copy all entries to dest */
135 return 1; 155 bytes_or_entries = ih_entry_count(ih);
136 } 156 leaf_copy_dir_entries(dest_bi, src, FIRST_TO_LAST, 0, 0,
137 157 bytes_or_entries);
138 /* copy part of the body of the first item of SOURCE to the end of the body of the last item of the DEST 158 return 1;
139 part defined by 'bytes_or_entries'; if bytes_or_entries == -1 copy whole body; don't create new item header 159 }
140 */ 160
141 if ( bytes_or_entries == -1 ) 161 /* copy part of the body of the first item of SOURCE to the end of the body of the last item of the DEST
142 bytes_or_entries = ih_item_len(ih); 162 part defined by 'bytes_or_entries'; if bytes_or_entries == -1 copy whole body; don't create new item header
163 */
164 if (bytes_or_entries == -1)
165 bytes_or_entries = ih_item_len(ih);
143 166
144#ifdef CONFIG_REISERFS_CHECK 167#ifdef CONFIG_REISERFS_CHECK
145 else { 168 else {
146 if (bytes_or_entries == ih_item_len(ih) && is_indirect_le_ih(ih)) 169 if (bytes_or_entries == ih_item_len(ih)
147 if (get_ih_free_space (ih)) 170 && is_indirect_le_ih(ih))
148 reiserfs_panic (NULL, "vs-10020: leaf_copy_boundary_item: " 171 if (get_ih_free_space(ih))
149 "last unformatted node must be filled entirely (%h)", 172 reiserfs_panic(NULL,
150 ih); 173 "vs-10020: leaf_copy_boundary_item: "
151 } 174 "last unformatted node must be filled entirely (%h)",
175 ih);
176 }
152#endif 177#endif
153
154 /* merge first item (or its part) of src buffer with the last
155 item of dest buffer. Both are of the same file */
156 leaf_paste_in_buffer (dest_bi,
157 dest_nr_item - 1, ih_item_len(dih), bytes_or_entries, B_I_PITEM(src,ih), 0
158 );
159
160 if (is_indirect_le_ih (dih)) {
161 RFALSE( get_ih_free_space (dih),
162 "vs-10030: merge to left: last unformatted node of non-last indirect item %h must have zerto free space",
163 ih);
164 if (bytes_or_entries == ih_item_len(ih))
165 set_ih_free_space (dih, get_ih_free_space (ih));
166 }
167
168 return 1;
169 }
170
171
172 /* copy boundary item to right (last_first == LAST_TO_FIRST) */
173
174 /* ( DEST is empty or last item of SOURCE and first item of DEST
175 are the items of different object or of different types )
176 */
177 src_nr_item = B_NR_ITEMS (src);
178 ih = B_N_PITEM_HEAD (src, src_nr_item - 1);
179 dih = B_N_PITEM_HEAD (dest, 0);
180
181 if (!dest_nr_item || !op_is_left_mergeable (&(dih->ih_key), src->b_size))
182 return 0;
183
184 if ( is_direntry_le_ih (ih)) {
185 if ( bytes_or_entries == -1 )
186 /* bytes_or_entries = entries number in last item body of SOURCE */
187 bytes_or_entries = ih_entry_count(ih);
188
189 leaf_copy_dir_entries (dest_bi, src, LAST_TO_FIRST, src_nr_item - 1, ih_entry_count(ih) - bytes_or_entries, bytes_or_entries);
190 return 1;
191 }
192
193 /* copy part of the body of the last item of SOURCE to the begin of the body of the first item of the DEST;
194 part defined by 'bytes_or_entries'; if byte_or_entriess == -1 copy whole body; change first item key of the DEST;
195 don't create new item header
196 */
197
198 RFALSE( is_indirect_le_ih(ih) && get_ih_free_space (ih),
199 "vs-10040: merge to right: last unformatted node of non-last indirect item must be filled entirely (%h)",
200 ih);
201
202 if ( bytes_or_entries == -1 ) {
203 /* bytes_or_entries = length of last item body of SOURCE */
204 bytes_or_entries = ih_item_len(ih);
205
206 RFALSE( le_ih_k_offset (dih) !=
207 le_ih_k_offset (ih) + op_bytes_number (ih, src->b_size),
208 "vs-10050: items %h and %h do not match", ih, dih);
209
210 /* change first item key of the DEST */
211 set_le_ih_k_offset (dih, le_ih_k_offset (ih));
212
213 /* item becomes non-mergeable */
214 /* or mergeable if left item was */
215 set_le_ih_k_type (dih, le_ih_k_type (ih));
216 } else {
217 /* merge to right only part of item */
218 RFALSE( ih_item_len(ih) <= bytes_or_entries,
219 "vs-10060: no so much bytes %lu (needed %lu)",
220 ( unsigned long )ih_item_len(ih), ( unsigned long )bytes_or_entries);
221
222 /* change first item key of the DEST */
223 if ( is_direct_le_ih (dih) ) {
224 RFALSE( le_ih_k_offset (dih) <= (unsigned long)bytes_or_entries,
225 "vs-10070: dih %h, bytes_or_entries(%d)", dih, bytes_or_entries);
226 set_le_ih_k_offset (dih, le_ih_k_offset (dih) - bytes_or_entries);
227 } else {
228 RFALSE( le_ih_k_offset (dih) <=
229 (bytes_or_entries / UNFM_P_SIZE) * dest->b_size,
230 "vs-10080: dih %h, bytes_or_entries(%d)",
231 dih, (bytes_or_entries/UNFM_P_SIZE)*dest->b_size);
232 set_le_ih_k_offset (dih, le_ih_k_offset (dih) - ((bytes_or_entries / UNFM_P_SIZE) * dest->b_size));
233 }
234 }
235
236 leaf_paste_in_buffer (dest_bi, 0, 0, bytes_or_entries, B_I_PITEM(src,ih) + ih_item_len(ih) - bytes_or_entries, 0);
237 return 1;
238}
239 178
179 /* merge first item (or its part) of src buffer with the last
180 item of dest buffer. Both are of the same file */
181 leaf_paste_in_buffer(dest_bi,
182 dest_nr_item - 1, ih_item_len(dih),
183 bytes_or_entries, B_I_PITEM(src, ih), 0);
184
185 if (is_indirect_le_ih(dih)) {
186 RFALSE(get_ih_free_space(dih),
187 "vs-10030: merge to left: last unformatted node of non-last indirect item %h must have zerto free space",
188 ih);
189 if (bytes_or_entries == ih_item_len(ih))
190 set_ih_free_space(dih, get_ih_free_space(ih));
191 }
192
193 return 1;
194 }
195
196 /* copy boundary item to right (last_first == LAST_TO_FIRST) */
197
198 /* ( DEST is empty or last item of SOURCE and first item of DEST
199 are the items of different object or of different types )
200 */
201 src_nr_item = B_NR_ITEMS(src);
202 ih = B_N_PITEM_HEAD(src, src_nr_item - 1);
203 dih = B_N_PITEM_HEAD(dest, 0);
204
205 if (!dest_nr_item || !op_is_left_mergeable(&(dih->ih_key), src->b_size))
206 return 0;
207
208 if (is_direntry_le_ih(ih)) {
209 if (bytes_or_entries == -1)
210 /* bytes_or_entries = entries number in last item body of SOURCE */
211 bytes_or_entries = ih_entry_count(ih);
212
213 leaf_copy_dir_entries(dest_bi, src, LAST_TO_FIRST,
214 src_nr_item - 1,
215 ih_entry_count(ih) - bytes_or_entries,
216 bytes_or_entries);
217 return 1;
218 }
219
220 /* copy part of the body of the last item of SOURCE to the begin of the body of the first item of the DEST;
221 part defined by 'bytes_or_entries'; if byte_or_entriess == -1 copy whole body; change first item key of the DEST;
222 don't create new item header
223 */
224
225 RFALSE(is_indirect_le_ih(ih) && get_ih_free_space(ih),
226 "vs-10040: merge to right: last unformatted node of non-last indirect item must be filled entirely (%h)",
227 ih);
228
229 if (bytes_or_entries == -1) {
230 /* bytes_or_entries = length of last item body of SOURCE */
231 bytes_or_entries = ih_item_len(ih);
232
233 RFALSE(le_ih_k_offset(dih) !=
234 le_ih_k_offset(ih) + op_bytes_number(ih, src->b_size),
235 "vs-10050: items %h and %h do not match", ih, dih);
236
237 /* change first item key of the DEST */
238 set_le_ih_k_offset(dih, le_ih_k_offset(ih));
239
240 /* item becomes non-mergeable */
241 /* or mergeable if left item was */
242 set_le_ih_k_type(dih, le_ih_k_type(ih));
243 } else {
244 /* merge to right only part of item */
245 RFALSE(ih_item_len(ih) <= bytes_or_entries,
246 "vs-10060: no so much bytes %lu (needed %lu)",
247 (unsigned long)ih_item_len(ih),
248 (unsigned long)bytes_or_entries);
249
250 /* change first item key of the DEST */
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,
255 bytes_or_entries);
256 set_le_ih_k_offset(dih,
257 le_ih_k_offset(dih) -
258 bytes_or_entries);
259 } else {
260 RFALSE(le_ih_k_offset(dih) <=
261 (bytes_or_entries / UNFM_P_SIZE) * dest->b_size,
262 "vs-10080: dih %h, bytes_or_entries(%d)",
263 dih,
264 (bytes_or_entries / UNFM_P_SIZE) * dest->b_size);
265 set_le_ih_k_offset(dih,
266 le_ih_k_offset(dih) -
267 ((bytes_or_entries / UNFM_P_SIZE) *
268 dest->b_size));
269 }
270 }
271
272 leaf_paste_in_buffer(dest_bi, 0, 0, bytes_or_entries,
273 B_I_PITEM(src,
274 ih) + ih_item_len(ih) - bytes_or_entries,
275 0);
276 return 1;
277}
240 278
241/* copy cpy_mun items from buffer src to buffer dest 279/* copy cpy_mun items from buffer src to buffer dest
242 * last_first == FIRST_TO_LAST means, that we copy cpy_num items beginning from first-th item in src to tail of dest 280 * last_first == FIRST_TO_LAST means, that we copy cpy_num items beginning from first-th item in src to tail of dest
243 * last_first == LAST_TO_FIRST means, that we copy cpy_num items beginning from first-th item in src to head of dest 281 * last_first == LAST_TO_FIRST means, that we copy cpy_num items beginning from first-th item in src to head of dest
244 */ 282 */
245static void leaf_copy_items_entirely (struct buffer_info * dest_bi, struct buffer_head * src, int last_first, 283static void leaf_copy_items_entirely(struct buffer_info *dest_bi,
246 int first, int cpy_num) 284 struct buffer_head *src, int last_first,
285 int first, int cpy_num)
247{ 286{
248 struct buffer_head * dest; 287 struct buffer_head *dest;
249 int nr, free_space; 288 int nr, free_space;
250 int dest_before; 289 int dest_before;
251 int last_loc, last_inserted_loc, location; 290 int last_loc, last_inserted_loc, location;
252 int i, j; 291 int i, j;
253 struct block_head * blkh; 292 struct block_head *blkh;
254 struct item_head * ih; 293 struct item_head *ih;
255 294
256 RFALSE( last_first != LAST_TO_FIRST && last_first != FIRST_TO_LAST, 295 RFALSE(last_first != LAST_TO_FIRST && last_first != FIRST_TO_LAST,
257 "vs-10090: bad last_first parameter %d", last_first); 296 "vs-10090: bad last_first parameter %d", last_first);
258 RFALSE( B_NR_ITEMS (src) - first < cpy_num, 297 RFALSE(B_NR_ITEMS(src) - first < cpy_num,
259 "vs-10100: too few items in source %d, required %d from %d", 298 "vs-10100: too few items in source %d, required %d from %d",
260 B_NR_ITEMS(src), cpy_num, first); 299 B_NR_ITEMS(src), cpy_num, first);
261 RFALSE( cpy_num < 0, "vs-10110: can not copy negative amount of items"); 300 RFALSE(cpy_num < 0, "vs-10110: can not copy negative amount of items");
262 RFALSE( ! dest_bi, "vs-10120: can not copy negative amount of items"); 301 RFALSE(!dest_bi, "vs-10120: can not copy negative amount of items");
263 302
264 dest = dest_bi->bi_bh; 303 dest = dest_bi->bi_bh;
265 304
266 RFALSE( ! dest, "vs-10130: can not copy negative amount of items"); 305 RFALSE(!dest, "vs-10130: can not copy negative amount of items");
267 306
268 if (cpy_num == 0) 307 if (cpy_num == 0)
269 return; 308 return;
270 309
271 blkh = B_BLK_HEAD(dest); 310 blkh = B_BLK_HEAD(dest);
272 nr = blkh_nr_item( blkh ); 311 nr = blkh_nr_item(blkh);
273 free_space = blkh_free_space(blkh); 312 free_space = blkh_free_space(blkh);
274 313
275 /* we will insert items before 0-th or nr-th item in dest buffer. It depends of last_first parameter */ 314 /* we will insert items before 0-th or nr-th item in dest buffer. It depends of last_first parameter */
276 dest_before = (last_first == LAST_TO_FIRST) ? 0 : nr; 315 dest_before = (last_first == LAST_TO_FIRST) ? 0 : nr;
277 316
278 /* location of head of first new item */ 317 /* location of head of first new item */
279 ih = B_N_PITEM_HEAD (dest, dest_before); 318 ih = B_N_PITEM_HEAD(dest, dest_before);
280 319
281 RFALSE( blkh_free_space(blkh) < cpy_num * IH_SIZE, 320 RFALSE(blkh_free_space(blkh) < cpy_num * IH_SIZE,
282 "vs-10140: not enough free space for headers %d (needed %d)", 321 "vs-10140: not enough free space for headers %d (needed %d)",
283 B_FREE_SPACE (dest), cpy_num * IH_SIZE); 322 B_FREE_SPACE(dest), cpy_num * IH_SIZE);
284 323
285 /* prepare space for headers */ 324 /* prepare space for headers */
286 memmove (ih + cpy_num, ih, (nr-dest_before) * IH_SIZE); 325 memmove(ih + cpy_num, ih, (nr - dest_before) * IH_SIZE);
287
288 /* copy item headers */
289 memcpy (ih, B_N_PITEM_HEAD (src, first), cpy_num * IH_SIZE);
290
291 free_space -= (IH_SIZE * cpy_num);
292 set_blkh_free_space( blkh, free_space );
293
294 /* location of unmovable item */
295 j = location = (dest_before == 0) ? dest->b_size : ih_location(ih-1);
296 for (i = dest_before; i < nr + cpy_num; i ++) {
297 location -= ih_item_len( ih + i - dest_before );
298 put_ih_location( ih + i - dest_before, location );
299 }
300
301 /* prepare space for items */
302 last_loc = ih_location( &(ih[nr+cpy_num-1-dest_before]) );
303 last_inserted_loc = ih_location( &(ih[cpy_num-1]) );
304
305 /* check free space */
306 RFALSE( free_space < j - last_inserted_loc,
307 "vs-10150: not enough free space for items %d (needed %d)",
308 free_space, j - last_inserted_loc);
309
310 memmove (dest->b_data + last_loc,
311 dest->b_data + last_loc + j - last_inserted_loc,
312 last_inserted_loc - last_loc);
313
314 /* copy items */
315 memcpy (dest->b_data + last_inserted_loc, B_N_PITEM(src,(first + cpy_num - 1)),
316 j - last_inserted_loc);
317
318 /* sizes, item number */
319 set_blkh_nr_item( blkh, nr + cpy_num );
320 set_blkh_free_space( blkh, free_space - (j - last_inserted_loc) );
321
322 do_balance_mark_leaf_dirty (dest_bi->tb, dest, 0);
323
324 if (dest_bi->bi_parent) {
325 struct disk_child *t_dc;
326 t_dc = B_N_CHILD (dest_bi->bi_parent, dest_bi->bi_position);
327 RFALSE( dc_block_number(t_dc) != dest->b_blocknr,
328 "vs-10160: block number in bh does not match to field in disk_child structure %lu and %lu",
329 ( long unsigned ) dest->b_blocknr,
330 ( long unsigned ) dc_block_number(t_dc));
331 put_dc_size( t_dc, dc_size(t_dc) + (j - last_inserted_loc + IH_SIZE * cpy_num ) );
332
333 do_balance_mark_internal_dirty (dest_bi->tb, dest_bi->bi_parent, 0);
334 }
335}
336 326
327 /* copy item headers */
328 memcpy(ih, B_N_PITEM_HEAD(src, first), cpy_num * IH_SIZE);
329
330 free_space -= (IH_SIZE * cpy_num);
331 set_blkh_free_space(blkh, free_space);
332
333 /* location of unmovable item */
334 j = location = (dest_before == 0) ? dest->b_size : ih_location(ih - 1);
335 for (i = dest_before; i < nr + cpy_num; i++) {
336 location -= ih_item_len(ih + i - dest_before);
337 put_ih_location(ih + i - dest_before, location);
338 }
339
340 /* prepare space for items */
341 last_loc = ih_location(&(ih[nr + cpy_num - 1 - dest_before]));
342 last_inserted_loc = ih_location(&(ih[cpy_num - 1]));
343
344 /* check free space */
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);
348
349 memmove(dest->b_data + last_loc,
350 dest->b_data + last_loc + j - last_inserted_loc,
351 last_inserted_loc - last_loc);
352
353 /* copy items */
354 memcpy(dest->b_data + last_inserted_loc,
355 B_N_PITEM(src, (first + cpy_num - 1)), j - last_inserted_loc);
356
357 /* sizes, item number */
358 set_blkh_nr_item(blkh, nr + cpy_num);
359 set_blkh_free_space(blkh, free_space - (j - last_inserted_loc));
360
361 do_balance_mark_leaf_dirty(dest_bi->tb, dest, 0);
362
363 if (dest_bi->bi_parent) {
364 struct disk_child *t_dc;
365 t_dc = B_N_CHILD(dest_bi->bi_parent, dest_bi->bi_position);
366 RFALSE(dc_block_number(t_dc) != dest->b_blocknr,
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,
369 (long unsigned)dc_block_number(t_dc));
370 put_dc_size(t_dc,
371 dc_size(t_dc) + (j - last_inserted_loc +
372 IH_SIZE * cpy_num));
373
374 do_balance_mark_internal_dirty(dest_bi->tb, dest_bi->bi_parent,
375 0);
376 }
377}
337 378
338/* This function splits the (liquid) item into two items (useful when 379/* This function splits the (liquid) item into two items (useful when
339 shifting part of an item into another node.) */ 380 shifting part of an item into another node.) */
340static void leaf_item_bottle (struct buffer_info * dest_bi, struct buffer_head * src, int last_first, 381static void leaf_item_bottle(struct buffer_info *dest_bi,
341 int item_num, int cpy_bytes) 382 struct buffer_head *src, int last_first,
383 int item_num, int cpy_bytes)
342{ 384{
343 struct buffer_head * dest = dest_bi->bi_bh; 385 struct buffer_head *dest = dest_bi->bi_bh;
344 struct item_head * ih; 386 struct item_head *ih;
345 387
346 RFALSE( cpy_bytes == -1, "vs-10170: bytes == - 1 means: do not split item"); 388 RFALSE(cpy_bytes == -1,
347 389 "vs-10170: bytes == - 1 means: do not split item");
348 if ( last_first == FIRST_TO_LAST ) { 390
349 /* if ( if item in position item_num in buffer SOURCE is directory item ) */ 391 if (last_first == FIRST_TO_LAST) {
350 if (is_direntry_le_ih (ih = B_N_PITEM_HEAD(src,item_num))) 392 /* if ( if item in position item_num in buffer SOURCE is directory item ) */
351 leaf_copy_dir_entries (dest_bi, src, FIRST_TO_LAST, item_num, 0, cpy_bytes); 393 if (is_direntry_le_ih(ih = B_N_PITEM_HEAD(src, item_num)))
352 else { 394 leaf_copy_dir_entries(dest_bi, src, FIRST_TO_LAST,
353 struct item_head n_ih; 395 item_num, 0, cpy_bytes);
354 396 else {
355 /* copy part of the body of the item number 'item_num' of SOURCE to the end of the DEST 397 struct item_head n_ih;
356 part defined by 'cpy_bytes'; create new item header; change old item_header (????); 398
357 n_ih = new item_header; 399 /* copy part of the body of the item number 'item_num' of SOURCE to the end of the DEST
358 */ 400 part defined by 'cpy_bytes'; create new item header; change old item_header (????);
359 memcpy (&n_ih, ih, IH_SIZE); 401 n_ih = new item_header;
360 put_ih_item_len( &n_ih, cpy_bytes ); 402 */
361 if (is_indirect_le_ih (ih)) { 403 memcpy(&n_ih, ih, IH_SIZE);
362 RFALSE( cpy_bytes == ih_item_len(ih) && get_ih_free_space(ih), 404 put_ih_item_len(&n_ih, cpy_bytes);
363 "vs-10180: when whole indirect item is bottle to left neighbor, it must have free_space==0 (not %lu)", 405 if (is_indirect_le_ih(ih)) {
364 ( long unsigned ) get_ih_free_space (ih)); 406 RFALSE(cpy_bytes == ih_item_len(ih)
365 set_ih_free_space (&n_ih, 0); 407 && get_ih_free_space(ih),
366 } 408 "vs-10180: when whole indirect item is bottle to left neighbor, it must have free_space==0 (not %lu)",
367 409 (long unsigned)get_ih_free_space(ih));
368 RFALSE( op_is_left_mergeable (&(ih->ih_key), src->b_size), 410 set_ih_free_space(&n_ih, 0);
369 "vs-10190: bad mergeability of item %h", ih); 411 }
370 n_ih.ih_version = ih->ih_version; /* JDM Endian safe, both le */ 412
371 leaf_insert_into_buf (dest_bi, B_NR_ITEMS(dest), &n_ih, B_N_PITEM (src, item_num), 0); 413 RFALSE(op_is_left_mergeable(&(ih->ih_key), src->b_size),
414 "vs-10190: bad mergeability of item %h", ih);
415 n_ih.ih_version = ih->ih_version; /* JDM Endian safe, both le */
416 leaf_insert_into_buf(dest_bi, B_NR_ITEMS(dest), &n_ih,
417 B_N_PITEM(src, item_num), 0);
418 }
419 } else {
420 /* if ( if item in position item_num in buffer SOURCE is directory item ) */
421 if (is_direntry_le_ih(ih = B_N_PITEM_HEAD(src, item_num)))
422 leaf_copy_dir_entries(dest_bi, src, LAST_TO_FIRST,
423 item_num,
424 I_ENTRY_COUNT(ih) - cpy_bytes,
425 cpy_bytes);
426 else {
427 struct item_head n_ih;
428
429 /* copy part of the body of the item number 'item_num' of SOURCE to the begin of the DEST
430 part defined by 'cpy_bytes'; create new item header;
431 n_ih = new item_header;
432 */
433 memcpy(&n_ih, ih, SHORT_KEY_SIZE);
434
435 n_ih.ih_version = ih->ih_version; /* JDM Endian safe, both le */
436
437 if (is_direct_le_ih(ih)) {
438 set_le_ih_k_offset(&n_ih,
439 le_ih_k_offset(ih) +
440 ih_item_len(ih) - cpy_bytes);
441 set_le_ih_k_type(&n_ih, TYPE_DIRECT);
442 set_ih_free_space(&n_ih, MAX_US_INT);
443 } else {
444 /* indirect item */
445 RFALSE(!cpy_bytes && get_ih_free_space(ih),
446 "vs-10200: ih->ih_free_space must be 0 when indirect item will be appended");
447 set_le_ih_k_offset(&n_ih,
448 le_ih_k_offset(ih) +
449 (ih_item_len(ih) -
450 cpy_bytes) / UNFM_P_SIZE *
451 dest->b_size);
452 set_le_ih_k_type(&n_ih, TYPE_INDIRECT);
453 set_ih_free_space(&n_ih, get_ih_free_space(ih));
454 }
455
456 /* set item length */
457 put_ih_item_len(&n_ih, cpy_bytes);
458
459 n_ih.ih_version = ih->ih_version; /* JDM Endian safe, both le */
460
461 leaf_insert_into_buf(dest_bi, 0, &n_ih,
462 B_N_PITEM(src,
463 item_num) +
464 ih_item_len(ih) - cpy_bytes, 0);
465 }
372 } 466 }
373 } else {
374 /* if ( if item in position item_num in buffer SOURCE is directory item ) */
375 if (is_direntry_le_ih(ih = B_N_PITEM_HEAD (src, item_num)))
376 leaf_copy_dir_entries (dest_bi, src, LAST_TO_FIRST, item_num, I_ENTRY_COUNT(ih) - cpy_bytes, cpy_bytes);
377 else {
378 struct item_head n_ih;
379
380 /* copy part of the body of the item number 'item_num' of SOURCE to the begin of the DEST
381 part defined by 'cpy_bytes'; create new item header;
382 n_ih = new item_header;
383 */
384 memcpy (&n_ih, ih, SHORT_KEY_SIZE);
385
386 n_ih.ih_version = ih->ih_version; /* JDM Endian safe, both le */
387
388 if (is_direct_le_ih (ih)) {
389 set_le_ih_k_offset (&n_ih, le_ih_k_offset (ih) + ih_item_len(ih) - cpy_bytes);
390 set_le_ih_k_type (&n_ih, TYPE_DIRECT);
391 set_ih_free_space (&n_ih, MAX_US_INT);
392 } else {
393 /* indirect item */
394 RFALSE( !cpy_bytes && get_ih_free_space (ih),
395 "vs-10200: ih->ih_free_space must be 0 when indirect item will be appended");
396 set_le_ih_k_offset (&n_ih, le_ih_k_offset (ih) + (ih_item_len(ih) - cpy_bytes) / UNFM_P_SIZE * dest->b_size);
397 set_le_ih_k_type (&n_ih, TYPE_INDIRECT);
398 set_ih_free_space (&n_ih, get_ih_free_space (ih));
399 }
400
401 /* set item length */
402 put_ih_item_len( &n_ih, cpy_bytes );
403
404 n_ih.ih_version = ih->ih_version; /* JDM Endian safe, both le */
405
406 leaf_insert_into_buf (dest_bi, 0, &n_ih, B_N_PITEM(src,item_num) + ih_item_len(ih) - cpy_bytes, 0);
407 }
408 }
409} 467}
410 468
411
412/* If cpy_bytes equals minus one than copy cpy_num whole items from SOURCE to DEST. 469/* If cpy_bytes equals minus one than copy cpy_num whole items from SOURCE to DEST.
413 If cpy_bytes not equal to minus one than copy cpy_num-1 whole items from SOURCE to DEST. 470 If cpy_bytes not equal to minus one than copy cpy_num-1 whole items from SOURCE to DEST.
414 From last item copy cpy_num bytes for regular item and cpy_num directory entries for 471 From last item copy cpy_num bytes for regular item and cpy_num directory entries for
415 directory item. */ 472 directory item. */
416static int leaf_copy_items (struct buffer_info * dest_bi, struct buffer_head * src, int last_first, int cpy_num, 473static int leaf_copy_items(struct buffer_info *dest_bi, struct buffer_head *src,
417 int cpy_bytes) 474 int last_first, int cpy_num, int cpy_bytes)
418{ 475{
419 struct buffer_head * dest; 476 struct buffer_head *dest;
420 int pos, i, src_nr_item, bytes; 477 int pos, i, src_nr_item, bytes;
421 478
422 dest = dest_bi->bi_bh; 479 dest = dest_bi->bi_bh;
423 RFALSE( !dest || !src, "vs-10210: !dest || !src"); 480 RFALSE(!dest || !src, "vs-10210: !dest || !src");
424 RFALSE( last_first != FIRST_TO_LAST && last_first != LAST_TO_FIRST, 481 RFALSE(last_first != FIRST_TO_LAST && last_first != LAST_TO_FIRST,
425 "vs-10220:last_first != FIRST_TO_LAST && last_first != LAST_TO_FIRST"); 482 "vs-10220:last_first != FIRST_TO_LAST && last_first != LAST_TO_FIRST");
426 RFALSE( B_NR_ITEMS(src) < cpy_num, 483 RFALSE(B_NR_ITEMS(src) < cpy_num,
427 "vs-10230: No enough items: %d, req. %d", B_NR_ITEMS(src), cpy_num); 484 "vs-10230: No enough items: %d, req. %d", B_NR_ITEMS(src),
428 RFALSE( cpy_num < 0,"vs-10240: cpy_num < 0 (%d)", cpy_num); 485 cpy_num);
429 486 RFALSE(cpy_num < 0, "vs-10240: cpy_num < 0 (%d)", cpy_num);
430 if ( cpy_num == 0 ) 487
431 return 0; 488 if (cpy_num == 0)
432 489 return 0;
433 if ( last_first == FIRST_TO_LAST ) { 490
434 /* copy items to left */ 491 if (last_first == FIRST_TO_LAST) {
435 pos = 0; 492 /* copy items to left */
436 if ( cpy_num == 1 ) 493 pos = 0;
437 bytes = cpy_bytes; 494 if (cpy_num == 1)
438 else 495 bytes = cpy_bytes;
439 bytes = -1; 496 else
440 497 bytes = -1;
441 /* copy the first item or it part or nothing to the end of the DEST (i = leaf_copy_boundary_item(DEST,SOURCE,0,bytes)) */ 498
442 i = leaf_copy_boundary_item (dest_bi, src, FIRST_TO_LAST, bytes); 499 /* copy the first item or it part or nothing to the end of the DEST (i = leaf_copy_boundary_item(DEST,SOURCE,0,bytes)) */
443 cpy_num -= i; 500 i = leaf_copy_boundary_item(dest_bi, src, FIRST_TO_LAST, bytes);
444 if ( cpy_num == 0 ) 501 cpy_num -= i;
445 return i; 502 if (cpy_num == 0)
446 pos += i; 503 return i;
447 if ( cpy_bytes == -1 ) 504 pos += i;
448 /* copy first cpy_num items starting from position 'pos' of SOURCE to end of DEST */ 505 if (cpy_bytes == -1)
449 leaf_copy_items_entirely (dest_bi, src, FIRST_TO_LAST, pos, cpy_num); 506 /* copy first cpy_num items starting from position 'pos' of SOURCE to end of DEST */
450 else { 507 leaf_copy_items_entirely(dest_bi, src, FIRST_TO_LAST,
451 /* copy first cpy_num-1 items starting from position 'pos-1' of the SOURCE to the end of the DEST */ 508 pos, cpy_num);
452 leaf_copy_items_entirely (dest_bi, src, FIRST_TO_LAST, pos, cpy_num-1); 509 else {
453 510 /* copy first cpy_num-1 items starting from position 'pos-1' of the SOURCE to the end of the DEST */
454 /* copy part of the item which number is cpy_num+pos-1 to the end of the DEST */ 511 leaf_copy_items_entirely(dest_bi, src, FIRST_TO_LAST,
455 leaf_item_bottle (dest_bi, src, FIRST_TO_LAST, cpy_num+pos-1, cpy_bytes); 512 pos, cpy_num - 1);
456 } 513
457 } else { 514 /* copy part of the item which number is cpy_num+pos-1 to the end of the DEST */
458 /* copy items to right */ 515 leaf_item_bottle(dest_bi, src, FIRST_TO_LAST,
459 src_nr_item = B_NR_ITEMS (src); 516 cpy_num + pos - 1, cpy_bytes);
460 if ( cpy_num == 1 ) 517 }
461 bytes = cpy_bytes; 518 } else {
462 else 519 /* copy items to right */
463 bytes = -1; 520 src_nr_item = B_NR_ITEMS(src);
464 521 if (cpy_num == 1)
465 /* copy the last item or it part or nothing to the begin of the DEST (i = leaf_copy_boundary_item(DEST,SOURCE,1,bytes)); */ 522 bytes = cpy_bytes;
466 i = leaf_copy_boundary_item (dest_bi, src, LAST_TO_FIRST, bytes); 523 else
467 524 bytes = -1;
468 cpy_num -= i; 525
469 if ( cpy_num == 0 ) 526 /* copy the last item or it part or nothing to the begin of the DEST (i = leaf_copy_boundary_item(DEST,SOURCE,1,bytes)); */
470 return i; 527 i = leaf_copy_boundary_item(dest_bi, src, LAST_TO_FIRST, bytes);
471 528
472 pos = src_nr_item - cpy_num - i; 529 cpy_num -= i;
473 if ( cpy_bytes == -1 ) { 530 if (cpy_num == 0)
474 /* starting from position 'pos' copy last cpy_num items of SOURCE to begin of DEST */ 531 return i;
475 leaf_copy_items_entirely (dest_bi, src, LAST_TO_FIRST, pos, cpy_num); 532
476 } else { 533 pos = src_nr_item - cpy_num - i;
477 /* copy last cpy_num-1 items starting from position 'pos+1' of the SOURCE to the begin of the DEST; */ 534 if (cpy_bytes == -1) {
478 leaf_copy_items_entirely (dest_bi, src, LAST_TO_FIRST, pos+1, cpy_num-1); 535 /* starting from position 'pos' copy last cpy_num items of SOURCE to begin of DEST */
479 536 leaf_copy_items_entirely(dest_bi, src, LAST_TO_FIRST,
480 /* copy part of the item which number is pos to the begin of the DEST */ 537 pos, cpy_num);
481 leaf_item_bottle (dest_bi, src, LAST_TO_FIRST, pos, cpy_bytes); 538 } else {
482 } 539 /* copy last cpy_num-1 items starting from position 'pos+1' of the SOURCE to the begin of the DEST; */
483 } 540 leaf_copy_items_entirely(dest_bi, src, LAST_TO_FIRST,
484 return i; 541 pos + 1, cpy_num - 1);
542
543 /* copy part of the item which number is pos to the begin of the DEST */
544 leaf_item_bottle(dest_bi, src, LAST_TO_FIRST, pos,
545 cpy_bytes);
546 }
547 }
548 return i;
485} 549}
486 550
487
488/* there are types of coping: from S[0] to L[0], from S[0] to R[0], 551/* there are types of coping: from S[0] to L[0], from S[0] to R[0],
489 from R[0] to L[0]. for each of these we have to define parent and 552 from R[0] to L[0]. for each of these we have to define parent and
490 positions of destination and source buffers */ 553 positions of destination and source buffers */
491static void leaf_define_dest_src_infos (int shift_mode, struct tree_balance * tb, struct buffer_info * dest_bi, 554static void leaf_define_dest_src_infos(int shift_mode, struct tree_balance *tb,
492 struct buffer_info * src_bi, int * first_last, 555 struct buffer_info *dest_bi,
493 struct buffer_head * Snew) 556 struct buffer_info *src_bi,
557 int *first_last,
558 struct buffer_head *Snew)
494{ 559{
495 memset (dest_bi, 0, sizeof (struct buffer_info)); 560 memset(dest_bi, 0, sizeof(struct buffer_info));
496 memset (src_bi, 0, sizeof (struct buffer_info)); 561 memset(src_bi, 0, sizeof(struct buffer_info));
497 562
498 /* define dest, src, dest parent, dest position */ 563 /* define dest, src, dest parent, dest position */
499 switch (shift_mode) { 564 switch (shift_mode) {
500 case LEAF_FROM_S_TO_L: /* it is used in leaf_shift_left */ 565 case LEAF_FROM_S_TO_L: /* it is used in leaf_shift_left */
501 src_bi->tb = tb; 566 src_bi->tb = tb;
502 src_bi->bi_bh = PATH_PLAST_BUFFER (tb->tb_path); 567 src_bi->bi_bh = PATH_PLAST_BUFFER(tb->tb_path);
503 src_bi->bi_parent = PATH_H_PPARENT (tb->tb_path, 0); 568 src_bi->bi_parent = PATH_H_PPARENT(tb->tb_path, 0);
504 src_bi->bi_position = PATH_H_B_ITEM_ORDER (tb->tb_path, 0); /* src->b_item_order */ 569 src_bi->bi_position = PATH_H_B_ITEM_ORDER(tb->tb_path, 0); /* src->b_item_order */
505 dest_bi->tb = tb; 570 dest_bi->tb = tb;
506 dest_bi->bi_bh = tb->L[0]; 571 dest_bi->bi_bh = tb->L[0];
507 dest_bi->bi_parent = tb->FL[0]; 572 dest_bi->bi_parent = tb->FL[0];
508 dest_bi->bi_position = get_left_neighbor_position (tb, 0); 573 dest_bi->bi_position = get_left_neighbor_position(tb, 0);
509 *first_last = FIRST_TO_LAST; 574 *first_last = FIRST_TO_LAST;
510 break; 575 break;
511 576
512 case LEAF_FROM_S_TO_R: /* it is used in leaf_shift_right */ 577 case LEAF_FROM_S_TO_R: /* it is used in leaf_shift_right */
513 src_bi->tb = tb; 578 src_bi->tb = tb;
514 src_bi->bi_bh = PATH_PLAST_BUFFER (tb->tb_path); 579 src_bi->bi_bh = PATH_PLAST_BUFFER(tb->tb_path);
515 src_bi->bi_parent = PATH_H_PPARENT (tb->tb_path, 0); 580 src_bi->bi_parent = PATH_H_PPARENT(tb->tb_path, 0);
516 src_bi->bi_position = PATH_H_B_ITEM_ORDER (tb->tb_path, 0); 581 src_bi->bi_position = PATH_H_B_ITEM_ORDER(tb->tb_path, 0);
517 dest_bi->tb = tb; 582 dest_bi->tb = tb;
518 dest_bi->bi_bh = tb->R[0]; 583 dest_bi->bi_bh = tb->R[0];
519 dest_bi->bi_parent = tb->FR[0]; 584 dest_bi->bi_parent = tb->FR[0];
520 dest_bi->bi_position = get_right_neighbor_position (tb, 0); 585 dest_bi->bi_position = get_right_neighbor_position(tb, 0);
521 *first_last = LAST_TO_FIRST; 586 *first_last = LAST_TO_FIRST;
522 break; 587 break;
523 588
524 case LEAF_FROM_R_TO_L: /* it is used in balance_leaf_when_delete */ 589 case LEAF_FROM_R_TO_L: /* it is used in balance_leaf_when_delete */
525 src_bi->tb = tb; 590 src_bi->tb = tb;
526 src_bi->bi_bh = tb->R[0]; 591 src_bi->bi_bh = tb->R[0];
527 src_bi->bi_parent = tb->FR[0]; 592 src_bi->bi_parent = tb->FR[0];
528 src_bi->bi_position = get_right_neighbor_position (tb, 0); 593 src_bi->bi_position = get_right_neighbor_position(tb, 0);
529 dest_bi->tb = tb; 594 dest_bi->tb = tb;
530 dest_bi->bi_bh = tb->L[0]; 595 dest_bi->bi_bh = tb->L[0];
531 dest_bi->bi_parent = tb->FL[0]; 596 dest_bi->bi_parent = tb->FL[0];
532 dest_bi->bi_position = get_left_neighbor_position (tb, 0); 597 dest_bi->bi_position = get_left_neighbor_position(tb, 0);
533 *first_last = FIRST_TO_LAST; 598 *first_last = FIRST_TO_LAST;
534 break; 599 break;
535 600
536 case LEAF_FROM_L_TO_R: /* it is used in balance_leaf_when_delete */ 601 case LEAF_FROM_L_TO_R: /* it is used in balance_leaf_when_delete */
537 src_bi->tb = tb; 602 src_bi->tb = tb;
538 src_bi->bi_bh = tb->L[0]; 603 src_bi->bi_bh = tb->L[0];
539 src_bi->bi_parent = tb->FL[0]; 604 src_bi->bi_parent = tb->FL[0];
540 src_bi->bi_position = get_left_neighbor_position (tb, 0); 605 src_bi->bi_position = get_left_neighbor_position(tb, 0);
541 dest_bi->tb = tb; 606 dest_bi->tb = tb;
542 dest_bi->bi_bh = tb->R[0]; 607 dest_bi->bi_bh = tb->R[0];
543 dest_bi->bi_parent = tb->FR[0]; 608 dest_bi->bi_parent = tb->FR[0];
544 dest_bi->bi_position = get_right_neighbor_position (tb, 0); 609 dest_bi->bi_position = get_right_neighbor_position(tb, 0);
545 *first_last = LAST_TO_FIRST; 610 *first_last = LAST_TO_FIRST;
546 break; 611 break;
547 612
548 case LEAF_FROM_S_TO_SNEW: 613 case LEAF_FROM_S_TO_SNEW:
549 src_bi->tb = tb; 614 src_bi->tb = tb;
550 src_bi->bi_bh = PATH_PLAST_BUFFER (tb->tb_path); 615 src_bi->bi_bh = PATH_PLAST_BUFFER(tb->tb_path);
551 src_bi->bi_parent = PATH_H_PPARENT (tb->tb_path, 0); 616 src_bi->bi_parent = PATH_H_PPARENT(tb->tb_path, 0);
552 src_bi->bi_position = PATH_H_B_ITEM_ORDER (tb->tb_path, 0); 617 src_bi->bi_position = PATH_H_B_ITEM_ORDER(tb->tb_path, 0);
553 dest_bi->tb = tb; 618 dest_bi->tb = tb;
554 dest_bi->bi_bh = Snew; 619 dest_bi->bi_bh = Snew;
555 dest_bi->bi_parent = NULL; 620 dest_bi->bi_parent = NULL;
556 dest_bi->bi_position = 0; 621 dest_bi->bi_position = 0;
557 *first_last = LAST_TO_FIRST; 622 *first_last = LAST_TO_FIRST;
558 break; 623 break;
559 624
560 default: 625 default:
561 reiserfs_panic (NULL, "vs-10250: leaf_define_dest_src_infos: shift type is unknown (%d)", shift_mode); 626 reiserfs_panic(NULL,
562 } 627 "vs-10250: leaf_define_dest_src_infos: shift type is unknown (%d)",
563 RFALSE( src_bi->bi_bh == 0 || dest_bi->bi_bh == 0, 628 shift_mode);
564 "vs-10260: mode==%d, source (%p) or dest (%p) buffer is initialized incorrectly", 629 }
565 shift_mode, src_bi->bi_bh, dest_bi->bi_bh); 630 RFALSE(src_bi->bi_bh == 0 || dest_bi->bi_bh == 0,
631 "vs-10260: mode==%d, source (%p) or dest (%p) buffer is initialized incorrectly",
632 shift_mode, src_bi->bi_bh, dest_bi->bi_bh);
566} 633}
567 634
568
569
570
571/* copy mov_num items and mov_bytes of the (mov_num-1)th item to 635/* copy mov_num items and mov_bytes of the (mov_num-1)th item to
572 neighbor. Delete them from source */ 636 neighbor. Delete them from source */
573int leaf_move_items (int shift_mode, struct tree_balance * tb, int mov_num, int mov_bytes, struct buffer_head * Snew) 637int leaf_move_items(int shift_mode, struct tree_balance *tb, int mov_num,
638 int mov_bytes, struct buffer_head *Snew)
574{ 639{
575 int ret_value; 640 int ret_value;
576 struct buffer_info dest_bi, src_bi; 641 struct buffer_info dest_bi, src_bi;
577 int first_last; 642 int first_last;
578 643
579 leaf_define_dest_src_infos (shift_mode, tb, &dest_bi, &src_bi, &first_last, Snew); 644 leaf_define_dest_src_infos(shift_mode, tb, &dest_bi, &src_bi,
645 &first_last, Snew);
580 646
581 ret_value = leaf_copy_items (&dest_bi, src_bi.bi_bh, first_last, mov_num, mov_bytes); 647 ret_value =
648 leaf_copy_items(&dest_bi, src_bi.bi_bh, first_last, mov_num,
649 mov_bytes);
582 650
583 leaf_delete_items (&src_bi, first_last, (first_last == FIRST_TO_LAST) ? 0 : (B_NR_ITEMS(src_bi.bi_bh) - mov_num), mov_num, mov_bytes); 651 leaf_delete_items(&src_bi, first_last,
652 (first_last ==
653 FIRST_TO_LAST) ? 0 : (B_NR_ITEMS(src_bi.bi_bh) -
654 mov_num), mov_num, mov_bytes);
584 655
585 656 return ret_value;
586 return ret_value;
587} 657}
588 658
589
590/* Shift shift_num items (and shift_bytes of last shifted item if shift_bytes != -1) 659/* Shift shift_num items (and shift_bytes of last shifted item if shift_bytes != -1)
591 from S[0] to L[0] and replace the delimiting key */ 660 from S[0] to L[0] and replace the delimiting key */
592int leaf_shift_left (struct tree_balance * tb, int shift_num, int shift_bytes) 661int leaf_shift_left(struct tree_balance *tb, int shift_num, int shift_bytes)
593{ 662{
594 struct buffer_head * S0 = PATH_PLAST_BUFFER (tb->tb_path); 663 struct buffer_head *S0 = PATH_PLAST_BUFFER(tb->tb_path);
595 int i; 664 int i;
596 665
597 /* move shift_num (and shift_bytes bytes) items from S[0] to left neighbor L[0] */ 666 /* move shift_num (and shift_bytes bytes) items from S[0] to left neighbor L[0] */
598 i = leaf_move_items (LEAF_FROM_S_TO_L, tb, shift_num, shift_bytes, NULL); 667 i = leaf_move_items(LEAF_FROM_S_TO_L, tb, shift_num, shift_bytes, NULL);
599 668
600 if ( shift_num ) { 669 if (shift_num) {
601 if (B_NR_ITEMS (S0) == 0) { /* number of items in S[0] == 0 */ 670 if (B_NR_ITEMS(S0) == 0) { /* number of items in S[0] == 0 */
602 671
603 RFALSE( shift_bytes != -1, 672 RFALSE(shift_bytes != -1,
604 "vs-10270: S0 is empty now, but shift_bytes != -1 (%d)", 673 "vs-10270: S0 is empty now, but shift_bytes != -1 (%d)",
605 shift_bytes); 674 shift_bytes);
606#ifdef CONFIG_REISERFS_CHECK 675#ifdef CONFIG_REISERFS_CHECK
607 if (tb->tb_mode == M_PASTE || tb->tb_mode == M_INSERT) { 676 if (tb->tb_mode == M_PASTE || tb->tb_mode == M_INSERT) {
608 print_cur_tb ("vs-10275"); 677 print_cur_tb("vs-10275");
609 reiserfs_panic (tb->tb_sb, "vs-10275: leaf_shift_left: balance condition corrupted (%c)", tb->tb_mode); 678 reiserfs_panic(tb->tb_sb,
610 } 679 "vs-10275: leaf_shift_left: balance condition corrupted (%c)",
680 tb->tb_mode);
681 }
611#endif 682#endif
612 683
613 if (PATH_H_POSITION (tb->tb_path, 1) == 0) 684 if (PATH_H_POSITION(tb->tb_path, 1) == 0)
614 replace_key (tb, tb->CFL[0], tb->lkey[0], PATH_H_PPARENT (tb->tb_path, 0), 0); 685 replace_key(tb, tb->CFL[0], tb->lkey[0],
615 686 PATH_H_PPARENT(tb->tb_path, 0), 0);
616 } else { 687
617 /* replace lkey in CFL[0] by 0-th key from S[0]; */ 688 } else {
618 replace_key (tb, tb->CFL[0], tb->lkey[0], S0, 0); 689 /* replace lkey in CFL[0] by 0-th key from S[0]; */
619 690 replace_key(tb, tb->CFL[0], tb->lkey[0], S0, 0);
620 RFALSE( (shift_bytes != -1 && 691
621 !(is_direntry_le_ih (B_N_PITEM_HEAD (S0, 0)) 692 RFALSE((shift_bytes != -1 &&
622 && !I_ENTRY_COUNT (B_N_PITEM_HEAD (S0, 0)))) && 693 !(is_direntry_le_ih(B_N_PITEM_HEAD(S0, 0))
623 (!op_is_left_mergeable (B_N_PKEY (S0, 0), S0->b_size)), 694 && !I_ENTRY_COUNT(B_N_PITEM_HEAD(S0, 0)))) &&
624 "vs-10280: item must be mergeable"); 695 (!op_is_left_mergeable
625 } 696 (B_N_PKEY(S0, 0), S0->b_size)),
626 } 697 "vs-10280: item must be mergeable");
627 698 }
628 return i; 699 }
629}
630
631
632
633 700
701 return i;
702}
634 703
635/* CLEANING STOPPED HERE */ 704/* CLEANING STOPPED HERE */
636 705
637
638
639
640/* Shift shift_num (shift_bytes) items from S[0] to the right neighbor, and replace the delimiting key */ 706/* Shift shift_num (shift_bytes) items from S[0] to the right neighbor, and replace the delimiting key */
641int leaf_shift_right( 707int leaf_shift_right(struct tree_balance *tb, int shift_num, int shift_bytes)
642 struct tree_balance * tb,
643 int shift_num,
644 int shift_bytes
645 )
646{ 708{
647 // struct buffer_head * S0 = PATH_PLAST_BUFFER (tb->tb_path); 709 // struct buffer_head * S0 = PATH_PLAST_BUFFER (tb->tb_path);
648 int ret_value; 710 int ret_value;
649 711
650 /* move shift_num (and shift_bytes) items from S[0] to right neighbor R[0] */ 712 /* move shift_num (and shift_bytes) items from S[0] to right neighbor R[0] */
651 ret_value = leaf_move_items (LEAF_FROM_S_TO_R, tb, shift_num, shift_bytes, NULL); 713 ret_value =
714 leaf_move_items(LEAF_FROM_S_TO_R, tb, shift_num, shift_bytes, NULL);
652 715
653 /* replace rkey in CFR[0] by the 0-th key from R[0] */ 716 /* replace rkey in CFR[0] by the 0-th key from R[0] */
654 if (shift_num) { 717 if (shift_num) {
655 replace_key (tb, tb->CFR[0], tb->rkey[0], tb->R[0], 0); 718 replace_key(tb, tb->CFR[0], tb->rkey[0], tb->R[0], 0);
656 719
657 } 720 }
658 721
659 return ret_value; 722 return ret_value;
660} 723}
661 724
662 725static void leaf_delete_items_entirely(struct buffer_info *bi,
663 726 int first, int del_num);
664static void leaf_delete_items_entirely (struct buffer_info * bi,
665 int first, int del_num);
666/* If del_bytes == -1, starting from position 'first' delete del_num items in whole in buffer CUR. 727/* If del_bytes == -1, starting from position 'first' delete del_num items in whole in buffer CUR.
667 If not. 728 If not.
668 If last_first == 0. Starting from position 'first' delete del_num-1 items in whole. Delete part of body of 729 If last_first == 0. Starting from position 'first' delete del_num-1 items in whole. Delete part of body of
@@ -670,287 +731,292 @@ static void leaf_delete_items_entirely (struct buffer_info * bi,
670 If last_first == 1. Starting from position 'first+1' delete del_num-1 items in whole. Delete part of body of 731 If last_first == 1. Starting from position 'first+1' delete del_num-1 items in whole. Delete part of body of
671 the last item . Part defined by del_bytes. Don't delete last item header. 732 the last item . Part defined by del_bytes. Don't delete last item header.
672*/ 733*/
673void leaf_delete_items (struct buffer_info * cur_bi, int last_first, 734void leaf_delete_items(struct buffer_info *cur_bi, int last_first,
674 int first, int del_num, int del_bytes) 735 int first, int del_num, int del_bytes)
675{ 736{
676 struct buffer_head * bh; 737 struct buffer_head *bh;
677 int item_amount = B_NR_ITEMS (bh = cur_bi->bi_bh); 738 int item_amount = B_NR_ITEMS(bh = cur_bi->bi_bh);
678 739
679 RFALSE( !bh, "10155: bh is not defined"); 740 RFALSE(!bh, "10155: bh is not defined");
680 RFALSE( del_num < 0, "10160: del_num can not be < 0. del_num==%d", del_num); 741 RFALSE(del_num < 0, "10160: del_num can not be < 0. del_num==%d",
681 RFALSE( first < 0 || first + del_num > item_amount, 742 del_num);
682 "10165: invalid number of first item to be deleted (%d) or " 743 RFALSE(first < 0
683 "no so much items (%d) to delete (only %d)", 744 || first + del_num > item_amount,
684 first, first + del_num, item_amount); 745 "10165: invalid number of first item to be deleted (%d) or "
685 746 "no so much items (%d) to delete (only %d)", first,
686 if ( del_num == 0 ) 747 first + del_num, item_amount);
687 return; 748
688 749 if (del_num == 0)
689 if ( first == 0 && del_num == item_amount && del_bytes == -1 ) { 750 return;
690 make_empty_node (cur_bi); 751
691 do_balance_mark_leaf_dirty (cur_bi->tb, bh, 0); 752 if (first == 0 && del_num == item_amount && del_bytes == -1) {
692 return; 753 make_empty_node(cur_bi);
693 } 754 do_balance_mark_leaf_dirty(cur_bi->tb, bh, 0);
694 755 return;
695 if ( del_bytes == -1 )
696 /* delete del_num items beginning from item in position first */
697 leaf_delete_items_entirely (cur_bi, first, del_num);
698 else {
699 if ( last_first == FIRST_TO_LAST ) {
700 /* delete del_num-1 items beginning from item in position first */
701 leaf_delete_items_entirely (cur_bi, first, del_num-1);
702
703 /* delete the part of the first item of the bh
704 do not delete item header
705 */
706 leaf_cut_from_buffer (cur_bi, 0, 0, del_bytes);
707 } else {
708 struct item_head * ih;
709 int len;
710
711 /* delete del_num-1 items beginning from item in position first+1 */
712 leaf_delete_items_entirely (cur_bi, first+1, del_num-1);
713
714 if (is_direntry_le_ih (ih = B_N_PITEM_HEAD(bh, B_NR_ITEMS(bh)-1))) /* the last item is directory */
715 /* len = numbers of directory entries in this item */
716 len = ih_entry_count(ih);
717 else
718 /* len = body len of item */
719 len = ih_item_len(ih);
720
721 /* delete the part of the last item of the bh
722 do not delete item header
723 */
724 leaf_cut_from_buffer (cur_bi, B_NR_ITEMS(bh)-1, len - del_bytes, del_bytes);
725 } 756 }
726 }
727}
728 757
758 if (del_bytes == -1)
759 /* delete del_num items beginning from item in position first */
760 leaf_delete_items_entirely(cur_bi, first, del_num);
761 else {
762 if (last_first == FIRST_TO_LAST) {
763 /* delete del_num-1 items beginning from item in position first */
764 leaf_delete_items_entirely(cur_bi, first, del_num - 1);
765
766 /* delete the part of the first item of the bh
767 do not delete item header
768 */
769 leaf_cut_from_buffer(cur_bi, 0, 0, del_bytes);
770 } else {
771 struct item_head *ih;
772 int len;
773
774 /* delete del_num-1 items beginning from item in position first+1 */
775 leaf_delete_items_entirely(cur_bi, first + 1,
776 del_num - 1);
777
778 if (is_direntry_le_ih
779 (ih = B_N_PITEM_HEAD(bh, B_NR_ITEMS(bh) - 1)))
780 /* the last item is directory */
781 /* len = numbers of directory entries in this item */
782 len = ih_entry_count(ih);
783 else
784 /* len = body len of item */
785 len = ih_item_len(ih);
786
787 /* delete the part of the last item of the bh
788 do not delete item header
789 */
790 leaf_cut_from_buffer(cur_bi, B_NR_ITEMS(bh) - 1,
791 len - del_bytes, del_bytes);
792 }
793 }
794}
729 795
730/* insert item into the leaf node in position before */ 796/* insert item into the leaf node in position before */
731void leaf_insert_into_buf (struct buffer_info * bi, int before, 797void leaf_insert_into_buf(struct buffer_info *bi, int before,
732 struct item_head * inserted_item_ih, 798 struct item_head *inserted_item_ih,
733 const char * inserted_item_body, 799 const char *inserted_item_body, int zeros_number)
734 int zeros_number)
735{ 800{
736 struct buffer_head * bh = bi->bi_bh; 801 struct buffer_head *bh = bi->bi_bh;
737 int nr, free_space; 802 int nr, free_space;
738 struct block_head * blkh; 803 struct block_head *blkh;
739 struct item_head * ih; 804 struct item_head *ih;
740 int i; 805 int i;
741 int last_loc, unmoved_loc; 806 int last_loc, unmoved_loc;
742 char * to; 807 char *to;
743 808
744 809 blkh = B_BLK_HEAD(bh);
745 blkh = B_BLK_HEAD(bh); 810 nr = blkh_nr_item(blkh);
746 nr = blkh_nr_item(blkh); 811 free_space = blkh_free_space(blkh);
747 free_space = blkh_free_space( blkh ); 812
748 813 /* check free space */
749 /* check free space */ 814 RFALSE(free_space < ih_item_len(inserted_item_ih) + IH_SIZE,
750 RFALSE( free_space < ih_item_len(inserted_item_ih) + IH_SIZE, 815 "vs-10170: not enough free space in block %z, new item %h",
751 "vs-10170: not enough free space in block %z, new item %h", 816 bh, inserted_item_ih);
752 bh, inserted_item_ih); 817 RFALSE(zeros_number > ih_item_len(inserted_item_ih),
753 RFALSE( zeros_number > ih_item_len(inserted_item_ih), 818 "vs-10172: zero number == %d, item length == %d",
754 "vs-10172: zero number == %d, item length == %d", 819 zeros_number, ih_item_len(inserted_item_ih));
755 zeros_number, ih_item_len(inserted_item_ih)); 820
756 821 /* get item new item must be inserted before */
757 822 ih = B_N_PITEM_HEAD(bh, before);
758 /* get item new item must be inserted before */ 823
759 ih = B_N_PITEM_HEAD (bh, before); 824 /* prepare space for the body of new item */
760 825 last_loc = nr ? ih_location(&(ih[nr - before - 1])) : bh->b_size;
761 /* prepare space for the body of new item */ 826 unmoved_loc = before ? ih_location(ih - 1) : bh->b_size;
762 last_loc = nr ? ih_location( &(ih[nr - before - 1]) ) : bh->b_size; 827
763 unmoved_loc = before ? ih_location( ih-1 ) : bh->b_size; 828 memmove(bh->b_data + last_loc - ih_item_len(inserted_item_ih),
764 829 bh->b_data + last_loc, unmoved_loc - last_loc);
765 830
766 memmove (bh->b_data + last_loc - ih_item_len(inserted_item_ih), 831 to = bh->b_data + unmoved_loc - ih_item_len(inserted_item_ih);
767 bh->b_data + last_loc, unmoved_loc - last_loc); 832 memset(to, 0, zeros_number);
768 833 to += zeros_number;
769 to = bh->b_data + unmoved_loc - ih_item_len(inserted_item_ih); 834
770 memset (to, 0, zeros_number); 835 /* copy body to prepared space */
771 to += zeros_number; 836 if (inserted_item_body)
772 837 memmove(to, inserted_item_body,
773 /* copy body to prepared space */ 838 ih_item_len(inserted_item_ih) - zeros_number);
774 if (inserted_item_body) 839 else
775 memmove (to, inserted_item_body, ih_item_len(inserted_item_ih) - zeros_number); 840 memset(to, '\0', ih_item_len(inserted_item_ih) - zeros_number);
776 else 841
777 memset(to, '\0', ih_item_len(inserted_item_ih) - zeros_number); 842 /* insert item header */
778 843 memmove(ih + 1, ih, IH_SIZE * (nr - before));
779 /* insert item header */ 844 memmove(ih, inserted_item_ih, IH_SIZE);
780 memmove (ih + 1, ih, IH_SIZE * (nr - before)); 845
781 memmove (ih, inserted_item_ih, IH_SIZE); 846 /* change locations */
782 847 for (i = before; i < nr + 1; i++) {
783 /* change locations */ 848 unmoved_loc -= ih_item_len(&(ih[i - before]));
784 for (i = before; i < nr + 1; i ++) 849 put_ih_location(&(ih[i - before]), unmoved_loc);
785 { 850 }
786 unmoved_loc -= ih_item_len( &(ih[i-before]));
787 put_ih_location( &(ih[i-before]), unmoved_loc );
788 }
789
790 /* sizes, free space, item number */
791 set_blkh_nr_item( blkh, blkh_nr_item(blkh) + 1 );
792 set_blkh_free_space( blkh,
793 free_space - (IH_SIZE + ih_item_len(inserted_item_ih ) ) );
794 do_balance_mark_leaf_dirty (bi->tb, bh, 1);
795
796 if (bi->bi_parent) {
797 struct disk_child *t_dc;
798 t_dc = B_N_CHILD (bi->bi_parent, bi->bi_position);
799 put_dc_size( t_dc, dc_size(t_dc) + (IH_SIZE + ih_item_len(inserted_item_ih)));
800 do_balance_mark_internal_dirty (bi->tb, bi->bi_parent, 0);
801 }
802}
803 851
852 /* sizes, free space, item number */
853 set_blkh_nr_item(blkh, blkh_nr_item(blkh) + 1);
854 set_blkh_free_space(blkh,
855 free_space - (IH_SIZE +
856 ih_item_len(inserted_item_ih)));
857 do_balance_mark_leaf_dirty(bi->tb, bh, 1);
858
859 if (bi->bi_parent) {
860 struct disk_child *t_dc;
861 t_dc = B_N_CHILD(bi->bi_parent, bi->bi_position);
862 put_dc_size(t_dc,
863 dc_size(t_dc) + (IH_SIZE +
864 ih_item_len(inserted_item_ih)));
865 do_balance_mark_internal_dirty(bi->tb, bi->bi_parent, 0);
866 }
867}
804 868
805/* paste paste_size bytes to affected_item_num-th item. 869/* paste paste_size bytes to affected_item_num-th item.
806 When item is a directory, this only prepare space for new entries */ 870 When item is a directory, this only prepare space for new entries */
807void leaf_paste_in_buffer (struct buffer_info * bi, int affected_item_num, 871void leaf_paste_in_buffer(struct buffer_info *bi, int affected_item_num,
808 int pos_in_item, int paste_size, 872 int pos_in_item, int paste_size,
809 const char * body, 873 const char *body, int zeros_number)
810 int zeros_number)
811{ 874{
812 struct buffer_head * bh = bi->bi_bh; 875 struct buffer_head *bh = bi->bi_bh;
813 int nr, free_space; 876 int nr, free_space;
814 struct block_head * blkh; 877 struct block_head *blkh;
815 struct item_head * ih; 878 struct item_head *ih;
816 int i; 879 int i;
817 int last_loc, unmoved_loc; 880 int last_loc, unmoved_loc;
818 881
819 blkh = B_BLK_HEAD(bh); 882 blkh = B_BLK_HEAD(bh);
820 nr = blkh_nr_item(blkh); 883 nr = blkh_nr_item(blkh);
821 free_space = blkh_free_space(blkh); 884 free_space = blkh_free_space(blkh);
822 885
823 886 /* check free space */
824 /* check free space */ 887 RFALSE(free_space < paste_size,
825 RFALSE( free_space < paste_size, 888 "vs-10175: not enough free space: needed %d, available %d",
826 "vs-10175: not enough free space: needed %d, available %d", 889 paste_size, free_space);
827 paste_size, free_space);
828 890
829#ifdef CONFIG_REISERFS_CHECK 891#ifdef CONFIG_REISERFS_CHECK
830 if (zeros_number > paste_size) { 892 if (zeros_number > paste_size) {
831 print_cur_tb ("10177"); 893 print_cur_tb("10177");
832 reiserfs_panic ( NULL, "vs-10177: leaf_paste_in_buffer: ero number == %d, paste_size == %d", 894 reiserfs_panic(NULL,
833 zeros_number, paste_size); 895 "vs-10177: leaf_paste_in_buffer: ero number == %d, paste_size == %d",
834 } 896 zeros_number, paste_size);
835#endif /* CONFIG_REISERFS_CHECK */ 897 }
836 898#endif /* CONFIG_REISERFS_CHECK */
837 899
838 /* item to be appended */ 900 /* item to be appended */
839 ih = B_N_PITEM_HEAD(bh, affected_item_num); 901 ih = B_N_PITEM_HEAD(bh, affected_item_num);
840 902
841 last_loc = ih_location( &(ih[nr - affected_item_num - 1]) ); 903 last_loc = ih_location(&(ih[nr - affected_item_num - 1]));
842 unmoved_loc = affected_item_num ? ih_location( ih-1 ) : bh->b_size; 904 unmoved_loc = affected_item_num ? ih_location(ih - 1) : bh->b_size;
843 905
844 /* prepare space */ 906 /* prepare space */
845 memmove (bh->b_data + last_loc - paste_size, bh->b_data + last_loc, 907 memmove(bh->b_data + last_loc - paste_size, bh->b_data + last_loc,
846 unmoved_loc - last_loc); 908 unmoved_loc - last_loc);
847 909
848 910 /* change locations */
849 /* change locations */ 911 for (i = affected_item_num; i < nr; i++)
850 for (i = affected_item_num; i < nr; i ++) 912 put_ih_location(&(ih[i - affected_item_num]),
851 put_ih_location( &(ih[i-affected_item_num]), 913 ih_location(&(ih[i - affected_item_num])) -
852 ih_location( &(ih[i-affected_item_num])) - paste_size ); 914 paste_size);
853 915
854 if ( body ) { 916 if (body) {
855 if (!is_direntry_le_ih (ih)) { 917 if (!is_direntry_le_ih(ih)) {
856 if (!pos_in_item) { 918 if (!pos_in_item) {
857 /* shift data to right */ 919 /* shift data to right */
858 memmove (bh->b_data + ih_location(ih) + paste_size, 920 memmove(bh->b_data + ih_location(ih) +
859 bh->b_data + ih_location(ih), ih_item_len(ih)); 921 paste_size,
860 /* paste data in the head of item */ 922 bh->b_data + ih_location(ih),
861 memset (bh->b_data + ih_location(ih), 0, zeros_number); 923 ih_item_len(ih));
862 memcpy (bh->b_data + ih_location(ih) + zeros_number, body, paste_size - zeros_number); 924 /* paste data in the head of item */
863 } else { 925 memset(bh->b_data + ih_location(ih), 0,
864 memset (bh->b_data + unmoved_loc - paste_size, 0, zeros_number); 926 zeros_number);
865 memcpy (bh->b_data + unmoved_loc - paste_size + zeros_number, body, paste_size - zeros_number); 927 memcpy(bh->b_data + ih_location(ih) +
866 } 928 zeros_number, body,
929 paste_size - zeros_number);
930 } else {
931 memset(bh->b_data + unmoved_loc - paste_size, 0,
932 zeros_number);
933 memcpy(bh->b_data + unmoved_loc - paste_size +
934 zeros_number, body,
935 paste_size - zeros_number);
936 }
937 }
938 } else
939 memset(bh->b_data + unmoved_loc - paste_size, '\0', paste_size);
940
941 put_ih_item_len(ih, ih_item_len(ih) + paste_size);
942
943 /* change free space */
944 set_blkh_free_space(blkh, free_space - paste_size);
945
946 do_balance_mark_leaf_dirty(bi->tb, bh, 0);
947
948 if (bi->bi_parent) {
949 struct disk_child *t_dc =
950 B_N_CHILD(bi->bi_parent, bi->bi_position);
951 put_dc_size(t_dc, dc_size(t_dc) + paste_size);
952 do_balance_mark_internal_dirty(bi->tb, bi->bi_parent, 0);
867 } 953 }
868 }
869 else
870 memset(bh->b_data + unmoved_loc - paste_size, '\0', paste_size);
871
872 put_ih_item_len( ih, ih_item_len(ih) + paste_size );
873
874 /* change free space */
875 set_blkh_free_space( blkh, free_space - paste_size );
876
877 do_balance_mark_leaf_dirty (bi->tb, bh, 0);
878
879 if (bi->bi_parent) {
880 struct disk_child *t_dc = B_N_CHILD (bi->bi_parent, bi->bi_position);
881 put_dc_size( t_dc, dc_size(t_dc) + paste_size );
882 do_balance_mark_internal_dirty (bi->tb, bi->bi_parent, 0);
883 }
884} 954}
885 955
886
887/* cuts DEL_COUNT entries beginning from FROM-th entry. Directory item 956/* cuts DEL_COUNT entries beginning from FROM-th entry. Directory item
888 does not have free space, so it moves DEHs and remaining records as 957 does not have free space, so it moves DEHs and remaining records as
889 necessary. Return value is size of removed part of directory item 958 necessary. Return value is size of removed part of directory item
890 in bytes. */ 959 in bytes. */
891static int leaf_cut_entries ( 960static int leaf_cut_entries(struct buffer_head *bh,
892 struct buffer_head * bh, 961 struct item_head *ih, int from, int del_count)
893 struct item_head * ih,
894 int from,
895 int del_count
896 )
897{ 962{
898 char * item; 963 char *item;
899 struct reiserfs_de_head * deh; 964 struct reiserfs_de_head *deh;
900 int prev_record_offset; /* offset of record, that is (from-1)th */ 965 int prev_record_offset; /* offset of record, that is (from-1)th */
901 char * prev_record; /* */ 966 char *prev_record; /* */
902 int cut_records_len; /* length of all removed records */ 967 int cut_records_len; /* length of all removed records */
903 int i; 968 int i;
904 969
905 970 /* make sure, that item is directory and there are enough entries to
906 /* make sure, that item is directory and there are enough entries to 971 remove */
907 remove */ 972 RFALSE(!is_direntry_le_ih(ih), "10180: item is not directory item");
908 RFALSE( !is_direntry_le_ih (ih), "10180: item is not directory item"); 973 RFALSE(I_ENTRY_COUNT(ih) < from + del_count,
909 RFALSE( I_ENTRY_COUNT(ih) < from + del_count, 974 "10185: item contains not enough entries: entry_cout = %d, from = %d, to delete = %d",
910 "10185: item contains not enough entries: entry_cout = %d, from = %d, to delete = %d", 975 I_ENTRY_COUNT(ih), from, del_count);
911 I_ENTRY_COUNT(ih), from, del_count); 976
912 977 if (del_count == 0)
913 if (del_count == 0) 978 return 0;
914 return 0; 979
915 980 /* first byte of item */
916 /* first byte of item */ 981 item = bh->b_data + ih_location(ih);
917 item = bh->b_data + ih_location(ih); 982
918 983 /* entry head array */
919 /* entry head array */ 984 deh = B_I_DEH(bh, ih);
920 deh = B_I_DEH (bh, ih); 985
921 986 /* first byte of remaining entries, those are BEFORE cut entries
922 /* first byte of remaining entries, those are BEFORE cut entries 987 (prev_record) and length of all removed records (cut_records_len) */
923 (prev_record) and length of all removed records (cut_records_len) */ 988 prev_record_offset =
924 prev_record_offset = (from ? deh_location( &(deh[from - 1])) : ih_item_len(ih)); 989 (from ? deh_location(&(deh[from - 1])) : ih_item_len(ih));
925 cut_records_len = prev_record_offset/*from_record*/ - 990 cut_records_len = prev_record_offset /*from_record */ -
926 deh_location( &(deh[from + del_count - 1])); 991 deh_location(&(deh[from + del_count - 1]));
927 prev_record = item + prev_record_offset; 992 prev_record = item + prev_record_offset;
928 993
929 994 /* adjust locations of remaining entries */
930 /* adjust locations of remaining entries */ 995 for (i = I_ENTRY_COUNT(ih) - 1; i > from + del_count - 1; i--)
931 for (i = I_ENTRY_COUNT(ih) - 1; i > from + del_count - 1; i --) 996 put_deh_location(&(deh[i]),
932 put_deh_location( &(deh[i]), 997 deh_location(&deh[i]) -
933 deh_location( &deh[i] ) - (DEH_SIZE * del_count ) ); 998 (DEH_SIZE * del_count));
934 999
935 for (i = 0; i < from; i ++) 1000 for (i = 0; i < from; i++)
936 put_deh_location( &(deh[i]), 1001 put_deh_location(&(deh[i]),
937 deh_location( &deh[i] ) - (DEH_SIZE * del_count + cut_records_len) ); 1002 deh_location(&deh[i]) - (DEH_SIZE * del_count +
938 1003 cut_records_len));
939 put_ih_entry_count( ih, ih_entry_count(ih) - del_count ); 1004
940 1005 put_ih_entry_count(ih, ih_entry_count(ih) - del_count);
941 /* shift entry head array and entries those are AFTER removed entries */ 1006
942 memmove ((char *)(deh + from), 1007 /* shift entry head array and entries those are AFTER removed entries */
943 deh + from + del_count, 1008 memmove((char *)(deh + from),
944 prev_record - cut_records_len - (char *)(deh + from + del_count)); 1009 deh + from + del_count,
945 1010 prev_record - cut_records_len - (char *)(deh + from +
946 /* shift records, those are BEFORE removed entries */ 1011 del_count));
947 memmove (prev_record - cut_records_len - DEH_SIZE * del_count, 1012
948 prev_record, item + ih_item_len(ih) - prev_record); 1013 /* shift records, those are BEFORE removed entries */
949 1014 memmove(prev_record - cut_records_len - DEH_SIZE * del_count,
950 return DEH_SIZE * del_count + cut_records_len; 1015 prev_record, item + ih_item_len(ih) - prev_record);
1016
1017 return DEH_SIZE * del_count + cut_records_len;
951} 1018}
952 1019
953
954/* when cut item is part of regular file 1020/* when cut item is part of regular file
955 pos_in_item - first byte that must be cut 1021 pos_in_item - first byte that must be cut
956 cut_size - number of bytes to be cut beginning from pos_in_item 1022 cut_size - number of bytes to be cut beginning from pos_in_item
@@ -959,264 +1025,278 @@ static int leaf_cut_entries (
959 pos_in_item - number of first deleted entry 1025 pos_in_item - number of first deleted entry
960 cut_size - count of deleted entries 1026 cut_size - count of deleted entries
961 */ 1027 */
962void leaf_cut_from_buffer (struct buffer_info * bi, int cut_item_num, 1028void leaf_cut_from_buffer(struct buffer_info *bi, int cut_item_num,
963 int pos_in_item, int cut_size) 1029 int pos_in_item, int cut_size)
964{ 1030{
965 int nr; 1031 int nr;
966 struct buffer_head * bh = bi->bi_bh; 1032 struct buffer_head *bh = bi->bi_bh;
967 struct block_head * blkh; 1033 struct block_head *blkh;
968 struct item_head * ih; 1034 struct item_head *ih;
969 int last_loc, unmoved_loc; 1035 int last_loc, unmoved_loc;
970 int i; 1036 int i;
971 1037
972 blkh = B_BLK_HEAD(bh); 1038 blkh = B_BLK_HEAD(bh);
973 nr = blkh_nr_item(blkh); 1039 nr = blkh_nr_item(blkh);
974 1040
975 /* item head of truncated item */ 1041 /* item head of truncated item */
976 ih = B_N_PITEM_HEAD (bh, cut_item_num); 1042 ih = B_N_PITEM_HEAD(bh, cut_item_num);
977 1043
978 if (is_direntry_le_ih (ih)) { 1044 if (is_direntry_le_ih(ih)) {
979 /* first cut entry ()*/ 1045 /* first cut entry () */
980 cut_size = leaf_cut_entries (bh, ih, pos_in_item, cut_size); 1046 cut_size = leaf_cut_entries(bh, ih, pos_in_item, cut_size);
981 if (pos_in_item == 0) { 1047 if (pos_in_item == 0) {
982 /* change key */ 1048 /* change key */
983 RFALSE( cut_item_num, 1049 RFALSE(cut_item_num,
984 "when 0-th enrty of item is cut, that item must be first in the node, not %d-th", cut_item_num); 1050 "when 0-th enrty of item is cut, that item must be first in the node, not %d-th",
985 /* change item key by key of first entry in the item */ 1051 cut_item_num);
986 set_le_ih_k_offset (ih, deh_offset(B_I_DEH (bh, ih))); 1052 /* change item key by key of first entry in the item */
987 /*memcpy (&ih->ih_key.k_offset, &(B_I_DEH (bh, ih)->deh_offset), SHORT_KEY_SIZE);*/ 1053 set_le_ih_k_offset(ih, deh_offset(B_I_DEH(bh, ih)));
988 } 1054 /*memcpy (&ih->ih_key.k_offset, &(B_I_DEH (bh, ih)->deh_offset), SHORT_KEY_SIZE); */
989 } else { 1055 }
990 /* item is direct or indirect */ 1056 } else {
991 RFALSE( is_statdata_le_ih (ih), "10195: item is stat data"); 1057 /* item is direct or indirect */
992 RFALSE( pos_in_item && pos_in_item + cut_size != ih_item_len(ih), 1058 RFALSE(is_statdata_le_ih(ih), "10195: item is stat data");
993 "10200: invalid offset (%lu) or trunc_size (%lu) or ih_item_len (%lu)", 1059 RFALSE(pos_in_item && pos_in_item + cut_size != ih_item_len(ih),
994 ( long unsigned ) pos_in_item, ( long unsigned ) cut_size, 1060 "10200: invalid offset (%lu) or trunc_size (%lu) or ih_item_len (%lu)",
995 ( long unsigned ) ih_item_len (ih)); 1061 (long unsigned)pos_in_item, (long unsigned)cut_size,
996 1062 (long unsigned)ih_item_len(ih));
997 /* shift item body to left if cut is from the head of item */ 1063
998 if (pos_in_item == 0) { 1064 /* shift item body to left if cut is from the head of item */
999 memmove( bh->b_data + ih_location(ih), 1065 if (pos_in_item == 0) {
1000 bh->b_data + ih_location(ih) + cut_size, 1066 memmove(bh->b_data + ih_location(ih),
1001 ih_item_len(ih) - cut_size); 1067 bh->b_data + ih_location(ih) + cut_size,
1002 1068 ih_item_len(ih) - cut_size);
1003 /* change key of item */ 1069
1004 if (is_direct_le_ih (ih)) 1070 /* change key of item */
1005 set_le_ih_k_offset (ih, le_ih_k_offset (ih) + cut_size); 1071 if (is_direct_le_ih(ih))
1006 else { 1072 set_le_ih_k_offset(ih,
1007 set_le_ih_k_offset (ih, le_ih_k_offset (ih) + (cut_size / UNFM_P_SIZE) * bh->b_size); 1073 le_ih_k_offset(ih) +
1008 RFALSE( ih_item_len(ih) == cut_size && get_ih_free_space (ih), 1074 cut_size);
1009 "10205: invalid ih_free_space (%h)", ih); 1075 else {
1010 } 1076 set_le_ih_k_offset(ih,
1011 } 1077 le_ih_k_offset(ih) +
1012 } 1078 (cut_size / UNFM_P_SIZE) *
1013 1079 bh->b_size);
1014 1080 RFALSE(ih_item_len(ih) == cut_size
1015 /* location of the last item */ 1081 && get_ih_free_space(ih),
1016 last_loc = ih_location( &(ih[nr - cut_item_num - 1]) ); 1082 "10205: invalid ih_free_space (%h)", ih);
1017 1083 }
1018 /* location of the item, which is remaining at the same place */ 1084 }
1019 unmoved_loc = cut_item_num ? ih_location(ih-1) : bh->b_size; 1085 }
1020 1086
1021 1087 /* location of the last item */
1022 /* shift */ 1088 last_loc = ih_location(&(ih[nr - cut_item_num - 1]));
1023 memmove (bh->b_data + last_loc + cut_size, bh->b_data + last_loc, 1089
1024 unmoved_loc - last_loc - cut_size); 1090 /* location of the item, which is remaining at the same place */
1025 1091 unmoved_loc = cut_item_num ? ih_location(ih - 1) : bh->b_size;
1026 /* change item length */ 1092
1027 put_ih_item_len( ih, ih_item_len(ih) - cut_size ); 1093 /* shift */
1028 1094 memmove(bh->b_data + last_loc + cut_size, bh->b_data + last_loc,
1029 if (is_indirect_le_ih (ih)) { 1095 unmoved_loc - last_loc - cut_size);
1030 if (pos_in_item) 1096
1031 set_ih_free_space (ih, 0); 1097 /* change item length */
1032 } 1098 put_ih_item_len(ih, ih_item_len(ih) - cut_size);
1033
1034 /* change locations */
1035 for (i = cut_item_num; i < nr; i ++)
1036 put_ih_location( &(ih[i-cut_item_num]), ih_location( &ih[i-cut_item_num]) + cut_size );
1037
1038 /* size, free space */
1039 set_blkh_free_space( blkh, blkh_free_space(blkh) + cut_size );
1040
1041 do_balance_mark_leaf_dirty (bi->tb, bh, 0);
1042
1043 if (bi->bi_parent) {
1044 struct disk_child *t_dc;
1045 t_dc = B_N_CHILD (bi->bi_parent, bi->bi_position);
1046 put_dc_size( t_dc, dc_size(t_dc) - cut_size );
1047 do_balance_mark_internal_dirty (bi->tb, bi->bi_parent, 0);
1048 }
1049}
1050 1099
1100 if (is_indirect_le_ih(ih)) {
1101 if (pos_in_item)
1102 set_ih_free_space(ih, 0);
1103 }
1104
1105 /* change locations */
1106 for (i = cut_item_num; i < nr; i++)
1107 put_ih_location(&(ih[i - cut_item_num]),
1108 ih_location(&ih[i - cut_item_num]) + cut_size);
1109
1110 /* size, free space */
1111 set_blkh_free_space(blkh, blkh_free_space(blkh) + cut_size);
1112
1113 do_balance_mark_leaf_dirty(bi->tb, bh, 0);
1114
1115 if (bi->bi_parent) {
1116 struct disk_child *t_dc;
1117 t_dc = B_N_CHILD(bi->bi_parent, bi->bi_position);
1118 put_dc_size(t_dc, dc_size(t_dc) - cut_size);
1119 do_balance_mark_internal_dirty(bi->tb, bi->bi_parent, 0);
1120 }
1121}
1051 1122
1052/* delete del_num items from buffer starting from the first'th item */ 1123/* delete del_num items from buffer starting from the first'th item */
1053static void leaf_delete_items_entirely (struct buffer_info * bi, 1124static void leaf_delete_items_entirely(struct buffer_info *bi,
1054 int first, int del_num) 1125 int first, int del_num)
1055{ 1126{
1056 struct buffer_head * bh = bi->bi_bh; 1127 struct buffer_head *bh = bi->bi_bh;
1057 int nr; 1128 int nr;
1058 int i, j; 1129 int i, j;
1059 int last_loc, last_removed_loc; 1130 int last_loc, last_removed_loc;
1060 struct block_head * blkh; 1131 struct block_head *blkh;
1061 struct item_head * ih; 1132 struct item_head *ih;
1062 1133
1063 RFALSE( bh == NULL, "10210: buffer is 0"); 1134 RFALSE(bh == NULL, "10210: buffer is 0");
1064 RFALSE( del_num < 0, "10215: del_num less than 0 (%d)", del_num); 1135 RFALSE(del_num < 0, "10215: del_num less than 0 (%d)", del_num);
1065 1136
1066 if (del_num == 0) 1137 if (del_num == 0)
1067 return; 1138 return;
1068 1139
1069 blkh = B_BLK_HEAD(bh); 1140 blkh = B_BLK_HEAD(bh);
1070 nr = blkh_nr_item(blkh); 1141 nr = blkh_nr_item(blkh);
1071
1072 RFALSE( first < 0 || first + del_num > nr,
1073 "10220: first=%d, number=%d, there is %d items", first, del_num, nr);
1074
1075 if (first == 0 && del_num == nr) {
1076 /* this does not work */
1077 make_empty_node (bi);
1078
1079 do_balance_mark_leaf_dirty (bi->tb, bh, 0);
1080 return;
1081 }
1082
1083 ih = B_N_PITEM_HEAD (bh, first);
1084
1085 /* location of unmovable item */
1086 j = (first == 0) ? bh->b_size : ih_location(ih-1);
1087
1088 /* delete items */
1089 last_loc = ih_location( &(ih[nr-1-first]) );
1090 last_removed_loc = ih_location( &(ih[del_num-1]) );
1091
1092 memmove (bh->b_data + last_loc + j - last_removed_loc,
1093 bh->b_data + last_loc, last_removed_loc - last_loc);
1094
1095 /* delete item headers */
1096 memmove (ih, ih + del_num, (nr - first - del_num) * IH_SIZE);
1097
1098 /* change item location */
1099 for (i = first; i < nr - del_num; i ++)
1100 put_ih_location( &(ih[i-first]), ih_location( &(ih[i-first]) ) + (j - last_removed_loc) );
1101
1102 /* sizes, item number */
1103 set_blkh_nr_item( blkh, blkh_nr_item(blkh) - del_num );
1104 set_blkh_free_space( blkh, blkh_free_space(blkh) + (j - last_removed_loc + IH_SIZE * del_num) );
1105
1106 do_balance_mark_leaf_dirty (bi->tb, bh, 0);
1107
1108 if (bi->bi_parent) {
1109 struct disk_child *t_dc = B_N_CHILD (bi->bi_parent, bi->bi_position);
1110 put_dc_size( t_dc, dc_size(t_dc) -
1111 (j - last_removed_loc + IH_SIZE * del_num));
1112 do_balance_mark_internal_dirty (bi->tb, bi->bi_parent, 0);
1113 }
1114}
1115 1142
1143 RFALSE(first < 0 || first + del_num > nr,
1144 "10220: first=%d, number=%d, there is %d items", first, del_num,
1145 nr);
1146
1147 if (first == 0 && del_num == nr) {
1148 /* this does not work */
1149 make_empty_node(bi);
1150
1151 do_balance_mark_leaf_dirty(bi->tb, bh, 0);
1152 return;
1153 }
1116 1154
1155 ih = B_N_PITEM_HEAD(bh, first);
1117 1156
1157 /* location of unmovable item */
1158 j = (first == 0) ? bh->b_size : ih_location(ih - 1);
1118 1159
1160 /* delete items */
1161 last_loc = ih_location(&(ih[nr - 1 - first]));
1162 last_removed_loc = ih_location(&(ih[del_num - 1]));
1163
1164 memmove(bh->b_data + last_loc + j - last_removed_loc,
1165 bh->b_data + last_loc, last_removed_loc - last_loc);
1166
1167 /* delete item headers */
1168 memmove(ih, ih + del_num, (nr - first - del_num) * IH_SIZE);
1169
1170 /* change item location */
1171 for (i = first; i < nr - del_num; i++)
1172 put_ih_location(&(ih[i - first]),
1173 ih_location(&(ih[i - first])) + (j -
1174 last_removed_loc));
1175
1176 /* sizes, item number */
1177 set_blkh_nr_item(blkh, blkh_nr_item(blkh) - del_num);
1178 set_blkh_free_space(blkh,
1179 blkh_free_space(blkh) + (j - last_removed_loc +
1180 IH_SIZE * del_num));
1181
1182 do_balance_mark_leaf_dirty(bi->tb, bh, 0);
1183
1184 if (bi->bi_parent) {
1185 struct disk_child *t_dc =
1186 B_N_CHILD(bi->bi_parent, bi->bi_position);
1187 put_dc_size(t_dc,
1188 dc_size(t_dc) - (j - last_removed_loc +
1189 IH_SIZE * del_num));
1190 do_balance_mark_internal_dirty(bi->tb, bi->bi_parent, 0);
1191 }
1192}
1119 1193
1120/* paste new_entry_count entries (new_dehs, records) into position before to item_num-th item */ 1194/* paste new_entry_count entries (new_dehs, records) into position before to item_num-th item */
1121void leaf_paste_entries ( 1195void leaf_paste_entries(struct buffer_head *bh,
1122 struct buffer_head * bh,
1123 int item_num, 1196 int item_num,
1124 int before, 1197 int before,
1125 int new_entry_count, 1198 int new_entry_count,
1126 struct reiserfs_de_head * new_dehs, 1199 struct reiserfs_de_head *new_dehs,
1127 const char * records, 1200 const char *records, int paste_size)
1128 int paste_size
1129 )
1130{ 1201{
1131 struct item_head * ih; 1202 struct item_head *ih;
1132 char * item; 1203 char *item;
1133 struct reiserfs_de_head * deh; 1204 struct reiserfs_de_head *deh;
1134 char * insert_point; 1205 char *insert_point;
1135 int i, old_entry_num; 1206 int i, old_entry_num;
1136 1207
1137 if (new_entry_count == 0) 1208 if (new_entry_count == 0)
1138 return; 1209 return;
1139 1210
1140 ih = B_N_PITEM_HEAD(bh, item_num); 1211 ih = B_N_PITEM_HEAD(bh, item_num);
1141 1212
1142 /* make sure, that item is directory, and there are enough records in it */ 1213 /* make sure, that item is directory, and there are enough records in it */
1143 RFALSE( !is_direntry_le_ih (ih), "10225: item is not directory item"); 1214 RFALSE(!is_direntry_le_ih(ih), "10225: item is not directory item");
1144 RFALSE( I_ENTRY_COUNT (ih) < before, 1215 RFALSE(I_ENTRY_COUNT(ih) < before,
1145 "10230: there are no entry we paste entries before. entry_count = %d, before = %d", 1216 "10230: there are no entry we paste entries before. entry_count = %d, before = %d",
1146 I_ENTRY_COUNT (ih), before); 1217 I_ENTRY_COUNT(ih), before);
1147 1218
1148 1219 /* first byte of dest item */
1149 /* first byte of dest item */ 1220 item = bh->b_data + ih_location(ih);
1150 item = bh->b_data + ih_location(ih); 1221
1151 1222 /* entry head array */
1152 /* entry head array */ 1223 deh = B_I_DEH(bh, ih);
1153 deh = B_I_DEH (bh, ih); 1224
1154 1225 /* new records will be pasted at this point */
1155 /* new records will be pasted at this point */ 1226 insert_point =
1156 insert_point = item + (before ? deh_location( &(deh[before - 1])) : (ih_item_len(ih) - paste_size)); 1227 item +
1157 1228 (before ? deh_location(&(deh[before - 1]))
1158 /* adjust locations of records that will be AFTER new records */ 1229 : (ih_item_len(ih) - paste_size));
1159 for (i = I_ENTRY_COUNT(ih) - 1; i >= before; i --) 1230
1160 put_deh_location( &(deh[i]), 1231 /* adjust locations of records that will be AFTER new records */
1161 deh_location(&(deh[i])) + (DEH_SIZE * new_entry_count )); 1232 for (i = I_ENTRY_COUNT(ih) - 1; i >= before; i--)
1162 1233 put_deh_location(&(deh[i]),
1163 /* adjust locations of records that will be BEFORE new records */ 1234 deh_location(&(deh[i])) +
1164 for (i = 0; i < before; i ++) 1235 (DEH_SIZE * new_entry_count));
1165 put_deh_location( &(deh[i]), deh_location(&(deh[i])) + paste_size ); 1236
1166 1237 /* adjust locations of records that will be BEFORE new records */
1167 old_entry_num = I_ENTRY_COUNT(ih); 1238 for (i = 0; i < before; i++)
1168 put_ih_entry_count( ih, ih_entry_count(ih) + new_entry_count ); 1239 put_deh_location(&(deh[i]),
1169 1240 deh_location(&(deh[i])) + paste_size);
1170 /* prepare space for pasted records */ 1241
1171 memmove (insert_point + paste_size, insert_point, item + (ih_item_len(ih) - paste_size) - insert_point); 1242 old_entry_num = I_ENTRY_COUNT(ih);
1172 1243 put_ih_entry_count(ih, ih_entry_count(ih) + new_entry_count);
1173 /* copy new records */ 1244
1174 memcpy (insert_point + DEH_SIZE * new_entry_count, records, 1245 /* prepare space for pasted records */
1175 paste_size - DEH_SIZE * new_entry_count); 1246 memmove(insert_point + paste_size, insert_point,
1176 1247 item + (ih_item_len(ih) - paste_size) - insert_point);
1177 /* prepare space for new entry heads */ 1248
1178 deh += before; 1249 /* copy new records */
1179 memmove ((char *)(deh + new_entry_count), deh, insert_point - (char *)deh); 1250 memcpy(insert_point + DEH_SIZE * new_entry_count, records,
1180 1251 paste_size - DEH_SIZE * new_entry_count);
1181 /* copy new entry heads */ 1252
1182 deh = (struct reiserfs_de_head *)((char *)deh); 1253 /* prepare space for new entry heads */
1183 memcpy (deh, new_dehs, DEH_SIZE * new_entry_count); 1254 deh += before;
1184 1255 memmove((char *)(deh + new_entry_count), deh,
1185 /* set locations of new records */ 1256 insert_point - (char *)deh);
1186 for (i = 0; i < new_entry_count; i ++) 1257
1187 { 1258 /* copy new entry heads */
1188 put_deh_location( &(deh[i]), 1259 deh = (struct reiserfs_de_head *)((char *)deh);
1189 deh_location( &(deh[i] )) + 1260 memcpy(deh, new_dehs, DEH_SIZE * new_entry_count);
1190 (- deh_location( &(new_dehs[new_entry_count - 1])) + 1261
1191 insert_point + DEH_SIZE * new_entry_count - item)); 1262 /* set locations of new records */
1192 } 1263 for (i = 0; i < new_entry_count; i++) {
1193 1264 put_deh_location(&(deh[i]),
1194 1265 deh_location(&(deh[i])) +
1195 /* change item key if necessary (when we paste before 0-th entry */ 1266 (-deh_location
1196 if (!before) 1267 (&(new_dehs[new_entry_count - 1])) +
1197 { 1268 insert_point + DEH_SIZE * new_entry_count -
1198 set_le_ih_k_offset (ih, deh_offset(new_dehs)); 1269 item));
1270 }
1271
1272 /* change item key if necessary (when we paste before 0-th entry */
1273 if (!before) {
1274 set_le_ih_k_offset(ih, deh_offset(new_dehs));
1199/* memcpy (&ih->ih_key.k_offset, 1275/* memcpy (&ih->ih_key.k_offset,
1200 &new_dehs->deh_offset, SHORT_KEY_SIZE);*/ 1276 &new_dehs->deh_offset, SHORT_KEY_SIZE);*/
1201 } 1277 }
1202
1203#ifdef CONFIG_REISERFS_CHECK 1278#ifdef CONFIG_REISERFS_CHECK
1204 { 1279 {
1205 int prev, next; 1280 int prev, next;
1206 /* check record locations */ 1281 /* check record locations */
1207 deh = B_I_DEH (bh, ih); 1282 deh = B_I_DEH(bh, ih);
1208 for (i = 0; i < I_ENTRY_COUNT(ih); i ++) { 1283 for (i = 0; i < I_ENTRY_COUNT(ih); i++) {
1209 next = (i < I_ENTRY_COUNT(ih) - 1) ? deh_location( &(deh[i + 1])) : 0; 1284 next =
1210 prev = (i != 0) ? deh_location( &(deh[i - 1]) ) : 0; 1285 (i <
1211 1286 I_ENTRY_COUNT(ih) -
1212 if (prev && prev <= deh_location( &(deh[i]))) 1287 1) ? deh_location(&(deh[i + 1])) : 0;
1213 reiserfs_warning (NULL, "vs-10240: leaf_paste_entries: directory item (%h) corrupted (prev %a, cur(%d) %a)", 1288 prev = (i != 0) ? deh_location(&(deh[i - 1])) : 0;
1214 ih, deh + i - 1, i, deh + i); 1289
1215 if (next && next >= deh_location( &(deh[i]))) 1290 if (prev && prev <= deh_location(&(deh[i])))
1216 reiserfs_warning (NULL, "vs-10250: leaf_paste_entries: directory item (%h) corrupted (cur(%d) %a, next %a)", 1291 reiserfs_warning(NULL,
1217 ih, i, deh + i, deh + i + 1); 1292 "vs-10240: leaf_paste_entries: directory item (%h) corrupted (prev %a, cur(%d) %a)",
1218 } 1293 ih, deh + i - 1, i, deh + i);
1219 } 1294 if (next && next >= deh_location(&(deh[i])))
1295 reiserfs_warning(NULL,
1296 "vs-10250: leaf_paste_entries: directory item (%h) corrupted (cur(%d) %a, next %a)",
1297 ih, i, deh + i, deh + i + 1);
1298 }
1299 }
1220#endif 1300#endif
1221 1301
1222} 1302}