revert-mm-fix-blkdev-size-calculation-in-generic_write_checks
[linux-2.6/linux-trees-mm.git] / fs / reiser4 / plugin / item / extent.c
blobe35a4d5b78686285bb31631028d8916e004f8ed7
1 /* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */
3 #include "item.h"
4 #include "../../key.h"
5 #include "../../super.h"
6 #include "../../carry.h"
7 #include "../../inode.h"
8 #include "../../page_cache.h"
9 #include "../../flush.h"
10 #include "../object.h"
12 /* prepare structure reiser4_item_data. It is used to put one extent unit into tree */
13 /* Audited by: green(2002.06.13) */
14 reiser4_item_data *init_new_extent(reiser4_item_data * data, void *ext_unit,
15 int nr_extents)
17 data->data = ext_unit;
18 /* data->data is kernel space */
19 data->user = 0;
20 data->length = sizeof(reiser4_extent) * nr_extents;
21 data->arg = NULL;
22 data->iplug = item_plugin_by_id(EXTENT_POINTER_ID);
23 return data;
26 /* how many bytes are addressed by @nr first extents of the extent item */
27 reiser4_block_nr reiser4_extent_size(const coord_t * coord, pos_in_node_t nr)
29 pos_in_node_t i;
30 reiser4_block_nr blocks;
31 reiser4_extent *ext;
33 ext = item_body_by_coord(coord);
34 assert("vs-263", nr <= nr_units_extent(coord));
36 blocks = 0;
37 for (i = 0; i < nr; i++, ext++) {
38 blocks += extent_get_width(ext);
41 return blocks * current_blocksize;
44 extent_state state_of_extent(reiser4_extent * ext)
46 switch ((int)extent_get_start(ext)) {
47 case 0:
48 return HOLE_EXTENT;
49 case 1:
50 return UNALLOCATED_EXTENT;
51 default:
52 break;
54 return ALLOCATED_EXTENT;
57 int extent_is_unallocated(const coord_t * item)
59 assert("jmacd-5133", item_is_extent(item));
61 return state_of_extent(extent_by_coord(item)) == UNALLOCATED_EXTENT;
64 /* set extent's start and width */
65 void reiser4_set_extent(reiser4_extent * ext, reiser4_block_nr start,
66 reiser4_block_nr width)
68 extent_set_start(ext, start);
69 extent_set_width(ext, width);
72 /**
73 * reiser4_replace_extent - replace extent and paste 1 or 2 after it
74 * @un_extent: coordinate of extent to be overwritten
75 * @lh: need better comment
76 * @key: need better comment
77 * @exts_to_add: data prepared for insertion into tree
78 * @replace: need better comment
79 * @flags: need better comment
80 * @return_insert_position: need better comment
82 * Overwrites one extent, pastes 1 or 2 more ones after overwritten one. If
83 * @return_inserted_position is 1 - @un_extent and @lh are returned set to
84 * first of newly inserted units, if it is 0 - @un_extent and @lh are returned
85 * set to extent which was overwritten.
87 int reiser4_replace_extent(struct replace_handle *h,
88 int return_inserted_position)
90 int result;
91 znode *orig_znode;
92 /*ON_DEBUG(reiser4_extent orig_ext);*/ /* this is for debugging */
94 assert("vs-990", coord_is_existing_unit(h->coord));
95 assert("vs-1375", znode_is_write_locked(h->coord->node));
96 assert("vs-1426", extent_get_width(&h->overwrite) != 0);
97 assert("vs-1427", extent_get_width(&h->new_extents[0]) != 0);
98 assert("vs-1427", ergo(h->nr_new_extents == 2,
99 extent_get_width(&h->new_extents[1]) != 0));
101 /* compose structure for paste */
102 init_new_extent(&h->item, &h->new_extents[0], h->nr_new_extents);
104 coord_dup(&h->coord_after, h->coord);
105 init_lh(&h->lh_after);
106 copy_lh(&h->lh_after, h->lh);
107 reiser4_tap_init(&h->watch, &h->coord_after, &h->lh_after, ZNODE_WRITE_LOCK);
108 reiser4_tap_monitor(&h->watch);
110 ON_DEBUG(h->orig_ext = *extent_by_coord(h->coord));
111 orig_znode = h->coord->node;
113 #if REISER4_DEBUG
114 /* make sure that key is set properly */
115 unit_key_by_coord(h->coord, &h->tmp);
116 set_key_offset(&h->tmp,
117 get_key_offset(&h->tmp) +
118 extent_get_width(&h->overwrite) * current_blocksize);
119 assert("vs-1080", keyeq(&h->tmp, &h->paste_key));
120 #endif
122 /* set insert point after unit to be replaced */
123 h->coord->between = AFTER_UNIT;
125 result = insert_into_item(h->coord, return_inserted_position ? h->lh : NULL,
126 &h->paste_key, &h->item, h->flags);
127 if (!result) {
128 /* now we have to replace the unit after which new units were
129 inserted. Its position is tracked by @watch */
130 reiser4_extent *ext;
131 znode *node;
133 node = h->coord_after.node;
134 if (node != orig_znode) {
135 coord_clear_iplug(&h->coord_after);
136 result = zload(node);
139 if (likely(!result)) {
140 ext = extent_by_coord(&h->coord_after);
142 assert("vs-987", znode_is_loaded(node));
143 assert("vs-988", !memcmp(ext, &h->orig_ext, sizeof(*ext)));
145 /* overwrite extent unit */
146 memcpy(ext, &h->overwrite, sizeof(reiser4_extent));
147 znode_make_dirty(node);
149 if (node != orig_znode)
150 zrelse(node);
152 if (return_inserted_position == 0) {
153 /* coord and lh are to be set to overwritten
154 extent */
155 assert("vs-1662",
156 WITH_DATA(node, !memcmp(&h->overwrite,
157 extent_by_coord(
158 &h->coord_after),
159 sizeof(reiser4_extent))));
161 *h->coord = h->coord_after;
162 done_lh(h->lh);
163 copy_lh(h->lh, &h->lh_after);
164 } else {
165 /* h->coord and h->lh are to be set to first of
166 inserted units */
167 assert("vs-1663",
168 WITH_DATA(h->coord->node,
169 !memcmp(&h->new_extents[0],
170 extent_by_coord(h->coord),
171 sizeof(reiser4_extent))));
172 assert("vs-1664", h->lh->node == h->coord->node);
176 reiser4_tap_done(&h->watch);
178 return result;
181 lock_handle *znode_lh(znode *node)
183 assert("vs-1371", znode_is_write_locked(node));
184 assert("vs-1372", znode_is_wlocked_once(node));
185 return list_entry(node->lock.owners.next, lock_handle, owners_link);
189 * Local variables:
190 * c-indentation-style: "K&R"
191 * mode-name: "LC"
192 * c-basic-offset: 8
193 * tab-width: 8
194 * fill-column: 79
195 * scroll-step: 1
196 * End: