1 /* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */
3 /* definition of item plugins. */
5 #include "../../forward.h"
6 #include "../../debug.h"
8 #include "../../coord.h"
9 #include "../plugin_header.h"
13 #include "static_stat.h"
14 #include "../plugin.h"
15 #include "../../znode.h"
16 #include "../../tree.h"
17 #include "../../context.h"
20 /* return pointer to item body */
21 void item_body_by_coord_hard(coord_t
* coord
/* coord to query */ )
23 assert("nikita-324", coord
!= NULL
);
24 assert("nikita-325", coord
->node
!= NULL
);
25 assert("nikita-326", znode_is_loaded(coord
->node
));
26 assert("nikita-3200", coord
->offset
== INVALID_OFFSET
);
29 node_plugin_by_node(coord
->node
)->item_by_coord(coord
) -
31 ON_DEBUG(coord
->body_v
= coord
->node
->times_locked
);
34 void *item_body_by_coord_easy(const coord_t
* coord
/* coord to query */ )
36 return zdata(coord
->node
) + coord
->offset
;
41 int item_body_is_valid(const coord_t
* coord
)
45 node_plugin_by_node(coord
->node
)->item_by_coord(coord
) -
51 /* return length of item at @coord */
52 pos_in_node_t
item_length_by_coord(const coord_t
* coord
/* coord to query */ )
56 assert("nikita-327", coord
!= NULL
);
57 assert("nikita-328", coord
->node
!= NULL
);
58 assert("nikita-329", znode_is_loaded(coord
->node
));
60 len
= node_plugin_by_node(coord
->node
)->length_by_coord(coord
);
64 void obtain_item_plugin(const coord_t
* coord
)
66 assert("nikita-330", coord
!= NULL
);
67 assert("nikita-331", coord
->node
!= NULL
);
68 assert("nikita-332", znode_is_loaded(coord
->node
));
70 coord_set_iplug((coord_t
*) coord
,
71 node_plugin_by_node(coord
->node
)->
72 plugin_by_coord(coord
));
75 node_plugin_by_node(coord
->node
)->plugin_by_coord(coord
));
78 /* return id of item */
79 /* Audited by: green(2002.06.15) */
80 item_id
item_id_by_coord(const coord_t
* coord
/* coord to query */ )
82 assert("vs-539", coord
!= NULL
);
83 assert("vs-538", coord
->node
!= NULL
);
84 assert("vs-537", znode_is_loaded(coord
->node
));
85 assert("vs-536", item_plugin_by_coord(coord
) != NULL
);
87 item_id_by_plugin(item_plugin_by_coord(coord
)) < LAST_ITEM_ID
);
89 return item_id_by_plugin(item_plugin_by_coord(coord
));
92 /* return key of item at @coord */
93 /* Audited by: green(2002.06.15) */
94 reiser4_key
*item_key_by_coord(const coord_t
* coord
/* coord to query */ ,
95 reiser4_key
* key
/* result */ )
97 assert("nikita-338", coord
!= NULL
);
98 assert("nikita-339", coord
->node
!= NULL
);
99 assert("nikita-340", znode_is_loaded(coord
->node
));
101 return node_plugin_by_node(coord
->node
)->key_at(coord
, key
);
104 /* this returns max key in the item */
105 reiser4_key
*max_item_key_by_coord(const coord_t
* coord
/* coord to query */ ,
106 reiser4_key
* key
/* result */ )
110 assert("nikita-338", coord
!= NULL
);
111 assert("nikita-339", coord
->node
!= NULL
);
112 assert("nikita-340", znode_is_loaded(coord
->node
));
114 /* make coord pointing to last item's unit */
115 coord_dup(&last
, coord
);
116 last
.unit_pos
= coord_num_units(&last
) - 1;
117 assert("vs-1560", coord_is_existing_unit(&last
));
119 max_unit_key_by_coord(&last
, key
);
123 /* return key of unit at @coord */
124 reiser4_key
*unit_key_by_coord(const coord_t
* coord
/* coord to query */ ,
125 reiser4_key
* key
/* result */ )
127 assert("nikita-772", coord
!= NULL
);
128 assert("nikita-774", coord
->node
!= NULL
);
129 assert("nikita-775", znode_is_loaded(coord
->node
));
131 if (item_plugin_by_coord(coord
)->b
.unit_key
!= NULL
)
132 return item_plugin_by_coord(coord
)->b
.unit_key(coord
, key
);
134 return item_key_by_coord(coord
, key
);
137 /* return the biggest key contained the unit @coord */
138 reiser4_key
*max_unit_key_by_coord(const coord_t
* coord
/* coord to query */ ,
139 reiser4_key
* key
/* result */ )
141 assert("nikita-772", coord
!= NULL
);
142 assert("nikita-774", coord
->node
!= NULL
);
143 assert("nikita-775", znode_is_loaded(coord
->node
));
145 if (item_plugin_by_coord(coord
)->b
.max_unit_key
!= NULL
)
146 return item_plugin_by_coord(coord
)->b
.max_unit_key(coord
, key
);
148 return unit_key_by_coord(coord
, key
);
151 /* ->max_key_inside() method for items consisting of exactly one key (like
153 static reiser4_key
*max_key_inside_single_key(const coord_t
*
154 coord
/* coord of item */ ,
156 result
/* resulting key */ )
158 assert("nikita-604", coord
!= NULL
);
160 /* coord -> key is starting key of this item and it has to be already
162 return unit_key_by_coord(coord
, result
);
165 /* ->nr_units() method for items consisting of exactly one unit always */
167 nr_units_single_unit(const coord_t
* coord UNUSED_ARG
/* coord of item */ )
173 paste_no_paste(coord_t
* coord UNUSED_ARG
,
174 reiser4_item_data
* data UNUSED_ARG
,
175 carry_plugin_info
* info UNUSED_ARG
)
180 /* default ->fast_paste() method */
182 agree_to_fast_op(const coord_t
* coord UNUSED_ARG
/* coord of item */ )
187 int item_can_contain_key(const coord_t
* item
/* coord of item */ ,
188 const reiser4_key
* key
/* key to check */ ,
189 const reiser4_item_data
* data
/* parameters of item
193 reiser4_key min_key_in_item
;
194 reiser4_key max_key_in_item
;
196 assert("nikita-1658", item
!= NULL
);
197 assert("nikita-1659", key
!= NULL
);
199 iplug
= item_plugin_by_coord(item
);
200 if (iplug
->b
.can_contain_key
!= NULL
)
201 return iplug
->b
.can_contain_key(item
, key
, data
);
203 assert("nikita-1681", iplug
->b
.max_key_inside
!= NULL
);
204 item_key_by_coord(item
, &min_key_in_item
);
205 iplug
->b
.max_key_inside(item
, &max_key_in_item
);
207 /* can contain key if
208 min_key_in_item <= key &&
209 key <= max_key_in_item
211 return keyle(&min_key_in_item
, key
)
212 && keyle(key
, &max_key_in_item
);
216 /* mergeable method for non mergeable items */
218 not_mergeable(const coord_t
* i1 UNUSED_ARG
, const coord_t
* i2 UNUSED_ARG
)
223 /* return 0 if @item1 and @item2 are not mergeable, !0 - otherwise */
224 int are_items_mergeable(const coord_t
* i1
/* coord of first item */ ,
225 const coord_t
* i2
/* coord of second item */ )
231 assert("nikita-1336", i1
!= NULL
);
232 assert("nikita-1337", i2
!= NULL
);
234 iplug
= item_plugin_by_coord(i1
);
235 assert("nikita-1338", iplug
!= NULL
);
237 /* NOTE-NIKITA are_items_mergeable() is also called by assertions in
238 shifting code when nodes are in "suspended" state. */
239 assert("nikita-1663",
240 keyle(item_key_by_coord(i1
, &k1
), item_key_by_coord(i2
, &k2
)));
242 if (iplug
->b
.mergeable
!= NULL
) {
243 return iplug
->b
.mergeable(i1
, i2
);
244 } else if (iplug
->b
.max_key_inside
!= NULL
) {
245 iplug
->b
.max_key_inside(i1
, &k1
);
246 item_key_by_coord(i2
, &k2
);
248 /* mergeable if ->max_key_inside() >= key of i2; */
249 return keyge(iplug
->b
.max_key_inside(i1
, &k1
),
250 item_key_by_coord(i2
, &k2
));
252 item_key_by_coord(i1
, &k1
);
253 item_key_by_coord(i2
, &k2
);
256 (get_key_locality(&k1
) == get_key_locality(&k2
)) &&
257 (get_key_objectid(&k1
) == get_key_objectid(&k2
))
258 && (iplug
== item_plugin_by_coord(i2
));
262 int item_is_extent(const coord_t
* item
)
264 assert("vs-482", coord_is_existing_item(item
));
265 return item_id_by_coord(item
) == EXTENT_POINTER_ID
;
268 int item_is_tail(const coord_t
* item
)
270 assert("vs-482", coord_is_existing_item(item
));
271 return item_id_by_coord(item
) == FORMATTING_ID
;
276 int item_is_statdata(const coord_t
* item
)
278 assert("vs-516", coord_is_existing_item(item
));
279 return plugin_of_group(item_plugin_by_coord(item
), STAT_DATA_ITEM_TYPE
);
282 int item_is_ctail(const coord_t
* item
)
284 assert("edward-xx", coord_is_existing_item(item
));
285 return item_id_by_coord(item
) == CTAIL_ID
;
288 #endif /* REISER4_DEBUG */
290 static int change_item(struct inode
*inode
,
291 reiser4_plugin
* plugin
,
294 /* cannot change constituent item (sd, or dir_item) */
295 return RETERR(-EINVAL
);
298 static reiser4_plugin_ops item_plugin_ops
= {
303 .change
= change_item
306 item_plugin item_plugins
[LAST_ITEM_ID
] = {
307 [STATIC_STAT_DATA_ID
] = {
309 .type_id
= REISER4_ITEM_PLUGIN_TYPE
,
310 .id
= STATIC_STAT_DATA_ID
,
311 .groups
= (1 << STAT_DATA_ITEM_TYPE
),
312 .pops
= &item_plugin_ops
,
315 .linkage
= {NULL
, NULL
}
318 .max_key_inside
= max_key_inside_single_key
,
319 .can_contain_key
= NULL
,
320 .mergeable
= not_mergeable
,
321 .nr_units
= nr_units_single_unit
,
324 .paste
= paste_no_paste
,
334 .max_unit_key
= NULL
,
336 .item_data_by_flow
= NULL
,
342 .utmost_child
= NULL
,
343 .utmost_child_real_block
= NULL
,
350 .init_inode
= init_inode_static_sd
,
351 .save_len
= save_len_static_sd
,
352 .save
= save_static_sd
356 [SIMPLE_DIR_ENTRY_ID
] = {
358 .type_id
= REISER4_ITEM_PLUGIN_TYPE
,
359 .id
= SIMPLE_DIR_ENTRY_ID
,
360 .groups
= (1 << DIR_ENTRY_ITEM_TYPE
),
361 .pops
= &item_plugin_ops
,
363 .desc
= "directory entry",
364 .linkage
= {NULL
, NULL
}
367 .max_key_inside
= max_key_inside_single_key
,
368 .can_contain_key
= NULL
,
370 .nr_units
= nr_units_single_unit
,
383 .max_unit_key
= NULL
,
385 .item_data_by_flow
= NULL
,
391 .utmost_child
= NULL
,
392 .utmost_child_real_block
= NULL
,
399 .extract_key
= extract_key_de
,
400 .update_key
= update_key_de
,
401 .extract_name
= extract_name_de
,
402 .extract_file_type
= extract_file_type_de
,
403 .add_entry
= add_entry_de
,
404 .rem_entry
= rem_entry_de
,
405 .max_name_len
= max_name_len_de
409 [COMPOUND_DIR_ID
] = {
411 .type_id
= REISER4_ITEM_PLUGIN_TYPE
,
412 .id
= COMPOUND_DIR_ID
,
413 .groups
= (1 << DIR_ENTRY_ITEM_TYPE
),
414 .pops
= &item_plugin_ops
,
416 .desc
= "compressed directory entry",
417 .linkage
= {NULL
, NULL
}
420 .max_key_inside
= max_key_inside_cde
,
421 .can_contain_key
= can_contain_key_cde
,
422 .mergeable
= mergeable_cde
,
423 .nr_units
= nr_units_cde
,
424 .lookup
= lookup_cde
,
427 .fast_paste
= agree_to_fast_op
,
428 .can_shift
= can_shift_cde
,
429 .copy_units
= copy_units_cde
,
433 .cut_units
= cut_units_cde
,
434 .kill_units
= kill_units_cde
,
435 .unit_key
= unit_key_cde
,
436 .max_unit_key
= unit_key_cde
,
437 .estimate
= estimate_cde
,
438 .item_data_by_flow
= NULL
,
440 .check
= reiser4_check_cde
444 .utmost_child
= NULL
,
445 .utmost_child_real_block
= NULL
,
452 .extract_key
= extract_key_cde
,
453 .update_key
= update_key_cde
,
454 .extract_name
= extract_name_cde
,
455 .extract_file_type
= extract_file_type_de
,
456 .add_entry
= add_entry_cde
,
457 .rem_entry
= rem_entry_cde
,
458 .max_name_len
= max_name_len_cde
462 [NODE_POINTER_ID
] = {
464 .type_id
= REISER4_ITEM_PLUGIN_TYPE
,
465 .id
= NODE_POINTER_ID
,
466 .groups
= (1 << INTERNAL_ITEM_TYPE
),
469 .desc
= "internal item",
470 .linkage
= {NULL
, NULL
}
473 .max_key_inside
= NULL
,
474 .can_contain_key
= NULL
,
475 .mergeable
= mergeable_internal
,
476 .nr_units
= nr_units_single_unit
,
477 .lookup
= lookup_internal
,
483 .create_hook
= create_hook_internal
,
484 .kill_hook
= kill_hook_internal
,
485 .shift_hook
= shift_hook_internal
,
489 .max_unit_key
= NULL
,
491 .item_data_by_flow
= NULL
,
493 .check
= check__internal
497 .utmost_child
= utmost_child_internal
,
498 .utmost_child_real_block
=
499 utmost_child_real_block_internal
,
500 .update
= reiser4_update_internal
,
506 .down_link
= down_link_internal
,
507 .has_pointer_to
= has_pointer_to_internal
511 [EXTENT_POINTER_ID
] = {
513 .type_id
= REISER4_ITEM_PLUGIN_TYPE
,
514 .id
= EXTENT_POINTER_ID
,
515 .groups
= (1 << UNIX_FILE_METADATA_ITEM_TYPE
),
518 .desc
= "extent item",
519 .linkage
= {NULL
, NULL
}
522 .max_key_inside
= max_key_inside_extent
,
523 .can_contain_key
= can_contain_key_extent
,
524 .mergeable
= mergeable_extent
,
525 .nr_units
= nr_units_extent
,
526 .lookup
= lookup_extent
,
528 .paste
= paste_extent
,
529 .fast_paste
= agree_to_fast_op
,
530 .can_shift
= can_shift_extent
,
531 .create_hook
= create_hook_extent
,
532 .copy_units
= copy_units_extent
,
533 .kill_hook
= kill_hook_extent
,
535 .cut_units
= cut_units_extent
,
536 .kill_units
= kill_units_extent
,
537 .unit_key
= unit_key_extent
,
538 .max_unit_key
= max_unit_key_extent
,
540 .item_data_by_flow
= NULL
,
542 .check
= reiser4_check_extent
546 .utmost_child
= utmost_child_extent
,
547 .utmost_child_real_block
=
548 utmost_child_real_block_extent
,
550 .scan
= reiser4_scan_extent
,
552 .key_by_offset
= key_by_offset_extent
556 .write
= reiser4_write_extent
,
557 .read
= reiser4_read_extent
,
558 .readpage
= reiser4_readpage_extent
,
559 .get_block
= get_block_address_extent
,
560 .append_key
= append_key_extent
,
561 .init_coord_extension
=
562 init_coord_extension_extent
568 .type_id
= REISER4_ITEM_PLUGIN_TYPE
,
570 .groups
= (1 << UNIX_FILE_METADATA_ITEM_TYPE
),
573 .desc
= "body (or tail?) item",
574 .linkage
= {NULL
, NULL
}
577 .max_key_inside
= max_key_inside_tail
,
578 .can_contain_key
= can_contain_key_tail
,
579 .mergeable
= mergeable_tail
,
580 .nr_units
= nr_units_tail
,
581 .lookup
= lookup_tail
,
584 .fast_paste
= agree_to_fast_op
,
585 .can_shift
= can_shift_tail
,
587 .copy_units
= copy_units_tail
,
588 .kill_hook
= kill_hook_tail
,
590 .cut_units
= cut_units_tail
,
591 .kill_units
= kill_units_tail
,
592 .unit_key
= unit_key_tail
,
593 .max_unit_key
= unit_key_tail
,
595 .item_data_by_flow
= NULL
,
601 .utmost_child
= NULL
,
602 .utmost_child_real_block
= NULL
,
609 .write
= reiser4_write_tail
,
610 .read
= reiser4_read_tail
,
611 .readpage
= readpage_tail
,
612 .get_block
= get_block_address_tail
,
613 .append_key
= append_key_tail
,
614 .init_coord_extension
=
615 init_coord_extension_tail
621 .type_id
= REISER4_ITEM_PLUGIN_TYPE
,
623 .groups
= (1 << UNIX_FILE_METADATA_ITEM_TYPE
),
626 .desc
= "cryptcompress tail item",
627 .linkage
= {NULL
, NULL
}
630 .max_key_inside
= max_key_inside_tail
,
631 .can_contain_key
= can_contain_key_ctail
,
632 .mergeable
= mergeable_ctail
,
633 .nr_units
= nr_units_ctail
,
636 .paste
= paste_ctail
,
637 .fast_paste
= agree_to_fast_op
,
638 .can_shift
= can_shift_ctail
,
639 .create_hook
= create_hook_ctail
,
640 .copy_units
= copy_units_ctail
,
641 .kill_hook
= kill_hook_ctail
,
642 .shift_hook
= shift_hook_ctail
,
643 .cut_units
= cut_units_ctail
,
644 .kill_units
= kill_units_ctail
,
645 .unit_key
= unit_key_tail
,
646 .max_unit_key
= unit_key_tail
,
647 .estimate
= estimate_ctail
,
648 .item_data_by_flow
= NULL
,
654 .utmost_child
= utmost_child_ctail
,
655 /* FIXME-EDWARD: write this */
656 .utmost_child_real_block
= NULL
,
659 .convert
= convert_ctail
665 .readpage
= readpage_ctail
,
666 .get_block
= get_block_address_tail
,
667 .append_key
= append_key_ctail
,
668 .init_coord_extension
=
669 init_coord_extension_tail
675 .type_id
= REISER4_ITEM_PLUGIN_TYPE
,
677 .groups
= (1 << OTHER_ITEM_TYPE
),
680 .desc
= "black box item",
681 .linkage
= {NULL
, NULL
}
684 .max_key_inside
= NULL
,
685 .can_contain_key
= NULL
,
686 .mergeable
= not_mergeable
,
687 .nr_units
= nr_units_single_unit
,
688 /* to need for ->lookup method */
701 .max_unit_key
= NULL
,
703 .item_data_by_flow
= NULL
,
713 c-indentation-style: "K&R"