On Tue, Nov 06, 2007 at 02:33:53AM -0800, akpm@linux-foundation.org wrote:
[mmotm.git] / fs / reiser4 / plugin / item / ctail.c
blob147bbdaf2c6a12b3b48a9eeb9db9c281407952f0
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 int cluster_shift)
901 int result;
902 carry_pool *pool;
903 carry_level *lowest_level;
904 reiser4_item_data *data;
905 carry_op *op;
907 pool =
908 init_carry_pool(sizeof(*pool) + 3 * sizeof(*lowest_level) +
909 sizeof(*data));
910 if (IS_ERR(pool))
911 return PTR_ERR(pool);
912 lowest_level = (carry_level *) (pool + 1);
913 init_carry_level(lowest_level, pool);
914 data = (reiser4_item_data *) (lowest_level + 3);
916 assert("edward-466", coord->between == AFTER_ITEM
917 || coord->between == AFTER_UNIT || coord->between == BEFORE_ITEM
918 || coord->between == EMPTY_NODE
919 || coord->between == BEFORE_UNIT);
921 if (coord->between == AFTER_UNIT) {
922 coord->unit_pos = 0;
923 coord->between = AFTER_ITEM;
925 op = reiser4_post_carry(lowest_level, COP_INSERT_FLOW, coord->node,
926 0 /* operate directly on coord -> node */);
927 if (IS_ERR(op) || (op == NULL)) {
928 done_carry_pool(pool);
929 return RETERR(op ? PTR_ERR(op) : -EIO);
931 data->user = 0;
932 data->iplug = item_plugin_by_id(CTAIL_ID);
933 data->arg = &cluster_shift;
935 data->length = 0;
936 data->data = NULL;
938 op->u.insert_flow.flags = COPI_DONT_SHIFT_LEFT | COPI_DONT_SHIFT_RIGHT;
939 op->u.insert_flow.insert_point = coord;
940 op->u.insert_flow.flow = f;
941 op->u.insert_flow.data = data;
942 op->u.insert_flow.new_nodes = 0;
944 lowest_level->track_type = CARRY_TRACK_CHANGE;
945 lowest_level->tracked = lh;
947 result = reiser4_carry(lowest_level, NULL);
948 done_carry_pool(pool);
950 return result;
953 /* Implementation of CRC_APPEND_ITEM mode of ctail conversion */
954 static int insert_cryptcompress_flow_in_place(coord_t * coord,
955 lock_handle * lh, flow_t * f,
956 int cluster_shift)
958 int ret;
959 coord_t pos;
960 lock_handle lock;
962 assert("edward-484",
963 coord->between == AT_UNIT || coord->between == AFTER_ITEM);
964 assert("edward-485", item_id_by_coord(coord) == CTAIL_ID);
966 coord_dup(&pos, coord);
967 pos.unit_pos = 0;
968 pos.between = AFTER_ITEM;
970 init_lh(&lock);
971 copy_lh(&lock, lh);
973 ret = insert_cryptcompress_flow(&pos, &lock, f, cluster_shift);
974 done_lh(&lock);
975 assert("edward-1347", znode_is_write_locked(lh->node));
976 assert("edward-1228", !ret);
977 return ret;
980 /* Implementation of CRC_OVERWRITE_ITEM mode of ctail conversion */
981 static int overwrite_ctail(coord_t * coord, flow_t * f)
983 unsigned count;
985 assert("edward-269", f->user == 0);
986 assert("edward-270", f->data != NULL);
987 assert("edward-271", f->length > 0);
988 assert("edward-272", coord_is_existing_unit(coord));
989 assert("edward-273", coord->unit_pos == 0);
990 assert("edward-274", znode_is_write_locked(coord->node));
991 assert("edward-275", reiser4_schedulable());
992 assert("edward-467", item_id_by_coord(coord) == CTAIL_ID);
993 assert("edward-1243", ctail_ok(coord));
995 count = nr_units_ctail(coord);
997 if (count > f->length)
998 count = f->length;
999 memcpy(first_unit(coord), f->data, count);
1000 move_flow_forward(f, count);
1001 coord->unit_pos += count;
1002 return 0;
1005 /* Implementation of CRC_CUT_ITEM mode of ctail conversion:
1006 cut ctail (part or whole) starting from next unit position */
1007 static int cut_ctail(coord_t * coord)
1009 coord_t stop;
1011 assert("edward-435", coord->between == AT_UNIT &&
1012 coord->item_pos < coord_num_items(coord) &&
1013 coord->unit_pos <= coord_num_units(coord));
1015 if (coord->unit_pos == coord_num_units(coord))
1016 /* nothing to cut */
1017 return 0;
1018 coord_dup(&stop, coord);
1019 stop.unit_pos = coord_last_unit_pos(coord);
1021 return cut_node_content(coord, &stop, NULL, NULL, NULL);
1024 int ctail_insert_unprepped_cluster(struct cluster_handle * clust,
1025 struct inode * inode)
1027 int result;
1028 assert("edward-1244", inode != NULL);
1029 assert("edward-1245", clust->hint != NULL);
1030 assert("edward-1246", clust->dstat == FAKE_DISK_CLUSTER);
1031 assert("edward-1247", clust->reserved == 1);
1033 result = get_disk_cluster_locked(clust, inode, ZNODE_WRITE_LOCK);
1034 if (cbk_errored(result))
1035 return result;
1036 assert("edward-1249", result == CBK_COORD_NOTFOUND);
1037 assert("edward-1250", znode_is_write_locked(clust->hint->lh.node));
1039 assert("edward-1295",
1040 clust->hint->ext_coord.lh->node ==
1041 clust->hint->ext_coord.coord.node);
1043 coord_set_between_clusters(&clust->hint->ext_coord.coord);
1045 result = insert_unprepped_ctail(clust, inode);
1046 all_grabbed2free();
1048 assert("edward-1251", !result);
1049 assert("edward-1252", cryptcompress_inode_ok(inode));
1050 assert("edward-1253", znode_is_write_locked(clust->hint->lh.node));
1051 assert("edward-1254",
1052 reiser4_clustered_blocks(reiser4_get_current_sb()));
1053 assert("edward-1255",
1054 znode_convertible(clust->hint->ext_coord.coord.node));
1056 return result;
1059 static int do_convert_ctail(flush_pos_t * pos, cryptcompress_write_mode_t mode)
1061 int result = 0;
1062 struct convert_item_info * info;
1064 assert("edward-468", pos != NULL);
1065 assert("edward-469", pos->sq != NULL);
1066 assert("edward-845", item_convert_data(pos) != NULL);
1068 info = item_convert_data(pos);
1069 assert("edward-679", info->flow.data != NULL);
1071 switch (mode) {
1072 case CRC_APPEND_ITEM:
1073 assert("edward-1229", info->flow.length != 0);
1074 assert("edward-1256",
1075 cluster_shift_ok(cluster_shift_by_coord(&pos->coord)));
1076 result =
1077 insert_cryptcompress_flow_in_place(&pos->coord,
1078 &pos->lock,
1079 &info->flow,
1080 info->cluster_shift);
1081 break;
1082 case CRC_OVERWRITE_ITEM:
1083 assert("edward-1230", info->flow.length != 0);
1084 overwrite_ctail(&pos->coord, &info->flow);
1085 if (info->flow.length != 0)
1086 break;
1087 case CRC_CUT_ITEM:
1088 assert("edward-1231", info->flow.length == 0);
1089 result = cut_ctail(&pos->coord);
1090 break;
1091 default:
1092 result = RETERR(-EIO);
1093 impossible("edward-244", "bad convert mode");
1095 return result;
1098 /* plugin->u.item.f.scan */
1099 int scan_ctail(flush_scan * scan)
1101 int result = 0;
1102 struct page *page;
1103 struct inode *inode;
1104 jnode *node = scan->node;
1106 assert("edward-227", scan->node != NULL);
1107 assert("edward-228", jnode_is_cluster_page(scan->node));
1108 assert("edward-639", znode_is_write_locked(scan->parent_lock.node));
1110 page = jnode_page(node);
1111 inode = page->mapping->host;
1113 if (!reiser4_scanning_left(scan))
1114 return result;
1115 if (!ZF_ISSET(scan->parent_lock.node, JNODE_DIRTY))
1116 znode_make_dirty(scan->parent_lock.node);
1118 if (!znode_convertible(scan->parent_lock.node)) {
1119 if (JF_ISSET(scan->node, JNODE_DIRTY))
1120 znode_set_convertible(scan->parent_lock.node);
1121 else {
1122 warning("edward-681",
1123 "cluster page is already processed");
1124 return -EAGAIN;
1127 return result;
1130 /* If true, this function attaches children */
1131 static int should_attach_convert_idata(flush_pos_t * pos)
1133 int result;
1134 assert("edward-431", pos != NULL);
1135 assert("edward-432", pos->child == NULL);
1136 assert("edward-619", znode_is_write_locked(pos->coord.node));
1137 assert("edward-470",
1138 item_plugin_by_coord(&pos->coord) ==
1139 item_plugin_by_id(CTAIL_ID));
1141 /* check for leftmost child */
1142 utmost_child_ctail(&pos->coord, LEFT_SIDE, &pos->child);
1144 if (!pos->child)
1145 return 0;
1146 spin_lock_jnode(pos->child);
1147 result = (JF_ISSET(pos->child, JNODE_DIRTY) &&
1148 pos->child->atom == ZJNODE(pos->coord.node)->atom);
1149 spin_unlock_jnode(pos->child);
1150 if (!result && pos->child) {
1151 /* existing child isn't to attach, clear up this one */
1152 jput(pos->child);
1153 pos->child = NULL;
1155 return result;
1159 * Collect all needed information about the object here,
1160 * as in-memory inode can be evicted from memory before
1161 * disk update completion.
1163 static int init_convert_data_ctail(struct convert_item_info * idata,
1164 struct inode *inode)
1166 assert("edward-813", idata != NULL);
1167 assert("edward-814", inode != NULL);
1169 idata->cluster_shift = inode_cluster_shift(inode);
1170 idata->d_cur = DC_FIRST_ITEM;
1171 idata->d_next = DC_INVALID_STATE;
1173 return 0;
1176 static int alloc_item_convert_data(struct convert_info * sq)
1178 assert("edward-816", sq != NULL);
1179 assert("edward-817", sq->itm == NULL);
1181 sq->itm = kmalloc(sizeof(*sq->itm), reiser4_ctx_gfp_mask_get());
1182 if (sq->itm == NULL)
1183 return RETERR(-ENOMEM);
1184 return 0;
1187 static void free_item_convert_data(struct convert_info * sq)
1189 assert("edward-818", sq != NULL);
1190 assert("edward-819", sq->itm != NULL);
1191 assert("edward-820", sq->iplug != NULL);
1193 kfree(sq->itm);
1194 sq->itm = NULL;
1195 return;
1198 static int alloc_convert_data(flush_pos_t * pos)
1200 assert("edward-821", pos != NULL);
1201 assert("edward-822", pos->sq == NULL);
1203 pos->sq = kmalloc(sizeof(*pos->sq), reiser4_ctx_gfp_mask_get());
1204 if (!pos->sq)
1205 return RETERR(-ENOMEM);
1206 memset(pos->sq, 0, sizeof(*pos->sq));
1207 cluster_init_write(&pos->sq->clust, NULL);
1208 return 0;
1211 void free_convert_data(flush_pos_t * pos)
1213 struct convert_info *sq;
1215 assert("edward-823", pos != NULL);
1216 assert("edward-824", pos->sq != NULL);
1218 sq = pos->sq;
1219 if (sq->itm)
1220 free_item_convert_data(sq);
1221 put_cluster_handle(&sq->clust);
1222 kfree(pos->sq);
1223 pos->sq = NULL;
1224 return;
1227 static int init_item_convert_data(flush_pos_t * pos, struct inode *inode)
1229 struct convert_info *sq;
1231 assert("edward-825", pos != NULL);
1232 assert("edward-826", pos->sq != NULL);
1233 assert("edward-827", item_convert_data(pos) != NULL);
1234 assert("edward-828", inode != NULL);
1236 sq = pos->sq;
1238 memset(sq->itm, 0, sizeof(*sq->itm));
1240 /* iplug->init_convert_data() */
1241 return init_convert_data_ctail(sq->itm, inode);
1244 /* create and attach disk cluster info used by 'convert' phase of the flush
1245 squalloc() */
1246 static int attach_convert_idata(flush_pos_t * pos, struct inode *inode)
1248 int ret = 0;
1249 struct convert_item_info *info;
1250 struct cluster_handle *clust;
1251 file_plugin *fplug = inode_file_plugin(inode);
1252 compression_plugin *cplug = inode_compression_plugin(inode);
1254 assert("edward-248", pos != NULL);
1255 assert("edward-249", pos->child != NULL);
1256 assert("edward-251", inode != NULL);
1257 assert("edward-682", cryptcompress_inode_ok(inode));
1258 assert("edward-252",
1259 fplug == file_plugin_by_id(CRYPTCOMPRESS_FILE_PLUGIN_ID));
1260 assert("edward-473",
1261 item_plugin_by_coord(&pos->coord) ==
1262 item_plugin_by_id(CTAIL_ID));
1264 if (!pos->sq) {
1265 ret = alloc_convert_data(pos);
1266 if (ret)
1267 return ret;
1269 clust = &pos->sq->clust;
1270 ret = grab_coa(&clust->tc, cplug);
1271 if (ret)
1272 goto err;
1273 ret = set_cluster_by_page(clust,
1274 jnode_page(pos->child),
1275 MAX_CLUSTER_NRPAGES);
1276 if (ret)
1277 goto err;
1279 assert("edward-829", pos->sq != NULL);
1280 assert("edward-250", item_convert_data(pos) == NULL);
1282 pos->sq->iplug = item_plugin_by_id(CTAIL_ID);
1284 ret = alloc_item_convert_data(pos->sq);
1285 if (ret)
1286 goto err;
1287 ret = init_item_convert_data(pos, inode);
1288 if (ret)
1289 goto err;
1290 info = item_convert_data(pos);
1292 ret = checkout_logical_cluster(clust, pos->child, inode);
1293 if (ret)
1294 goto err;
1296 reiser4_deflate_cluster(clust, inode);
1297 inc_item_convert_count(pos);
1299 /* prepare flow for insertion */
1300 fplug->flow_by_inode(inode,
1301 (const char __user *)tfm_stream_data(&clust->tc, OUTPUT_STREAM),
1302 0 /* kernel space */ ,
1303 clust->tc.len,
1304 clust_to_off(clust->index, inode),
1305 WRITE_OP, &info->flow);
1306 jput(pos->child);
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-1212", info->flow.length == 0);
1325 free_item_convert_data(sq);
1326 return;
1329 /* plugin->u.item.f.utmost_child */
1331 /* This function sets leftmost child for a first cluster item,
1332 if the child exists, and NULL in other cases.
1333 NOTE-EDWARD: Do not call this for RIGHT_SIDE */
1335 int utmost_child_ctail(const coord_t * coord, sideof side, jnode ** child)
1337 reiser4_key key;
1339 item_key_by_coord(coord, &key);
1341 assert("edward-257", coord != NULL);
1342 assert("edward-258", child != NULL);
1343 assert("edward-259", side == LEFT_SIDE);
1344 assert("edward-260",
1345 item_plugin_by_coord(coord) == item_plugin_by_id(CTAIL_ID));
1347 if (!is_disk_cluster_key(&key, coord))
1348 *child = NULL;
1349 else
1350 *child = jlookup(current_tree,
1351 get_key_objectid(item_key_by_coord
1352 (coord, &key)),
1353 off_to_pg(get_key_offset(&key)));
1354 return 0;
1357 /* Returns true if @p2 is the next item to @p1
1358 in the _same_ disk cluster.
1359 Disk cluster is a set of items. If ->clustered() != NULL,
1360 with each item the whole disk cluster should be read/modified
1363 /* Go rightward and check for next disk cluster item, set
1364 * d_next to DC_CHAINED_ITEM, if the last one exists.
1365 * If the current position is last item, go to right neighbor.
1366 * Skip empty nodes. Note, that right neighbors may be not in
1367 * the slum because of races. If so, make it dirty and
1368 * convertible.
1370 static int next_item_dc_stat(flush_pos_t * pos)
1372 int ret = 0;
1373 int stop = 0;
1374 znode *cur;
1375 coord_t coord;
1376 lock_handle lh;
1377 lock_handle right_lock;
1379 assert("edward-1232", !node_is_empty(pos->coord.node));
1380 assert("edward-1014",
1381 pos->coord.item_pos < coord_num_items(&pos->coord));
1382 assert("edward-1015", chaining_data_present(pos));
1383 assert("edward-1017",
1384 item_convert_data(pos)->d_next == DC_INVALID_STATE);
1386 item_convert_data(pos)->d_next = DC_AFTER_CLUSTER;
1388 if (item_convert_data(pos)->d_cur == DC_AFTER_CLUSTER)
1389 return ret;
1390 if (pos->coord.item_pos < coord_num_items(&pos->coord) - 1)
1391 return ret;
1393 /* Check next slum item.
1394 * Note, that it can not be killed by concurrent truncate,
1395 * as the last one will want the lock held by us.
1397 init_lh(&right_lock);
1398 cur = pos->coord.node;
1400 while (!stop) {
1401 init_lh(&lh);
1402 ret = reiser4_get_right_neighbor(&lh,
1403 cur,
1404 ZNODE_WRITE_LOCK,
1405 GN_CAN_USE_UPPER_LEVELS);
1406 if (ret)
1407 break;
1408 ret = zload(lh.node);
1409 if (ret) {
1410 done_lh(&lh);
1411 break;
1413 coord_init_before_first_item(&coord, lh.node);
1415 if (node_is_empty(lh.node)) {
1416 znode_make_dirty(lh.node);
1417 znode_set_convertible(lh.node);
1418 stop = 0;
1419 } else if (same_disk_cluster(&pos->coord, &coord)) {
1421 item_convert_data(pos)->d_next = DC_CHAINED_ITEM;
1423 if (!ZF_ISSET(lh.node, JNODE_DIRTY)) {
1425 warning("edward-1024",
1426 "next slum item mergeable, "
1427 "but znode %p isn't dirty\n",
1428 lh.node);
1430 znode_make_dirty(lh.node);
1432 if (!znode_convertible(lh.node)) {
1434 warning("edward-1272",
1435 "next slum item mergeable, "
1436 "but znode %p isn't convertible\n",
1437 lh.node);
1439 znode_set_convertible(lh.node);
1441 stop = 1;
1442 } else
1443 stop = 1;
1444 zrelse(lh.node);
1445 done_lh(&right_lock);
1446 copy_lh(&right_lock, &lh);
1447 done_lh(&lh);
1448 cur = right_lock.node;
1450 done_lh(&right_lock);
1452 if (ret == -E_NO_NEIGHBOR)
1453 ret = 0;
1454 return ret;
1457 static int
1458 assign_convert_mode(struct convert_item_info * idata,
1459 cryptcompress_write_mode_t * mode)
1461 int result = 0;
1463 assert("edward-1025", idata != NULL);
1465 if (idata->flow.length) {
1466 /* append or overwrite */
1467 switch (idata->d_cur) {
1468 case DC_FIRST_ITEM:
1469 case DC_CHAINED_ITEM:
1470 *mode = CRC_OVERWRITE_ITEM;
1471 break;
1472 case DC_AFTER_CLUSTER:
1473 *mode = CRC_APPEND_ITEM;
1474 break;
1475 default:
1476 impossible("edward-1018", "wrong current item state");
1478 } else {
1479 /* cut or invalidate */
1480 switch (idata->d_cur) {
1481 case DC_FIRST_ITEM:
1482 case DC_CHAINED_ITEM:
1483 *mode = CRC_CUT_ITEM;
1484 break;
1485 case DC_AFTER_CLUSTER:
1486 result = 1;
1487 break;
1488 default:
1489 impossible("edward-1019", "wrong current item state");
1492 return result;
1495 /* plugin->u.item.f.convert */
1496 /* write ctail in guessed mode */
1497 int convert_ctail(flush_pos_t * pos)
1499 int result;
1500 int nr_items;
1501 cryptcompress_write_mode_t mode = CRC_OVERWRITE_ITEM;
1503 assert("edward-1020", pos != NULL);
1504 assert("edward-1213", coord_num_items(&pos->coord) != 0);
1505 assert("edward-1257", item_id_by_coord(&pos->coord) == CTAIL_ID);
1506 assert("edward-1258", ctail_ok(&pos->coord));
1507 assert("edward-261", pos->coord.node != NULL);
1509 nr_items = coord_num_items(&pos->coord);
1510 if (!chaining_data_present(pos)) {
1511 if (should_attach_convert_idata(pos)) {
1512 /* attach convert item info */
1513 struct inode *inode;
1515 assert("edward-264", pos->child != NULL);
1516 assert("edward-265", jnode_page(pos->child) != NULL);
1517 assert("edward-266",
1518 jnode_page(pos->child)->mapping != NULL);
1520 inode = jnode_page(pos->child)->mapping->host;
1522 assert("edward-267", inode != NULL);
1524 /* attach item convert info by child and put the last one */
1525 result = attach_convert_idata(pos, inode);
1526 pos->child = NULL;
1527 if (result == -E_REPEAT) {
1528 /* jnode became clean, or there is no dirty
1529 pages (nothing to update in disk cluster) */
1530 warning("edward-1021",
1531 "convert_ctail: nothing to attach");
1532 return 0;
1534 if (result != 0)
1535 return result;
1536 } else
1537 /* unconvertible */
1538 return 0;
1539 } else {
1540 /* use old convert info */
1542 struct convert_item_info *idata;
1544 idata = item_convert_data(pos);
1546 result = assign_convert_mode(idata, &mode);
1547 if (result) {
1548 /* disk cluster is over,
1549 nothing to update anymore */
1550 detach_convert_idata(pos->sq);
1551 return 0;
1555 assert("edward-433", chaining_data_present(pos));
1556 assert("edward-1022",
1557 pos->coord.item_pos < coord_num_items(&pos->coord));
1559 /* check if next item is of current disk cluster */
1560 result = next_item_dc_stat(pos);
1561 if (result) {
1562 detach_convert_idata(pos->sq);
1563 return result;
1565 result = do_convert_ctail(pos, mode);
1566 if (result) {
1567 detach_convert_idata(pos->sq);
1568 return result;
1570 switch (mode) {
1571 case CRC_CUT_ITEM:
1572 assert("edward-1214", item_convert_data(pos)->flow.length == 0);
1573 assert("edward-1215",
1574 coord_num_items(&pos->coord) == nr_items ||
1575 coord_num_items(&pos->coord) == nr_items - 1);
1576 if (item_convert_data(pos)->d_next == DC_CHAINED_ITEM)
1577 break;
1578 if (coord_num_items(&pos->coord) != nr_items) {
1579 /* the item was killed, no more chained items */
1580 detach_convert_idata(pos->sq);
1581 if (!node_is_empty(pos->coord.node))
1582 /* make sure the next item will be scanned */
1583 coord_init_before_item(&pos->coord);
1584 break;
1586 case CRC_APPEND_ITEM:
1587 assert("edward-434", item_convert_data(pos)->flow.length == 0);
1588 detach_convert_idata(pos->sq);
1589 break;
1590 case CRC_OVERWRITE_ITEM:
1591 if (coord_is_unprepped_ctail(&pos->coord)) {
1592 /* convert unpprepped ctail to prepped one */
1593 assert("edward-1259",
1594 cluster_shift_ok(item_convert_data(pos)->
1595 cluster_shift));
1596 put_unaligned((d8)item_convert_data(pos)->cluster_shift,
1597 &ctail_formatted_at(&pos->coord)->
1598 cluster_shift);
1600 break;
1602 return result;
1605 /* Make Linus happy.
1606 Local variables:
1607 c-indentation-style: "K&R"
1608 mode-name: "LC"
1609 c-basic-offset: 8
1610 tab-width: 8
1611 fill-column: 120
1612 End: