1 /* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */
4 #include "../../tree.h"
5 #include "../../jnode.h"
6 #include "../../super.h"
7 #include "../../flush.h"
8 #include "../../carry.h"
11 #include <linux/pagemap.h>
13 static reiser4_block_nr
extent_unit_start(const coord_t
* item
);
15 /* Return either first or last extent (depending on @side) of the item
16 @coord is set to. Set @pos_in_unit either to first or to last block
18 static reiser4_extent
*extent_utmost_ext(const coord_t
* coord
, sideof side
,
19 reiser4_block_nr
* pos_in_unit
)
23 if (side
== LEFT_SIDE
) {
24 /* get first extent of item */
25 ext
= extent_item(coord
);
28 /* get last extent of item and last position within it */
29 assert("vs-363", side
== RIGHT_SIDE
);
30 ext
= extent_item(coord
) + coord_last_unit_pos(coord
);
31 *pos_in_unit
= extent_get_width(ext
) - 1;
37 /* item_plugin->f.utmost_child */
38 /* Return the child. Coord is set to extent item. Find jnode corresponding
39 either to first or to last unformatted node pointed by the item */
40 int utmost_child_extent(const coord_t
* coord
, sideof side
, jnode
** childp
)
43 reiser4_block_nr pos_in_unit
;
45 ext
= extent_utmost_ext(coord
, side
, &pos_in_unit
);
47 switch (state_of_extent(ext
)) {
51 case ALLOCATED_EXTENT
:
52 case UNALLOCATED_EXTENT
:
55 /* this should never happen */
64 if (side
== LEFT_SIDE
) {
65 /* get key of first byte addressed by the extent */
66 item_key_by_coord(coord
, &key
);
68 /* get key of byte which next after last byte addressed by the extent */
69 append_key_extent(coord
, &key
);
73 (get_key_offset(&key
) >> PAGE_CACHE_SHIFT
) < ~0ul);
74 /* index of first or last (depending on @side) page addressed
77 (unsigned long)(get_key_offset(&key
) >> PAGE_CACHE_SHIFT
);
78 if (side
== RIGHT_SIDE
)
81 tree
= coord
->node
->zjnode
.tree
;
82 *childp
= jlookup(tree
, get_key_objectid(&key
), index
);
88 /* item_plugin->f.utmost_child_real_block */
89 /* Return the child's block, if allocated. */
91 utmost_child_real_block_extent(const coord_t
* coord
, sideof side
,
92 reiser4_block_nr
* block
)
96 ext
= extent_by_coord(coord
);
98 switch (state_of_extent(ext
)) {
99 case ALLOCATED_EXTENT
:
100 *block
= extent_get_start(ext
);
101 if (side
== RIGHT_SIDE
)
102 *block
+= extent_get_width(ext
) - 1;
105 case UNALLOCATED_EXTENT
:
109 /* this should never happen */
110 assert("vs-1418", 0);
116 /* item_plugin->f.scan */
117 /* Performs leftward scanning starting from an unformatted node and its parent coordinate.
118 This scan continues, advancing the parent coordinate, until either it encounters a
119 formatted child or it finishes scanning this node.
121 If unallocated, the entire extent must be dirty and in the same atom. (Actually, I'm
122 not sure this is last property (same atom) is enforced, but it should be the case since
123 one atom must write the parent and the others must read the parent, thus fusing?). In
124 any case, the code below asserts this case for unallocated extents. Unallocated
125 extents are thus optimized because we can skip to the endpoint when scanning.
127 It returns control to reiser4_scan_extent, handles these terminating conditions,
128 e.g., by loading the next twig.
130 int reiser4_scan_extent(flush_scan
* scan
)
134 unsigned long scan_index
, unit_index
, unit_width
, scan_max
, scan_dist
;
135 reiser4_block_nr unit_start
;
138 int ret
= 0, allocated
, incr
;
141 if (!JF_ISSET(scan
->node
, JNODE_DIRTY
)) {
143 return 0; /* Race with truncate, this node is already
147 coord_dup(&coord
, &scan
->parent_coord
);
149 assert("jmacd-1404", !reiser4_scan_finished(scan
));
150 assert("jmacd-1405", jnode_get_level(scan
->node
) == LEAF_LEVEL
);
151 assert("jmacd-1406", jnode_is_unformatted(scan
->node
));
153 /* The scan_index variable corresponds to the current page index of the
154 unformatted block scan position. */
155 scan_index
= index_jnode(scan
->node
);
157 assert("jmacd-7889", item_is_extent(&coord
));
160 /* objectid of file */
161 oid
= get_key_objectid(item_key_by_coord(&coord
, &key
));
163 allocated
= !extent_is_unallocated(&coord
);
164 /* Get the values of this extent unit: */
165 unit_index
= extent_unit_index(&coord
);
166 unit_width
= extent_unit_width(&coord
);
167 unit_start
= extent_unit_start(&coord
);
169 assert("jmacd-7187", unit_width
> 0);
170 assert("jmacd-7188", scan_index
>= unit_index
);
171 assert("jmacd-7189", scan_index
<= unit_index
+ unit_width
- 1);
173 /* Depending on the scan direction, we set different maximum values for scan_index
174 (scan_max) and the number of nodes that would be passed if the scan goes the
175 entire way (scan_dist). Incr is an integer reflecting the incremental
176 direction of scan_index. */
177 if (reiser4_scanning_left(scan
)) {
178 scan_max
= unit_index
;
179 scan_dist
= scan_index
- unit_index
;
182 scan_max
= unit_index
+ unit_width
- 1;
183 scan_dist
= scan_max
- unit_index
;
187 tree
= coord
.node
->zjnode
.tree
;
189 /* If the extent is allocated we have to check each of its blocks. If the extent
190 is unallocated we can skip to the scan_max. */
193 neighbor
= jlookup(tree
, oid
, scan_index
);
194 if (neighbor
== NULL
)
195 goto stop_same_parent
;
197 if (scan
->node
!= neighbor
198 && !reiser4_scan_goto(scan
, neighbor
)) {
199 /* @neighbor was jput() by reiser4_scan_goto */
200 goto stop_same_parent
;
203 ret
= scan_set_current(scan
, neighbor
, 1, &coord
);
208 /* reference to @neighbor is stored in @scan, no need
212 } while (incr
+ scan_max
!= scan_index
);
215 /* Optimized case for unallocated extents, skip to the end. */
216 neighbor
= jlookup(tree
, oid
, scan_max
/*index */ );
217 if (neighbor
== NULL
) {
218 /* Race with truncate */
225 reiser4_blocknr_is_fake(jnode_get_block(neighbor
)));
227 ret
= scan_set_current(scan
, neighbor
, scan_dist
, &coord
);
233 if (coord_sideof_unit(&coord
, scan
->direction
) == 0
234 && item_is_extent(&coord
)) {
235 /* Continue as long as there are more extent units. */
238 extent_unit_index(&coord
) +
239 (reiser4_scanning_left(scan
) ?
240 extent_unit_width(&coord
) - 1 : 0);
247 /* If we are scanning left and we stop in the middle of an allocated
248 extent, we know the preceder immediately.. */
249 /* middle of extent is (scan_index - unit_index) != 0. */
250 if (reiser4_scanning_left(scan
) &&
251 (scan_index
- unit_index
) != 0) {
252 /* FIXME(B): Someone should step-through and verify that this preceder
253 calculation is indeed correct. */
254 /* @unit_start is starting block (number) of extent
255 unit. Flush stopped at the @scan_index block from
256 the beginning of the file, which is (scan_index -
257 unit_index) block within extent.
260 /* skip preceder update when we are at hole */
262 unit_start
+ scan_index
- unit_index
;
263 check_preceder(scan
->preceder_blk
);
267 /* In this case, we leave coord set to the parent of scan->node. */
271 /* In this case, we are still scanning, coord is set to the next item which is
272 either off-the-end of the node or not an extent. */
273 assert("jmacd-8912", scan
->stop
== 0);
275 (coord_is_after_sideof_unit(&coord
, scan
->direction
)
276 || !item_is_extent(&coord
)));
284 /* ask block allocator for some blocks */
285 static void extent_allocate_blocks(reiser4_blocknr_hint
*preceder
,
286 reiser4_block_nr wanted_count
,
287 reiser4_block_nr
*first_allocated
,
288 reiser4_block_nr
*allocated
,
289 block_stage_t block_stage
)
291 *allocated
= wanted_count
;
292 preceder
->max_dist
= 0; /* scan whole disk, if needed */
294 /* that number of blocks (wanted_count) is either in UNALLOCATED or in GRABBED */
295 preceder
->block_stage
= block_stage
;
297 /* FIXME: we do not handle errors here now */
299 reiser4_alloc_blocks(preceder
, first_allocated
, allocated
,
301 /* update flush_pos's preceder to last allocated block number */
302 preceder
->blk
= *first_allocated
+ *allocated
- 1;
305 /* when on flush time unallocated extent is to be replaced with allocated one it may happen that one unallocated extent
306 will have to be replaced with set of allocated extents. In this case insert_into_item will be called which may have
307 to add new nodes into tree. Space for that is taken from inviolable reserve (5%). */
308 static reiser4_block_nr
reserve_replace(void)
310 reiser4_block_nr grabbed
, needed
;
312 grabbed
= get_current_context()->grabbed_blocks
;
313 needed
= estimate_one_insert_into_item(current_tree
);
314 check_me("vpf-340", !reiser4_grab_space_force(needed
, BA_RESERVED
));
318 static void free_replace_reserved(reiser4_block_nr grabbed
)
320 reiser4_context
*ctx
;
322 ctx
= get_current_context();
323 grabbed2free(ctx
, get_super_private(ctx
->super
),
324 ctx
->grabbed_blocks
- grabbed
);
327 /* Block offset of first block addressed by unit */
328 __u64
extent_unit_index(const coord_t
* item
)
332 assert("vs-648", coord_is_existing_unit(item
));
333 unit_key_by_coord(item
, &key
);
334 return get_key_offset(&key
) >> current_blocksize_bits
;
337 /* AUDIT shouldn't return value be of reiser4_block_nr type?
338 Josh's answer: who knows? Is a "number of blocks" the same type as "block offset"? */
339 __u64
extent_unit_width(const coord_t
* item
)
341 assert("vs-649", coord_is_existing_unit(item
));
342 return width_by_coord(item
);
345 /* Starting block location of this unit */
346 static reiser4_block_nr
extent_unit_start(const coord_t
* item
)
348 return extent_get_start(extent_by_coord(item
));
352 * split_allocated_extent -
356 * replace allocated extent with two allocated extents
358 static int split_allocated_extent(coord_t
*coord
, reiser4_block_nr pos_in_unit
)
361 struct replace_handle
*h
;
363 reiser4_block_nr grabbed
;
365 ext
= extent_by_coord(coord
);
366 assert("vs-1410", state_of_extent(ext
) == ALLOCATED_EXTENT
);
367 assert("vs-1411", extent_get_width(ext
) > pos_in_unit
);
369 h
= kmalloc(sizeof(*h
), reiser4_ctx_gfp_mask_get());
371 return RETERR(-ENOMEM
);
373 h
->lh
= znode_lh(coord
->node
);
375 unit_key_by_coord(coord
, h
->pkey
);
376 set_key_offset(h
->pkey
,
377 (get_key_offset(h
->pkey
) +
378 pos_in_unit
* current_blocksize
));
379 reiser4_set_extent(&h
->overwrite
, extent_get_start(ext
),
381 reiser4_set_extent(&h
->new_extents
[0],
382 extent_get_start(ext
) + pos_in_unit
,
383 extent_get_width(ext
) - pos_in_unit
);
384 h
->nr_new_extents
= 1;
385 h
->flags
= COPI_DONT_SHIFT_LEFT
;
386 h
->paste_key
= h
->key
;
388 /* reserve space for extent unit paste, @grabbed is reserved before */
389 grabbed
= reserve_replace();
390 result
= reiser4_replace_extent(h
, 0 /* leave @coord set to overwritten
392 /* restore reserved */
393 free_replace_reserved(grabbed
);
398 /* replace extent @ext by extent @replace. Try to merge @replace with previous extent of the item (if there is
399 one). Return 1 if it succeeded, 0 - otherwise */
400 static int try_to_merge_with_left(coord_t
*coord
, reiser4_extent
*ext
,
401 reiser4_extent
*replace
)
403 assert("vs-1415", extent_by_coord(coord
) == ext
);
405 if (coord
->unit_pos
== 0
406 || state_of_extent(ext
- 1) != ALLOCATED_EXTENT
)
407 /* @ext either does not exist or is not allocated extent */
409 if (extent_get_start(ext
- 1) + extent_get_width(ext
- 1) !=
410 extent_get_start(replace
))
413 /* we can glue, widen previous unit */
414 extent_set_width(ext
- 1,
415 extent_get_width(ext
- 1) + extent_get_width(replace
));
417 if (extent_get_width(ext
) != extent_get_width(replace
)) {
418 /* make current extent narrower */
419 if (state_of_extent(ext
) == ALLOCATED_EXTENT
)
420 extent_set_start(ext
,
421 extent_get_start(ext
) +
422 extent_get_width(replace
));
423 extent_set_width(ext
,
424 extent_get_width(ext
) -
425 extent_get_width(replace
));
427 /* current extent completely glued with its left neighbor, remove it */
430 coord_dup(&from
, coord
);
431 from
.unit_pos
= nr_units_extent(coord
) - 1;
432 coord_dup(&to
, &from
);
434 /* currently cut from extent can cut either from the beginning or from the end. Move place which got
435 freed after unit removal to end of item */
436 memmove(ext
, ext
+ 1,
438 coord
->unit_pos
) * sizeof(reiser4_extent
));
439 /* wipe part of item which is going to be cut, so that node_check will not be confused */
440 cut_node_content(&from
, &to
, NULL
, NULL
, NULL
);
442 znode_make_dirty(coord
->node
);
443 /* move coord back */
449 * conv_extent - replace extent with 2 ones
450 * @coord: coordinate of extent to be replaced
451 * @replace: extent to overwrite the one @coord is set to
453 * Overwrites extent @coord is set to and paste one extent unit after
454 * overwritten one if @replace is shorter than initial extent
456 static int conv_extent(coord_t
*coord
, reiser4_extent
*replace
)
459 struct replace_handle
*h
;
461 reiser4_block_nr start
, width
, new_width
;
462 reiser4_block_nr grabbed
;
465 ext
= extent_by_coord(coord
);
466 state
= state_of_extent(ext
);
467 start
= extent_get_start(ext
);
468 width
= extent_get_width(ext
);
469 new_width
= extent_get_width(replace
);
471 assert("vs-1458", (state
== UNALLOCATED_EXTENT
||
472 state
== ALLOCATED_EXTENT
));
473 assert("vs-1459", width
>= new_width
);
475 if (try_to_merge_with_left(coord
, ext
, replace
)) {
476 /* merged @replace with left neighbor. Current unit is either
477 removed or narrowed */
481 if (width
== new_width
) {
482 /* replace current extent with @replace */
484 znode_make_dirty(coord
->node
);
488 h
= kmalloc(sizeof(*h
), reiser4_ctx_gfp_mask_get());
490 return RETERR(-ENOMEM
);
492 h
->lh
= znode_lh(coord
->node
);
494 unit_key_by_coord(coord
, h
->pkey
);
495 set_key_offset(h
->pkey
,
496 (get_key_offset(h
->pkey
) + new_width
* current_blocksize
));
497 h
->overwrite
= *replace
;
499 /* replace @ext with @replace and padding extent */
500 reiser4_set_extent(&h
->new_extents
[0],
501 (state
== ALLOCATED_EXTENT
) ?
502 (start
+ new_width
) :
503 UNALLOCATED_EXTENT_START
,
505 h
->nr_new_extents
= 1;
506 h
->flags
= COPI_DONT_SHIFT_LEFT
;
507 h
->paste_key
= h
->key
;
509 /* reserve space for extent unit paste, @grabbed is reserved before */
510 grabbed
= reserve_replace();
511 result
= reiser4_replace_extent(h
, 0 /* leave @coord set to overwritten
514 /* restore reserved */
515 free_replace_reserved(grabbed
);
521 * assign_real_blocknrs
523 * @oid: objectid of file jnodes to assign block number to belongs to
524 * @index: first jnode on the range
525 * @count: number of jnodes to assign block numbers to
526 * @first: start of allocated block range
528 * Assigns block numbers to each of @count jnodes. Index of first jnode is
529 * @index. Jnodes get lookuped with jlookup.
531 static void assign_real_blocknrs(flush_pos_t
*flush_pos
, oid_t oid
,
532 unsigned long index
, reiser4_block_nr count
,
533 reiser4_block_nr first
)
540 atom
= atom_locked_by_fq(flush_pos
->fq
);
541 assert("vs-1468", atom
);
542 BUG_ON(atom
== NULL
);
546 for (i
= 0; i
< count
; ++i
, ++index
) {
549 node
= jlookup(tree
, oid
, index
);
550 assert("", node
!= NULL
);
551 BUG_ON(node
== NULL
);
553 spin_lock_jnode(node
);
554 assert("", !jnode_is_flushprepped(node
));
555 assert("vs-1475", node
->atom
== atom
);
556 assert("vs-1476", atomic_read(&node
->x_count
) > 0);
558 JF_CLR(node
, JNODE_FLUSH_RESERVED
);
559 jnode_set_block(node
, &first
);
560 unformatted_make_reloc(node
, flush_pos
->fq
);
561 ON_DEBUG(count_jnode(node
->atom
, node
, NODE_LIST(node
),
563 spin_unlock_jnode(node
);
566 atomic_dec(&node
->x_count
);
570 spin_unlock_atom(atom
);
575 * make_node_ovrwr - assign node to overwrite set
576 * @jnodes: overwrite set list head
577 * @node: jnode to belong to overwrite set
579 * Sets OVRWR jnode state bit and puts @node to the end of list head @jnodes
580 * which is an accumulator for nodes before they get to overwrite set list of
583 static void make_node_ovrwr(struct list_head
*jnodes
, jnode
*node
)
585 spin_lock_jnode(node
);
587 assert("zam-917", !JF_ISSET(node
, JNODE_RELOC
));
588 assert("zam-918", !JF_ISSET(node
, JNODE_OVRWR
));
590 JF_SET(node
, JNODE_OVRWR
);
591 list_move_tail(&node
->capture_link
, jnodes
);
592 ON_DEBUG(count_jnode(node
->atom
, node
, DIRTY_LIST
, OVRWR_LIST
, 0));
594 spin_unlock_jnode(node
);
598 * mark_jnodes_overwrite - put bunch of jnodes to overwrite set
599 * @flush_pos: flush position
600 * @oid: objectid of file jnodes belong to
601 * @index: starting index
602 * @width: extent width
604 * Puts nodes of one extent (file objectid @oid, extent width @width) to atom's
605 * overwrite set. Starting from the one with index @index. If end of slum is
606 * detected (node is not found or flushprepped) - stop iterating and set flush
607 * position's state to POS_INVALID.
609 static void mark_jnodes_overwrite(flush_pos_t
*flush_pos
, oid_t oid
,
610 unsigned long index
, reiser4_block_nr width
)
620 atom
= atom_locked_by_fq(reiser4_pos_fq(flush_pos
));
621 assert("vs-1478", atom
);
623 for (i
= flush_pos
->pos_in_unit
; i
< width
; i
++, index
++) {
624 node
= jlookup(tree
, oid
, index
);
626 flush_pos
->state
= POS_INVALID
;
629 if (jnode_check_flushprepped(node
)) {
630 flush_pos
->state
= POS_INVALID
;
631 atomic_dec(&node
->x_count
);
634 if (node
->atom
!= atom
) {
635 flush_pos
->state
= POS_INVALID
;
636 atomic_dec(&node
->x_count
);
639 make_node_ovrwr(&jnodes
, node
);
640 atomic_dec(&node
->x_count
);
643 list_splice_init(&jnodes
, ATOM_OVRWR_LIST(atom
)->prev
);
644 spin_unlock_atom(atom
);
648 * allocated_extent_slum_size
656 static int allocated_extent_slum_size(flush_pos_t
*flush_pos
, oid_t oid
,
657 unsigned long index
, unsigned long count
)
664 atom
= atom_locked_by_fq(reiser4_pos_fq(flush_pos
));
665 assert("vs-1468", atom
);
669 for (i
= 0; i
< count
; ++i
, ++index
) {
672 node
= jlookup(tree
, oid
, index
);
676 if (jnode_check_flushprepped(node
)) {
677 atomic_dec(&node
->x_count
);
681 if (node
->atom
!= atom
) {
683 * this is possible on overwrite: extent_write may
684 * capture several unformatted nodes without capturing
685 * any formatted nodes.
687 atomic_dec(&node
->x_count
);
691 assert("vs-1476", atomic_read(&node
->x_count
) > 1);
692 atomic_dec(&node
->x_count
);
696 spin_unlock_atom(atom
);
705 * this is called by handle_pos_on_twig to proceed extent unit flush_pos->coord
706 * is set to. It is to prepare for flushing sequence of not flushprepped nodes
707 * (slum). It supposes that slum starts at flush_pos->pos_in_unit position
708 * within the extent. Slum gets to relocate set if flush_pos->leaf_relocate is
709 * set to 1 and to overwrite set otherwise
711 int reiser4_alloc_extent(flush_pos_t
*flush_pos
)
715 reiser4_extent replace_ext
;
717 reiser4_block_nr
protected;
718 reiser4_block_nr start
;
723 reiser4_block_nr first_allocated
;
726 block_stage_t block_stage
;
728 assert("vs-1468", flush_pos
->state
== POS_ON_EPOINT
);
729 assert("vs-1469", coord_is_existing_unit(&flush_pos
->coord
)
730 && item_is_extent(&flush_pos
->coord
));
732 coord
= &flush_pos
->coord
;
734 ext
= extent_by_coord(coord
);
735 state
= state_of_extent(ext
);
736 if (state
== HOLE_EXTENT
) {
737 flush_pos
->state
= POS_INVALID
;
741 item_key_by_coord(coord
, &key
);
742 oid
= get_key_objectid(&key
);
743 index
= extent_unit_index(coord
) + flush_pos
->pos_in_unit
;
744 start
= extent_get_start(ext
);
745 width
= extent_get_width(ext
);
747 assert("vs-1457", width
> flush_pos
->pos_in_unit
);
749 if (flush_pos
->leaf_relocate
|| state
== UNALLOCATED_EXTENT
) {
751 if (flush_pos
->pos_in_unit
) {
752 /* split extent unit into two */
754 split_allocated_extent(coord
,
755 flush_pos
->pos_in_unit
);
756 flush_pos
->pos_in_unit
= 0;
760 /* limit number of nodes to allocate */
761 if (flush_pos
->nr_to_write
< width
)
762 width
= flush_pos
->nr_to_write
;
764 if (state
== ALLOCATED_EXTENT
) {
766 * all protected nodes are not flushprepped, therefore
767 * they are counted as flush_reserved
769 block_stage
= BLOCK_FLUSH_RESERVED
;
770 protected = allocated_extent_slum_size(flush_pos
, oid
,
772 if (protected == 0) {
773 flush_pos
->state
= POS_INVALID
;
774 flush_pos
->pos_in_unit
= 0;
778 block_stage
= BLOCK_UNALLOCATED
;
783 * look at previous unit if possible. If it is allocated, make
784 * preceder more precise
786 if (coord
->unit_pos
&&
787 (state_of_extent(ext
- 1) == ALLOCATED_EXTENT
))
788 reiser4_pos_hint(flush_pos
)->blk
=
789 extent_get_start(ext
- 1) +
790 extent_get_width(ext
- 1);
792 /* allocate new block numbers for protected nodes */
793 extent_allocate_blocks(reiser4_pos_hint(flush_pos
),
795 &first_allocated
, &allocated
,
798 if (state
== ALLOCATED_EXTENT
)
800 * on relocating - free nodes which are going to be
803 reiser4_dealloc_blocks(&start
, &allocated
,
804 BLOCK_ALLOCATED
, BA_DEFER
);
806 /* assign new block numbers to protected nodes */
807 assign_real_blocknrs(flush_pos
, oid
, index
, allocated
, first_allocated
);
809 /* prepare extent which will replace current one */
810 reiser4_set_extent(&replace_ext
, first_allocated
, allocated
);
812 /* adjust extent item */
813 result
= conv_extent(coord
, &replace_ext
);
814 if (result
!= 0 && result
!= -ENOMEM
) {
816 "Failed to allocate extent. Should not happen\n");
821 * break flush: we prepared for flushing as many blocks as we
824 if (flush_pos
->nr_to_write
== allocated
)
825 flush_pos
->state
= POS_INVALID
;
828 mark_jnodes_overwrite(flush_pos
, oid
, index
, width
);
830 flush_pos
->pos_in_unit
= 0;
834 /* if @key is glueable to the item @coord is set to */
835 static int must_insert(const coord_t
*coord
, const reiser4_key
*key
)
839 if (item_id_by_coord(coord
) == EXTENT_POINTER_ID
840 && keyeq(append_key_extent(coord
, &last
), key
))
845 /* copy extent @copy to the end of @node. It may have to either insert new item after the last one, or append last item,
846 or modify last unit of last item to have greater width */
847 static int put_unit_to_end(znode
*node
, const reiser4_key
*key
,
848 reiser4_extent
*copy_ext
)
852 cop_insert_flag flags
;
853 reiser4_extent
*last_ext
;
854 reiser4_item_data data
;
856 /* set coord after last unit in an item */
857 coord_init_last_unit(&coord
, node
);
858 coord
.between
= AFTER_UNIT
;
861 COPI_DONT_SHIFT_LEFT
| COPI_DONT_SHIFT_RIGHT
| COPI_DONT_ALLOCATE
;
862 if (must_insert(&coord
, key
)) {
864 insert_by_coord(&coord
, init_new_extent(&data
, copy_ext
, 1),
865 key
, NULL
/*lh */ , flags
);
868 /* try to glue with last unit */
869 last_ext
= extent_by_coord(&coord
);
870 if (state_of_extent(last_ext
) &&
871 extent_get_start(last_ext
) + extent_get_width(last_ext
) ==
872 extent_get_start(copy_ext
)) {
873 /* widen last unit of node */
874 extent_set_width(last_ext
,
875 extent_get_width(last_ext
) +
876 extent_get_width(copy_ext
));
877 znode_make_dirty(node
);
881 /* FIXME: put an assertion here that we can not merge last unit in @node and new unit */
883 insert_into_item(&coord
, NULL
/*lh */ , key
,
884 init_new_extent(&data
, copy_ext
, 1),
888 assert("vs-438", result
== 0 || result
== -E_NODE_FULL
);
892 /* @coord is set to extent unit */
893 squeeze_result
squalloc_extent(znode
*left
, const coord_t
*coord
,
894 flush_pos_t
*flush_pos
,
895 reiser4_key
*stop_key
)
900 reiser4_block_nr start
;
903 reiser4_block_nr first_allocated
;
906 reiser4_extent copy_extent
;
909 block_stage_t block_stage
;
911 assert("vs-1457", flush_pos
->pos_in_unit
== 0);
912 assert("vs-1467", coord_is_leftmost_unit(coord
));
913 assert("vs-1467", item_is_extent(coord
));
915 ext
= extent_by_coord(coord
);
916 index
= extent_unit_index(coord
);
917 start
= extent_get_start(ext
);
918 width
= extent_get_width(ext
);
919 state
= state_of_extent(ext
);
920 unit_key_by_coord(coord
, &key
);
921 oid
= get_key_objectid(&key
);
923 if ((flush_pos
->leaf_relocate
&& state
== ALLOCATED_EXTENT
) ||
924 (state
== UNALLOCATED_EXTENT
)) {
926 if (state
== ALLOCATED_EXTENT
) {
927 /* all protected nodes are not flushprepped, therefore
928 * they are counted as flush_reserved */
929 block_stage
= BLOCK_FLUSH_RESERVED
;
930 protected = allocated_extent_slum_size(flush_pos
, oid
,
932 if (protected == 0) {
933 flush_pos
->state
= POS_INVALID
;
934 flush_pos
->pos_in_unit
= 0;
938 block_stage
= BLOCK_UNALLOCATED
;
943 * look at previous unit if possible. If it is allocated, make
944 * preceder more precise
946 if (coord
->unit_pos
&&
947 (state_of_extent(ext
- 1) == ALLOCATED_EXTENT
))
948 reiser4_pos_hint(flush_pos
)->blk
=
949 extent_get_start(ext
- 1) +
950 extent_get_width(ext
- 1);
952 /* allocate new block numbers for protected nodes */
953 extent_allocate_blocks(reiser4_pos_hint(flush_pos
),
955 &first_allocated
, &allocated
,
958 /* prepare extent which will be copied to left */
959 reiser4_set_extent(©_extent
, first_allocated
, allocated
);
961 result
= put_unit_to_end(left
, &key
, ©_extent
);
962 if (result
== -E_NODE_FULL
) {
963 int target_block_stage
;
965 /* free blocks which were just allocated */
968 ALLOCATED_EXTENT
) ? BLOCK_FLUSH_RESERVED
:
970 reiser4_dealloc_blocks(&first_allocated
, &allocated
,
974 /* rewind the preceder. */
975 flush_pos
->preceder
.blk
= first_allocated
;
976 check_preceder(flush_pos
->preceder
.blk
);
978 return SQUEEZE_TARGET_FULL
;
981 if (state
== ALLOCATED_EXTENT
) {
982 /* free nodes which were relocated */
983 reiser4_dealloc_blocks(&start
, &allocated
,
984 BLOCK_ALLOCATED
, BA_DEFER
);
987 /* assign new block numbers to protected nodes */
988 assign_real_blocknrs(flush_pos
, oid
, index
, allocated
,
992 get_key_offset(&key
) +
993 (allocated
<< current_blocksize_bits
));
996 * overwrite: try to copy unit as it is to left neighbor and
997 * make all first not flushprepped nodes overwrite nodes
999 reiser4_set_extent(©_extent
, start
, width
);
1000 result
= put_unit_to_end(left
, &key
, ©_extent
);
1001 if (result
== -E_NODE_FULL
)
1002 return SQUEEZE_TARGET_FULL
;
1004 if (state
!= HOLE_EXTENT
)
1005 mark_jnodes_overwrite(flush_pos
, oid
, index
, width
);
1006 set_key_offset(&key
,
1007 get_key_offset(&key
) +
1008 (width
<< current_blocksize_bits
));
1011 return SQUEEZE_CONTINUE
;
1014 int key_by_offset_extent(struct inode
*inode
, loff_t off
, reiser4_key
* key
)
1016 return key_by_inode_and_offset_common(inode
, off
, key
);
1021 * c-indentation-style: "K&R"