Btrfs: Move device information into the super block so it can be scanned
[safe/jmp/linux-2.6] / fs / btrfs / volumes.c
1 /*
2  * Copyright (C) 2007 Oracle.  All rights reserved.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public
6  * License v2 as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public
14  * License along with this program; if not, write to the
15  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16  * Boston, MA 021110-1307, USA.
17  */
18 #include <linux/sched.h>
19 #include <linux/bio.h>
20 #include "ctree.h"
21 #include "extent_map.h"
22 #include "disk-io.h"
23 #include "transaction.h"
24 #include "print-tree.h"
25 #include "volumes.h"
26
27 struct map_lookup {
28         struct btrfs_device *dev;
29         u64 physical;
30 };
31
32 /*
33  * this uses a pretty simple search, the expectation is that it is
34  * called very infrequently and that a given device has a small number
35  * of extents
36  */
37 static int find_free_dev_extent(struct btrfs_trans_handle *trans,
38                                 struct btrfs_device *device,
39                                 struct btrfs_path *path,
40                                 u64 num_bytes, u64 *start)
41 {
42         struct btrfs_key key;
43         struct btrfs_root *root = device->dev_root;
44         struct btrfs_dev_extent *dev_extent = NULL;
45         u64 hole_size = 0;
46         u64 last_byte = 0;
47         u64 search_start = 0;
48         u64 search_end = device->total_bytes;
49         int ret;
50         int slot = 0;
51         int start_found;
52         struct extent_buffer *l;
53
54         start_found = 0;
55         path->reada = 2;
56
57         /* FIXME use last free of some kind */
58
59         key.objectid = device->devid;
60         key.offset = search_start;
61         key.type = BTRFS_DEV_EXTENT_KEY;
62         ret = btrfs_search_slot(trans, root, &key, path, 0, 0);
63         if (ret < 0)
64                 goto error;
65         ret = btrfs_previous_item(root, path, 0, key.type);
66         if (ret < 0)
67                 goto error;
68         l = path->nodes[0];
69         btrfs_item_key_to_cpu(l, &key, path->slots[0]);
70         while (1) {
71                 l = path->nodes[0];
72                 slot = path->slots[0];
73                 if (slot >= btrfs_header_nritems(l)) {
74                         ret = btrfs_next_leaf(root, path);
75                         if (ret == 0)
76                                 continue;
77                         if (ret < 0)
78                                 goto error;
79 no_more_items:
80                         if (!start_found) {
81                                 if (search_start >= search_end) {
82                                         ret = -ENOSPC;
83                                         goto error;
84                                 }
85                                 *start = search_start;
86                                 start_found = 1;
87                                 goto check_pending;
88                         }
89                         *start = last_byte > search_start ?
90                                 last_byte : search_start;
91                         if (search_end <= *start) {
92                                 ret = -ENOSPC;
93                                 goto error;
94                         }
95                         goto check_pending;
96                 }
97                 btrfs_item_key_to_cpu(l, &key, slot);
98
99                 if (key.objectid < device->devid)
100                         goto next;
101
102                 if (key.objectid > device->devid)
103                         goto no_more_items;
104
105                 if (key.offset >= search_start && key.offset > last_byte &&
106                     start_found) {
107                         if (last_byte < search_start)
108                                 last_byte = search_start;
109                         hole_size = key.offset - last_byte;
110                         if (key.offset > last_byte &&
111                             hole_size >= num_bytes) {
112                                 *start = last_byte;
113                                 goto check_pending;
114                         }
115                 }
116                 if (btrfs_key_type(&key) != BTRFS_DEV_EXTENT_KEY) {
117                         goto next;
118                 }
119
120                 start_found = 1;
121                 dev_extent = btrfs_item_ptr(l, slot, struct btrfs_dev_extent);
122                 last_byte = key.offset + btrfs_dev_extent_length(l, dev_extent);
123 next:
124                 path->slots[0]++;
125                 cond_resched();
126         }
127 check_pending:
128         /* we have to make sure we didn't find an extent that has already
129          * been allocated by the map tree or the original allocation
130          */
131         btrfs_release_path(root, path);
132         BUG_ON(*start < search_start);
133
134         if (*start + num_bytes > search_end) {
135                 ret = -ENOSPC;
136                 goto error;
137         }
138         /* check for pending inserts here */
139         return 0;
140
141 error:
142         btrfs_release_path(root, path);
143         return ret;
144 }
145
146 int btrfs_alloc_dev_extent(struct btrfs_trans_handle *trans,
147                            struct btrfs_device *device,
148                            u64 owner, u64 num_bytes, u64 *start)
149 {
150         int ret;
151         struct btrfs_path *path;
152         struct btrfs_root *root = device->dev_root;
153         struct btrfs_dev_extent *extent;
154         struct extent_buffer *leaf;
155         struct btrfs_key key;
156
157         path = btrfs_alloc_path();
158         if (!path)
159                 return -ENOMEM;
160
161         ret = find_free_dev_extent(trans, device, path, num_bytes, start);
162         if (ret) {
163                 goto err;
164         }
165
166         key.objectid = device->devid;
167         key.offset = *start;
168         key.type = BTRFS_DEV_EXTENT_KEY;
169         ret = btrfs_insert_empty_item(trans, root, path, &key,
170                                       sizeof(*extent));
171         BUG_ON(ret);
172
173         leaf = path->nodes[0];
174         extent = btrfs_item_ptr(leaf, path->slots[0],
175                                 struct btrfs_dev_extent);
176         btrfs_set_dev_extent_owner(leaf, extent, owner);
177         btrfs_set_dev_extent_length(leaf, extent, num_bytes);
178         btrfs_mark_buffer_dirty(leaf);
179 err:
180         btrfs_free_path(path);
181         return ret;
182 }
183
184 static int find_next_chunk(struct btrfs_root *root, u64 *objectid)
185 {
186         struct btrfs_path *path;
187         int ret;
188         struct btrfs_key key;
189         struct btrfs_key found_key;
190
191         path = btrfs_alloc_path();
192         BUG_ON(!path);
193
194         key.objectid = (u64)-1;
195         key.offset = (u64)-1;
196         key.type = BTRFS_CHUNK_ITEM_KEY;
197
198         ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
199         if (ret < 0)
200                 goto error;
201
202         BUG_ON(ret == 0);
203
204         ret = btrfs_previous_item(root, path, 0, BTRFS_CHUNK_ITEM_KEY);
205         if (ret) {
206                 *objectid = 0;
207         } else {
208                 btrfs_item_key_to_cpu(path->nodes[0], &found_key,
209                                       path->slots[0]);
210                 *objectid = found_key.objectid + found_key.offset;
211         }
212         ret = 0;
213 error:
214         btrfs_free_path(path);
215         return ret;
216 }
217
218 static int find_next_devid(struct btrfs_root *root, struct btrfs_path *path,
219                            u64 *objectid)
220 {
221         int ret;
222         struct btrfs_key key;
223         struct btrfs_key found_key;
224
225         key.objectid = BTRFS_DEV_ITEMS_OBJECTID;
226         key.type = BTRFS_DEV_ITEM_KEY;
227         key.offset = (u64)-1;
228
229         ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
230         if (ret < 0)
231                 goto error;
232
233         BUG_ON(ret == 0);
234
235         ret = btrfs_previous_item(root, path, BTRFS_DEV_ITEMS_OBJECTID,
236                                   BTRFS_DEV_ITEM_KEY);
237         if (ret) {
238                 *objectid = 1;
239         } else {
240                 btrfs_item_key_to_cpu(path->nodes[0], &found_key,
241                                       path->slots[0]);
242                 *objectid = found_key.offset + 1;
243         }
244         ret = 0;
245 error:
246         btrfs_release_path(root, path);
247         return ret;
248 }
249
250 /*
251  * the device information is stored in the chunk root
252  * the btrfs_device struct should be fully filled in
253  */
254 int btrfs_add_device(struct btrfs_trans_handle *trans,
255                      struct btrfs_root *root,
256                      struct btrfs_device *device)
257 {
258         int ret;
259         struct btrfs_path *path;
260         struct btrfs_dev_item *dev_item;
261         struct extent_buffer *leaf;
262         struct btrfs_key key;
263         unsigned long ptr;
264         u64 free_devid;
265
266         root = root->fs_info->chunk_root;
267
268         path = btrfs_alloc_path();
269         if (!path)
270                 return -ENOMEM;
271
272         ret = find_next_devid(root, path, &free_devid);
273         if (ret)
274                 goto out;
275
276         key.objectid = BTRFS_DEV_ITEMS_OBJECTID;
277         key.type = BTRFS_DEV_ITEM_KEY;
278         key.offset = free_devid;
279
280         ret = btrfs_insert_empty_item(trans, root, path, &key,
281                                       sizeof(*dev_item));
282         if (ret)
283                 goto out;
284
285         leaf = path->nodes[0];
286         dev_item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_dev_item);
287
288         btrfs_set_device_id(leaf, dev_item, device->devid);
289         btrfs_set_device_type(leaf, dev_item, device->type);
290         btrfs_set_device_io_align(leaf, dev_item, device->io_align);
291         btrfs_set_device_io_width(leaf, dev_item, device->io_width);
292         btrfs_set_device_sector_size(leaf, dev_item, device->sector_size);
293         btrfs_set_device_total_bytes(leaf, dev_item, device->total_bytes);
294         btrfs_set_device_bytes_used(leaf, dev_item, device->bytes_used);
295
296         ptr = (unsigned long)btrfs_device_uuid(dev_item);
297         write_extent_buffer(leaf, device->uuid, ptr, BTRFS_DEV_UUID_SIZE);
298         btrfs_mark_buffer_dirty(leaf);
299         ret = 0;
300
301 out:
302         btrfs_free_path(path);
303         return ret;
304 }
305 int btrfs_update_device(struct btrfs_trans_handle *trans,
306                         struct btrfs_device *device)
307 {
308         int ret;
309         struct btrfs_path *path;
310         struct btrfs_root *root;
311         struct btrfs_dev_item *dev_item;
312         struct extent_buffer *leaf;
313         struct btrfs_key key;
314
315         root = device->dev_root->fs_info->chunk_root;
316
317         path = btrfs_alloc_path();
318         if (!path)
319                 return -ENOMEM;
320
321         key.objectid = BTRFS_DEV_ITEMS_OBJECTID;
322         key.type = BTRFS_DEV_ITEM_KEY;
323         key.offset = device->devid;
324
325         ret = btrfs_search_slot(trans, root, &key, path, 0, 1);
326         if (ret < 0)
327                 goto out;
328
329         if (ret > 0) {
330                 ret = -ENOENT;
331                 goto out;
332         }
333
334         leaf = path->nodes[0];
335         dev_item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_dev_item);
336
337         btrfs_set_device_id(leaf, dev_item, device->devid);
338         btrfs_set_device_type(leaf, dev_item, device->type);
339         btrfs_set_device_io_align(leaf, dev_item, device->io_align);
340         btrfs_set_device_io_width(leaf, dev_item, device->io_width);
341         btrfs_set_device_sector_size(leaf, dev_item, device->sector_size);
342         btrfs_set_device_total_bytes(leaf, dev_item, device->total_bytes);
343         btrfs_set_device_bytes_used(leaf, dev_item, device->bytes_used);
344         btrfs_mark_buffer_dirty(leaf);
345
346 out:
347         btrfs_free_path(path);
348         return ret;
349 }
350
351 int btrfs_add_system_chunk(struct btrfs_trans_handle *trans,
352                            struct btrfs_root *root,
353                            struct btrfs_key *key,
354                            struct btrfs_chunk *chunk, int item_size)
355 {
356         struct btrfs_super_block *super_copy = &root->fs_info->super_copy;
357         struct btrfs_disk_key disk_key;
358         u32 array_size;
359         u8 *ptr;
360
361         array_size = btrfs_super_sys_array_size(super_copy);
362         if (array_size + item_size > BTRFS_SYSTEM_CHUNK_ARRAY_SIZE)
363                 return -EFBIG;
364
365         ptr = super_copy->sys_chunk_array + array_size;
366         btrfs_cpu_key_to_disk(&disk_key, key);
367         memcpy(ptr, &disk_key, sizeof(disk_key));
368         ptr += sizeof(disk_key);
369         memcpy(ptr, chunk, item_size);
370         item_size += sizeof(disk_key);
371         btrfs_set_super_sys_array_size(super_copy, array_size + item_size);
372         return 0;
373 }
374
375 int btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
376                       struct btrfs_root *extent_root, u64 *start,
377                       u64 *num_bytes, u64 type)
378 {
379         u64 dev_offset;
380         struct btrfs_root *chunk_root = extent_root->fs_info->chunk_root;
381         struct btrfs_stripe *stripes;
382         struct btrfs_device *device = NULL;
383         struct btrfs_chunk *chunk;
384         struct list_head private_devs;
385         struct list_head *dev_list = &extent_root->fs_info->devices;
386         struct list_head *cur;
387         struct extent_map_tree *em_tree;
388         struct map_lookup *map;
389         struct extent_map *em;
390         u64 physical;
391         u64 calc_size = 1024 * 1024 * 1024;
392         u64 avail;
393         u64 max_avail = 0;
394         int num_stripes = 1;
395         int looped = 0;
396         int ret;
397         int index;
398         struct btrfs_key key;
399
400         if (list_empty(dev_list))
401                 return -ENOSPC;
402 again:
403         INIT_LIST_HEAD(&private_devs);
404         cur = dev_list->next;
405         index = 0;
406         /* build a private list of devices we will allocate from */
407         while(index < num_stripes) {
408                 device = list_entry(cur, struct btrfs_device, dev_list);
409                 avail = device->total_bytes - device->bytes_used;
410                 cur = cur->next;
411                 if (avail > max_avail)
412                         max_avail = avail;
413                 if (avail >= calc_size) {
414                         list_move_tail(&device->dev_list, &private_devs);
415                         index++;
416                 }
417                 if (cur == dev_list)
418                         break;
419         }
420         if (index < num_stripes) {
421                 list_splice(&private_devs, dev_list);
422                 if (!looped && max_avail > 0) {
423                         looped = 1;
424                         calc_size = max_avail;
425                         goto again;
426                 }
427                 return -ENOSPC;
428         }
429
430         ret = find_next_chunk(chunk_root, &key.objectid);
431         if (ret)
432                 return ret;
433
434         chunk = kmalloc(btrfs_chunk_item_size(num_stripes), GFP_NOFS);
435         if (!chunk)
436                 return -ENOMEM;
437
438         stripes = &chunk->stripe;
439
440         *num_bytes = calc_size;
441         index = 0;
442         while(index < num_stripes) {
443                 BUG_ON(list_empty(&private_devs));
444                 cur = private_devs.next;
445                 device = list_entry(cur, struct btrfs_device, dev_list);
446                 list_move_tail(&device->dev_list, dev_list);
447
448                 ret = btrfs_alloc_dev_extent(trans, device,
449                                              key.objectid,
450                                              calc_size, &dev_offset);
451                 BUG_ON(ret);
452
453                 device->bytes_used += calc_size;
454                 ret = btrfs_update_device(trans, device);
455                 BUG_ON(ret);
456
457                 btrfs_set_stack_stripe_devid(stripes + index, device->devid);
458                 btrfs_set_stack_stripe_offset(stripes + index, dev_offset);
459                 physical = dev_offset;
460                 index++;
461         }
462         BUG_ON(!list_empty(&private_devs));
463
464         /* key.objectid was set above */
465         key.offset = *num_bytes;
466         key.type = BTRFS_CHUNK_ITEM_KEY;
467         btrfs_set_stack_chunk_owner(chunk, extent_root->root_key.objectid);
468         btrfs_set_stack_chunk_stripe_len(chunk, 64 * 1024);
469         btrfs_set_stack_chunk_type(chunk, type);
470         btrfs_set_stack_chunk_num_stripes(chunk, num_stripes);
471         btrfs_set_stack_chunk_io_align(chunk, extent_root->sectorsize);
472         btrfs_set_stack_chunk_io_width(chunk, extent_root->sectorsize);
473         btrfs_set_stack_chunk_sector_size(chunk, extent_root->sectorsize);
474
475         ret = btrfs_insert_item(trans, chunk_root, &key, chunk,
476                                 btrfs_chunk_item_size(num_stripes));
477         BUG_ON(ret);
478         *start = key.objectid;
479
480         em = alloc_extent_map(GFP_NOFS);
481         if (!em)
482                 return -ENOMEM;
483         map = kmalloc(sizeof(*map), GFP_NOFS);
484         if (!map) {
485                 free_extent_map(em);
486                 return -ENOMEM;
487         }
488
489         em->bdev = (struct block_device *)map;
490         em->start = key.objectid;
491         em->len = key.offset;
492         em->block_start = 0;
493
494         map->physical = physical;
495         map->dev = device;
496
497         if (!map->dev) {
498                 kfree(map);
499                 free_extent_map(em);
500                 return -EIO;
501         }
502         kfree(chunk);
503
504         em_tree = &extent_root->fs_info->mapping_tree.map_tree;
505         spin_lock(&em_tree->lock);
506         ret = add_extent_mapping(em_tree, em);
507         BUG_ON(ret);
508         spin_unlock(&em_tree->lock);
509         free_extent_map(em);
510         return ret;
511 }
512
513 void btrfs_mapping_init(struct btrfs_mapping_tree *tree)
514 {
515         extent_map_tree_init(&tree->map_tree, GFP_NOFS);
516 }
517
518 void btrfs_mapping_tree_free(struct btrfs_mapping_tree *tree)
519 {
520         struct extent_map *em;
521
522         while(1) {
523                 spin_lock(&tree->map_tree.lock);
524                 em = lookup_extent_mapping(&tree->map_tree, 0, (u64)-1);
525                 if (em)
526                         remove_extent_mapping(&tree->map_tree, em);
527                 spin_unlock(&tree->map_tree.lock);
528                 if (!em)
529                         break;
530                 kfree(em->bdev);
531                 /* once for us */
532                 free_extent_map(em);
533                 /* once for the tree */
534                 free_extent_map(em);
535         }
536 }
537
538 int btrfs_map_block(struct btrfs_mapping_tree *map_tree,
539                     u64 logical, u64 *phys, u64 *length,
540                     struct btrfs_device **dev)
541 {
542         struct extent_map *em;
543         struct map_lookup *map;
544         struct extent_map_tree *em_tree = &map_tree->map_tree;
545         u64 offset;
546
547
548         spin_lock(&em_tree->lock);
549         em = lookup_extent_mapping(em_tree, logical, *length);
550         BUG_ON(!em);
551
552         BUG_ON(em->start > logical || em->start + em->len < logical);
553         map = (struct map_lookup *)em->bdev;
554         offset = logical - em->start;
555         *phys = map->physical + offset;
556         *length = em->len - offset;
557         *dev = map->dev;
558         free_extent_map(em);
559         spin_unlock(&em_tree->lock);
560         return 0;
561 }
562
563 int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio)
564 {
565         struct btrfs_mapping_tree *map_tree;
566         struct btrfs_device *dev;
567         u64 logical = bio->bi_sector << 9;
568         u64 physical;
569         u64 length = 0;
570         u64 map_length;
571         struct bio_vec *bvec;
572         int i;
573         int ret;
574
575         bio_for_each_segment(bvec, bio, i) {
576                 length += bvec->bv_len;
577         }
578         map_tree = &root->fs_info->mapping_tree;
579         map_length = length;
580         ret = btrfs_map_block(map_tree, logical, &physical, &map_length, &dev);
581         BUG_ON(map_length < length);
582         bio->bi_sector = physical >> 9;
583         bio->bi_bdev = dev->bdev;
584         submit_bio(rw, bio);
585         return 0;
586 }
587
588 struct btrfs_device *btrfs_find_device(struct btrfs_root *root, u64 devid)
589 {
590         struct btrfs_device *dev;
591         struct list_head *cur = root->fs_info->devices.next;
592         struct list_head *head = &root->fs_info->devices;
593
594         while(cur != head) {
595                 dev = list_entry(cur, struct btrfs_device, dev_list);
596                 if (dev->devid == devid)
597                         return dev;
598                 cur = cur->next;
599         }
600         return NULL;
601 }
602
603 static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key,
604                           struct extent_buffer *leaf,
605                           struct btrfs_chunk *chunk)
606 {
607         struct btrfs_mapping_tree *map_tree = &root->fs_info->mapping_tree;
608         struct map_lookup *map;
609         struct extent_map *em;
610         u64 logical;
611         u64 length;
612         u64 devid;
613         int ret;
614
615         logical = key->objectid;
616         length = key->offset;
617         spin_lock(&map_tree->map_tree.lock);
618         em = lookup_extent_mapping(&map_tree->map_tree, logical, 1);
619
620         /* already mapped? */
621         if (em && em->start <= logical && em->start + em->len > logical) {
622                 free_extent_map(em);
623                 spin_unlock(&map_tree->map_tree.lock);
624                 return 0;
625         } else if (em) {
626                 free_extent_map(em);
627         }
628         spin_unlock(&map_tree->map_tree.lock);
629
630         map = kzalloc(sizeof(*map), GFP_NOFS);
631         if (!map)
632                 return -ENOMEM;
633
634         em = alloc_extent_map(GFP_NOFS);
635         if (!em)
636                 return -ENOMEM;
637         map = kmalloc(sizeof(*map), GFP_NOFS);
638         if (!map) {
639                 free_extent_map(em);
640                 return -ENOMEM;
641         }
642
643         em->bdev = (struct block_device *)map;
644         em->start = logical;
645         em->len = length;
646         em->block_start = 0;
647
648         map->physical = btrfs_stripe_offset_nr(leaf, chunk, 0);
649         devid = btrfs_stripe_devid_nr(leaf, chunk, 0);
650         map->dev = btrfs_find_device(root, devid);
651         if (!map->dev) {
652                 kfree(map);
653                 free_extent_map(em);
654                 return -EIO;
655         }
656
657         spin_lock(&map_tree->map_tree.lock);
658         ret = add_extent_mapping(&map_tree->map_tree, em);
659         BUG_ON(ret);
660         spin_unlock(&map_tree->map_tree.lock);
661         free_extent_map(em);
662
663         return 0;
664 }
665
666 static int fill_device_from_item(struct extent_buffer *leaf,
667                                  struct btrfs_dev_item *dev_item,
668                                  struct btrfs_device *device)
669 {
670         unsigned long ptr;
671
672         device->devid = btrfs_device_id(leaf, dev_item);
673         device->total_bytes = btrfs_device_total_bytes(leaf, dev_item);
674         device->bytes_used = btrfs_device_bytes_used(leaf, dev_item);
675         device->type = btrfs_device_type(leaf, dev_item);
676         device->io_align = btrfs_device_io_align(leaf, dev_item);
677         device->io_width = btrfs_device_io_width(leaf, dev_item);
678         device->sector_size = btrfs_device_sector_size(leaf, dev_item);
679
680         ptr = (unsigned long)btrfs_device_uuid(dev_item);
681         read_extent_buffer(leaf, device->uuid, ptr, BTRFS_DEV_UUID_SIZE);
682
683         return 0;
684 }
685
686 static int read_one_dev(struct btrfs_root *root,
687                         struct extent_buffer *leaf,
688                         struct btrfs_dev_item *dev_item)
689 {
690         struct btrfs_device *device;
691         u64 devid;
692         int ret;
693
694         devid = btrfs_device_id(leaf, dev_item);
695         device = btrfs_find_device(root, devid);
696         if (!device) {
697                 device = kmalloc(sizeof(*device), GFP_NOFS);
698                 if (!device)
699                         return -ENOMEM;
700                 list_add(&device->dev_list, &root->fs_info->devices);
701         }
702
703         fill_device_from_item(leaf, dev_item, device);
704         device->dev_root = root->fs_info->dev_root;
705         device->bdev = root->fs_info->sb->s_bdev;
706         ret = 0;
707 #if 0
708         ret = btrfs_open_device(device);
709         if (ret) {
710                 kfree(device);
711         }
712 #endif
713         return ret;
714 }
715
716 int btrfs_read_super_device(struct btrfs_root *root, struct extent_buffer *buf)
717 {
718         struct btrfs_dev_item *dev_item;
719
720         dev_item = (struct btrfs_dev_item *)offsetof(struct btrfs_super_block,
721                                                      dev_item);
722         return read_one_dev(root, buf, dev_item);
723 }
724
725 int btrfs_read_sys_array(struct btrfs_root *root)
726 {
727         struct btrfs_super_block *super_copy = &root->fs_info->super_copy;
728         struct extent_buffer *sb = root->fs_info->sb_buffer;
729         struct btrfs_disk_key *disk_key;
730         struct btrfs_chunk *chunk;
731         struct btrfs_key key;
732         u32 num_stripes;
733         u32 array_size;
734         u32 len = 0;
735         u8 *ptr;
736         unsigned long sb_ptr;
737         u32 cur;
738         int ret;
739
740         array_size = btrfs_super_sys_array_size(super_copy);
741
742         /*
743          * we do this loop twice, once for the device items and
744          * once for all of the chunks.  This way there are device
745          * structs filled in for every chunk
746          */
747         ptr = super_copy->sys_chunk_array;
748         sb_ptr = offsetof(struct btrfs_super_block, sys_chunk_array);
749         cur = 0;
750
751         while (cur < array_size) {
752                 disk_key = (struct btrfs_disk_key *)ptr;
753                 btrfs_disk_key_to_cpu(&key, disk_key);
754
755                 len = sizeof(*disk_key);
756                 ptr += len;
757                 sb_ptr += len;
758                 cur += len;
759
760                 if (key.type == BTRFS_CHUNK_ITEM_KEY) {
761                         chunk = (struct btrfs_chunk *)sb_ptr;
762                         ret = read_one_chunk(root, &key, sb, chunk);
763                         BUG_ON(ret);
764                         num_stripes = btrfs_chunk_num_stripes(sb, chunk);
765                         len = btrfs_chunk_item_size(num_stripes);
766                 } else {
767                         BUG();
768                 }
769                 ptr += len;
770                 sb_ptr += len;
771                 cur += len;
772         }
773         return 0;
774 }
775
776 int btrfs_read_chunk_tree(struct btrfs_root *root)
777 {
778         struct btrfs_path *path;
779         struct extent_buffer *leaf;
780         struct btrfs_key key;
781         struct btrfs_key found_key;
782         int ret;
783         int slot;
784
785         root = root->fs_info->chunk_root;
786
787         path = btrfs_alloc_path();
788         if (!path)
789                 return -ENOMEM;
790
791         /* first we search for all of the device items, and then we
792          * read in all of the chunk items.  This way we can create chunk
793          * mappings that reference all of the devices that are afound
794          */
795         key.objectid = BTRFS_DEV_ITEMS_OBJECTID;
796         key.offset = 0;
797         key.type = 0;
798 again:
799         ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
800         while(1) {
801                 leaf = path->nodes[0];
802                 slot = path->slots[0];
803                 if (slot >= btrfs_header_nritems(leaf)) {
804                         ret = btrfs_next_leaf(root, path);
805                         if (ret == 0)
806                                 continue;
807                         if (ret < 0)
808                                 goto error;
809                         break;
810                 }
811                 btrfs_item_key_to_cpu(leaf, &found_key, slot);
812                 if (key.objectid == BTRFS_DEV_ITEMS_OBJECTID) {
813                         if (found_key.objectid != BTRFS_DEV_ITEMS_OBJECTID)
814                                 break;
815                         if (found_key.type == BTRFS_DEV_ITEM_KEY) {
816                                 struct btrfs_dev_item *dev_item;
817                                 dev_item = btrfs_item_ptr(leaf, slot,
818                                                   struct btrfs_dev_item);
819                                 ret = read_one_dev(root, leaf, dev_item);
820                                 BUG_ON(ret);
821                         }
822                 } else if (found_key.type == BTRFS_CHUNK_ITEM_KEY) {
823                         struct btrfs_chunk *chunk;
824                         chunk = btrfs_item_ptr(leaf, slot, struct btrfs_chunk);
825                         ret = read_one_chunk(root, &found_key, leaf, chunk);
826                 }
827                 path->slots[0]++;
828         }
829         if (key.objectid == BTRFS_DEV_ITEMS_OBJECTID) {
830                 key.objectid = 0;
831                 btrfs_release_path(root, path);
832                 goto again;
833         }
834
835         btrfs_free_path(path);
836         ret = 0;
837 error:
838         return ret;
839 }
840