revert-mm-fix-blkdev-size-calculation-in-generic_write_checks
[linux-2.6/linux-trees-mm.git] / fs / reiser4 / plugin / item / ctail.c
blob14e0b75fd05ea4c88a86974a852e1ab2048da64b
1 /* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */
3 /* ctails (aka "clustered tails") are items for cryptcompress objects */
5 /* DESCRIPTION:
7 Each cryptcompress object is stored on disk as a set of clusters sliced
8 into ctails.
10 Internal on-disk structure:
12 HEADER (1) Here stored disk cluster shift
13 BODY
16 #include "../../forward.h"
17 #include "../../debug.h"
18 #include "../../dformat.h"
19 #include "../../kassign.h"
20 #include "../../key.h"
21 #include "../../coord.h"
22 #include "item.h"
23 #include "../node/node.h"
24 #include "../plugin.h"
25 #include "../object.h"
26 #include "../../znode.h"
27 #include "../../carry.h"
28 #include "../../tree.h"
29 #include "../../inode.h"
30 #include "../../super.h"
31 #include "../../context.h"
32 #include "../../page_cache.h"
33 #include "../cluster.h"
34 #include "../../flush.h"
35 #include "../../tree_walk.h"
37 #include <linux/pagevec.h>
38 #include <linux/swap.h>
39 #include <linux/fs.h>
41 /* return body of ctail item at @coord */
42 static ctail_item_format *ctail_formatted_at(const coord_t * coord)
44 assert("edward-60", coord != NULL);
45 return item_body_by_coord(coord);
48 static int cluster_shift_by_coord(const coord_t * coord)
50 return get_unaligned(&ctail_formatted_at(coord)->cluster_shift);
53 static inline void dclust_set_extension_shift(hint_t * hint)
55 assert("edward-1270",
56 item_id_by_coord(&hint->ext_coord.coord) == CTAIL_ID);
57 hint->ext_coord.extension.ctail.shift =
58 cluster_shift_by_coord(&hint->ext_coord.coord);
61 static loff_t off_by_coord(const coord_t * coord)
63 reiser4_key key;
64 return get_key_offset(item_key_by_coord(coord, &key));
67 int coord_is_unprepped_ctail(const coord_t * coord)
69 assert("edward-1233", coord != NULL);
70 assert("edward-1234", item_id_by_coord(coord) == CTAIL_ID);
71 assert("edward-1235",
72 ergo((int)cluster_shift_by_coord(coord) == (int)UCTAIL_SHIFT,
73 nr_units_ctail(coord) == (pos_in_node_t) UCTAIL_NR_UNITS));
75 return (int)cluster_shift_by_coord(coord) == (int)UCTAIL_SHIFT;
78 static cloff_t clust_by_coord(const coord_t * coord, struct inode *inode)
80 int shift;
82 if (inode != NULL) {
83 shift = inode_cluster_shift(inode);
84 assert("edward-1236",
85 ergo(!coord_is_unprepped_ctail(coord),
86 shift == cluster_shift_by_coord(coord)));
87 } else {
88 assert("edward-1237", !coord_is_unprepped_ctail(coord));
89 shift = cluster_shift_by_coord(coord);
91 return off_by_coord(coord) >> shift;
94 static int disk_cluster_size(const coord_t * coord)
96 assert("edward-1156",
97 item_plugin_by_coord(coord) == item_plugin_by_id(CTAIL_ID));
98 /* calculation of disk cluster size
99 is meaninless if ctail is unprepped */
100 assert("edward-1238", !coord_is_unprepped_ctail(coord));
102 return 1 << cluster_shift_by_coord(coord);
105 /* true if the key is of first disk cluster item */
106 static int is_disk_cluster_key(const reiser4_key * key, const coord_t * coord)
108 assert("edward-1239", item_id_by_coord(coord) == CTAIL_ID);
110 return coord_is_unprepped_ctail(coord) ||
111 ((get_key_offset(key) &
112 ((loff_t) disk_cluster_size(coord) - 1)) == 0);
115 static char *first_unit(coord_t * coord)
117 /* FIXME: warning: pointer of type `void *' used in arithmetic */
118 return (char *)item_body_by_coord(coord) + sizeof(ctail_item_format);
121 /* plugin->u.item.b.max_key_inside :
122 tail_max_key_inside */
124 /* plugin->u.item.b.can_contain_key */
126 can_contain_key_ctail(const coord_t * coord, const reiser4_key * key,
127 const reiser4_item_data * data)
129 reiser4_key item_key;
131 if (item_plugin_by_coord(coord) != data->iplug)
132 return 0;
134 item_key_by_coord(coord, &item_key);
135 if (get_key_locality(key) != get_key_locality(&item_key) ||
136 get_key_objectid(key) != get_key_objectid(&item_key))
137 return 0;
138 if (get_key_offset(&item_key) + nr_units_ctail(coord) !=
139 get_key_offset(key))
140 return 0;
141 if (is_disk_cluster_key(key, coord))
142 return 0;
143 return 1;
146 /* plugin->u.item.b.mergeable */
147 int mergeable_ctail(const coord_t * p1, const coord_t * p2)
149 reiser4_key key1, key2;
151 assert("edward-62", item_id_by_coord(p1) == CTAIL_ID);
152 assert("edward-61", plugin_of_group(item_plugin_by_coord(p1),
153 UNIX_FILE_METADATA_ITEM_TYPE));
155 if (item_id_by_coord(p2) != CTAIL_ID) {
156 /* second item is of another type */
157 return 0;
160 item_key_by_coord(p1, &key1);
161 item_key_by_coord(p2, &key2);
162 if (get_key_locality(&key1) != get_key_locality(&key2) ||
163 get_key_objectid(&key1) != get_key_objectid(&key2) ||
164 get_key_type(&key1) != get_key_type(&key2)) {
165 /* items of different objects */
166 return 0;
168 if (get_key_offset(&key1) + nr_units_ctail(p1) != get_key_offset(&key2))
169 /* not adjacent items */
170 return 0;
171 if (is_disk_cluster_key(&key2, p2))
172 return 0;
173 return 1;
176 /* plugin->u.item.b.nr_units */
177 pos_in_node_t nr_units_ctail(const coord_t * coord)
179 return (item_length_by_coord(coord) -
180 sizeof(ctail_formatted_at(coord)->cluster_shift));
183 /* plugin->u.item.b.estimate:
184 estimate how much space is needed to insert/paste @data->length bytes
185 into ctail at @coord */
186 int estimate_ctail(const coord_t * coord /* coord of item */ ,
187 const reiser4_item_data *
188 data /* parameters for new item */ )
190 if (coord == NULL)
191 /* insert */
192 return (sizeof(ctail_item_format) + data->length);
193 else
194 /* paste */
195 return data->length;
198 /* ->init() method for this item plugin. */
199 int init_ctail(coord_t * to /* coord of item */ ,
200 coord_t * from /* old_item */ ,
201 reiser4_item_data * data /* structure used for insertion */ )
203 int cluster_shift; /* cpu value to convert */
205 if (data) {
206 assert("edward-463", data->length > sizeof(ctail_item_format));
207 cluster_shift = *((int *)(data->arg));
208 data->length -= sizeof(ctail_item_format);
209 } else {
210 assert("edward-464", from != NULL);
211 assert("edward-855", ctail_ok(from));
212 cluster_shift = (int)(cluster_shift_by_coord(from));
214 put_unaligned((d8)cluster_shift, &ctail_formatted_at(to)->cluster_shift);
215 assert("edward-856", ctail_ok(to));
216 return 0;
219 /* plugin->u.item.b.lookup:
220 NULL: We are looking for item keys only */
222 #if REISER4_DEBUG
223 int ctail_ok(const coord_t * coord)
225 return coord_is_unprepped_ctail(coord) ||
226 cluster_shift_ok(cluster_shift_by_coord(coord));
229 /* plugin->u.item.b.check */
230 int check_ctail(const coord_t * coord, const char **error)
232 if (!ctail_ok(coord)) {
233 if (error)
234 *error = "bad cluster shift in ctail";
235 return 1;
237 return 0;
239 #endif
241 /* plugin->u.item.b.paste */
243 paste_ctail(coord_t * coord, reiser4_item_data * data,
244 carry_plugin_info * info UNUSED_ARG)
246 unsigned old_nr_units;
248 assert("edward-268", data->data != NULL);
249 /* copy only from kernel space */
250 assert("edward-66", data->user == 0);
252 old_nr_units =
253 item_length_by_coord(coord) - sizeof(ctail_item_format) -
254 data->length;
256 /* ctail items never get pasted in the middle */
258 if (coord->unit_pos == 0 && coord->between == AT_UNIT) {
260 /* paste at the beginning when create new item */
261 assert("edward-450",
262 item_length_by_coord(coord) ==
263 data->length + sizeof(ctail_item_format));
264 assert("edward-451", old_nr_units == 0);
265 } else if (coord->unit_pos == old_nr_units - 1
266 && coord->between == AFTER_UNIT) {
268 /* paste at the end */
269 coord->unit_pos++;
270 } else
271 impossible("edward-453", "bad paste position");
273 memcpy(first_unit(coord) + coord->unit_pos, data->data, data->length);
275 assert("edward-857", ctail_ok(coord));
277 return 0;
280 /* plugin->u.item.b.fast_paste */
282 /* plugin->u.item.b.can_shift
283 number of units is returned via return value, number of bytes via @size. For
284 ctail items they coincide */
286 can_shift_ctail(unsigned free_space, coord_t * source,
287 znode * target, shift_direction direction UNUSED_ARG,
288 unsigned *size /* number of bytes */ , unsigned want)
290 /* make sure that that we do not want to shift more than we have */
291 assert("edward-68", want > 0 && want <= nr_units_ctail(source));
293 *size = min(want, free_space);
295 if (!target) {
296 /* new item will be created */
297 if (*size <= sizeof(ctail_item_format)) {
298 *size = 0;
299 return 0;
301 return *size - sizeof(ctail_item_format);
303 return *size;
306 /* plugin->u.item.b.copy_units
307 cooperates with ->can_shift() */
308 void
309 copy_units_ctail(coord_t * target, coord_t * source,
310 unsigned from, unsigned count /* units */ ,
311 shift_direction where_is_free_space,
312 unsigned free_space /* bytes */ )
314 /* make sure that item @target is expanded already */
315 assert("edward-69", (unsigned)item_length_by_coord(target) >= count);
316 assert("edward-70", free_space == count || free_space == count + 1);
318 assert("edward-858", ctail_ok(source));
320 if (where_is_free_space == SHIFT_LEFT) {
321 /* append item @target with @count first bytes of @source:
322 this restriction came from ordinary tails */
323 assert("edward-71", from == 0);
324 assert("edward-860", ctail_ok(target));
326 memcpy(first_unit(target) + nr_units_ctail(target) - count,
327 first_unit(source), count);
328 } else {
329 /* target item is moved to right already */
330 reiser4_key key;
332 assert("edward-72", nr_units_ctail(source) == from + count);
334 if (free_space == count) {
335 init_ctail(target, source, NULL);
336 } else {
337 /* new item has been created */
338 assert("edward-862", ctail_ok(target));
340 memcpy(first_unit(target), first_unit(source) + from, count);
342 assert("edward-863", ctail_ok(target));
344 /* new units are inserted before first unit in an item,
345 therefore, we have to update item key */
346 item_key_by_coord(source, &key);
347 set_key_offset(&key, get_key_offset(&key) + from);
349 node_plugin_by_node(target->node)->update_item_key(target, &key,
350 NULL /*info */);
354 /* plugin->u.item.b.create_hook */
355 int create_hook_ctail(const coord_t * coord, void *arg)
357 assert("edward-864", znode_is_loaded(coord->node));
359 znode_set_convertible(coord->node);
360 return 0;
363 /* plugin->u.item.b.kill_hook */
364 int kill_hook_ctail(const coord_t * coord, pos_in_node_t from,
365 pos_in_node_t count, carry_kill_data * kdata)
367 struct inode *inode;
369 assert("edward-1157", item_id_by_coord(coord) == CTAIL_ID);
370 assert("edward-291", znode_is_write_locked(coord->node));
372 inode = kdata->inode;
373 if (inode) {
374 reiser4_key key;
375 struct cryptcompress_info * info;
376 cloff_t index;
378 item_key_by_coord(coord, &key);
379 info = cryptcompress_inode_data(inode);
380 index = off_to_clust(get_key_offset(&key), inode);
382 if (from == 0) {
383 info->trunc_index = index;
384 if (is_disk_cluster_key(&key, coord)) {
386 * first item of disk cluster is to be killed
388 truncate_complete_page_cluster(
389 inode, index, kdata->params.truncate);
390 inode_sub_bytes(inode,
391 inode_cluster_size(inode));
395 return 0;
398 /* for shift_hook_ctail(),
399 return true if the first disk cluster item has dirty child
401 static int ctail_convertible(const coord_t * coord)
403 int result;
404 reiser4_key key;
405 jnode *child = NULL;
407 assert("edward-477", coord != NULL);
408 assert("edward-478", item_id_by_coord(coord) == CTAIL_ID);
410 if (coord_is_unprepped_ctail(coord))
411 /* unprepped ctail should be converted */
412 return 1;
414 item_key_by_coord(coord, &key);
415 child = jlookup(current_tree,
416 get_key_objectid(&key),
417 off_to_pg(off_by_coord(coord)));
418 if (!child)
419 return 0;
420 result = JF_ISSET(child, JNODE_DIRTY);
421 jput(child);
422 return result;
425 /* FIXME-EDWARD */
426 /* plugin->u.item.b.shift_hook */
427 int shift_hook_ctail(const coord_t * item /* coord of item */ ,
428 unsigned from UNUSED_ARG /* start unit */ ,
429 unsigned count UNUSED_ARG /* stop unit */ ,
430 znode * old_node /* old parent */ )
432 assert("edward-479", item != NULL);
433 assert("edward-480", item->node != old_node);
435 if (!znode_convertible(old_node) || znode_convertible(item->node))
436 return 0;
437 if (ctail_convertible(item))
438 znode_set_convertible(item->node);
439 return 0;
442 static int
443 cut_or_kill_ctail_units(coord_t * coord, pos_in_node_t from, pos_in_node_t to,
444 int cut, void *p, reiser4_key * smallest_removed,
445 reiser4_key * new_first)
447 pos_in_node_t count; /* number of units to cut */
448 char *item;
450 count = to - from + 1;
451 item = item_body_by_coord(coord);
453 assert("edward-74", ergo(from != 0, to == coord_last_unit_pos(coord)));
455 if (smallest_removed) {
456 /* store smallest key removed */
457 item_key_by_coord(coord, smallest_removed);
458 set_key_offset(smallest_removed,
459 get_key_offset(smallest_removed) + from);
462 if (new_first) {
463 assert("vs-1531", from == 0);
465 item_key_by_coord(coord, new_first);
466 set_key_offset(new_first,
467 get_key_offset(new_first) + from + count);
470 if (!cut)
471 kill_hook_ctail(coord, from, 0, (struct carry_kill_data *)p);
473 if (from == 0) {
474 if (count != nr_units_ctail(coord)) {
475 /* part of item is removed, so move free space at the beginning
476 of the item and update item key */
477 reiser4_key key;
478 memcpy(item + to + 1, item, sizeof(ctail_item_format));
479 item_key_by_coord(coord, &key);
480 set_key_offset(&key, get_key_offset(&key) + count);
481 node_plugin_by_node(coord->node)->update_item_key(coord,
482 &key,
483 NULL);
484 } else {
485 /* cut_units should not be called to cut evrything */
486 assert("vs-1532", ergo(cut, 0));
487 /* whole item is cut, so more then amount of space occupied
488 by units got freed */
489 count += sizeof(ctail_item_format);
491 if (REISER4_DEBUG)
492 memset(item, 0, count);
493 } else if (REISER4_DEBUG)
494 memset(item + sizeof(ctail_item_format) + from, 0, count);
495 return count;
498 /* plugin->u.item.b.cut_units */
500 cut_units_ctail(coord_t * item, pos_in_node_t from, pos_in_node_t to,
501 carry_cut_data * cdata, reiser4_key * smallest_removed,
502 reiser4_key * new_first)
504 return cut_or_kill_ctail_units(item, from, to, 1, NULL,
505 smallest_removed, new_first);
508 /* plugin->u.item.b.kill_units */
510 kill_units_ctail(coord_t * item, pos_in_node_t from, pos_in_node_t to,
511 struct carry_kill_data *kdata, reiser4_key * smallest_removed,
512 reiser4_key * new_first)
514 return cut_or_kill_ctail_units(item, from, to, 0, kdata,
515 smallest_removed, new_first);
518 /* plugin->u.item.s.file.read */
519 int read_ctail(struct file *file UNUSED_ARG, flow_t * f, hint_t * hint)
521 uf_coord_t *uf_coord;
522 coord_t *coord;
524 uf_coord = &hint->ext_coord;
525 coord = &uf_coord->coord;
526 assert("edward-127", f->user == 0);
527 assert("edward-129", coord && coord->node);
528 assert("edward-130", coord_is_existing_unit(coord));
529 assert("edward-132", znode_is_loaded(coord->node));
531 /* start read only from the beginning of ctail */
532 assert("edward-133", coord->unit_pos == 0);
533 /* read only whole ctails */
534 assert("edward-135", nr_units_ctail(coord) <= f->length);
536 assert("edward-136", reiser4_schedulable());
537 assert("edward-886", ctail_ok(coord));
539 if (f->data)
540 memcpy(f->data, (char *)first_unit(coord),
541 (size_t) nr_units_ctail(coord));
543 dclust_set_extension_shift(hint);
544 mark_page_accessed(znode_page(coord->node));
545 move_flow_forward(f, nr_units_ctail(coord));
547 return 0;
551 * Prepare transform stream with plain text for page
552 * @page taking into account synchronization issues.
554 static int ctail_read_disk_cluster(struct cluster_handle * clust,
555 struct inode * inode, struct page * page,
556 znode_lock_mode mode)
558 int result;
560 assert("edward-1450", mode == ZNODE_READ_LOCK || ZNODE_WRITE_LOCK);
561 assert("edward-671", clust->hint != NULL);
562 assert("edward-140", clust->dstat == INVAL_DISK_CLUSTER);
563 assert("edward-672", cryptcompress_inode_ok(inode));
564 assert("edward-1527", PageLocked(page));
566 unlock_page(page);
568 /* set input stream */
569 result = grab_tfm_stream(inode, &clust->tc, INPUT_STREAM);
570 if (result) {
571 lock_page(page);
572 return result;
574 result = find_disk_cluster(clust, inode, 1 /* read items */, mode);
575 lock_page(page);
576 if (result)
577 return result;
579 * at this point we have locked position in the tree
581 assert("edward-1528", znode_is_any_locked(clust->hint->lh.node));
583 if (page->mapping != inode->i_mapping) {
584 /* page was truncated */
585 reiser4_unset_hint(clust->hint);
586 reset_cluster_params(clust);
587 return AOP_TRUNCATED_PAGE;
589 if (PageUptodate(page)) {
590 /* disk cluster can be obsolete, don't use it! */
591 reiser4_unset_hint(clust->hint);
592 reset_cluster_params(clust);
593 return 0;
595 if (clust->dstat == FAKE_DISK_CLUSTER ||
596 clust->dstat == UNPR_DISK_CLUSTER ||
597 clust->dstat == TRNC_DISK_CLUSTER) {
599 * this information about disk cluster will be valid
600 * as long as we keep the position in the tree locked
602 tfm_cluster_set_uptodate(&clust->tc);
603 return 0;
605 /* now prepare output stream.. */
606 result = grab_coa(&clust->tc, inode_compression_plugin(inode));
607 if (result)
608 return result;
609 /* ..and fill this with plain text */
610 result = reiser4_inflate_cluster(clust, inode);
611 if (result)
612 return result;
614 * The stream is ready! It won't be obsolete as
615 * long as we keep last disk cluster item locked.
617 tfm_cluster_set_uptodate(&clust->tc);
618 return 0;
622 * fill one page with plain text.
624 int do_readpage_ctail(struct inode * inode, struct cluster_handle * clust,
625 struct page *page, znode_lock_mode mode)
627 int ret;
628 unsigned cloff;
629 char *data;
630 size_t to_page;
631 struct tfm_cluster * tc = &clust->tc;
633 assert("edward-212", PageLocked(page));
635 if (unlikely(page->mapping != inode->i_mapping))
636 return AOP_TRUNCATED_PAGE;
637 if (PageUptodate(page))
638 goto exit;
639 to_page = pbytes(page_index(page), inode);
640 if (to_page == 0) {
641 zero_user(page, 0, PAGE_CACHE_SIZE);
642 SetPageUptodate(page);
643 goto exit;
645 if (!tfm_cluster_is_uptodate(&clust->tc)) {
646 clust->index = pg_to_clust(page->index, inode);
648 /* this will unlock/lock the page */
649 ret = ctail_read_disk_cluster(clust, inode, page, mode);
651 assert("edward-212", PageLocked(page));
652 if (ret)
653 return ret;
655 /* refresh bytes */
656 to_page = pbytes(page_index(page), inode);
657 if (to_page == 0) {
658 zero_user(page, 0, PAGE_CACHE_SIZE);
659 SetPageUptodate(page);
660 goto exit;
663 if (PageUptodate(page))
664 /* somebody else fill it already */
665 goto exit;
667 assert("edward-119", tfm_cluster_is_uptodate(tc));
668 assert("edward-1529", znode_is_any_locked(clust->hint->lh.node));
670 switch (clust->dstat) {
671 case UNPR_DISK_CLUSTER:
672 BUG_ON(1);
673 case TRNC_DISK_CLUSTER:
675 * Race with truncate!
676 * We resolve it in favour of the last one (the only way,
677 * as in this case plain text is unrecoverable)
679 case FAKE_DISK_CLUSTER:
680 /* fill the page by zeroes */
681 zero_user(page, 0, PAGE_CACHE_SIZE);
682 SetPageUptodate(page);
683 break;
684 case PREP_DISK_CLUSTER:
685 /* fill page by transformed stream with plain text */
686 assert("edward-1058", !PageUptodate(page));
687 assert("edward-120", tc->len <= inode_cluster_size(inode));
689 /* page index in this logical cluster */
690 cloff = pg_to_off_to_cloff(page->index, inode);
692 data = kmap(page);
693 memcpy(data, tfm_stream_data(tc, OUTPUT_STREAM) + cloff, to_page);
694 memset(data + to_page, 0, (size_t) PAGE_CACHE_SIZE - to_page);
695 flush_dcache_page(page);
696 kunmap(page);
697 SetPageUptodate(page);
698 break;
699 default:
700 impossible("edward-1169", "bad disk cluster state");
702 exit:
703 return 0;
706 /* plugin->u.item.s.file.readpage */
707 int readpage_ctail(void *vp, struct page *page)
709 int result;
710 hint_t * hint;
711 struct cluster_handle * clust = vp;
713 assert("edward-114", clust != NULL);
714 assert("edward-115", PageLocked(page));
715 assert("edward-116", !PageUptodate(page));
716 assert("edward-118", page->mapping && page->mapping->host);
717 assert("edward-867", !tfm_cluster_is_uptodate(&clust->tc));
719 hint = kmalloc(sizeof(*hint), reiser4_ctx_gfp_mask_get());
720 if (hint == NULL) {
721 unlock_page(page);
722 return RETERR(-ENOMEM);
724 clust->hint = hint;
725 result = load_file_hint(clust->file, hint);
726 if (result) {
727 kfree(hint);
728 unlock_page(page);
729 return result;
731 assert("vs-25", hint->ext_coord.lh == &hint->lh);
733 result = do_readpage_ctail(page->mapping->host, clust, page,
734 ZNODE_READ_LOCK);
735 assert("edward-213", PageLocked(page));
736 assert("edward-1163", ergo(!result, PageUptodate(page)));
738 unlock_page(page);
739 done_lh(&hint->lh);
740 hint->ext_coord.valid = 0;
741 save_file_hint(clust->file, hint);
742 kfree(hint);
743 tfm_cluster_clr_uptodate(&clust->tc);
745 return result;
748 /* Helper function for ->readpages() */
749 static int ctail_read_page_cluster(struct cluster_handle * clust,
750 struct inode *inode)
752 int i;
753 int result;
754 assert("edward-779", clust != NULL);
755 assert("edward-1059", clust->win == NULL);
756 assert("edward-780", inode != NULL);
758 result = prepare_page_cluster(inode, clust, READ_OP);
759 if (result)
760 return result;
762 assert("edward-781", !tfm_cluster_is_uptodate(&clust->tc));
764 for (i = 0; i < clust->nr_pages; i++) {
765 struct page *page = clust->pages[i];
766 lock_page(page);
767 result = do_readpage_ctail(inode, clust, page, ZNODE_READ_LOCK);
768 unlock_page(page);
769 if (result)
770 break;
772 tfm_cluster_clr_uptodate(&clust->tc);
773 put_page_cluster(clust, inode, READ_OP);
774 return result;
777 /* filler for read_cache_pages() */
778 static int ctail_readpages_filler(void * data, struct page * page)
780 int ret = 0;
781 struct cluster_handle * clust = data;
782 struct inode * inode = clust->file->f_dentry->d_inode;
784 assert("edward-1525", page->mapping == inode->i_mapping);
786 if (PageUptodate(page)) {
787 unlock_page(page);
788 return 0;
790 if (pbytes(page_index(page), inode) == 0) {
791 zero_user(page, 0, PAGE_CACHE_SIZE);
792 SetPageUptodate(page);
793 unlock_page(page);
794 return 0;
796 move_cluster_forward(clust, inode, page->index);
797 unlock_page(page);
799 * read the whole page cluster
801 ret = ctail_read_page_cluster(clust, inode);
803 assert("edward-869", !tfm_cluster_is_uptodate(&clust->tc));
804 return ret;
808 * We populate a bit more then upper readahead suggests:
809 * with each nominated page we read the whole page cluster
810 * this page belongs to.
812 int readpages_ctail(struct file *file, struct address_space *mapping,
813 struct list_head *pages)
815 int ret = 0;
816 hint_t *hint;
817 struct cluster_handle clust;
818 struct inode *inode = mapping->host;
820 assert("edward-1521", inode == file->f_dentry->d_inode);
822 cluster_init_read(&clust, NULL);
823 clust.file = file;
824 hint = kmalloc(sizeof(*hint), reiser4_ctx_gfp_mask_get());
825 if (hint == NULL) {
826 warning("vs-28", "failed to allocate hint");
827 ret = RETERR(-ENOMEM);
828 goto exit1;
830 clust.hint = hint;
831 ret = load_file_hint(clust.file, hint);
832 if (ret) {
833 warning("edward-1522", "failed to load hint");
834 goto exit2;
836 assert("vs-26", hint->ext_coord.lh == &hint->lh);
837 ret = alloc_cluster_pgset(&clust, cluster_nrpages(inode));
838 if (ret) {
839 warning("edward-1523", "failed to alloc pgset");
840 goto exit3;
842 ret = read_cache_pages(mapping, pages, ctail_readpages_filler, &clust);
844 assert("edward-870", !tfm_cluster_is_uptodate(&clust.tc));
845 exit3:
846 done_lh(&hint->lh);
847 save_file_hint(file, hint);
848 hint->ext_coord.valid = 0;
849 exit2:
850 kfree(hint);
851 exit1:
852 put_cluster_handle(&clust);
853 return ret;
857 plugin->u.item.s.file.append_key
858 key of the first item of the next disk cluster
860 reiser4_key *append_key_ctail(const coord_t * coord, reiser4_key * key)
862 assert("edward-1241", item_id_by_coord(coord) == CTAIL_ID);
863 assert("edward-1242", cluster_shift_ok(cluster_shift_by_coord(coord)));
865 item_key_by_coord(coord, key);
866 set_key_offset(key, ((__u64) (clust_by_coord(coord, NULL)) + 1)
867 << cluster_shift_by_coord(coord));
868 return key;
871 static int insert_unprepped_ctail(struct cluster_handle * clust,
872 struct inode *inode)
874 int result;
875 char buf[UCTAIL_NR_UNITS];
876 reiser4_item_data data;
877 reiser4_key key;
878 int shift = (int)UCTAIL_SHIFT;
880 memset(buf, 0, (size_t) UCTAIL_NR_UNITS);
881 result = key_by_inode_cryptcompress(inode,
882 clust_to_off(clust->index, inode),
883 &key);
884 if (result)
885 return result;
886 data.user = 0;
887 data.iplug = item_plugin_by_id(CTAIL_ID);
888 data.arg = &shift;
889 data.length = sizeof(ctail_item_format) + (size_t) UCTAIL_NR_UNITS;
890 data.data = buf;
892 result = insert_by_coord(&clust->hint->ext_coord.coord,
893 &data, &key, clust->hint->ext_coord.lh, 0);
894 return result;
897 static int
898 insert_cryptcompress_flow(coord_t * coord, lock_handle * lh, flow_t * f,
899 struct inode *inode)
901 int result;
902 carry_pool *pool;
903 carry_level *lowest_level;
904 reiser4_item_data *data;
905 carry_op *op;
906 int cluster_shift = inode_cluster_shift(inode);
908 pool =
909 init_carry_pool(sizeof(*pool) + 3 * sizeof(*lowest_level) +
910 sizeof(*data));
911 if (IS_ERR(pool))
912 return PTR_ERR(pool);
913 lowest_level = (carry_level *) (pool + 1);
914 init_carry_level(lowest_level, pool);
915 data = (reiser4_item_data *) (lowest_level + 3);
917 assert("edward-466", coord->between == AFTER_ITEM
918 || coord->between == AFTER_UNIT || coord->between == BEFORE_ITEM
919 || coord->between == EMPTY_NODE
920 || coord->between == BEFORE_UNIT);
922 if (coord->between == AFTER_UNIT) {
923 coord->unit_pos = 0;
924 coord->between = AFTER_ITEM;
926 op = reiser4_post_carry(lowest_level, COP_INSERT_FLOW, coord->node,
927 0 /* operate directly on coord -> node */);
928 if (IS_ERR(op) || (op == NULL)) {
929 done_carry_pool(pool);
930 return RETERR(op ? PTR_ERR(op) : -EIO);
932 data->user = 0;
933 data->iplug = item_plugin_by_id(CTAIL_ID);
934 data->arg = &cluster_shift;
936 data->length = 0;
937 data->data = NULL;
939 op->u.insert_flow.flags = COPI_DONT_SHIFT_LEFT | COPI_DONT_SHIFT_RIGHT;
940 op->u.insert_flow.insert_point = coord;
941 op->u.insert_flow.flow = f;
942 op->u.insert_flow.data = data;
943 op->u.insert_flow.new_nodes = 0;
945 lowest_level->track_type = CARRY_TRACK_CHANGE;
946 lowest_level->tracked = lh;
948 result = reiser4_carry(lowest_level, NULL);
949 done_carry_pool(pool);
951 return result;
954 /* Implementation of CRC_APPEND_ITEM mode of ctail conversion */
955 static int insert_cryptcompress_flow_in_place(coord_t * coord,
956 lock_handle * lh, flow_t * f,
957 struct inode *inode)
959 int ret;
960 coord_t pos;
961 lock_handle lock;
963 assert("edward-674", f->length <= inode_scaled_cluster_size(inode));
964 assert("edward-484", coord->between == AT_UNIT
965 || coord->between == AFTER_ITEM);
966 assert("edward-485", item_id_by_coord(coord) == CTAIL_ID);
968 coord_dup(&pos, coord);
969 pos.unit_pos = 0;
970 pos.between = AFTER_ITEM;
972 init_lh(&lock);
973 copy_lh(&lock, lh);
975 ret = insert_cryptcompress_flow(&pos, &lock, f, inode);
976 done_lh(&lock);
977 assert("edward-1347", znode_is_write_locked(lh->node));
978 assert("edward-1228", !ret);
979 return ret;
982 /* Implementation of CRC_OVERWRITE_ITEM mode of ctail conversion */
983 static int overwrite_ctail(coord_t * coord, flow_t * f)
985 unsigned count;
987 assert("edward-269", f->user == 0);
988 assert("edward-270", f->data != NULL);
989 assert("edward-271", f->length > 0);
990 assert("edward-272", coord_is_existing_unit(coord));
991 assert("edward-273", coord->unit_pos == 0);
992 assert("edward-274", znode_is_write_locked(coord->node));
993 assert("edward-275", reiser4_schedulable());
994 assert("edward-467", item_id_by_coord(coord) == CTAIL_ID);
995 assert("edward-1243", ctail_ok(coord));
997 count = nr_units_ctail(coord);
999 if (count > f->length)
1000 count = f->length;
1001 memcpy(first_unit(coord), f->data, count);
1002 move_flow_forward(f, count);
1003 coord->unit_pos += count;
1004 return 0;
1007 /* Implementation of CRC_CUT_ITEM mode of ctail conversion:
1008 cut ctail (part or whole) starting from next unit position */
1009 static int cut_ctail(coord_t * coord)
1011 coord_t stop;
1013 assert("edward-435", coord->between == AT_UNIT &&
1014 coord->item_pos < coord_num_items(coord) &&
1015 coord->unit_pos <= coord_num_units(coord));
1017 if (coord->unit_pos == coord_num_units(coord))
1018 /* nothing to cut */
1019 return 0;
1020 coord_dup(&stop, coord);
1021 stop.unit_pos = coord_last_unit_pos(coord);
1023 return cut_node_content(coord, &stop, NULL, NULL, NULL);
1026 int ctail_insert_unprepped_cluster(struct cluster_handle * clust,
1027 struct inode * inode)
1029 int result;
1030 assert("edward-1244", inode != NULL);
1031 assert("edward-1245", clust->hint != NULL);
1032 assert("edward-1246", clust->dstat == FAKE_DISK_CLUSTER);
1033 assert("edward-1247", clust->reserved == 1);
1035 result = get_disk_cluster_locked(clust, inode, ZNODE_WRITE_LOCK);
1036 if (cbk_errored(result))
1037 return result;
1038 assert("edward-1249", result == CBK_COORD_NOTFOUND);
1039 assert("edward-1250", znode_is_write_locked(clust->hint->lh.node));
1041 assert("edward-1295",
1042 clust->hint->ext_coord.lh->node ==
1043 clust->hint->ext_coord.coord.node);
1045 coord_set_between_clusters(&clust->hint->ext_coord.coord);
1047 result = insert_unprepped_ctail(clust, inode);
1048 all_grabbed2free();
1050 assert("edward-1251", !result);
1051 assert("edward-1252", cryptcompress_inode_ok(inode));
1052 assert("edward-1253", znode_is_write_locked(clust->hint->lh.node));
1053 assert("edward-1254",
1054 reiser4_clustered_blocks(reiser4_get_current_sb()));
1055 assert("edward-1255",
1056 znode_convertible(clust->hint->ext_coord.coord.node));
1058 return result;
1061 static int do_convert_ctail(flush_pos_t * pos, cryptcompress_write_mode_t mode)
1063 int result = 0;
1064 struct convert_item_info * info;
1066 assert("edward-468", pos != NULL);
1067 assert("edward-469", pos->sq != NULL);
1068 assert("edward-845", item_convert_data(pos) != NULL);
1070 info = item_convert_data(pos);
1071 assert("edward-679", info->flow.data != NULL);
1073 switch (mode) {
1074 case CRC_APPEND_ITEM:
1075 assert("edward-1229", info->flow.length != 0);
1076 assert("edward-1256",
1077 cluster_shift_ok(cluster_shift_by_coord(&pos->coord)));
1078 result =
1079 insert_cryptcompress_flow_in_place(&pos->coord,
1080 &pos->lock,
1081 &info->flow,
1082 info->inode);
1083 break;
1084 case CRC_OVERWRITE_ITEM:
1085 assert("edward-1230", info->flow.length != 0);
1086 overwrite_ctail(&pos->coord, &info->flow);
1087 if (info->flow.length != 0)
1088 break;
1089 case CRC_CUT_ITEM:
1090 assert("edward-1231", info->flow.length == 0);
1091 result = cut_ctail(&pos->coord);
1092 break;
1093 default:
1094 result = RETERR(-EIO);
1095 impossible("edward-244", "bad convert mode");
1097 return result;
1100 /* plugin->u.item.f.scan */
1101 int scan_ctail(flush_scan * scan)
1103 int result = 0;
1104 struct page *page;
1105 struct inode *inode;
1106 jnode *node = scan->node;
1108 assert("edward-227", scan->node != NULL);
1109 assert("edward-228", jnode_is_cluster_page(scan->node));
1110 assert("edward-639", znode_is_write_locked(scan->parent_lock.node));
1112 page = jnode_page(node);
1113 inode = page->mapping->host;
1115 if (!reiser4_scanning_left(scan))
1116 return result;
1117 if (!ZF_ISSET(scan->parent_lock.node, JNODE_DIRTY))
1118 znode_make_dirty(scan->parent_lock.node);
1120 if (!znode_convertible(scan->parent_lock.node)) {
1121 if (JF_ISSET(scan->node, JNODE_DIRTY))
1122 znode_set_convertible(scan->parent_lock.node);
1123 else {
1124 warning("edward-681",
1125 "cluster page is already processed");
1126 return -EAGAIN;
1129 return result;
1132 /* If true, this function attaches children */
1133 static int should_attach_convert_idata(flush_pos_t * pos)
1135 int result;
1136 assert("edward-431", pos != NULL);
1137 assert("edward-432", pos->child == NULL);
1138 assert("edward-619", znode_is_write_locked(pos->coord.node));
1139 assert("edward-470",
1140 item_plugin_by_coord(&pos->coord) ==
1141 item_plugin_by_id(CTAIL_ID));
1143 /* check for leftmost child */
1144 utmost_child_ctail(&pos->coord, LEFT_SIDE, &pos->child);
1146 if (!pos->child)
1147 return 0;
1148 spin_lock_jnode(pos->child);
1149 result = (JF_ISSET(pos->child, JNODE_DIRTY) &&
1150 pos->child->atom == ZJNODE(pos->coord.node)->atom);
1151 spin_unlock_jnode(pos->child);
1152 if (!result && pos->child) {
1153 /* existing child isn't to attach, clear up this one */
1154 jput(pos->child);
1155 pos->child = NULL;
1157 return result;
1160 /* plugin->init_convert_data() */
1161 static int
1162 init_convert_data_ctail(struct convert_item_info * idata, struct inode *inode)
1164 assert("edward-813", idata != NULL);
1165 assert("edward-814", inode != NULL);
1167 idata->inode = inode;
1168 idata->d_cur = DC_FIRST_ITEM;
1169 idata->d_next = DC_INVALID_STATE;
1171 return 0;
1174 static int alloc_item_convert_data(struct convert_info * sq)
1176 assert("edward-816", sq != NULL);
1177 assert("edward-817", sq->itm == NULL);
1179 sq->itm = kmalloc(sizeof(*sq->itm), reiser4_ctx_gfp_mask_get());
1180 if (sq->itm == NULL)
1181 return RETERR(-ENOMEM);
1182 return 0;
1185 static void free_item_convert_data(struct convert_info * sq)
1187 assert("edward-818", sq != NULL);
1188 assert("edward-819", sq->itm != NULL);
1189 assert("edward-820", sq->iplug != NULL);
1191 kfree(sq->itm);
1192 sq->itm = NULL;
1193 return;
1196 static int alloc_convert_data(flush_pos_t * pos)
1198 assert("edward-821", pos != NULL);
1199 assert("edward-822", pos->sq == NULL);
1201 pos->sq = kmalloc(sizeof(*pos->sq), reiser4_ctx_gfp_mask_get());
1202 if (!pos->sq)
1203 return RETERR(-ENOMEM);
1204 memset(pos->sq, 0, sizeof(*pos->sq));
1205 cluster_init_write(&pos->sq->clust, NULL);
1206 return 0;
1209 void free_convert_data(flush_pos_t * pos)
1211 struct convert_info *sq;
1213 assert("edward-823", pos != NULL);
1214 assert("edward-824", pos->sq != NULL);
1216 sq = pos->sq;
1217 if (sq->itm)
1218 free_item_convert_data(sq);
1219 put_cluster_handle(&sq->clust);
1220 kfree(pos->sq);
1221 pos->sq = NULL;
1222 return;
1225 static int init_item_convert_data(flush_pos_t * pos, struct inode *inode)
1227 struct convert_info *sq;
1229 assert("edward-825", pos != NULL);
1230 assert("edward-826", pos->sq != NULL);
1231 assert("edward-827", item_convert_data(pos) != NULL);
1232 assert("edward-828", inode != NULL);
1234 sq = pos->sq;
1236 memset(sq->itm, 0, sizeof(*sq->itm));
1238 /* iplug->init_convert_data() */
1239 return init_convert_data_ctail(sq->itm, inode);
1242 /* create and attach disk cluster info used by 'convert' phase of the flush
1243 squalloc() */
1244 static int attach_convert_idata(flush_pos_t * pos, struct inode *inode)
1246 int ret = 0;
1247 struct convert_item_info *info;
1248 struct cluster_handle *clust;
1249 file_plugin *fplug = inode_file_plugin(inode);
1250 compression_plugin *cplug = inode_compression_plugin(inode);
1252 assert("edward-248", pos != NULL);
1253 assert("edward-249", pos->child != NULL);
1254 assert("edward-251", inode != NULL);
1255 assert("edward-682", cryptcompress_inode_ok(inode));
1256 assert("edward-252",
1257 fplug == file_plugin_by_id(CRYPTCOMPRESS_FILE_PLUGIN_ID));
1258 assert("edward-473",
1259 item_plugin_by_coord(&pos->coord) ==
1260 item_plugin_by_id(CTAIL_ID));
1262 if (!pos->sq) {
1263 ret = alloc_convert_data(pos);
1264 if (ret)
1265 return ret;
1267 clust = &pos->sq->clust;
1268 ret = grab_coa(&clust->tc, cplug);
1269 if (ret)
1270 goto err;
1271 ret = set_cluster_by_page(clust,
1272 jnode_page(pos->child),
1273 MAX_CLUSTER_NRPAGES);
1274 if (ret)
1275 goto err;
1277 assert("edward-829", pos->sq != NULL);
1278 assert("edward-250", item_convert_data(pos) == NULL);
1280 pos->sq->iplug = item_plugin_by_id(CTAIL_ID);
1282 ret = alloc_item_convert_data(pos->sq);
1283 if (ret)
1284 goto err;
1285 ret = init_item_convert_data(pos, inode);
1286 if (ret)
1287 goto err;
1288 info = item_convert_data(pos);
1290 ret = checkout_logical_cluster(clust, pos->child, inode);
1291 if (ret)
1292 goto err;
1294 reiser4_deflate_cluster(clust, inode);
1295 inc_item_convert_count(pos);
1297 /* prepare flow for insertion */
1298 fplug->flow_by_inode(info->inode,
1299 (const char __user *)tfm_stream_data(&clust->tc, OUTPUT_STREAM),
1300 0 /* kernel space */ ,
1301 clust->tc.len,
1302 clust_to_off(clust->index, inode),
1303 WRITE_OP, &info->flow);
1304 jput(pos->child);
1306 assert("edward-683", cryptcompress_inode_ok(inode));
1307 return 0;
1308 err:
1309 jput(pos->child);
1310 free_convert_data(pos);
1311 return ret;
1314 /* clear up disk cluster info */
1315 static void detach_convert_idata(struct convert_info * sq)
1317 struct convert_item_info *info;
1319 assert("edward-253", sq != NULL);
1320 assert("edward-840", sq->itm != NULL);
1322 info = sq->itm;
1323 assert("edward-255", info->inode != NULL);
1324 assert("edward-1212", info->flow.length == 0);
1326 free_item_convert_data(sq);
1327 return;
1330 /* plugin->u.item.f.utmost_child */
1332 /* This function sets leftmost child for a first cluster item,
1333 if the child exists, and NULL in other cases.
1334 NOTE-EDWARD: Do not call this for RIGHT_SIDE */
1336 int utmost_child_ctail(const coord_t * coord, sideof side, jnode ** child)
1338 reiser4_key key;
1340 item_key_by_coord(coord, &key);
1342 assert("edward-257", coord != NULL);
1343 assert("edward-258", child != NULL);
1344 assert("edward-259", side == LEFT_SIDE);
1345 assert("edward-260",
1346 item_plugin_by_coord(coord) == item_plugin_by_id(CTAIL_ID));
1348 if (!is_disk_cluster_key(&key, coord))
1349 *child = NULL;
1350 else
1351 *child = jlookup(current_tree,
1352 get_key_objectid(item_key_by_coord
1353 (coord, &key)),
1354 off_to_pg(get_key_offset(&key)));
1355 return 0;
1358 /* Returns true if @p2 is the next item to @p1
1359 in the _same_ disk cluster.
1360 Disk cluster is a set of items. If ->clustered() != NULL,
1361 with each item the whole disk cluster should be read/modified
1364 /* Go rightward and check for next disk cluster item, set
1365 * d_next to DC_CHAINED_ITEM, if the last one exists.
1366 * If the current position is last item, go to right neighbor.
1367 * Skip empty nodes. Note, that right neighbors may be not in
1368 * the slum because of races. If so, make it dirty and
1369 * convertible.
1371 static int next_item_dc_stat(flush_pos_t * pos)
1373 int ret = 0;
1374 int stop = 0;
1375 znode *cur;
1376 coord_t coord;
1377 lock_handle lh;
1378 lock_handle right_lock;
1380 assert("edward-1232", !node_is_empty(pos->coord.node));
1381 assert("edward-1014",
1382 pos->coord.item_pos < coord_num_items(&pos->coord));
1383 assert("edward-1015", chaining_data_present(pos));
1384 assert("edward-1017",
1385 item_convert_data(pos)->d_next == DC_INVALID_STATE);
1387 item_convert_data(pos)->d_next = DC_AFTER_CLUSTER;
1389 if (item_convert_data(pos)->d_cur == DC_AFTER_CLUSTER)
1390 return ret;
1391 if (pos->coord.item_pos < coord_num_items(&pos->coord) - 1)
1392 return ret;
1394 /* Check next slum item.
1395 * Note, that it can not be killed by concurrent truncate,
1396 * as the last one will want the lock held by us.
1398 init_lh(&right_lock);
1399 cur = pos->coord.node;
1401 while (!stop) {
1402 init_lh(&lh);
1403 ret = reiser4_get_right_neighbor(&lh,
1404 cur,
1405 ZNODE_WRITE_LOCK,
1406 GN_CAN_USE_UPPER_LEVELS);
1407 if (ret)
1408 break;
1409 ret = zload(lh.node);
1410 if (ret) {
1411 done_lh(&lh);
1412 break;
1414 coord_init_before_first_item(&coord, lh.node);
1416 if (node_is_empty(lh.node)) {
1417 znode_make_dirty(lh.node);
1418 znode_set_convertible(lh.node);
1419 stop = 0;
1420 } else if (same_disk_cluster(&pos->coord, &coord)) {
1422 item_convert_data(pos)->d_next = DC_CHAINED_ITEM;
1424 if (!ZF_ISSET(lh.node, JNODE_DIRTY)) {
1426 warning("edward-1024",
1427 "next slum item mergeable, "
1428 "but znode %p isn't dirty\n",
1429 lh.node);
1431 znode_make_dirty(lh.node);
1433 if (!znode_convertible(lh.node)) {
1435 warning("edward-1272",
1436 "next slum item mergeable, "
1437 "but znode %p isn't convertible\n",
1438 lh.node);
1440 znode_set_convertible(lh.node);
1442 stop = 1;
1443 } else
1444 stop = 1;
1445 zrelse(lh.node);
1446 done_lh(&right_lock);
1447 copy_lh(&right_lock, &lh);
1448 done_lh(&lh);
1449 cur = right_lock.node;
1451 done_lh(&right_lock);
1453 if (ret == -E_NO_NEIGHBOR)
1454 ret = 0;
1455 return ret;
1458 static int
1459 assign_convert_mode(struct convert_item_info * idata,
1460 cryptcompress_write_mode_t * mode)
1462 int result = 0;
1464 assert("edward-1025", idata != NULL);
1466 if (idata->flow.length) {
1467 /* append or overwrite */
1468 switch (idata->d_cur) {
1469 case DC_FIRST_ITEM:
1470 case DC_CHAINED_ITEM:
1471 *mode = CRC_OVERWRITE_ITEM;
1472 break;
1473 case DC_AFTER_CLUSTER:
1474 *mode = CRC_APPEND_ITEM;
1475 break;
1476 default:
1477 impossible("edward-1018", "wrong current item state");
1479 } else {
1480 /* cut or invalidate */
1481 switch (idata->d_cur) {
1482 case DC_FIRST_ITEM:
1483 case DC_CHAINED_ITEM:
1484 *mode = CRC_CUT_ITEM;
1485 break;
1486 case DC_AFTER_CLUSTER:
1487 result = 1;
1488 break;
1489 default:
1490 impossible("edward-1019", "wrong current item state");
1493 return result;
1496 /* plugin->u.item.f.convert */
1497 /* write ctail in guessed mode */
1498 int convert_ctail(flush_pos_t * pos)
1500 int result;
1501 int nr_items;
1502 cryptcompress_write_mode_t mode = CRC_OVERWRITE_ITEM;
1504 assert("edward-1020", pos != NULL);
1505 assert("edward-1213", coord_num_items(&pos->coord) != 0);
1506 assert("edward-1257", item_id_by_coord(&pos->coord) == CTAIL_ID);
1507 assert("edward-1258", ctail_ok(&pos->coord));
1508 assert("edward-261", pos->coord.node != NULL);
1510 nr_items = coord_num_items(&pos->coord);
1511 if (!chaining_data_present(pos)) {
1512 if (should_attach_convert_idata(pos)) {
1513 /* attach convert item info */
1514 struct inode *inode;
1516 assert("edward-264", pos->child != NULL);
1517 assert("edward-265", jnode_page(pos->child) != NULL);
1518 assert("edward-266",
1519 jnode_page(pos->child)->mapping != NULL);
1521 inode = jnode_page(pos->child)->mapping->host;
1523 assert("edward-267", inode != NULL);
1525 /* attach item convert info by child and put the last one */
1526 result = attach_convert_idata(pos, inode);
1527 pos->child = NULL;
1528 if (result == -E_REPEAT) {
1529 /* jnode became clean, or there is no dirty
1530 pages (nothing to update in disk cluster) */
1531 warning("edward-1021",
1532 "convert_ctail: nothing to attach");
1533 return 0;
1535 if (result != 0)
1536 return result;
1537 } else
1538 /* unconvertible */
1539 return 0;
1540 } else {
1541 /* use old convert info */
1543 struct convert_item_info *idata;
1545 idata = item_convert_data(pos);
1547 result = assign_convert_mode(idata, &mode);
1548 if (result) {
1549 /* disk cluster is over,
1550 nothing to update anymore */
1551 detach_convert_idata(pos->sq);
1552 return 0;
1556 assert("edward-433", chaining_data_present(pos));
1557 assert("edward-1022",
1558 pos->coord.item_pos < coord_num_items(&pos->coord));
1560 /* check if next item is of current disk cluster */
1561 result = next_item_dc_stat(pos);
1562 if (result) {
1563 detach_convert_idata(pos->sq);
1564 return result;
1566 result = do_convert_ctail(pos, mode);
1567 if (result) {
1568 detach_convert_idata(pos->sq);
1569 return result;
1571 switch (mode) {
1572 case CRC_CUT_ITEM:
1573 assert("edward-1214", item_convert_data(pos)->flow.length == 0);
1574 assert("edward-1215",
1575 coord_num_items(&pos->coord) == nr_items ||
1576 coord_num_items(&pos->coord) == nr_items - 1);
1577 if (item_convert_data(pos)->d_next == DC_CHAINED_ITEM)
1578 break;
1579 if (coord_num_items(&pos->coord) != nr_items) {
1580 /* the item was killed, no more chained items */
1581 detach_convert_idata(pos->sq);
1582 if (!node_is_empty(pos->coord.node))
1583 /* make sure the next item will be scanned */
1584 coord_init_before_item(&pos->coord);
1585 break;
1587 case CRC_APPEND_ITEM:
1588 assert("edward-434", item_convert_data(pos)->flow.length == 0);
1589 detach_convert_idata(pos->sq);
1590 break;
1591 case CRC_OVERWRITE_ITEM:
1592 if (coord_is_unprepped_ctail(&pos->coord)) {
1593 /* convert unpprepped ctail to prepped one */
1594 int shift;
1595 shift =
1596 inode_cluster_shift(item_convert_data(pos)->inode);
1597 assert("edward-1259", cluster_shift_ok(shift));
1598 put_unaligned((d8)shift,
1599 &ctail_formatted_at(&pos->coord)->
1600 cluster_shift);
1602 break;
1604 return result;
1607 /* Make Linus happy.
1608 Local variables:
1609 c-indentation-style: "K&R"
1610 mode-name: "LC"
1611 c-basic-offset: 8
1612 tab-width: 8
1613 fill-column: 120
1614 End: