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