aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/backref.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/backref.c')
-rw-r--r--fs/btrfs/backref.c568
1 files changed, 388 insertions, 180 deletions
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
index bcec06750232..7301cdb4b2cb 100644
--- a/fs/btrfs/backref.c
+++ b/fs/btrfs/backref.c
@@ -24,22 +24,135 @@
24#include "delayed-ref.h" 24#include "delayed-ref.h"
25#include "locking.h" 25#include "locking.h"
26 26
27struct extent_inode_elem {
28 u64 inum;
29 u64 offset;
30 struct extent_inode_elem *next;
31};
32
33static int check_extent_in_eb(struct btrfs_key *key, struct extent_buffer *eb,
34 struct btrfs_file_extent_item *fi,
35 u64 extent_item_pos,
36 struct extent_inode_elem **eie)
37{
38 u64 data_offset;
39 u64 data_len;
40 struct extent_inode_elem *e;
41
42 data_offset = btrfs_file_extent_offset(eb, fi);
43 data_len = btrfs_file_extent_num_bytes(eb, fi);
44
45 if (extent_item_pos < data_offset ||
46 extent_item_pos >= data_offset + data_len)
47 return 1;
48
49 e = kmalloc(sizeof(*e), GFP_NOFS);
50 if (!e)
51 return -ENOMEM;
52
53 e->next = *eie;
54 e->inum = key->objectid;
55 e->offset = key->offset + (extent_item_pos - data_offset);
56 *eie = e;
57
58 return 0;
59}
60
61static int find_extent_in_eb(struct extent_buffer *eb, u64 wanted_disk_byte,
62 u64 extent_item_pos,
63 struct extent_inode_elem **eie)
64{
65 u64 disk_byte;
66 struct btrfs_key key;
67 struct btrfs_file_extent_item *fi;
68 int slot;
69 int nritems;
70 int extent_type;
71 int ret;
72
73 /*
74 * from the shared data ref, we only have the leaf but we need
75 * the key. thus, we must look into all items and see that we
76 * find one (some) with a reference to our extent item.
77 */
78 nritems = btrfs_header_nritems(eb);
79 for (slot = 0; slot < nritems; ++slot) {
80 btrfs_item_key_to_cpu(eb, &key, slot);
81 if (key.type != BTRFS_EXTENT_DATA_KEY)
82 continue;
83 fi = btrfs_item_ptr(eb, slot, struct btrfs_file_extent_item);
84 extent_type = btrfs_file_extent_type(eb, fi);
85 if (extent_type == BTRFS_FILE_EXTENT_INLINE)
86 continue;
87 /* don't skip BTRFS_FILE_EXTENT_PREALLOC, we can handle that */
88 disk_byte = btrfs_file_extent_disk_bytenr(eb, fi);
89 if (disk_byte != wanted_disk_byte)
90 continue;
91
92 ret = check_extent_in_eb(&key, eb, fi, extent_item_pos, eie);
93 if (ret < 0)
94 return ret;
95 }
96
97 return 0;
98}
99
27/* 100/*
28 * this structure records all encountered refs on the way up to the root 101 * this structure records all encountered refs on the way up to the root
29 */ 102 */
30struct __prelim_ref { 103struct __prelim_ref {
31 struct list_head list; 104 struct list_head list;
32 u64 root_id; 105 u64 root_id;
33 struct btrfs_key key; 106 struct btrfs_key key_for_search;
34 int level; 107 int level;
35 int count; 108 int count;
109 struct extent_inode_elem *inode_list;
36 u64 parent; 110 u64 parent;
37 u64 wanted_disk_byte; 111 u64 wanted_disk_byte;
38}; 112};
39 113
114/*
115 * the rules for all callers of this function are:
116 * - obtaining the parent is the goal
117 * - if you add a key, you must know that it is a correct key
118 * - if you cannot add the parent or a correct key, then we will look into the
119 * block later to set a correct key
120 *
121 * delayed refs
122 * ============
123 * backref type | shared | indirect | shared | indirect
124 * information | tree | tree | data | data
125 * --------------------+--------+----------+--------+----------
126 * parent logical | y | - | - | -
127 * key to resolve | - | y | y | y
128 * tree block logical | - | - | - | -
129 * root for resolving | y | y | y | y
130 *
131 * - column 1: we've the parent -> done
132 * - column 2, 3, 4: we use the key to find the parent
133 *
134 * on disk refs (inline or keyed)
135 * ==============================
136 * backref type | shared | indirect | shared | indirect
137 * information | tree | tree | data | data
138 * --------------------+--------+----------+--------+----------
139 * parent logical | y | - | y | -
140 * key to resolve | - | - | - | y
141 * tree block logical | y | y | y | y
142 * root for resolving | - | y | y | y
143 *
144 * - column 1, 3: we've the parent -> done
145 * - column 2: we take the first key from the block to find the parent
146 * (see __add_missing_keys)
147 * - column 4: we use the key to find the parent
148 *
149 * additional information that's available but not required to find the parent
150 * block might help in merging entries to gain some speed.
151 */
152
40static int __add_prelim_ref(struct list_head *head, u64 root_id, 153static int __add_prelim_ref(struct list_head *head, u64 root_id,
41 struct btrfs_key *key, int level, u64 parent, 154 struct btrfs_key *key, int level,
42 u64 wanted_disk_byte, int count) 155 u64 parent, u64 wanted_disk_byte, int count)
43{ 156{
44 struct __prelim_ref *ref; 157 struct __prelim_ref *ref;
45 158
@@ -50,10 +163,11 @@ static int __add_prelim_ref(struct list_head *head, u64 root_id,
50 163
51 ref->root_id = root_id; 164 ref->root_id = root_id;
52 if (key) 165 if (key)
53 ref->key = *key; 166 ref->key_for_search = *key;
54 else 167 else
55 memset(&ref->key, 0, sizeof(ref->key)); 168 memset(&ref->key_for_search, 0, sizeof(ref->key_for_search));
56 169
170 ref->inode_list = NULL;
57 ref->level = level; 171 ref->level = level;
58 ref->count = count; 172 ref->count = count;
59 ref->parent = parent; 173 ref->parent = parent;
@@ -64,52 +178,75 @@ static int __add_prelim_ref(struct list_head *head, u64 root_id,
64} 178}
65 179
66static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path, 180static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path,
67 struct ulist *parents, 181 struct ulist *parents, int level,
68 struct extent_buffer *eb, int level, 182 struct btrfs_key *key_for_search, u64 time_seq,
69 u64 wanted_objectid, u64 wanted_disk_byte) 183 u64 wanted_disk_byte,
184 const u64 *extent_item_pos)
70{ 185{
71 int ret; 186 int ret = 0;
72 int slot; 187 int slot;
73 struct btrfs_file_extent_item *fi; 188 struct extent_buffer *eb;
74 struct btrfs_key key; 189 struct btrfs_key key;
190 struct btrfs_file_extent_item *fi;
191 struct extent_inode_elem *eie = NULL;
75 u64 disk_byte; 192 u64 disk_byte;
76 193
77add_parent: 194 if (level != 0) {
78 ret = ulist_add(parents, eb->start, 0, GFP_NOFS); 195 eb = path->nodes[level];
79 if (ret < 0) 196 ret = ulist_add(parents, eb->start, 0, GFP_NOFS);
80 return ret; 197 if (ret < 0)
81 198 return ret;
82 if (level != 0)
83 return 0; 199 return 0;
200 }
84 201
85 /* 202 /*
86 * if the current leaf is full with EXTENT_DATA items, we must 203 * We normally enter this function with the path already pointing to
87 * check the next one if that holds a reference as well. 204 * the first item to check. But sometimes, we may enter it with
88 * ref->count cannot be used to skip this check. 205 * slot==nritems. In that case, go to the next leaf before we continue.
89 * repeat this until we don't find any additional EXTENT_DATA items.
90 */ 206 */
91 while (1) { 207 if (path->slots[0] >= btrfs_header_nritems(path->nodes[0]))
92 ret = btrfs_next_leaf(root, path); 208 ret = btrfs_next_old_leaf(root, path, time_seq);
93 if (ret < 0)
94 return ret;
95 if (ret)
96 return 0;
97 209
210 while (!ret) {
98 eb = path->nodes[0]; 211 eb = path->nodes[0];
99 for (slot = 0; slot < btrfs_header_nritems(eb); ++slot) { 212 slot = path->slots[0];
100 btrfs_item_key_to_cpu(eb, &key, slot); 213
101 if (key.objectid != wanted_objectid || 214 btrfs_item_key_to_cpu(eb, &key, slot);
102 key.type != BTRFS_EXTENT_DATA_KEY) 215
103 return 0; 216 if (key.objectid != key_for_search->objectid ||
104 fi = btrfs_item_ptr(eb, slot, 217 key.type != BTRFS_EXTENT_DATA_KEY)
105 struct btrfs_file_extent_item); 218 break;
106 disk_byte = btrfs_file_extent_disk_bytenr(eb, fi); 219
107 if (disk_byte == wanted_disk_byte) 220 fi = btrfs_item_ptr(eb, slot, struct btrfs_file_extent_item);
108 goto add_parent; 221 disk_byte = btrfs_file_extent_disk_bytenr(eb, fi);
222
223 if (disk_byte == wanted_disk_byte) {
224 eie = NULL;
225 if (extent_item_pos) {
226 ret = check_extent_in_eb(&key, eb, fi,
227 *extent_item_pos,
228 &eie);
229 if (ret < 0)
230 break;
231 }
232 if (!ret) {
233 ret = ulist_add(parents, eb->start,
234 (unsigned long)eie, GFP_NOFS);
235 if (ret < 0)
236 break;
237 if (!extent_item_pos) {
238 ret = btrfs_next_old_leaf(root, path,
239 time_seq);
240 continue;
241 }
242 }
109 } 243 }
244 ret = btrfs_next_old_item(root, path, time_seq);
110 } 245 }
111 246
112 return 0; 247 if (ret > 0)
248 ret = 0;
249 return ret;
113} 250}
114 251
115/* 252/*
@@ -118,13 +255,14 @@ add_parent:
118 */ 255 */
119static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info, 256static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info,
120 int search_commit_root, 257 int search_commit_root,
258 u64 time_seq,
121 struct __prelim_ref *ref, 259 struct __prelim_ref *ref,
122 struct ulist *parents) 260 struct ulist *parents,
261 const u64 *extent_item_pos)
123{ 262{
124 struct btrfs_path *path; 263 struct btrfs_path *path;
125 struct btrfs_root *root; 264 struct btrfs_root *root;
126 struct btrfs_key root_key; 265 struct btrfs_key root_key;
127 struct btrfs_key key = {0};
128 struct extent_buffer *eb; 266 struct extent_buffer *eb;
129 int ret = 0; 267 int ret = 0;
130 int root_level; 268 int root_level;
@@ -152,12 +290,13 @@ static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info,
152 goto out; 290 goto out;
153 291
154 path->lowest_level = level; 292 path->lowest_level = level;
155 ret = btrfs_search_slot(NULL, root, &ref->key, path, 0, 0); 293 ret = btrfs_search_old_slot(root, &ref->key_for_search, path, time_seq);
156 pr_debug("search slot in root %llu (level %d, ref count %d) returned " 294 pr_debug("search slot in root %llu (level %d, ref count %d) returned "
157 "%d for key (%llu %u %llu)\n", 295 "%d for key (%llu %u %llu)\n",
158 (unsigned long long)ref->root_id, level, ref->count, ret, 296 (unsigned long long)ref->root_id, level, ref->count, ret,
159 (unsigned long long)ref->key.objectid, ref->key.type, 297 (unsigned long long)ref->key_for_search.objectid,
160 (unsigned long long)ref->key.offset); 298 ref->key_for_search.type,
299 (unsigned long long)ref->key_for_search.offset);
161 if (ret < 0) 300 if (ret < 0)
162 goto out; 301 goto out;
163 302
@@ -168,20 +307,9 @@ static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info,
168 goto out; 307 goto out;
169 } 308 }
170 309
171 if (level == 0) { 310 ret = add_all_parents(root, path, parents, level, &ref->key_for_search,
172 if (ret == 1 && path->slots[0] >= btrfs_header_nritems(eb)) { 311 time_seq, ref->wanted_disk_byte,
173 ret = btrfs_next_leaf(root, path); 312 extent_item_pos);
174 if (ret)
175 goto out;
176 eb = path->nodes[0];
177 }
178
179 btrfs_item_key_to_cpu(eb, &key, path->slots[0]);
180 }
181
182 /* the last two parameters will only be used for level == 0 */
183 ret = add_all_parents(root, path, parents, eb, level, key.objectid,
184 ref->wanted_disk_byte);
185out: 313out:
186 btrfs_free_path(path); 314 btrfs_free_path(path);
187 return ret; 315 return ret;
@@ -191,8 +319,9 @@ out:
191 * resolve all indirect backrefs from the list 319 * resolve all indirect backrefs from the list
192 */ 320 */
193static int __resolve_indirect_refs(struct btrfs_fs_info *fs_info, 321static int __resolve_indirect_refs(struct btrfs_fs_info *fs_info,
194 int search_commit_root, 322 int search_commit_root, u64 time_seq,
195 struct list_head *head) 323 struct list_head *head,
324 const u64 *extent_item_pos)
196{ 325{
197 int err; 326 int err;
198 int ret = 0; 327 int ret = 0;
@@ -201,6 +330,7 @@ static int __resolve_indirect_refs(struct btrfs_fs_info *fs_info,
201 struct __prelim_ref *new_ref; 330 struct __prelim_ref *new_ref;
202 struct ulist *parents; 331 struct ulist *parents;
203 struct ulist_node *node; 332 struct ulist_node *node;
333 struct ulist_iterator uiter;
204 334
205 parents = ulist_alloc(GFP_NOFS); 335 parents = ulist_alloc(GFP_NOFS);
206 if (!parents) 336 if (!parents)
@@ -217,7 +347,8 @@ static int __resolve_indirect_refs(struct btrfs_fs_info *fs_info,
217 if (ref->count == 0) 347 if (ref->count == 0)
218 continue; 348 continue;
219 err = __resolve_indirect_ref(fs_info, search_commit_root, 349 err = __resolve_indirect_ref(fs_info, search_commit_root,
220 ref, parents); 350 time_seq, ref, parents,
351 extent_item_pos);
221 if (err) { 352 if (err) {
222 if (ret == 0) 353 if (ret == 0)
223 ret = err; 354 ret = err;
@@ -225,11 +356,14 @@ static int __resolve_indirect_refs(struct btrfs_fs_info *fs_info,
225 } 356 }
226 357
227 /* we put the first parent into the ref at hand */ 358 /* we put the first parent into the ref at hand */
228 node = ulist_next(parents, NULL); 359 ULIST_ITER_INIT(&uiter);
360 node = ulist_next(parents, &uiter);
229 ref->parent = node ? node->val : 0; 361 ref->parent = node ? node->val : 0;
362 ref->inode_list =
363 node ? (struct extent_inode_elem *)node->aux : 0;
230 364
231 /* additional parents require new refs being added here */ 365 /* additional parents require new refs being added here */
232 while ((node = ulist_next(parents, node))) { 366 while ((node = ulist_next(parents, &uiter))) {
233 new_ref = kmalloc(sizeof(*new_ref), GFP_NOFS); 367 new_ref = kmalloc(sizeof(*new_ref), GFP_NOFS);
234 if (!new_ref) { 368 if (!new_ref) {
235 ret = -ENOMEM; 369 ret = -ENOMEM;
@@ -237,6 +371,8 @@ static int __resolve_indirect_refs(struct btrfs_fs_info *fs_info,
237 } 371 }
238 memcpy(new_ref, ref, sizeof(*ref)); 372 memcpy(new_ref, ref, sizeof(*ref));
239 new_ref->parent = node->val; 373 new_ref->parent = node->val;
374 new_ref->inode_list =
375 (struct extent_inode_elem *)node->aux;
240 list_add(&new_ref->list, &ref->list); 376 list_add(&new_ref->list, &ref->list);
241 } 377 }
242 ulist_reinit(parents); 378 ulist_reinit(parents);
@@ -246,10 +382,65 @@ static int __resolve_indirect_refs(struct btrfs_fs_info *fs_info,
246 return ret; 382 return ret;
247} 383}
248 384
385static inline int ref_for_same_block(struct __prelim_ref *ref1,
386 struct __prelim_ref *ref2)
387{
388 if (ref1->level != ref2->level)
389 return 0;
390 if (ref1->root_id != ref2->root_id)
391 return 0;
392 if (ref1->key_for_search.type != ref2->key_for_search.type)
393 return 0;
394 if (ref1->key_for_search.objectid != ref2->key_for_search.objectid)
395 return 0;
396 if (ref1->key_for_search.offset != ref2->key_for_search.offset)
397 return 0;
398 if (ref1->parent != ref2->parent)
399 return 0;
400
401 return 1;
402}
403
404/*
405 * read tree blocks and add keys where required.
406 */
407static int __add_missing_keys(struct btrfs_fs_info *fs_info,
408 struct list_head *head)
409{
410 struct list_head *pos;
411 struct extent_buffer *eb;
412
413 list_for_each(pos, head) {
414 struct __prelim_ref *ref;
415 ref = list_entry(pos, struct __prelim_ref, list);
416
417 if (ref->parent)
418 continue;
419 if (ref->key_for_search.type)
420 continue;
421 BUG_ON(!ref->wanted_disk_byte);
422 eb = read_tree_block(fs_info->tree_root, ref->wanted_disk_byte,
423 fs_info->tree_root->leafsize, 0);
424 BUG_ON(!eb);
425 btrfs_tree_read_lock(eb);
426 if (btrfs_header_level(eb) == 0)
427 btrfs_item_key_to_cpu(eb, &ref->key_for_search, 0);
428 else
429 btrfs_node_key_to_cpu(eb, &ref->key_for_search, 0);
430 btrfs_tree_read_unlock(eb);
431 free_extent_buffer(eb);
432 }
433 return 0;
434}
435
249/* 436/*
250 * merge two lists of backrefs and adjust counts accordingly 437 * merge two lists of backrefs and adjust counts accordingly
251 * 438 *
252 * mode = 1: merge identical keys, if key is set 439 * mode = 1: merge identical keys, if key is set
440 * FIXME: if we add more keys in __add_prelim_ref, we can merge more here.
441 * additionally, we could even add a key range for the blocks we
442 * looked into to merge even more (-> replace unresolved refs by those
443 * having a parent).
253 * mode = 2: merge identical parents 444 * mode = 2: merge identical parents
254 */ 445 */
255static int __merge_refs(struct list_head *head, int mode) 446static int __merge_refs(struct list_head *head, int mode)
@@ -263,20 +454,21 @@ static int __merge_refs(struct list_head *head, int mode)
263 454
264 ref1 = list_entry(pos1, struct __prelim_ref, list); 455 ref1 = list_entry(pos1, struct __prelim_ref, list);
265 456
266 if (mode == 1 && ref1->key.type == 0)
267 continue;
268 for (pos2 = pos1->next, n2 = pos2->next; pos2 != head; 457 for (pos2 = pos1->next, n2 = pos2->next; pos2 != head;
269 pos2 = n2, n2 = pos2->next) { 458 pos2 = n2, n2 = pos2->next) {
270 struct __prelim_ref *ref2; 459 struct __prelim_ref *ref2;
460 struct __prelim_ref *xchg;
271 461
272 ref2 = list_entry(pos2, struct __prelim_ref, list); 462 ref2 = list_entry(pos2, struct __prelim_ref, list);
273 463
274 if (mode == 1) { 464 if (mode == 1) {
275 if (memcmp(&ref1->key, &ref2->key, 465 if (!ref_for_same_block(ref1, ref2))
276 sizeof(ref1->key)) ||
277 ref1->level != ref2->level ||
278 ref1->root_id != ref2->root_id)
279 continue; 466 continue;
467 if (!ref1->parent && ref2->parent) {
468 xchg = ref1;
469 ref1 = ref2;
470 ref2 = xchg;
471 }
280 ref1->count += ref2->count; 472 ref1->count += ref2->count;
281 } else { 473 } else {
282 if (ref1->parent != ref2->parent) 474 if (ref1->parent != ref2->parent)
@@ -296,16 +488,17 @@ static int __merge_refs(struct list_head *head, int mode)
296 * smaller or equal that seq to the list 488 * smaller or equal that seq to the list
297 */ 489 */
298static int __add_delayed_refs(struct btrfs_delayed_ref_head *head, u64 seq, 490static int __add_delayed_refs(struct btrfs_delayed_ref_head *head, u64 seq,
299 struct btrfs_key *info_key,
300 struct list_head *prefs) 491 struct list_head *prefs)
301{ 492{
302 struct btrfs_delayed_extent_op *extent_op = head->extent_op; 493 struct btrfs_delayed_extent_op *extent_op = head->extent_op;
303 struct rb_node *n = &head->node.rb_node; 494 struct rb_node *n = &head->node.rb_node;
495 struct btrfs_key key;
496 struct btrfs_key op_key = {0};
304 int sgn; 497 int sgn;
305 int ret = 0; 498 int ret = 0;
306 499
307 if (extent_op && extent_op->update_key) 500 if (extent_op && extent_op->update_key)
308 btrfs_disk_key_to_cpu(info_key, &extent_op->key); 501 btrfs_disk_key_to_cpu(&op_key, &extent_op->key);
309 502
310 while ((n = rb_prev(n))) { 503 while ((n = rb_prev(n))) {
311 struct btrfs_delayed_ref_node *node; 504 struct btrfs_delayed_ref_node *node;
@@ -337,7 +530,7 @@ static int __add_delayed_refs(struct btrfs_delayed_ref_head *head, u64 seq,
337 struct btrfs_delayed_tree_ref *ref; 530 struct btrfs_delayed_tree_ref *ref;
338 531
339 ref = btrfs_delayed_node_to_tree_ref(node); 532 ref = btrfs_delayed_node_to_tree_ref(node);
340 ret = __add_prelim_ref(prefs, ref->root, info_key, 533 ret = __add_prelim_ref(prefs, ref->root, &op_key,
341 ref->level + 1, 0, node->bytenr, 534 ref->level + 1, 0, node->bytenr,
342 node->ref_mod * sgn); 535 node->ref_mod * sgn);
343 break; 536 break;
@@ -346,7 +539,7 @@ static int __add_delayed_refs(struct btrfs_delayed_ref_head *head, u64 seq,
346 struct btrfs_delayed_tree_ref *ref; 539 struct btrfs_delayed_tree_ref *ref;
347 540
348 ref = btrfs_delayed_node_to_tree_ref(node); 541 ref = btrfs_delayed_node_to_tree_ref(node);
349 ret = __add_prelim_ref(prefs, ref->root, info_key, 542 ret = __add_prelim_ref(prefs, ref->root, NULL,
350 ref->level + 1, ref->parent, 543 ref->level + 1, ref->parent,
351 node->bytenr, 544 node->bytenr,
352 node->ref_mod * sgn); 545 node->ref_mod * sgn);
@@ -354,8 +547,6 @@ static int __add_delayed_refs(struct btrfs_delayed_ref_head *head, u64 seq,
354 } 547 }
355 case BTRFS_EXTENT_DATA_REF_KEY: { 548 case BTRFS_EXTENT_DATA_REF_KEY: {
356 struct btrfs_delayed_data_ref *ref; 549 struct btrfs_delayed_data_ref *ref;
357 struct btrfs_key key;
358
359 ref = btrfs_delayed_node_to_data_ref(node); 550 ref = btrfs_delayed_node_to_data_ref(node);
360 551
361 key.objectid = ref->objectid; 552 key.objectid = ref->objectid;
@@ -368,7 +559,6 @@ static int __add_delayed_refs(struct btrfs_delayed_ref_head *head, u64 seq,
368 } 559 }
369 case BTRFS_SHARED_DATA_REF_KEY: { 560 case BTRFS_SHARED_DATA_REF_KEY: {
370 struct btrfs_delayed_data_ref *ref; 561 struct btrfs_delayed_data_ref *ref;
371 struct btrfs_key key;
372 562
373 ref = btrfs_delayed_node_to_data_ref(node); 563 ref = btrfs_delayed_node_to_data_ref(node);
374 564
@@ -394,8 +584,7 @@ static int __add_delayed_refs(struct btrfs_delayed_ref_head *head, u64 seq,
394 */ 584 */
395static int __add_inline_refs(struct btrfs_fs_info *fs_info, 585static int __add_inline_refs(struct btrfs_fs_info *fs_info,
396 struct btrfs_path *path, u64 bytenr, 586 struct btrfs_path *path, u64 bytenr,
397 struct btrfs_key *info_key, int *info_level, 587 int *info_level, struct list_head *prefs)
398 struct list_head *prefs)
399{ 588{
400 int ret = 0; 589 int ret = 0;
401 int slot; 590 int slot;
@@ -411,7 +600,7 @@ static int __add_inline_refs(struct btrfs_fs_info *fs_info,
411 * enumerate all inline refs 600 * enumerate all inline refs
412 */ 601 */
413 leaf = path->nodes[0]; 602 leaf = path->nodes[0];
414 slot = path->slots[0] - 1; 603 slot = path->slots[0];
415 604
416 item_size = btrfs_item_size_nr(leaf, slot); 605 item_size = btrfs_item_size_nr(leaf, slot);
417 BUG_ON(item_size < sizeof(*ei)); 606 BUG_ON(item_size < sizeof(*ei));
@@ -424,12 +613,9 @@ static int __add_inline_refs(struct btrfs_fs_info *fs_info,
424 613
425 if (flags & BTRFS_EXTENT_FLAG_TREE_BLOCK) { 614 if (flags & BTRFS_EXTENT_FLAG_TREE_BLOCK) {
426 struct btrfs_tree_block_info *info; 615 struct btrfs_tree_block_info *info;
427 struct btrfs_disk_key disk_key;
428 616
429 info = (struct btrfs_tree_block_info *)ptr; 617 info = (struct btrfs_tree_block_info *)ptr;
430 *info_level = btrfs_tree_block_level(leaf, info); 618 *info_level = btrfs_tree_block_level(leaf, info);
431 btrfs_tree_block_key(leaf, info, &disk_key);
432 btrfs_disk_key_to_cpu(info_key, &disk_key);
433 ptr += sizeof(struct btrfs_tree_block_info); 619 ptr += sizeof(struct btrfs_tree_block_info);
434 BUG_ON(ptr > end); 620 BUG_ON(ptr > end);
435 } else { 621 } else {
@@ -447,7 +633,7 @@ static int __add_inline_refs(struct btrfs_fs_info *fs_info,
447 633
448 switch (type) { 634 switch (type) {
449 case BTRFS_SHARED_BLOCK_REF_KEY: 635 case BTRFS_SHARED_BLOCK_REF_KEY:
450 ret = __add_prelim_ref(prefs, 0, info_key, 636 ret = __add_prelim_ref(prefs, 0, NULL,
451 *info_level + 1, offset, 637 *info_level + 1, offset,
452 bytenr, 1); 638 bytenr, 1);
453 break; 639 break;
@@ -462,8 +648,9 @@ static int __add_inline_refs(struct btrfs_fs_info *fs_info,
462 break; 648 break;
463 } 649 }
464 case BTRFS_TREE_BLOCK_REF_KEY: 650 case BTRFS_TREE_BLOCK_REF_KEY:
465 ret = __add_prelim_ref(prefs, offset, info_key, 651 ret = __add_prelim_ref(prefs, offset, NULL,
466 *info_level + 1, 0, bytenr, 1); 652 *info_level + 1, 0,
653 bytenr, 1);
467 break; 654 break;
468 case BTRFS_EXTENT_DATA_REF_KEY: { 655 case BTRFS_EXTENT_DATA_REF_KEY: {
469 struct btrfs_extent_data_ref *dref; 656 struct btrfs_extent_data_ref *dref;
@@ -477,8 +664,8 @@ static int __add_inline_refs(struct btrfs_fs_info *fs_info,
477 key.type = BTRFS_EXTENT_DATA_KEY; 664 key.type = BTRFS_EXTENT_DATA_KEY;
478 key.offset = btrfs_extent_data_ref_offset(leaf, dref); 665 key.offset = btrfs_extent_data_ref_offset(leaf, dref);
479 root = btrfs_extent_data_ref_root(leaf, dref); 666 root = btrfs_extent_data_ref_root(leaf, dref);
480 ret = __add_prelim_ref(prefs, root, &key, 0, 0, bytenr, 667 ret = __add_prelim_ref(prefs, root, &key, 0, 0,
481 count); 668 bytenr, count);
482 break; 669 break;
483 } 670 }
484 default: 671 default:
@@ -496,8 +683,7 @@ static int __add_inline_refs(struct btrfs_fs_info *fs_info,
496 */ 683 */
497static int __add_keyed_refs(struct btrfs_fs_info *fs_info, 684static int __add_keyed_refs(struct btrfs_fs_info *fs_info,
498 struct btrfs_path *path, u64 bytenr, 685 struct btrfs_path *path, u64 bytenr,
499 struct btrfs_key *info_key, int info_level, 686 int info_level, struct list_head *prefs)
500 struct list_head *prefs)
501{ 687{
502 struct btrfs_root *extent_root = fs_info->extent_root; 688 struct btrfs_root *extent_root = fs_info->extent_root;
503 int ret; 689 int ret;
@@ -527,7 +713,7 @@ static int __add_keyed_refs(struct btrfs_fs_info *fs_info,
527 713
528 switch (key.type) { 714 switch (key.type) {
529 case BTRFS_SHARED_BLOCK_REF_KEY: 715 case BTRFS_SHARED_BLOCK_REF_KEY:
530 ret = __add_prelim_ref(prefs, 0, info_key, 716 ret = __add_prelim_ref(prefs, 0, NULL,
531 info_level + 1, key.offset, 717 info_level + 1, key.offset,
532 bytenr, 1); 718 bytenr, 1);
533 break; 719 break;
@@ -543,8 +729,9 @@ static int __add_keyed_refs(struct btrfs_fs_info *fs_info,
543 break; 729 break;
544 } 730 }
545 case BTRFS_TREE_BLOCK_REF_KEY: 731 case BTRFS_TREE_BLOCK_REF_KEY:
546 ret = __add_prelim_ref(prefs, key.offset, info_key, 732 ret = __add_prelim_ref(prefs, key.offset, NULL,
547 info_level + 1, 0, bytenr, 1); 733 info_level + 1, 0,
734 bytenr, 1);
548 break; 735 break;
549 case BTRFS_EXTENT_DATA_REF_KEY: { 736 case BTRFS_EXTENT_DATA_REF_KEY: {
550 struct btrfs_extent_data_ref *dref; 737 struct btrfs_extent_data_ref *dref;
@@ -560,7 +747,7 @@ static int __add_keyed_refs(struct btrfs_fs_info *fs_info,
560 key.offset = btrfs_extent_data_ref_offset(leaf, dref); 747 key.offset = btrfs_extent_data_ref_offset(leaf, dref);
561 root = btrfs_extent_data_ref_root(leaf, dref); 748 root = btrfs_extent_data_ref_root(leaf, dref);
562 ret = __add_prelim_ref(prefs, root, &key, 0, 0, 749 ret = __add_prelim_ref(prefs, root, &key, 0, 0,
563 bytenr, count); 750 bytenr, count);
564 break; 751 break;
565 } 752 }
566 default: 753 default:
@@ -582,11 +769,12 @@ static int __add_keyed_refs(struct btrfs_fs_info *fs_info,
582 */ 769 */
583static int find_parent_nodes(struct btrfs_trans_handle *trans, 770static int find_parent_nodes(struct btrfs_trans_handle *trans,
584 struct btrfs_fs_info *fs_info, u64 bytenr, 771 struct btrfs_fs_info *fs_info, u64 bytenr,
585 u64 seq, struct ulist *refs, struct ulist *roots) 772 u64 delayed_ref_seq, u64 time_seq,
773 struct ulist *refs, struct ulist *roots,
774 const u64 *extent_item_pos)
586{ 775{
587 struct btrfs_key key; 776 struct btrfs_key key;
588 struct btrfs_path *path; 777 struct btrfs_path *path;
589 struct btrfs_key info_key = { 0 };
590 struct btrfs_delayed_ref_root *delayed_refs = NULL; 778 struct btrfs_delayed_ref_root *delayed_refs = NULL;
591 struct btrfs_delayed_ref_head *head; 779 struct btrfs_delayed_ref_head *head;
592 int info_level = 0; 780 int info_level = 0;
@@ -645,7 +833,7 @@ again:
645 btrfs_put_delayed_ref(&head->node); 833 btrfs_put_delayed_ref(&head->node);
646 goto again; 834 goto again;
647 } 835 }
648 ret = __add_delayed_refs(head, seq, &info_key, 836 ret = __add_delayed_refs(head, delayed_ref_seq,
649 &prefs_delayed); 837 &prefs_delayed);
650 if (ret) { 838 if (ret) {
651 spin_unlock(&delayed_refs->lock); 839 spin_unlock(&delayed_refs->lock);
@@ -659,16 +847,17 @@ again:
659 struct extent_buffer *leaf; 847 struct extent_buffer *leaf;
660 int slot; 848 int slot;
661 849
850 path->slots[0]--;
662 leaf = path->nodes[0]; 851 leaf = path->nodes[0];
663 slot = path->slots[0] - 1; 852 slot = path->slots[0];
664 btrfs_item_key_to_cpu(leaf, &key, slot); 853 btrfs_item_key_to_cpu(leaf, &key, slot);
665 if (key.objectid == bytenr && 854 if (key.objectid == bytenr &&
666 key.type == BTRFS_EXTENT_ITEM_KEY) { 855 key.type == BTRFS_EXTENT_ITEM_KEY) {
667 ret = __add_inline_refs(fs_info, path, bytenr, 856 ret = __add_inline_refs(fs_info, path, bytenr,
668 &info_key, &info_level, &prefs); 857 &info_level, &prefs);
669 if (ret) 858 if (ret)
670 goto out; 859 goto out;
671 ret = __add_keyed_refs(fs_info, path, bytenr, &info_key, 860 ret = __add_keyed_refs(fs_info, path, bytenr,
672 info_level, &prefs); 861 info_level, &prefs);
673 if (ret) 862 if (ret)
674 goto out; 863 goto out;
@@ -676,21 +865,18 @@ again:
676 } 865 }
677 btrfs_release_path(path); 866 btrfs_release_path(path);
678 867
679 /*
680 * when adding the delayed refs above, the info_key might not have
681 * been known yet. Go over the list and replace the missing keys
682 */
683 list_for_each_entry(ref, &prefs_delayed, list) {
684 if ((ref->key.offset | ref->key.type | ref->key.objectid) == 0)
685 memcpy(&ref->key, &info_key, sizeof(ref->key));
686 }
687 list_splice_init(&prefs_delayed, &prefs); 868 list_splice_init(&prefs_delayed, &prefs);
688 869
870 ret = __add_missing_keys(fs_info, &prefs);
871 if (ret)
872 goto out;
873
689 ret = __merge_refs(&prefs, 1); 874 ret = __merge_refs(&prefs, 1);
690 if (ret) 875 if (ret)
691 goto out; 876 goto out;
692 877
693 ret = __resolve_indirect_refs(fs_info, search_commit_root, &prefs); 878 ret = __resolve_indirect_refs(fs_info, search_commit_root, time_seq,
879 &prefs, extent_item_pos);
694 if (ret) 880 if (ret)
695 goto out; 881 goto out;
696 882
@@ -709,7 +895,33 @@ again:
709 BUG_ON(ret < 0); 895 BUG_ON(ret < 0);
710 } 896 }
711 if (ref->count && ref->parent) { 897 if (ref->count && ref->parent) {
712 ret = ulist_add(refs, ref->parent, 0, GFP_NOFS); 898 struct extent_inode_elem *eie = NULL;
899 if (extent_item_pos && !ref->inode_list) {
900 u32 bsz;
901 struct extent_buffer *eb;
902 bsz = btrfs_level_size(fs_info->extent_root,
903 info_level);
904 eb = read_tree_block(fs_info->extent_root,
905 ref->parent, bsz, 0);
906 BUG_ON(!eb);
907 ret = find_extent_in_eb(eb, bytenr,
908 *extent_item_pos, &eie);
909 ref->inode_list = eie;
910 free_extent_buffer(eb);
911 }
912 ret = ulist_add_merge(refs, ref->parent,
913 (unsigned long)ref->inode_list,
914 (unsigned long *)&eie, GFP_NOFS);
915 if (!ret && extent_item_pos) {
916 /*
917 * we've recorded that parent, so we must extend
918 * its inode list here
919 */
920 BUG_ON(!eie);
921 while (eie->next)
922 eie = eie->next;
923 eie->next = ref->inode_list;
924 }
713 BUG_ON(ret < 0); 925 BUG_ON(ret < 0);
714 } 926 }
715 kfree(ref); 927 kfree(ref);
@@ -734,6 +946,28 @@ out:
734 return ret; 946 return ret;
735} 947}
736 948
949static void free_leaf_list(struct ulist *blocks)
950{
951 struct ulist_node *node = NULL;
952 struct extent_inode_elem *eie;
953 struct extent_inode_elem *eie_next;
954 struct ulist_iterator uiter;
955
956 ULIST_ITER_INIT(&uiter);
957 while ((node = ulist_next(blocks, &uiter))) {
958 if (!node->aux)
959 continue;
960 eie = (struct extent_inode_elem *)node->aux;
961 for (; eie; eie = eie_next) {
962 eie_next = eie->next;
963 kfree(eie);
964 }
965 node->aux = 0;
966 }
967
968 ulist_free(blocks);
969}
970
737/* 971/*
738 * Finds all leafs with a reference to the specified combination of bytenr and 972 * Finds all leafs with a reference to the specified combination of bytenr and
739 * offset. key_list_head will point to a list of corresponding keys (caller must 973 * offset. key_list_head will point to a list of corresponding keys (caller must
@@ -744,7 +978,9 @@ out:
744 */ 978 */
745static int btrfs_find_all_leafs(struct btrfs_trans_handle *trans, 979static int btrfs_find_all_leafs(struct btrfs_trans_handle *trans,
746 struct btrfs_fs_info *fs_info, u64 bytenr, 980 struct btrfs_fs_info *fs_info, u64 bytenr,
747 u64 num_bytes, u64 seq, struct ulist **leafs) 981 u64 delayed_ref_seq, u64 time_seq,
982 struct ulist **leafs,
983 const u64 *extent_item_pos)
748{ 984{
749 struct ulist *tmp; 985 struct ulist *tmp;
750 int ret; 986 int ret;
@@ -758,11 +994,12 @@ static int btrfs_find_all_leafs(struct btrfs_trans_handle *trans,
758 return -ENOMEM; 994 return -ENOMEM;
759 } 995 }
760 996
761 ret = find_parent_nodes(trans, fs_info, bytenr, seq, *leafs, tmp); 997 ret = find_parent_nodes(trans, fs_info, bytenr, delayed_ref_seq,
998 time_seq, *leafs, tmp, extent_item_pos);
762 ulist_free(tmp); 999 ulist_free(tmp);
763 1000
764 if (ret < 0 && ret != -ENOENT) { 1001 if (ret < 0 && ret != -ENOENT) {
765 ulist_free(*leafs); 1002 free_leaf_list(*leafs);
766 return ret; 1003 return ret;
767 } 1004 }
768 1005
@@ -784,10 +1021,12 @@ static int btrfs_find_all_leafs(struct btrfs_trans_handle *trans,
784 */ 1021 */
785int btrfs_find_all_roots(struct btrfs_trans_handle *trans, 1022int btrfs_find_all_roots(struct btrfs_trans_handle *trans,
786 struct btrfs_fs_info *fs_info, u64 bytenr, 1023 struct btrfs_fs_info *fs_info, u64 bytenr,
787 u64 num_bytes, u64 seq, struct ulist **roots) 1024 u64 delayed_ref_seq, u64 time_seq,
1025 struct ulist **roots)
788{ 1026{
789 struct ulist *tmp; 1027 struct ulist *tmp;
790 struct ulist_node *node = NULL; 1028 struct ulist_node *node = NULL;
1029 struct ulist_iterator uiter;
791 int ret; 1030 int ret;
792 1031
793 tmp = ulist_alloc(GFP_NOFS); 1032 tmp = ulist_alloc(GFP_NOFS);
@@ -799,15 +1038,16 @@ int btrfs_find_all_roots(struct btrfs_trans_handle *trans,
799 return -ENOMEM; 1038 return -ENOMEM;
800 } 1039 }
801 1040
1041 ULIST_ITER_INIT(&uiter);
802 while (1) { 1042 while (1) {
803 ret = find_parent_nodes(trans, fs_info, bytenr, seq, 1043 ret = find_parent_nodes(trans, fs_info, bytenr, delayed_ref_seq,
804 tmp, *roots); 1044 time_seq, tmp, *roots, NULL);
805 if (ret < 0 && ret != -ENOENT) { 1045 if (ret < 0 && ret != -ENOENT) {
806 ulist_free(tmp); 1046 ulist_free(tmp);
807 ulist_free(*roots); 1047 ulist_free(*roots);
808 return ret; 1048 return ret;
809 } 1049 }
810 node = ulist_next(tmp, node); 1050 node = ulist_next(tmp, &uiter);
811 if (!node) 1051 if (!node)
812 break; 1052 break;
813 bytenr = node->val; 1053 bytenr = node->val;
@@ -1093,67 +1333,25 @@ int tree_backref_for_extent(unsigned long *ptr, struct extent_buffer *eb,
1093 return 0; 1333 return 0;
1094} 1334}
1095 1335
1096static int iterate_leaf_refs(struct btrfs_fs_info *fs_info, u64 logical, 1336static int iterate_leaf_refs(struct extent_inode_elem *inode_list,
1097 u64 orig_extent_item_objectid, 1337 u64 root, u64 extent_item_objectid,
1098 u64 extent_item_pos, u64 root,
1099 iterate_extent_inodes_t *iterate, void *ctx) 1338 iterate_extent_inodes_t *iterate, void *ctx)
1100{ 1339{
1101 u64 disk_byte; 1340 struct extent_inode_elem *eie;
1102 struct btrfs_key key;
1103 struct btrfs_file_extent_item *fi;
1104 struct extent_buffer *eb;
1105 int slot;
1106 int nritems;
1107 int ret = 0; 1341 int ret = 0;
1108 int extent_type;
1109 u64 data_offset;
1110 u64 data_len;
1111
1112 eb = read_tree_block(fs_info->tree_root, logical,
1113 fs_info->tree_root->leafsize, 0);
1114 if (!eb)
1115 return -EIO;
1116
1117 /*
1118 * from the shared data ref, we only have the leaf but we need
1119 * the key. thus, we must look into all items and see that we
1120 * find one (some) with a reference to our extent item.
1121 */
1122 nritems = btrfs_header_nritems(eb);
1123 for (slot = 0; slot < nritems; ++slot) {
1124 btrfs_item_key_to_cpu(eb, &key, slot);
1125 if (key.type != BTRFS_EXTENT_DATA_KEY)
1126 continue;
1127 fi = btrfs_item_ptr(eb, slot, struct btrfs_file_extent_item);
1128 extent_type = btrfs_file_extent_type(eb, fi);
1129 if (extent_type == BTRFS_FILE_EXTENT_INLINE)
1130 continue;
1131 /* don't skip BTRFS_FILE_EXTENT_PREALLOC, we can handle that */
1132 disk_byte = btrfs_file_extent_disk_bytenr(eb, fi);
1133 if (disk_byte != orig_extent_item_objectid)
1134 continue;
1135
1136 data_offset = btrfs_file_extent_offset(eb, fi);
1137 data_len = btrfs_file_extent_num_bytes(eb, fi);
1138
1139 if (extent_item_pos < data_offset ||
1140 extent_item_pos >= data_offset + data_len)
1141 continue;
1142 1342
1343 for (eie = inode_list; eie; eie = eie->next) {
1143 pr_debug("ref for %llu resolved, key (%llu EXTEND_DATA %llu), " 1344 pr_debug("ref for %llu resolved, key (%llu EXTEND_DATA %llu), "
1144 "root %llu\n", orig_extent_item_objectid, 1345 "root %llu\n", extent_item_objectid,
1145 key.objectid, key.offset, root); 1346 eie->inum, eie->offset, root);
1146 ret = iterate(key.objectid, 1347 ret = iterate(eie->inum, eie->offset, root, ctx);
1147 key.offset + (extent_item_pos - data_offset),
1148 root, ctx);
1149 if (ret) { 1348 if (ret) {
1150 pr_debug("stopping iteration because ret=%d\n", ret); 1349 pr_debug("stopping iteration for %llu due to ret=%d\n",
1350 extent_item_objectid, ret);
1151 break; 1351 break;
1152 } 1352 }
1153 } 1353 }
1154 1354
1155 free_extent_buffer(eb);
1156
1157 return ret; 1355 return ret;
1158} 1356}
1159 1357
@@ -1175,7 +1373,10 @@ int iterate_extent_inodes(struct btrfs_fs_info *fs_info,
1175 struct ulist *roots = NULL; 1373 struct ulist *roots = NULL;
1176 struct ulist_node *ref_node = NULL; 1374 struct ulist_node *ref_node = NULL;
1177 struct ulist_node *root_node = NULL; 1375 struct ulist_node *root_node = NULL;
1178 struct seq_list seq_elem; 1376 struct seq_list seq_elem = {};
1377 struct seq_list tree_mod_seq_elem = {};
1378 struct ulist_iterator ref_uiter;
1379 struct ulist_iterator root_uiter;
1179 struct btrfs_delayed_ref_root *delayed_refs = NULL; 1380 struct btrfs_delayed_ref_root *delayed_refs = NULL;
1180 1381
1181 pr_debug("resolving all inodes for extent %llu\n", 1382 pr_debug("resolving all inodes for extent %llu\n",
@@ -1192,34 +1393,41 @@ int iterate_extent_inodes(struct btrfs_fs_info *fs_info,
1192 spin_lock(&delayed_refs->lock); 1393 spin_lock(&delayed_refs->lock);
1193 btrfs_get_delayed_seq(delayed_refs, &seq_elem); 1394 btrfs_get_delayed_seq(delayed_refs, &seq_elem);
1194 spin_unlock(&delayed_refs->lock); 1395 spin_unlock(&delayed_refs->lock);
1396 btrfs_get_tree_mod_seq(fs_info, &tree_mod_seq_elem);
1195 } 1397 }
1196 1398
1197 ret = btrfs_find_all_leafs(trans, fs_info, extent_item_objectid, 1399 ret = btrfs_find_all_leafs(trans, fs_info, extent_item_objectid,
1198 extent_item_pos, seq_elem.seq, 1400 seq_elem.seq, tree_mod_seq_elem.seq, &refs,
1199 &refs); 1401 &extent_item_pos);
1200
1201 if (ret) 1402 if (ret)
1202 goto out; 1403 goto out;
1203 1404
1204 while (!ret && (ref_node = ulist_next(refs, ref_node))) { 1405 ULIST_ITER_INIT(&ref_uiter);
1205 ret = btrfs_find_all_roots(trans, fs_info, ref_node->val, -1, 1406 while (!ret && (ref_node = ulist_next(refs, &ref_uiter))) {
1206 seq_elem.seq, &roots); 1407 ret = btrfs_find_all_roots(trans, fs_info, ref_node->val,
1408 seq_elem.seq,
1409 tree_mod_seq_elem.seq, &roots);
1207 if (ret) 1410 if (ret)
1208 break; 1411 break;
1209 while (!ret && (root_node = ulist_next(roots, root_node))) { 1412 ULIST_ITER_INIT(&root_uiter);
1210 pr_debug("root %llu references leaf %llu\n", 1413 while (!ret && (root_node = ulist_next(roots, &root_uiter))) {
1211 root_node->val, ref_node->val); 1414 pr_debug("root %llu references leaf %llu, data list "
1212 ret = iterate_leaf_refs(fs_info, ref_node->val, 1415 "%#lx\n", root_node->val, ref_node->val,
1213 extent_item_objectid, 1416 ref_node->aux);
1214 extent_item_pos, root_node->val, 1417 ret = iterate_leaf_refs(
1215 iterate, ctx); 1418 (struct extent_inode_elem *)ref_node->aux,
1419 root_node->val, extent_item_objectid,
1420 iterate, ctx);
1216 } 1421 }
1422 ulist_free(roots);
1423 roots = NULL;
1217 } 1424 }
1218 1425
1219 ulist_free(refs); 1426 free_leaf_list(refs);
1220 ulist_free(roots); 1427 ulist_free(roots);
1221out: 1428out:
1222 if (!search_commit_root) { 1429 if (!search_commit_root) {
1430 btrfs_put_tree_mod_seq(fs_info, &tree_mod_seq_elem);
1223 btrfs_put_delayed_seq(delayed_refs, &seq_elem); 1431 btrfs_put_delayed_seq(delayed_refs, &seq_elem);
1224 btrfs_end_transaction(trans, fs_info->extent_root); 1432 btrfs_end_transaction(trans, fs_info->extent_root);
1225 } 1433 }