Write all super blocks during commit
[platform/upstream/btrfs-progs.git] / utils.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
19 #define _XOPEN_SOURCE 600
20 #define __USE_XOPEN2K
21 #include <stdio.h>
22 #include <stdlib.h>
23 #ifndef __CHECKER__
24 #include <sys/ioctl.h>
25 #include <sys/mount.h>
26 #endif
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <uuid/uuid.h>
30 #include <dirent.h>
31 #include <fcntl.h>
32 #include <unistd.h>
33 #include <mntent.h>
34 #include "kerncompat.h"
35 #include "radix-tree.h"
36 #include "ctree.h"
37 #include "disk-io.h"
38 #include "transaction.h"
39 #include "crc32c.h"
40 #include "utils.h"
41 #include "volumes.h"
42 #include "ioctl.h"
43
44 #ifdef __CHECKER__
45 #define BLKGETSIZE64 0
46 static inline int ioctl(int fd, int define, u64 *size) { return 0; }
47 #endif
48
49 static u64 reference_root_table[6] = {
50         [1] =   BTRFS_ROOT_TREE_OBJECTID,
51         [2] =   BTRFS_EXTENT_TREE_OBJECTID,
52         [3] =   BTRFS_CHUNK_TREE_OBJECTID,
53         [4] =   BTRFS_DEV_TREE_OBJECTID,
54         [5] =   BTRFS_FS_TREE_OBJECTID,
55 };
56
57 int make_btrfs(int fd, char *device_name,
58                u64 blocks[6], u64 num_bytes, u32 nodesize,
59                u32 leafsize, u32 sectorsize, u32 stripesize)
60 {
61         struct btrfs_super_block super;
62         struct extent_buffer *buf;
63         struct btrfs_root_item root_item;
64         struct btrfs_disk_key disk_key;
65         struct btrfs_extent_ref *extent_ref;
66         struct btrfs_extent_item *extent_item;
67         struct btrfs_inode_item *inode_item;
68         struct btrfs_chunk *chunk;
69         struct btrfs_dev_item *dev_item;
70         struct btrfs_dev_extent *dev_extent;
71         u8 *ptr;
72         int i;
73         int ret;
74         u32 itemoff;
75         u32 nritems = 0;
76         u64 hash;
77         u64 first_free;
78         u64 ref_gen;
79         u64 ref_root;
80         u32 array_size;
81         u32 item_size;
82
83         first_free = BTRFS_SUPER_INFO_OFFSET + sectorsize * 2 - 1;
84         first_free &= ~((u64)sectorsize - 1);
85
86         num_bytes = (num_bytes / sectorsize) * sectorsize;
87         uuid_generate(super.fsid);
88         btrfs_set_super_bytenr(&super, blocks[0]);
89         btrfs_set_super_num_devices(&super, 1);
90         strncpy((char *)&super.magic, BTRFS_MAGIC, sizeof(super.magic));
91         btrfs_set_super_generation(&super, 1);
92         btrfs_set_super_root(&super, blocks[1]);
93         btrfs_set_super_chunk_root(&super, blocks[3]);
94         btrfs_set_super_total_bytes(&super, num_bytes);
95         btrfs_set_super_bytes_used(&super, first_free + 5 * leafsize);
96         btrfs_set_super_root_dir(&super, 0);
97         btrfs_set_super_sectorsize(&super, sectorsize);
98         btrfs_set_super_leafsize(&super, leafsize);
99         btrfs_set_super_nodesize(&super, nodesize);
100         btrfs_set_super_stripesize(&super, stripesize);
101         btrfs_set_super_root_level(&super, 0);
102         btrfs_set_super_chunk_root_level(&super, 0);
103         btrfs_set_super_sys_array_size(&super, 0);
104
105         buf = malloc(sizeof(*buf) + max(sectorsize, leafsize));
106
107         /* create the tree of root objects */
108         memset(buf->data, 0, leafsize);
109         buf->len = leafsize;
110         btrfs_set_header_bytenr(buf, blocks[1]);
111         btrfs_set_header_nritems(buf, 3);
112         btrfs_set_header_generation(buf, 1);
113         btrfs_set_header_owner(buf, BTRFS_ROOT_TREE_OBJECTID);
114         write_extent_buffer(buf, super.fsid, (unsigned long)
115                             btrfs_header_fsid(buf), BTRFS_FSID_SIZE);
116
117         /* create the items for the root tree */
118         memset(&root_item, 0, sizeof(root_item));
119         inode_item = &root_item.inode;
120         btrfs_set_stack_inode_generation(inode_item, 1);
121         btrfs_set_stack_inode_size(inode_item, 3);
122         btrfs_set_stack_inode_nlink(inode_item, 1);
123         btrfs_set_stack_inode_nblocks(inode_item, 1);
124         btrfs_set_stack_inode_mode(inode_item, S_IFDIR | 0755);
125         btrfs_set_root_refs(&root_item, 1);
126         btrfs_set_root_used(&root_item, leafsize);
127
128         memset(&disk_key, 0, sizeof(disk_key));
129         btrfs_set_disk_key_type(&disk_key, BTRFS_ROOT_ITEM_KEY);
130         btrfs_set_disk_key_offset(&disk_key, 0);
131         nritems = 0;
132
133         itemoff = __BTRFS_LEAF_DATA_SIZE(leafsize) - sizeof(root_item);
134         btrfs_set_root_bytenr(&root_item, blocks[2]);
135         btrfs_set_disk_key_objectid(&disk_key, BTRFS_EXTENT_TREE_OBJECTID);
136         btrfs_set_item_key(buf, &disk_key, nritems);
137         btrfs_set_item_offset(buf, btrfs_item_nr(buf, nritems), itemoff);
138         btrfs_set_item_size(buf, btrfs_item_nr(buf, nritems),
139                             sizeof(root_item));
140         write_extent_buffer(buf, &root_item, btrfs_item_ptr_offset(buf,
141                             nritems), sizeof(root_item));
142         nritems++;
143
144         itemoff = itemoff - sizeof(root_item);
145         btrfs_set_root_bytenr(&root_item, blocks[4]);
146         btrfs_set_disk_key_objectid(&disk_key, BTRFS_DEV_TREE_OBJECTID);
147         btrfs_set_item_key(buf, &disk_key, nritems);
148         btrfs_set_item_offset(buf, btrfs_item_nr(buf, nritems), itemoff);
149         btrfs_set_item_size(buf, btrfs_item_nr(buf, nritems),
150                             sizeof(root_item));
151         write_extent_buffer(buf, &root_item,
152                             btrfs_item_ptr_offset(buf, nritems),
153                             sizeof(root_item));
154         nritems++;
155
156         itemoff = itemoff - sizeof(root_item);
157         btrfs_set_root_bytenr(&root_item, blocks[5]);
158         btrfs_set_disk_key_objectid(&disk_key, BTRFS_FS_TREE_OBJECTID);
159         btrfs_set_item_key(buf, &disk_key, nritems);
160         btrfs_set_item_offset(buf, btrfs_item_nr(buf, nritems), itemoff);
161         btrfs_set_item_size(buf, btrfs_item_nr(buf, nritems),
162                             sizeof(root_item));
163         write_extent_buffer(buf, &root_item,
164                             btrfs_item_ptr_offset(buf, nritems),
165                             sizeof(root_item));
166         nritems++;
167
168
169         csum_tree_block(NULL, buf, 0);
170         ret = pwrite(fd, buf->data, leafsize, blocks[1]);
171         BUG_ON(ret != leafsize);
172
173         /* create the items for the extent tree */
174         nritems = 0;
175         itemoff = __BTRFS_LEAF_DATA_SIZE(leafsize) -
176                   sizeof(struct btrfs_extent_item);
177         btrfs_set_disk_key_objectid(&disk_key, 0);
178         btrfs_set_disk_key_offset(&disk_key, first_free);
179         btrfs_set_disk_key_type(&disk_key, BTRFS_EXTENT_ITEM_KEY);
180         btrfs_set_item_key(buf, &disk_key, nritems);
181         btrfs_set_item_offset(buf, btrfs_item_nr(buf, nritems), itemoff);
182         btrfs_set_item_size(buf, btrfs_item_nr(buf,  nritems),
183                             sizeof(struct btrfs_extent_item));
184         extent_item = btrfs_item_ptr(buf, nritems, struct btrfs_extent_item);
185         btrfs_set_extent_refs(buf, extent_item, 1);
186         nritems++;
187         for (i = 1; i < 6; i++) {
188                 BUG_ON(blocks[i] < first_free);
189                 BUG_ON(blocks[i] < blocks[i - 1]);
190
191                 /* create extent item */
192                 itemoff = itemoff - sizeof(struct btrfs_extent_item);
193                 btrfs_set_disk_key_objectid(&disk_key, blocks[i]);
194                 btrfs_set_disk_key_offset(&disk_key, leafsize);
195                 btrfs_set_disk_key_type(&disk_key, BTRFS_EXTENT_ITEM_KEY);
196                 btrfs_set_item_key(buf, &disk_key, nritems);
197                 btrfs_set_item_offset(buf, btrfs_item_nr(buf, nritems),
198                                       itemoff);
199                 btrfs_set_item_size(buf, btrfs_item_nr(buf, nritems),
200                                     sizeof(struct btrfs_extent_item));
201                 extent_item = btrfs_item_ptr(buf, nritems,
202                                              struct btrfs_extent_item);
203                 btrfs_set_extent_refs(buf, extent_item, 1);
204                 nritems++;
205
206                 /* create extent ref */
207                 ref_root = reference_root_table[i];
208                 if (ref_root == BTRFS_FS_TREE_OBJECTID)
209                         ref_gen = 1;
210                 else
211                         ref_gen = 0;
212
213                 hash = btrfs_hash_extent_ref(ref_root, ref_gen, 0, 0);
214                 itemoff = itemoff - sizeof(struct btrfs_extent_ref);
215                 btrfs_set_disk_key_objectid(&disk_key, blocks[i]);
216                 btrfs_set_disk_key_offset(&disk_key, hash);
217                 btrfs_set_disk_key_type(&disk_key, BTRFS_EXTENT_REF_KEY);
218                 btrfs_set_item_key(buf, &disk_key, nritems);
219                 btrfs_set_item_offset(buf, btrfs_item_nr(buf, nritems),
220                                       itemoff);
221                 btrfs_set_item_size(buf, btrfs_item_nr(buf, nritems),
222                                     sizeof(struct btrfs_extent_ref));
223                 extent_ref = btrfs_item_ptr(buf, nritems,
224                                              struct btrfs_extent_ref);
225                 btrfs_set_ref_root(buf, extent_ref, ref_root);
226                 btrfs_set_ref_generation(buf, extent_ref, ref_gen);
227                 btrfs_set_ref_objectid(buf, extent_ref, 0);
228                 btrfs_set_ref_offset(buf, extent_ref, 0);
229                 nritems++;
230         }
231         btrfs_set_header_bytenr(buf, blocks[2]);
232         btrfs_set_header_owner(buf, BTRFS_EXTENT_TREE_OBJECTID);
233         btrfs_set_header_nritems(buf, nritems);
234         csum_tree_block(NULL, buf, 0);
235         ret = pwrite(fd, buf->data, leafsize, blocks[2]);
236         BUG_ON(ret != leafsize);
237
238         /* create the chunk tree */
239         nritems = 0;
240         item_size = btrfs_chunk_item_size(1);
241         itemoff = __BTRFS_LEAF_DATA_SIZE(leafsize) - item_size;
242
243         /* first we have chunk 0 */
244         btrfs_set_disk_key_objectid(&disk_key, 0);
245         btrfs_set_disk_key_offset(&disk_key, BTRFS_MKFS_SYSTEM_GROUP_SIZE);
246         btrfs_set_disk_key_type(&disk_key, BTRFS_CHUNK_ITEM_KEY);
247         btrfs_set_item_key(buf, &disk_key, nritems);
248         btrfs_set_item_offset(buf, btrfs_item_nr(buf, nritems), itemoff);
249         btrfs_set_item_size(buf, btrfs_item_nr(buf,  nritems), item_size);
250
251         chunk = btrfs_item_ptr(buf, nritems, struct btrfs_chunk);
252         btrfs_set_chunk_owner(buf, chunk, BTRFS_EXTENT_TREE_OBJECTID);
253         btrfs_set_chunk_stripe_len(buf, chunk, 64 * 1024);
254         btrfs_set_chunk_type(buf, chunk, BTRFS_BLOCK_GROUP_SYSTEM);
255         btrfs_set_chunk_io_align(buf, chunk, sectorsize);
256         btrfs_set_chunk_io_width(buf, chunk, sectorsize);
257         btrfs_set_chunk_sector_size(buf, chunk, sectorsize);
258         btrfs_set_chunk_num_stripes(buf, chunk, 1);
259         btrfs_set_stripe_devid_nr(buf, chunk, 0, 1);
260         btrfs_set_stripe_offset_nr(buf, chunk, 0, 0);
261
262         /* copy the key for the chunk to the system array */
263         ptr = super.sys_chunk_array;
264         array_size = sizeof(disk_key);
265
266         memcpy(ptr, &disk_key, sizeof(disk_key));
267         ptr += sizeof(disk_key);
268
269         /* copy the chunk to the system array */
270         read_extent_buffer(buf, ptr, (unsigned long)chunk, item_size);
271         array_size += item_size;
272         ptr += item_size;
273         btrfs_set_super_sys_array_size(&super, array_size);
274
275         /* then device 1 (there is no device 0) */
276         nritems++;
277         item_size = sizeof(*dev_item);
278         itemoff = itemoff - item_size;
279         btrfs_set_disk_key_objectid(&disk_key, BTRFS_DEV_ITEMS_OBJECTID);
280         btrfs_set_disk_key_offset(&disk_key, 1);
281         btrfs_set_disk_key_type(&disk_key, BTRFS_DEV_ITEM_KEY);
282         btrfs_set_item_key(buf, &disk_key, nritems);
283         btrfs_set_item_offset(buf, btrfs_item_nr(buf, nritems), itemoff);
284         btrfs_set_item_size(buf, btrfs_item_nr(buf, nritems), item_size);
285
286         dev_item = btrfs_item_ptr(buf, nritems, struct btrfs_dev_item);
287         btrfs_set_device_id(buf, dev_item, 1);
288         btrfs_set_device_total_bytes(buf, dev_item, num_bytes);
289         btrfs_set_device_bytes_used(buf, dev_item,
290                                     BTRFS_MKFS_SYSTEM_GROUP_SIZE);
291         btrfs_set_device_io_align(buf, dev_item, sectorsize);
292         btrfs_set_device_io_width(buf, dev_item, sectorsize);
293         btrfs_set_device_sector_size(buf, dev_item, sectorsize);
294         btrfs_set_device_type(buf, dev_item, 0);
295         nritems++;
296
297         uuid_generate(super.dev_item.uuid);
298
299         write_extent_buffer(buf, super.dev_item.uuid,
300                             (unsigned long)btrfs_device_uuid(dev_item),
301                             BTRFS_DEV_UUID_SIZE);
302         read_extent_buffer(buf, &super.dev_item, (unsigned long)dev_item,
303                            sizeof(*dev_item));
304
305         btrfs_set_header_bytenr(buf, blocks[3]);
306         btrfs_set_header_owner(buf, BTRFS_CHUNK_TREE_OBJECTID);
307         btrfs_set_header_nritems(buf, nritems);
308         csum_tree_block(NULL, buf, 0);
309         ret = pwrite(fd, buf->data, leafsize, blocks[3]);
310
311         /* create the device tree */
312         nritems = 0;
313         itemoff = __BTRFS_LEAF_DATA_SIZE(leafsize) -
314                 sizeof(struct btrfs_dev_extent);
315
316         btrfs_set_disk_key_objectid(&disk_key, 1);
317         btrfs_set_disk_key_offset(&disk_key, 0);
318         btrfs_set_disk_key_type(&disk_key, BTRFS_DEV_EXTENT_KEY);
319         btrfs_set_item_key(buf, &disk_key, nritems);
320         btrfs_set_item_offset(buf, btrfs_item_nr(buf, nritems), itemoff);
321         btrfs_set_item_size(buf, btrfs_item_nr(buf,  nritems),
322                             sizeof(struct btrfs_dev_extent));
323         dev_extent = btrfs_item_ptr(buf, nritems, struct btrfs_dev_extent);
324         btrfs_set_dev_extent_owner(buf, dev_extent, 0);
325         btrfs_set_dev_extent_length(buf, dev_extent,
326                                     BTRFS_MKFS_SYSTEM_GROUP_SIZE);
327         nritems++;
328
329         btrfs_set_header_bytenr(buf, blocks[4]);
330         btrfs_set_header_owner(buf, BTRFS_DEV_TREE_OBJECTID);
331         btrfs_set_header_nritems(buf, nritems);
332         csum_tree_block(NULL, buf, 0);
333         ret = pwrite(fd, buf->data, leafsize, blocks[4]);
334
335         /* finally create the FS root */
336         btrfs_set_header_bytenr(buf, blocks[5]);
337         btrfs_set_header_owner(buf, BTRFS_FS_TREE_OBJECTID);
338         btrfs_set_header_nritems(buf, 0);
339         csum_tree_block(NULL, buf, 0);
340         ret = pwrite(fd, buf->data, leafsize, blocks[5]);
341         BUG_ON(ret != leafsize);
342
343         /* and write out the super block */
344         BUG_ON(sizeof(super) > sectorsize);
345         memset(buf->data, 0, sectorsize);
346         memcpy(buf->data, &super, sizeof(super));
347         buf->len = sectorsize;
348         csum_tree_block(NULL, buf, 0);
349         ret = pwrite(fd, buf->data, sectorsize, blocks[0]);
350         BUG_ON(ret != sectorsize);
351
352
353         free(buf);
354         return 0;
355 }
356
357 static u64 device_size(int fd, struct stat *st)
358 {
359         u64 size;
360         if (S_ISREG(st->st_mode)) {
361                 return st->st_size;
362         }
363         if (!S_ISBLK(st->st_mode)) {
364                 return 0;
365         }
366         if (ioctl(fd, BLKGETSIZE64, &size) >= 0) {
367                 return size;
368         }
369         return 0;
370 }
371
372 static int zero_blocks(int fd, off_t start, size_t len)
373 {
374         char *buf = malloc(len);
375         int ret = 0;
376         ssize_t written;
377
378         if (!buf)
379                 return -ENOMEM;
380         memset(buf, 0, len);
381         written = pwrite(fd, buf, len, start);
382         if (written != len)
383                 ret = -EIO;
384         free(buf);
385         return ret;
386 }
387
388 static int zero_dev_start(int fd)
389 {
390         off_t start = 0;
391         size_t len = 2 * 1024 * 1024;
392
393 #ifdef __sparc__
394         /* don't overwrite the disk labels on sparc */
395         start = 1024;
396         len -= 1024;
397 #endif
398         return zero_blocks(fd, start, len);
399 }
400
401 static int zero_dev_end(int fd, u64 dev_size)
402 {
403         size_t len = 2 * 1024 * 1024;
404         off_t start = dev_size - len;
405
406         return zero_blocks(fd, start, len);
407 }
408
409 int btrfs_add_to_fsid(struct btrfs_trans_handle *trans,
410                       struct btrfs_root *root, int fd, u64 block_count,
411                       u32 io_width, u32 io_align, u32 sectorsize)
412 {
413         struct btrfs_super_block *disk_super;
414         struct btrfs_super_block *super = &root->fs_info->super_copy;
415         struct btrfs_device *device;
416         struct btrfs_dev_item *dev_item;
417         char *buf;
418         u64 total_bytes;
419         u64 num_devs;
420         int ret;
421
422         device = kmalloc(sizeof(*device), GFP_NOFS);
423         if (!device)
424                 return -ENOMEM;
425         buf = kmalloc(sectorsize, GFP_NOFS);
426         if (!buf) {
427                 kfree(device);
428                 return -ENOMEM;
429         }
430         BUG_ON(sizeof(*disk_super) > sectorsize);
431         memset(buf, 0, sectorsize);
432
433         disk_super = (struct btrfs_super_block *)buf;
434         dev_item = &disk_super->dev_item;
435
436         uuid_generate(device->uuid);
437         device->devid = 0;
438         device->type = 0;
439         device->io_width = io_width;
440         device->io_align = io_align;
441         device->sector_size = sectorsize;
442         device->fd = fd;
443         device->total_bytes = block_count;
444         device->bytes_used = 0;
445         device->total_ios = 0;
446         device->dev_root = root->fs_info->dev_root;
447
448         ret = btrfs_add_device(trans, root, device);
449         BUG_ON(ret);
450
451         total_bytes = btrfs_super_total_bytes(super) + block_count;
452         btrfs_set_super_total_bytes(super, total_bytes);
453
454         num_devs = btrfs_super_num_devices(super) + 1;
455         btrfs_set_super_num_devices(super, num_devs);
456
457         memcpy(disk_super, super, sizeof(*disk_super));
458
459         printf("adding device id %llu\n", (unsigned long long)device->devid);
460         btrfs_set_stack_device_id(dev_item, device->devid);
461         btrfs_set_stack_device_type(dev_item, device->type);
462         btrfs_set_stack_device_io_align(dev_item, device->io_align);
463         btrfs_set_stack_device_io_width(dev_item, device->io_width);
464         btrfs_set_stack_device_sector_size(dev_item, device->sector_size);
465         btrfs_set_stack_device_total_bytes(dev_item, device->total_bytes);
466         btrfs_set_stack_device_bytes_used(dev_item, device->bytes_used);
467         memcpy(&dev_item->uuid, device->uuid, BTRFS_DEV_UUID_SIZE);
468
469         ret = pwrite(fd, buf, sectorsize, BTRFS_SUPER_INFO_OFFSET);
470         BUG_ON(ret != sectorsize);
471
472         kfree(buf);
473         list_add(&device->dev_list, &root->fs_info->fs_devices->devices);
474         ret = btrfs_bootstrap_super_map(&root->fs_info->mapping_tree,
475                                         root->fs_info->fs_devices);
476         BUG_ON(ret);
477         return 0;
478 }
479
480 int btrfs_prepare_device(int fd, char *file, int zero_end, u64 *block_count_ret)
481 {
482         u64 block_count;
483         struct stat st;
484         int ret;
485
486         ret = fstat(fd, &st);
487         if (ret < 0) {
488                 fprintf(stderr, "unable to stat %s\n", file);
489                 exit(1);
490         }
491
492         block_count = device_size(fd, &st);
493         if (block_count == 0) {
494                 fprintf(stderr, "unable to find %s size\n", file);
495                 exit(1);
496         }
497         zero_end = 1;
498
499         if (block_count < 256 * 1024 * 1024) {
500                 fprintf(stderr, "device %s is too small\n", file);
501                 exit(1);
502         }
503         ret = zero_dev_start(fd);
504         if (ret) {
505                 fprintf(stderr, "failed to zero device start %d\n", ret);
506                 exit(1);
507         }
508
509         if (zero_end) {
510                 ret = zero_dev_end(fd, block_count);
511                 if (ret) {
512                         fprintf(stderr, "failed to zero device end %d\n", ret);
513                         exit(1);
514                 }
515         }
516         *block_count_ret = block_count;
517         return 0;
518 }
519
520 int btrfs_make_root_dir(struct btrfs_trans_handle *trans,
521                         struct btrfs_root *root, u64 objectid)
522 {
523         int ret;
524         struct btrfs_inode_item inode_item;
525
526         memset(&inode_item, 0, sizeof(inode_item));
527         btrfs_set_stack_inode_generation(&inode_item, trans->transid);
528         btrfs_set_stack_inode_size(&inode_item, 0);
529         btrfs_set_stack_inode_nlink(&inode_item, 1);
530         btrfs_set_stack_inode_nblocks(&inode_item, 1);
531         btrfs_set_stack_inode_mode(&inode_item, S_IFDIR | 0555);
532
533         if (root->fs_info->tree_root == root)
534                 btrfs_set_super_root_dir(&root->fs_info->super_copy, objectid);
535
536         ret = btrfs_insert_inode(trans, root, objectid, &inode_item);
537         if (ret)
538                 goto error;
539
540         ret = btrfs_insert_inode_ref(trans, root, "..", 2, objectid, objectid);
541         if (ret)
542                 goto error;
543
544         btrfs_set_root_dirid(&root->root_item, objectid);
545         ret = 0;
546 error:
547         return ret;
548 }
549
550 /*
551  * returns 1 if the device was mounted, < 0 on error or 0 if everything
552  * is safe to continue.  TODO, this should also scan multi-device filesystems
553  */
554 int check_mounted(char *file)
555 {
556         struct mntent *mnt;
557         struct stat st_buf;
558         dev_t file_dev = 0;
559         dev_t file_rdev = 0;
560         ino_t file_ino = 0;
561         FILE *f;
562         int ret = 0;
563
564         if ((f = setmntent ("/proc/mounts", "r")) == NULL)
565                 return -errno;
566
567         if (stat(file, &st_buf) < 0) {
568                 return -errno;
569         } else {
570                 if (S_ISBLK(st_buf.st_mode)) {
571                         file_rdev = st_buf.st_rdev;
572                 } else {
573                         file_dev = st_buf.st_dev;
574                         file_ino = st_buf.st_ino;
575                 }
576         }
577
578         while ((mnt = getmntent (f)) != NULL) {
579                 if (strcmp(file, mnt->mnt_fsname) == 0)
580                         break;
581
582                 if (stat(mnt->mnt_fsname, &st_buf) == 0) {
583                         if (S_ISBLK(st_buf.st_mode)) {
584                                 if (file_rdev && (file_rdev == st_buf.st_rdev))
585                                         break;
586                         } else if (file_dev && ((file_dev == st_buf.st_dev) &&
587                                                 (file_ino == st_buf.st_ino))) {
588                                         break;
589                         }
590                 }
591         }
592
593         if (mnt) {
594                 /* found an entry in mnt table */
595                 ret = 1;
596         }
597
598         endmntent (f);
599         return ret;
600 }
601
602 struct pending_dir {
603         struct list_head list;
604         char name[256];
605 };
606
607 int btrfs_register_one_device(char *fname)
608 {
609         struct btrfs_ioctl_vol_args args;
610         int fd;
611         int ret;
612
613         fd = open("/dev/btrfs-control", O_RDONLY);
614         if (fd < 0)
615                 return -EINVAL;
616         strcpy(args.name, fname);
617         ret = ioctl(fd, BTRFS_IOC_SCAN_DEV, &args);
618         close(fd);
619         return ret;
620 }
621
622 int btrfs_scan_one_dir(char *dirname, int run_ioctl)
623 {
624         DIR *dirp;
625         struct dirent *dirent;
626         struct pending_dir *pending;
627         struct stat st;
628         int ret;
629         int fd;
630         int dirname_len;
631         int pathlen;
632         char *fullpath;
633         struct list_head pending_list;
634         struct btrfs_fs_devices *tmp_devices;
635         u64 num_devices;
636
637         INIT_LIST_HEAD(&pending_list);
638
639         pending = malloc(sizeof(*pending));
640         if (!pending)
641                 return -ENOMEM;
642         strcpy(pending->name, dirname);
643
644 again:
645         dirname_len = strlen(pending->name);
646         pathlen = 1024;
647         fullpath = malloc(pathlen);
648         dirname = pending->name;
649
650         if (!fullpath) {
651                 ret = -ENOMEM;
652                 goto fail;
653         }
654         dirp = opendir(dirname);
655         if (!dirp) {
656                 fprintf(stderr, "Unable to open /sys/block for scanning\n");
657                 return -ENOENT;
658         }
659         while(1) {
660                 dirent = readdir(dirp);
661                 if (!dirent)
662                         break;
663                 if (dirent->d_name[0] == '.')
664                         continue;
665                 if (dirname_len + strlen(dirent->d_name) + 2 > pathlen) {
666                         ret = -EFAULT;
667                         goto fail;
668                 }
669                 snprintf(fullpath, pathlen, "%s/%s", dirname, dirent->d_name);
670                 ret = lstat(fullpath, &st);
671                 if (ret < 0) {
672                         fprintf(stderr, "failed to stat %s\n", fullpath);
673                         continue;
674                 }
675                 if (S_ISLNK(st.st_mode))
676                         continue;
677                 if (S_ISDIR(st.st_mode)) {
678                         struct pending_dir *next = malloc(sizeof(*next));
679                         if (!next) {
680                                 ret = -ENOMEM;
681                                 goto fail;
682                         }
683                         strcpy(next->name, fullpath);
684                         list_add_tail(&next->list, &pending_list);
685                 }
686                 if (!S_ISBLK(st.st_mode)) {
687                         continue;
688                 }
689                 fd = open(fullpath, O_RDONLY);
690                 if (fd < 0) {
691                         fprintf(stderr, "failed to read %s\n", fullpath);
692                         continue;
693                 }
694                 ret = btrfs_scan_one_device(fd, fullpath, &tmp_devices,
695                                             &num_devices,
696                                             BTRFS_SUPER_INFO_OFFSET);
697                 if (ret == 0 && run_ioctl > 0) {
698                         btrfs_register_one_device(fullpath);
699                 }
700                 close(fd);
701         }
702         if (!list_empty(&pending_list)) {
703                 free(pending);
704                 pending = list_entry(pending_list.next, struct pending_dir,
705                                      list);
706                 list_del(&pending->list);
707                 closedir(dirp);
708                 goto again;
709         }
710         ret = 0;
711 fail:
712         free(pending);
713         closedir(dirp);
714         return ret;
715 }
716
717 int btrfs_scan_for_fsid(struct btrfs_fs_devices *fs_devices, u64 total_devs,
718                         int run_ioctls)
719 {
720         return btrfs_scan_one_dir("/dev", run_ioctls);
721 }