revert-mm-fix-blkdev-size-calculation-in-generic_write_checks
[linux-2.6/linux-trees-mm.git] / fs / reiser4 / plugin / item / tail.c
blob1526db0189e3ea7fd6c5747eeac4f697f5930b5a
1 /* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */
3 #include "item.h"
4 #include "../../inode.h"
5 #include "../../page_cache.h"
6 #include "../../carry.h"
7 #include "../../vfs_ops.h"
9 #include <linux/quotaops.h>
10 #include <asm/uaccess.h>
11 #include <linux/swap.h>
12 #include <linux/writeback.h>
14 /* plugin->u.item.b.max_key_inside */
15 reiser4_key *max_key_inside_tail(const coord_t *coord, reiser4_key *key)
17 item_key_by_coord(coord, key);
18 set_key_offset(key, get_key_offset(reiser4_max_key()));
19 return key;
22 /* plugin->u.item.b.can_contain_key */
23 int can_contain_key_tail(const coord_t *coord, const reiser4_key *key,
24 const reiser4_item_data *data)
26 reiser4_key item_key;
28 if (item_plugin_by_coord(coord) != data->iplug)
29 return 0;
31 item_key_by_coord(coord, &item_key);
32 if (get_key_locality(key) != get_key_locality(&item_key) ||
33 get_key_objectid(key) != get_key_objectid(&item_key))
34 return 0;
36 return 1;
39 /* plugin->u.item.b.mergeable
40 first item is of tail type */
41 /* Audited by: green(2002.06.14) */
42 int mergeable_tail(const coord_t *p1, const coord_t *p2)
44 reiser4_key key1, key2;
46 assert("vs-535", plugin_of_group(item_plugin_by_coord(p1),
47 UNIX_FILE_METADATA_ITEM_TYPE));
48 assert("vs-365", item_id_by_coord(p1) == FORMATTING_ID);
50 if (item_id_by_coord(p2) != FORMATTING_ID) {
51 /* second item is of another type */
52 return 0;
55 item_key_by_coord(p1, &key1);
56 item_key_by_coord(p2, &key2);
57 if (get_key_locality(&key1) != get_key_locality(&key2) ||
58 get_key_objectid(&key1) != get_key_objectid(&key2)
59 || get_key_type(&key1) != get_key_type(&key2)) {
60 /* items of different objects */
61 return 0;
63 if (get_key_offset(&key1) + nr_units_tail(p1) != get_key_offset(&key2)) {
64 /* not adjacent items */
65 return 0;
67 return 1;
70 /* plugin->u.item.b.print
71 plugin->u.item.b.check */
73 /* plugin->u.item.b.nr_units */
74 pos_in_node_t nr_units_tail(const coord_t * coord)
76 return item_length_by_coord(coord);
79 /* plugin->u.item.b.lookup */
80 lookup_result
81 lookup_tail(const reiser4_key * key, lookup_bias bias, coord_t * coord)
83 reiser4_key item_key;
84 __u64 lookuped, offset;
85 unsigned nr_units;
87 item_key_by_coord(coord, &item_key);
88 offset = get_key_offset(item_key_by_coord(coord, &item_key));
89 nr_units = nr_units_tail(coord);
91 /* key we are looking for must be greater than key of item @coord */
92 assert("vs-416", keygt(key, &item_key));
94 /* offset we are looking for */
95 lookuped = get_key_offset(key);
97 if (lookuped >= offset && lookuped < offset + nr_units) {
98 /* byte we are looking for is in this item */
99 coord->unit_pos = lookuped - offset;
100 coord->between = AT_UNIT;
101 return CBK_COORD_FOUND;
104 /* set coord after last unit */
105 coord->unit_pos = nr_units - 1;
106 coord->between = AFTER_UNIT;
107 return bias ==
108 FIND_MAX_NOT_MORE_THAN ? CBK_COORD_FOUND : CBK_COORD_NOTFOUND;
111 /* plugin->u.item.b.paste */
113 paste_tail(coord_t *coord, reiser4_item_data *data,
114 carry_plugin_info *info UNUSED_ARG)
116 unsigned old_item_length;
117 char *item;
119 /* length the item had before resizing has been performed */
120 old_item_length = item_length_by_coord(coord) - data->length;
122 /* tail items never get pasted in the middle */
123 assert("vs-363",
124 (coord->unit_pos == 0 && coord->between == BEFORE_UNIT) ||
125 (coord->unit_pos == old_item_length - 1 &&
126 coord->between == AFTER_UNIT) ||
127 (coord->unit_pos == 0 && old_item_length == 0
128 && coord->between == AT_UNIT));
130 item = item_body_by_coord(coord);
131 if (coord->unit_pos == 0)
132 /* make space for pasted data when pasting at the beginning of
133 the item */
134 memmove(item + data->length, item, old_item_length);
136 if (coord->between == AFTER_UNIT)
137 coord->unit_pos++;
139 if (data->data) {
140 assert("vs-554", data->user == 0 || data->user == 1);
141 if (data->user) {
142 assert("nikita-3035", reiser4_schedulable());
143 /* copy from user space */
144 if (__copy_from_user(item + coord->unit_pos,
145 (const char __user *)data->data,
146 (unsigned)data->length))
147 return RETERR(-EFAULT);
148 } else
149 /* copy from kernel space */
150 memcpy(item + coord->unit_pos, data->data,
151 (unsigned)data->length);
152 } else {
153 memset(item + coord->unit_pos, 0, (unsigned)data->length);
155 return 0;
158 /* plugin->u.item.b.fast_paste */
160 /* plugin->u.item.b.can_shift
161 number of units is returned via return value, number of bytes via @size. For
162 tail items they coincide */
164 can_shift_tail(unsigned free_space, coord_t * source UNUSED_ARG,
165 znode * target UNUSED_ARG, shift_direction direction UNUSED_ARG,
166 unsigned *size, unsigned want)
168 /* make sure that that we do not want to shift more than we have */
169 assert("vs-364", want > 0
170 && want <= (unsigned)item_length_by_coord(source));
172 *size = min(want, free_space);
173 return *size;
176 /* plugin->u.item.b.copy_units */
177 void
178 copy_units_tail(coord_t * target, coord_t * source,
179 unsigned from, unsigned count,
180 shift_direction where_is_free_space,
181 unsigned free_space UNUSED_ARG)
183 /* make sure that item @target is expanded already */
184 assert("vs-366", (unsigned)item_length_by_coord(target) >= count);
185 assert("vs-370", free_space >= count);
187 if (where_is_free_space == SHIFT_LEFT) {
188 /* append item @target with @count first bytes of @source */
189 assert("vs-365", from == 0);
191 memcpy((char *)item_body_by_coord(target) +
192 item_length_by_coord(target) - count,
193 (char *)item_body_by_coord(source), count);
194 } else {
195 /* target item is moved to right already */
196 reiser4_key key;
198 assert("vs-367",
199 (unsigned)item_length_by_coord(source) == from + count);
201 memcpy((char *)item_body_by_coord(target),
202 (char *)item_body_by_coord(source) + from, count);
204 /* new units are inserted before first unit in an item,
205 therefore, we have to update item key */
206 item_key_by_coord(source, &key);
207 set_key_offset(&key, get_key_offset(&key) + from);
209 node_plugin_by_node(target->node)->update_item_key(target, &key,
210 NULL /*info */);
214 /* plugin->u.item.b.create_hook */
216 /* item_plugin->b.kill_hook
217 this is called when @count units starting from @from-th one are going to be removed
220 kill_hook_tail(const coord_t * coord, pos_in_node_t from,
221 pos_in_node_t count, struct carry_kill_data *kdata)
223 reiser4_key key;
224 loff_t start, end;
226 assert("vs-1577", kdata);
227 assert("vs-1579", kdata->inode);
229 item_key_by_coord(coord, &key);
230 start = get_key_offset(&key) + from;
231 end = start + count;
232 fake_kill_hook_tail(kdata->inode, start, end, kdata->params.truncate);
233 return 0;
236 /* plugin->u.item.b.shift_hook */
238 /* helper for kill_units_tail and cut_units_tail */
239 static int
240 do_cut_or_kill(coord_t * coord, pos_in_node_t from, pos_in_node_t to,
241 reiser4_key * smallest_removed, reiser4_key * new_first)
243 pos_in_node_t count;
245 /* this method is only called to remove part of item */
246 assert("vs-374", (to - from + 1) < item_length_by_coord(coord));
247 /* tails items are never cut from the middle of an item */
248 assert("vs-396", ergo(from != 0, to == coord_last_unit_pos(coord)));
249 assert("vs-1558", ergo(from == 0, to < coord_last_unit_pos(coord)));
251 count = to - from + 1;
253 if (smallest_removed) {
254 /* store smallest key removed */
255 item_key_by_coord(coord, smallest_removed);
256 set_key_offset(smallest_removed,
257 get_key_offset(smallest_removed) + from);
259 if (new_first) {
260 /* head of item is cut */
261 assert("vs-1529", from == 0);
263 item_key_by_coord(coord, new_first);
264 set_key_offset(new_first,
265 get_key_offset(new_first) + from + count);
268 if (REISER4_DEBUG)
269 memset((char *)item_body_by_coord(coord) + from, 0, count);
270 return count;
273 /* plugin->u.item.b.cut_units */
275 cut_units_tail(coord_t * coord, pos_in_node_t from, pos_in_node_t to,
276 struct carry_cut_data *cdata UNUSED_ARG,
277 reiser4_key * smallest_removed, reiser4_key * new_first)
279 return do_cut_or_kill(coord, from, to, smallest_removed, new_first);
282 /* plugin->u.item.b.kill_units */
284 kill_units_tail(coord_t * coord, pos_in_node_t from, pos_in_node_t to,
285 struct carry_kill_data *kdata, reiser4_key * smallest_removed,
286 reiser4_key * new_first)
288 kill_hook_tail(coord, from, to - from + 1, kdata);
289 return do_cut_or_kill(coord, from, to, smallest_removed, new_first);
292 /* plugin->u.item.b.unit_key */
293 reiser4_key *unit_key_tail(const coord_t * coord, reiser4_key * key)
295 assert("vs-375", coord_is_existing_unit(coord));
297 item_key_by_coord(coord, key);
298 set_key_offset(key, (get_key_offset(key) + coord->unit_pos));
300 return key;
303 /* plugin->u.item.b.estimate
304 plugin->u.item.b.item_data_by_flow */
306 /* tail redpage function. It is called from readpage_tail(). */
307 static int do_readpage_tail(uf_coord_t *uf_coord, struct page *page)
309 tap_t tap;
310 int result;
311 coord_t coord;
312 lock_handle lh;
313 int count, mapped;
314 struct inode *inode;
315 char *pagedata;
317 /* saving passed coord in order to do not move it by tap. */
318 init_lh(&lh);
319 copy_lh(&lh, uf_coord->lh);
320 inode = page->mapping->host;
321 coord_dup(&coord, &uf_coord->coord);
323 reiser4_tap_init(&tap, &coord, &lh, ZNODE_READ_LOCK);
325 if ((result = reiser4_tap_load(&tap)))
326 goto out_tap_done;
328 /* lookup until page is filled up. */
329 for (mapped = 0; mapped < PAGE_CACHE_SIZE; ) {
330 /* number of bytes to be copied to page */
331 count = item_length_by_coord(&coord) - coord.unit_pos;
332 if (count > PAGE_CACHE_SIZE - mapped)
333 count = PAGE_CACHE_SIZE - mapped;
335 /* attach @page to address space and get data address */
336 pagedata = kmap_atomic(page, KM_USER0);
338 /* copy tail item to page */
339 memcpy(pagedata + mapped,
340 ((char *)item_body_by_coord(&coord) + coord.unit_pos),
341 count);
342 mapped += count;
344 flush_dcache_page(page);
346 /* dettach page from address space */
347 kunmap_atomic(pagedata, KM_USER0);
349 /* Getting next tail item. */
350 if (mapped < PAGE_CACHE_SIZE) {
352 * unlock page in order to avoid keep it locked
353 * during tree lookup, which takes long term locks
355 unlock_page(page);
357 /* getting right neighbour. */
358 result = go_dir_el(&tap, RIGHT_SIDE, 0);
360 /* lock page back */
361 lock_page(page);
362 if (PageUptodate(page)) {
364 * another thread read the page, we have
365 * nothing to do
367 result = 0;
368 goto out_unlock_page;
371 if (result) {
372 if (result == -E_NO_NEIGHBOR) {
374 * rigth neighbor is not a formatted
375 * node
377 result = 0;
378 goto done;
379 } else {
380 goto out_tap_relse;
382 } else {
383 if (!inode_file_plugin(inode)->
384 owns_item(inode, &coord)) {
385 /* item of another file is found */
386 result = 0;
387 goto done;
393 done:
394 if (mapped != PAGE_CACHE_SIZE)
395 zero_user_segment(page, mapped, PAGE_CACHE_SIZE);
396 SetPageUptodate(page);
397 out_unlock_page:
398 unlock_page(page);
399 out_tap_relse:
400 reiser4_tap_relse(&tap);
401 out_tap_done:
402 reiser4_tap_done(&tap);
403 return result;
407 plugin->s.file.readpage
408 reiser4_read->unix_file_read->page_cache_readahead->reiser4_readpage->unix_file_readpage->readpage_tail
410 filemap_nopage->reiser4_readpage->readpage_unix_file->->readpage_tail
412 At the beginning: coord->node is read locked, zloaded, page is locked, coord is set to existing unit inside of tail
413 item. */
414 int readpage_tail(void *vp, struct page *page)
416 uf_coord_t *uf_coord = vp;
417 ON_DEBUG(coord_t * coord = &uf_coord->coord);
418 ON_DEBUG(reiser4_key key);
420 assert("umka-2515", PageLocked(page));
421 assert("umka-2516", !PageUptodate(page));
422 assert("umka-2517", !jprivate(page) && !PagePrivate(page));
423 assert("umka-2518", page->mapping && page->mapping->host);
425 assert("umka-2519", znode_is_loaded(coord->node));
426 assert("umka-2520", item_is_tail(coord));
427 assert("umka-2521", coord_is_existing_unit(coord));
428 assert("umka-2522", znode_is_rlocked(coord->node));
429 assert("umka-2523",
430 page->mapping->host->i_ino ==
431 get_key_objectid(item_key_by_coord(coord, &key)));
433 return do_readpage_tail(uf_coord, page);
437 * overwrite_tail
438 * @flow:
439 * @coord:
441 * Overwrites tail item or its part by user data. Returns number of bytes
442 * written or error code.
444 static int overwrite_tail(flow_t *flow, coord_t *coord)
446 unsigned count;
448 assert("vs-570", flow->user == 1);
449 assert("vs-946", flow->data);
450 assert("vs-947", coord_is_existing_unit(coord));
451 assert("vs-948", znode_is_write_locked(coord->node));
452 assert("nikita-3036", reiser4_schedulable());
454 count = item_length_by_coord(coord) - coord->unit_pos;
455 if (count > flow->length)
456 count = flow->length;
458 if (__copy_from_user((char *)item_body_by_coord(coord) + coord->unit_pos,
459 (const char __user *)flow->data, count))
460 return RETERR(-EFAULT);
462 znode_make_dirty(coord->node);
463 return count;
467 * insert_first_tail
468 * @inode:
469 * @flow:
470 * @coord:
471 * @lh:
473 * Returns number of bytes written or error code.
475 static ssize_t insert_first_tail(struct inode *inode, flow_t *flow,
476 coord_t *coord, lock_handle *lh)
478 int result;
479 loff_t to_write;
480 struct unix_file_info *uf_info;
482 if (get_key_offset(&flow->key) != 0) {
484 * file is empty and we have to write not to the beginning of
485 * file. Create a hole at the beginning of file. On success
486 * insert_flow returns 0 as number of written bytes which is
487 * what we have to return on padding a file with holes
489 flow->data = NULL;
490 flow->length = get_key_offset(&flow->key);
491 set_key_offset(&flow->key, 0);
493 * holes in files built of tails are stored just like if there
494 * were real data which are all zeros. Therefore we have to
495 * allocate quota here as well
497 if (DQUOT_ALLOC_SPACE_NODIRTY(inode, flow->length))
498 return RETERR(-EDQUOT);
499 result = reiser4_insert_flow(coord, lh, flow);
500 if (flow->length)
501 DQUOT_FREE_SPACE_NODIRTY(inode, flow->length);
503 uf_info = unix_file_inode_data(inode);
506 * first item insertion is only possible when writing to empty
507 * file or performing tail conversion
509 assert("", (uf_info->container == UF_CONTAINER_EMPTY ||
510 (reiser4_inode_get_flag(inode,
511 REISER4_PART_MIXED) &&
512 reiser4_inode_get_flag(inode,
513 REISER4_PART_IN_CONV))));
514 /* if file was empty - update its state */
515 if (result == 0 && uf_info->container == UF_CONTAINER_EMPTY)
516 uf_info->container = UF_CONTAINER_TAILS;
517 return result;
520 /* check quota before appending data */
521 if (DQUOT_ALLOC_SPACE_NODIRTY(inode, flow->length))
522 return RETERR(-EDQUOT);
524 to_write = flow->length;
525 result = reiser4_insert_flow(coord, lh, flow);
526 if (flow->length)
527 DQUOT_FREE_SPACE_NODIRTY(inode, flow->length);
528 return (to_write - flow->length) ? (to_write - flow->length) : result;
532 * append_tail
533 * @inode:
534 * @flow:
535 * @coord:
536 * @lh:
538 * Returns number of bytes written or error code.
540 static ssize_t append_tail(struct inode *inode,
541 flow_t *flow, coord_t *coord, lock_handle *lh)
543 int result;
544 reiser4_key append_key;
545 loff_t to_write;
547 if (!keyeq(&flow->key, append_key_tail(coord, &append_key))) {
548 flow->data = NULL;
549 flow->length = get_key_offset(&flow->key) - get_key_offset(&append_key);
550 set_key_offset(&flow->key, get_key_offset(&append_key));
552 * holes in files built of tails are stored just like if there
553 * were real data which are all zeros. Therefore we have to
554 * allocate quota here as well
556 if (DQUOT_ALLOC_SPACE_NODIRTY(inode, flow->length))
557 return RETERR(-EDQUOT);
558 result = reiser4_insert_flow(coord, lh, flow);
559 if (flow->length)
560 DQUOT_FREE_SPACE_NODIRTY(inode, flow->length);
561 return result;
564 /* check quota before appending data */
565 if (DQUOT_ALLOC_SPACE_NODIRTY(inode, flow->length))
566 return RETERR(-EDQUOT);
568 to_write = flow->length;
569 result = reiser4_insert_flow(coord, lh, flow);
570 if (flow->length)
571 DQUOT_FREE_SPACE_NODIRTY(inode, flow->length);
572 return (to_write - flow->length) ? (to_write - flow->length) : result;
576 * write_tail_reserve_space - reserve space for tail write operation
577 * @inode:
579 * Estimates and reserves space which may be required for writing one flow to a
580 * file
582 static int write_extent_reserve_space(struct inode *inode)
584 __u64 count;
585 reiser4_tree *tree;
588 * to write one flow to a file by tails we have to reserve disk space for:
590 * 1. find_file_item may have to insert empty node to the tree (empty
591 * leaf node between two extent items). This requires 1 block and
592 * number of blocks which are necessary to perform insertion of an
593 * internal item into twig level.
595 * 2. flow insertion
597 * 3. stat data update
599 tree = reiser4_tree_by_inode(inode);
600 count = estimate_one_insert_item(tree) +
601 estimate_insert_flow(tree->height) +
602 estimate_one_insert_item(tree);
603 grab_space_enable();
604 return reiser4_grab_space(count, 0 /* flags */);
607 #define PAGE_PER_FLOW 4
609 static loff_t faultin_user_pages(const char __user *buf, size_t count)
611 loff_t faulted;
612 int to_fault;
614 if (count > PAGE_PER_FLOW * PAGE_CACHE_SIZE)
615 count = PAGE_PER_FLOW * PAGE_CACHE_SIZE;
616 faulted = 0;
617 while (count > 0) {
618 to_fault = PAGE_CACHE_SIZE;
619 if (count < to_fault)
620 to_fault = count;
621 fault_in_pages_readable(buf + faulted, to_fault);
622 count -= to_fault;
623 faulted += to_fault;
625 return faulted;
629 * reiser4_write_extent - write method of tail item plugin
630 * @file: file to write to
631 * @buf: address of user-space buffer
632 * @count: number of bytes to write
633 * @pos: position in file to write to
635 * Returns number of written bytes or error code.
637 ssize_t reiser4_write_tail(struct file *file, const char __user *buf,
638 size_t count, loff_t *pos)
640 struct inode *inode;
641 struct hint hint;
642 int result;
643 flow_t flow;
644 coord_t *coord;
645 lock_handle *lh;
646 znode *loaded;
648 inode = file->f_dentry->d_inode;
650 if (write_extent_reserve_space(inode))
651 return RETERR(-ENOSPC);
653 result = load_file_hint(file, &hint);
654 BUG_ON(result != 0);
656 flow.length = faultin_user_pages(buf, count);
657 flow.user = 1;
658 memcpy(&flow.data, &buf, sizeof(buf));
659 flow.op = WRITE_OP;
660 key_by_inode_and_offset_common(inode, *pos, &flow.key);
662 result = find_file_item(&hint, &flow.key, ZNODE_WRITE_LOCK, inode);
663 if (IS_CBKERR(result))
664 return result;
666 coord = &hint.ext_coord.coord;
667 lh = hint.ext_coord.lh;
669 result = zload(coord->node);
670 BUG_ON(result != 0);
671 loaded = coord->node;
673 if (coord->between == AFTER_UNIT) {
674 /* append with data or hole */
675 result = append_tail(inode, &flow, coord, lh);
676 } else if (coord->between == AT_UNIT) {
677 /* overwrite */
678 result = overwrite_tail(&flow, coord);
679 } else {
680 /* no items of this file yet. insert data or hole */
681 result = insert_first_tail(inode, &flow, coord, lh);
683 zrelse(loaded);
684 if (result < 0) {
685 done_lh(lh);
686 return result;
689 /* seal and unlock znode */
690 hint.ext_coord.valid = 0;
691 if (hint.ext_coord.valid)
692 reiser4_set_hint(&hint, &flow.key, ZNODE_WRITE_LOCK);
693 else
694 reiser4_unset_hint(&hint);
696 save_file_hint(file, &hint);
697 return result;
700 #if REISER4_DEBUG
702 static int
703 coord_matches_key_tail(const coord_t * coord, const reiser4_key * key)
705 reiser4_key item_key;
707 assert("vs-1356", coord_is_existing_unit(coord));
708 assert("vs-1354", keylt(key, append_key_tail(coord, &item_key)));
709 assert("vs-1355", keyge(key, item_key_by_coord(coord, &item_key)));
710 return get_key_offset(key) ==
711 get_key_offset(&item_key) + coord->unit_pos;
715 #endif
717 /* plugin->u.item.s.file.read */
718 int reiser4_read_tail(struct file *file UNUSED_ARG, flow_t *f, hint_t *hint)
720 unsigned count;
721 int item_length;
722 coord_t *coord;
723 uf_coord_t *uf_coord;
725 uf_coord = &hint->ext_coord;
726 coord = &uf_coord->coord;
728 assert("vs-571", f->user == 1);
729 assert("vs-571", f->data);
730 assert("vs-967", coord && coord->node);
731 assert("vs-1117", znode_is_rlocked(coord->node));
732 assert("vs-1118", znode_is_loaded(coord->node));
734 assert("nikita-3037", reiser4_schedulable());
735 assert("vs-1357", coord_matches_key_tail(coord, &f->key));
737 /* calculate number of bytes to read off the item */
738 item_length = item_length_by_coord(coord);
739 count = item_length_by_coord(coord) - coord->unit_pos;
740 if (count > f->length)
741 count = f->length;
743 /* user page has to be brought in so that major page fault does not
744 * occur here when longtem lock is held */
745 if (__copy_to_user((char __user *)f->data,
746 ((char *)item_body_by_coord(coord) + coord->unit_pos),
747 count))
748 return RETERR(-EFAULT);
750 /* probably mark_page_accessed() should only be called if
751 * coord->unit_pos is zero. */
752 mark_page_accessed(znode_page(coord->node));
753 move_flow_forward(f, count);
755 coord->unit_pos += count;
756 if (item_length == coord->unit_pos) {
757 coord->unit_pos--;
758 coord->between = AFTER_UNIT;
760 reiser4_set_hint(hint, &f->key, ZNODE_READ_LOCK);
761 return 0;
765 plugin->u.item.s.file.append_key
766 key of first byte which is the next to last byte by addressed by this item
768 reiser4_key *append_key_tail(const coord_t * coord, reiser4_key * key)
770 item_key_by_coord(coord, key);
771 set_key_offset(key, get_key_offset(key) + item_length_by_coord(coord));
772 return key;
775 /* plugin->u.item.s.file.init_coord_extension */
776 void init_coord_extension_tail(uf_coord_t * uf_coord, loff_t lookuped)
778 uf_coord->valid = 1;
782 plugin->u.item.s.file.get_block
785 get_block_address_tail(const coord_t * coord, sector_t lblock, sector_t * block)
787 assert("nikita-3252", znode_get_level(coord->node) == LEAF_LEVEL);
789 if (reiser4_blocknr_is_fake(znode_get_block(coord->node)))
790 /* if node has'nt obtainet its block number yet, return 0.
791 * Lets avoid upsetting users with some cosmic numbers beyond
792 * the device capacity.*/
793 *block = 0;
794 else
795 *block = *znode_get_block(coord->node);
796 return 0;
800 * Local variables:
801 * c-indentation-style: "K&R"
802 * mode-name: "LC"
803 * c-basic-offset: 8
804 * tab-width: 8
805 * fill-column: 79
806 * scroll-step: 1
807 * End: