Fix inode link count checks in btrfsck
[btrfs-progs-unstable.git] / utils.c
blobfd894f3bf3568dcee790568065570464e88f0e1f
1 /*
2 * Copyright (C) 2007 Oracle. All rights reserved.
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.
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.
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.
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 <linux/loop.h>
35 #include <linux/major.h>
36 #include <linux/kdev_t.h>
37 #include <limits.h>
38 #include "kerncompat.h"
39 #include "radix-tree.h"
40 #include "ctree.h"
41 #include "disk-io.h"
42 #include "transaction.h"
43 #include "crc32c.h"
44 #include "utils.h"
45 #include "volumes.h"
46 #include "ioctl.h"
48 #ifdef __CHECKER__
49 #define BLKGETSIZE64 0
50 static inline int ioctl(int fd, int define, u64 *size) { return 0; }
51 #endif
53 static u64 reference_root_table[] = {
54 [1] = BTRFS_ROOT_TREE_OBJECTID,
55 [2] = BTRFS_EXTENT_TREE_OBJECTID,
56 [3] = BTRFS_CHUNK_TREE_OBJECTID,
57 [4] = BTRFS_DEV_TREE_OBJECTID,
58 [5] = BTRFS_FS_TREE_OBJECTID,
59 [6] = BTRFS_CSUM_TREE_OBJECTID,
62 int make_btrfs(int fd, const char *device, const char *label,
63 u64 blocks[7], u64 num_bytes, u32 nodesize,
64 u32 leafsize, u32 sectorsize, u32 stripesize)
66 struct btrfs_super_block super;
67 struct extent_buffer *buf;
68 struct btrfs_root_item root_item;
69 struct btrfs_disk_key disk_key;
70 struct btrfs_extent_item *extent_item;
71 struct btrfs_inode_item *inode_item;
72 struct btrfs_chunk *chunk;
73 struct btrfs_dev_item *dev_item;
74 struct btrfs_dev_extent *dev_extent;
75 u8 chunk_tree_uuid[BTRFS_UUID_SIZE];
76 u8 *ptr;
77 int i;
78 int ret;
79 u32 itemoff;
80 u32 nritems = 0;
81 u64 first_free;
82 u64 ref_root;
83 u32 array_size;
84 u32 item_size;
86 first_free = BTRFS_SUPER_INFO_OFFSET + sectorsize * 2 - 1;
87 first_free &= ~((u64)sectorsize - 1);
89 memset(&super, 0, sizeof(super));
91 num_bytes = (num_bytes / sectorsize) * sectorsize;
92 uuid_generate(super.fsid);
93 uuid_generate(super.dev_item.uuid);
94 uuid_generate(chunk_tree_uuid);
96 btrfs_set_super_bytenr(&super, blocks[0]);
97 btrfs_set_super_num_devices(&super, 1);
98 strncpy((char *)&super.magic, BTRFS_MAGIC, sizeof(super.magic));
99 btrfs_set_super_generation(&super, 1);
100 btrfs_set_super_root(&super, blocks[1]);
101 btrfs_set_super_chunk_root(&super, blocks[3]);
102 btrfs_set_super_total_bytes(&super, num_bytes);
103 btrfs_set_super_bytes_used(&super, 6 * leafsize);
104 btrfs_set_super_sectorsize(&super, sectorsize);
105 btrfs_set_super_leafsize(&super, leafsize);
106 btrfs_set_super_nodesize(&super, nodesize);
107 btrfs_set_super_stripesize(&super, stripesize);
108 btrfs_set_super_csum_type(&super, BTRFS_CSUM_TYPE_CRC32);
109 btrfs_set_super_chunk_root_generation(&super, 1);
110 if (label)
111 strcpy(super.label, label);
113 buf = malloc(sizeof(*buf) + max(sectorsize, leafsize));
115 /* create the tree of root objects */
116 memset(buf->data, 0, leafsize);
117 buf->len = leafsize;
118 btrfs_set_header_bytenr(buf, blocks[1]);
119 btrfs_set_header_nritems(buf, 4);
120 btrfs_set_header_generation(buf, 1);
121 btrfs_set_header_backref_rev(buf, BTRFS_MIXED_BACKREF_REV);
122 btrfs_set_header_owner(buf, BTRFS_ROOT_TREE_OBJECTID);
123 write_extent_buffer(buf, super.fsid, (unsigned long)
124 btrfs_header_fsid(buf), BTRFS_FSID_SIZE);
126 write_extent_buffer(buf, chunk_tree_uuid, (unsigned long)
127 btrfs_header_chunk_tree_uuid(buf),
128 BTRFS_UUID_SIZE);
130 /* create the items for the root tree */
131 memset(&root_item, 0, sizeof(root_item));
132 inode_item = &root_item.inode;
133 btrfs_set_stack_inode_generation(inode_item, 1);
134 btrfs_set_stack_inode_size(inode_item, 3);
135 btrfs_set_stack_inode_nlink(inode_item, 1);
136 btrfs_set_stack_inode_nbytes(inode_item, leafsize);
137 btrfs_set_stack_inode_mode(inode_item, S_IFDIR | 0755);
138 btrfs_set_root_refs(&root_item, 1);
139 btrfs_set_root_used(&root_item, leafsize);
140 btrfs_set_root_generation(&root_item, 1);
142 memset(&disk_key, 0, sizeof(disk_key));
143 btrfs_set_disk_key_type(&disk_key, BTRFS_ROOT_ITEM_KEY);
144 btrfs_set_disk_key_offset(&disk_key, 0);
145 nritems = 0;
147 itemoff = __BTRFS_LEAF_DATA_SIZE(leafsize) - sizeof(root_item);
148 btrfs_set_root_bytenr(&root_item, blocks[2]);
149 btrfs_set_disk_key_objectid(&disk_key, BTRFS_EXTENT_TREE_OBJECTID);
150 btrfs_set_item_key(buf, &disk_key, nritems);
151 btrfs_set_item_offset(buf, btrfs_item_nr(buf, nritems), itemoff);
152 btrfs_set_item_size(buf, btrfs_item_nr(buf, nritems),
153 sizeof(root_item));
154 write_extent_buffer(buf, &root_item, btrfs_item_ptr_offset(buf,
155 nritems), sizeof(root_item));
156 nritems++;
158 itemoff = itemoff - sizeof(root_item);
159 btrfs_set_root_bytenr(&root_item, blocks[4]);
160 btrfs_set_disk_key_objectid(&disk_key, BTRFS_DEV_TREE_OBJECTID);
161 btrfs_set_item_key(buf, &disk_key, nritems);
162 btrfs_set_item_offset(buf, btrfs_item_nr(buf, nritems), itemoff);
163 btrfs_set_item_size(buf, btrfs_item_nr(buf, nritems),
164 sizeof(root_item));
165 write_extent_buffer(buf, &root_item,
166 btrfs_item_ptr_offset(buf, nritems),
167 sizeof(root_item));
168 nritems++;
170 itemoff = itemoff - sizeof(root_item);
171 btrfs_set_root_bytenr(&root_item, blocks[5]);
172 btrfs_set_disk_key_objectid(&disk_key, BTRFS_FS_TREE_OBJECTID);
173 btrfs_set_item_key(buf, &disk_key, nritems);
174 btrfs_set_item_offset(buf, btrfs_item_nr(buf, nritems), itemoff);
175 btrfs_set_item_size(buf, btrfs_item_nr(buf, nritems),
176 sizeof(root_item));
177 write_extent_buffer(buf, &root_item,
178 btrfs_item_ptr_offset(buf, nritems),
179 sizeof(root_item));
180 nritems++;
182 itemoff = itemoff - sizeof(root_item);
183 btrfs_set_root_bytenr(&root_item, blocks[6]);
184 btrfs_set_disk_key_objectid(&disk_key, BTRFS_CSUM_TREE_OBJECTID);
185 btrfs_set_item_key(buf, &disk_key, nritems);
186 btrfs_set_item_offset(buf, btrfs_item_nr(buf, nritems), itemoff);
187 btrfs_set_item_size(buf, btrfs_item_nr(buf, nritems),
188 sizeof(root_item));
189 write_extent_buffer(buf, &root_item,
190 btrfs_item_ptr_offset(buf, nritems),
191 sizeof(root_item));
192 nritems++;
195 csum_tree_block_size(buf, BTRFS_CRC32_SIZE, 0);
196 ret = pwrite(fd, buf->data, leafsize, blocks[1]);
197 BUG_ON(ret != leafsize);
199 /* create the items for the extent tree */
200 nritems = 0;
201 itemoff = __BTRFS_LEAF_DATA_SIZE(leafsize);
202 for (i = 1; i < 7; i++) {
203 BUG_ON(blocks[i] < first_free);
204 BUG_ON(blocks[i] < blocks[i - 1]);
206 /* create extent item */
207 itemoff -= sizeof(struct btrfs_extent_item) +
208 sizeof(struct btrfs_tree_block_info);
209 btrfs_set_disk_key_objectid(&disk_key, blocks[i]);
210 btrfs_set_disk_key_offset(&disk_key, leafsize);
211 btrfs_set_disk_key_type(&disk_key, BTRFS_EXTENT_ITEM_KEY);
212 btrfs_set_item_key(buf, &disk_key, nritems);
213 btrfs_set_item_offset(buf, btrfs_item_nr(buf, nritems),
214 itemoff);
215 btrfs_set_item_size(buf, btrfs_item_nr(buf, nritems),
216 sizeof(struct btrfs_extent_item) +
217 sizeof(struct btrfs_tree_block_info));
218 extent_item = btrfs_item_ptr(buf, nritems,
219 struct btrfs_extent_item);
220 btrfs_set_extent_refs(buf, extent_item, 1);
221 btrfs_set_extent_generation(buf, extent_item, 1);
222 btrfs_set_extent_flags(buf, extent_item,
223 BTRFS_EXTENT_FLAG_TREE_BLOCK);
224 nritems++;
226 /* create extent ref */
227 ref_root = reference_root_table[i];
228 btrfs_set_disk_key_objectid(&disk_key, blocks[i]);
229 btrfs_set_disk_key_offset(&disk_key, ref_root);
230 btrfs_set_disk_key_type(&disk_key, BTRFS_TREE_BLOCK_REF_KEY);
231 btrfs_set_item_key(buf, &disk_key, nritems);
232 btrfs_set_item_offset(buf, btrfs_item_nr(buf, nritems),
233 itemoff);
234 btrfs_set_item_size(buf, btrfs_item_nr(buf, nritems), 0);
235 nritems++;
237 btrfs_set_header_bytenr(buf, blocks[2]);
238 btrfs_set_header_owner(buf, BTRFS_EXTENT_TREE_OBJECTID);
239 btrfs_set_header_nritems(buf, nritems);
240 csum_tree_block_size(buf, BTRFS_CRC32_SIZE, 0);
241 ret = pwrite(fd, buf->data, leafsize, blocks[2]);
242 BUG_ON(ret != leafsize);
244 /* create the chunk tree */
245 nritems = 0;
246 item_size = sizeof(*dev_item);
247 itemoff = __BTRFS_LEAF_DATA_SIZE(leafsize) - item_size;
249 /* first device 1 (there is no device 0) */
250 btrfs_set_disk_key_objectid(&disk_key, BTRFS_DEV_ITEMS_OBJECTID);
251 btrfs_set_disk_key_offset(&disk_key, 1);
252 btrfs_set_disk_key_type(&disk_key, BTRFS_DEV_ITEM_KEY);
253 btrfs_set_item_key(buf, &disk_key, nritems);
254 btrfs_set_item_offset(buf, btrfs_item_nr(buf, nritems), itemoff);
255 btrfs_set_item_size(buf, btrfs_item_nr(buf, nritems), item_size);
257 dev_item = btrfs_item_ptr(buf, nritems, struct btrfs_dev_item);
258 btrfs_set_device_id(buf, dev_item, 1);
259 btrfs_set_device_generation(buf, dev_item, 0);
260 btrfs_set_device_total_bytes(buf, dev_item, num_bytes);
261 btrfs_set_device_bytes_used(buf, dev_item,
262 BTRFS_MKFS_SYSTEM_GROUP_SIZE);
263 btrfs_set_device_io_align(buf, dev_item, sectorsize);
264 btrfs_set_device_io_width(buf, dev_item, sectorsize);
265 btrfs_set_device_sector_size(buf, dev_item, sectorsize);
266 btrfs_set_device_type(buf, dev_item, 0);
268 write_extent_buffer(buf, super.dev_item.uuid,
269 (unsigned long)btrfs_device_uuid(dev_item),
270 BTRFS_UUID_SIZE);
271 write_extent_buffer(buf, super.fsid,
272 (unsigned long)btrfs_device_fsid(dev_item),
273 BTRFS_UUID_SIZE);
274 read_extent_buffer(buf, &super.dev_item, (unsigned long)dev_item,
275 sizeof(*dev_item));
277 nritems++;
278 item_size = btrfs_chunk_item_size(1);
279 itemoff = itemoff - item_size;
281 /* then we have chunk 0 */
282 btrfs_set_disk_key_objectid(&disk_key, BTRFS_FIRST_CHUNK_TREE_OBJECTID);
283 btrfs_set_disk_key_offset(&disk_key, 0);
284 btrfs_set_disk_key_type(&disk_key, BTRFS_CHUNK_ITEM_KEY);
285 btrfs_set_item_key(buf, &disk_key, nritems);
286 btrfs_set_item_offset(buf, btrfs_item_nr(buf, nritems), itemoff);
287 btrfs_set_item_size(buf, btrfs_item_nr(buf, nritems), item_size);
289 chunk = btrfs_item_ptr(buf, nritems, struct btrfs_chunk);
290 btrfs_set_chunk_length(buf, chunk, BTRFS_MKFS_SYSTEM_GROUP_SIZE);
291 btrfs_set_chunk_owner(buf, chunk, BTRFS_EXTENT_TREE_OBJECTID);
292 btrfs_set_chunk_stripe_len(buf, chunk, 64 * 1024);
293 btrfs_set_chunk_type(buf, chunk, BTRFS_BLOCK_GROUP_SYSTEM);
294 btrfs_set_chunk_io_align(buf, chunk, sectorsize);
295 btrfs_set_chunk_io_width(buf, chunk, sectorsize);
296 btrfs_set_chunk_sector_size(buf, chunk, sectorsize);
297 btrfs_set_chunk_num_stripes(buf, chunk, 1);
298 btrfs_set_stripe_devid_nr(buf, chunk, 0, 1);
299 btrfs_set_stripe_offset_nr(buf, chunk, 0, 0);
300 nritems++;
302 write_extent_buffer(buf, super.dev_item.uuid,
303 (unsigned long)btrfs_stripe_dev_uuid(&chunk->stripe),
304 BTRFS_UUID_SIZE);
306 /* copy the key for the chunk to the system array */
307 ptr = super.sys_chunk_array;
308 array_size = sizeof(disk_key);
310 memcpy(ptr, &disk_key, sizeof(disk_key));
311 ptr += sizeof(disk_key);
313 /* copy the chunk to the system array */
314 read_extent_buffer(buf, ptr, (unsigned long)chunk, item_size);
315 array_size += item_size;
316 ptr += item_size;
317 btrfs_set_super_sys_array_size(&super, array_size);
319 btrfs_set_header_bytenr(buf, blocks[3]);
320 btrfs_set_header_owner(buf, BTRFS_CHUNK_TREE_OBJECTID);
321 btrfs_set_header_nritems(buf, nritems);
322 csum_tree_block_size(buf, BTRFS_CRC32_SIZE, 0);
323 ret = pwrite(fd, buf->data, leafsize, blocks[3]);
325 /* create the device tree */
326 nritems = 0;
327 itemoff = __BTRFS_LEAF_DATA_SIZE(leafsize) -
328 sizeof(struct btrfs_dev_extent);
330 btrfs_set_disk_key_objectid(&disk_key, 1);
331 btrfs_set_disk_key_offset(&disk_key, 0);
332 btrfs_set_disk_key_type(&disk_key, BTRFS_DEV_EXTENT_KEY);
333 btrfs_set_item_key(buf, &disk_key, nritems);
334 btrfs_set_item_offset(buf, btrfs_item_nr(buf, nritems), itemoff);
335 btrfs_set_item_size(buf, btrfs_item_nr(buf, nritems),
336 sizeof(struct btrfs_dev_extent));
337 dev_extent = btrfs_item_ptr(buf, nritems, struct btrfs_dev_extent);
338 btrfs_set_dev_extent_chunk_tree(buf, dev_extent,
339 BTRFS_CHUNK_TREE_OBJECTID);
340 btrfs_set_dev_extent_chunk_objectid(buf, dev_extent,
341 BTRFS_FIRST_CHUNK_TREE_OBJECTID);
342 btrfs_set_dev_extent_chunk_offset(buf, dev_extent, 0);
344 write_extent_buffer(buf, chunk_tree_uuid,
345 (unsigned long)btrfs_dev_extent_chunk_tree_uuid(dev_extent),
346 BTRFS_UUID_SIZE);
348 btrfs_set_dev_extent_length(buf, dev_extent,
349 BTRFS_MKFS_SYSTEM_GROUP_SIZE);
350 nritems++;
352 btrfs_set_header_bytenr(buf, blocks[4]);
353 btrfs_set_header_owner(buf, BTRFS_DEV_TREE_OBJECTID);
354 btrfs_set_header_nritems(buf, nritems);
355 csum_tree_block_size(buf, BTRFS_CRC32_SIZE, 0);
356 ret = pwrite(fd, buf->data, leafsize, blocks[4]);
358 /* create the FS root */
359 btrfs_set_header_bytenr(buf, blocks[5]);
360 btrfs_set_header_owner(buf, BTRFS_FS_TREE_OBJECTID);
361 btrfs_set_header_nritems(buf, 0);
362 csum_tree_block_size(buf, BTRFS_CRC32_SIZE, 0);
363 ret = pwrite(fd, buf->data, leafsize, blocks[5]);
364 BUG_ON(ret != leafsize);
366 /* finally create the csum root */
367 btrfs_set_header_bytenr(buf, blocks[6]);
368 btrfs_set_header_owner(buf, BTRFS_CSUM_TREE_OBJECTID);
369 btrfs_set_header_nritems(buf, 0);
370 csum_tree_block_size(buf, BTRFS_CRC32_SIZE, 0);
371 ret = pwrite(fd, buf->data, leafsize, blocks[6]);
372 BUG_ON(ret != leafsize);
374 /* and write out the super block */
375 BUG_ON(sizeof(super) > sectorsize);
376 memset(buf->data, 0, sectorsize);
377 memcpy(buf->data, &super, sizeof(super));
378 buf->len = sectorsize;
379 csum_tree_block_size(buf, BTRFS_CRC32_SIZE, 0);
380 ret = pwrite(fd, buf->data, sectorsize, blocks[0]);
381 BUG_ON(ret != sectorsize);
384 free(buf);
385 return 0;
388 static u64 device_size(int fd, struct stat *st)
390 u64 size;
391 if (S_ISREG(st->st_mode)) {
392 return st->st_size;
394 if (!S_ISBLK(st->st_mode)) {
395 return 0;
397 if (ioctl(fd, BLKGETSIZE64, &size) >= 0) {
398 return size;
400 return 0;
403 static int zero_blocks(int fd, off_t start, size_t len)
405 char *buf = malloc(len);
406 int ret = 0;
407 ssize_t written;
409 if (!buf)
410 return -ENOMEM;
411 memset(buf, 0, len);
412 written = pwrite(fd, buf, len, start);
413 if (written != len)
414 ret = -EIO;
415 free(buf);
416 return ret;
419 static int zero_dev_start(int fd)
421 off_t start = 0;
422 size_t len = 2 * 1024 * 1024;
424 #ifdef __sparc__
425 /* don't overwrite the disk labels on sparc */
426 start = 1024;
427 len -= 1024;
428 #endif
429 return zero_blocks(fd, start, len);
432 static int zero_dev_end(int fd, u64 dev_size)
434 size_t len = 2 * 1024 * 1024;
435 off_t start = dev_size - len;
437 return zero_blocks(fd, start, len);
440 int btrfs_add_to_fsid(struct btrfs_trans_handle *trans,
441 struct btrfs_root *root, int fd, char *path,
442 u64 block_count, u32 io_width, u32 io_align,
443 u32 sectorsize)
445 struct btrfs_super_block *disk_super;
446 struct btrfs_super_block *super = &root->fs_info->super_copy;
447 struct btrfs_device *device;
448 struct btrfs_dev_item *dev_item;
449 char *buf;
450 u64 total_bytes;
451 u64 num_devs;
452 int ret;
454 device = kmalloc(sizeof(*device), GFP_NOFS);
455 if (!device)
456 return -ENOMEM;
457 buf = kmalloc(sectorsize, GFP_NOFS);
458 if (!buf) {
459 kfree(device);
460 return -ENOMEM;
462 BUG_ON(sizeof(*disk_super) > sectorsize);
463 memset(buf, 0, sectorsize);
465 disk_super = (struct btrfs_super_block *)buf;
466 dev_item = &disk_super->dev_item;
468 uuid_generate(device->uuid);
469 device->devid = 0;
470 device->type = 0;
471 device->io_width = io_width;
472 device->io_align = io_align;
473 device->sector_size = sectorsize;
474 device->fd = fd;
475 device->writeable = 1;
476 device->total_bytes = block_count;
477 device->bytes_used = 0;
478 device->total_ios = 0;
479 device->dev_root = root->fs_info->dev_root;
481 ret = btrfs_add_device(trans, root, device);
482 BUG_ON(ret);
484 total_bytes = btrfs_super_total_bytes(super) + block_count;
485 btrfs_set_super_total_bytes(super, total_bytes);
487 num_devs = btrfs_super_num_devices(super) + 1;
488 btrfs_set_super_num_devices(super, num_devs);
490 memcpy(disk_super, super, sizeof(*disk_super));
492 printf("adding device %s id %llu\n", path,
493 (unsigned long long)device->devid);
495 btrfs_set_super_bytenr(disk_super, BTRFS_SUPER_INFO_OFFSET);
496 btrfs_set_stack_device_id(dev_item, device->devid);
497 btrfs_set_stack_device_type(dev_item, device->type);
498 btrfs_set_stack_device_io_align(dev_item, device->io_align);
499 btrfs_set_stack_device_io_width(dev_item, device->io_width);
500 btrfs_set_stack_device_sector_size(dev_item, device->sector_size);
501 btrfs_set_stack_device_total_bytes(dev_item, device->total_bytes);
502 btrfs_set_stack_device_bytes_used(dev_item, device->bytes_used);
503 memcpy(&dev_item->uuid, device->uuid, BTRFS_UUID_SIZE);
505 ret = pwrite(fd, buf, sectorsize, BTRFS_SUPER_INFO_OFFSET);
506 BUG_ON(ret != sectorsize);
508 kfree(buf);
509 list_add(&device->dev_list, &root->fs_info->fs_devices->devices);
510 device->fs_devices = root->fs_info->fs_devices;
511 return 0;
514 int btrfs_prepare_device(int fd, char *file, int zero_end, u64 *block_count_ret)
516 u64 block_count;
517 u64 bytenr;
518 struct stat st;
519 int i, ret;
521 ret = fstat(fd, &st);
522 if (ret < 0) {
523 fprintf(stderr, "unable to stat %s\n", file);
524 exit(1);
527 block_count = device_size(fd, &st);
528 if (block_count == 0) {
529 fprintf(stderr, "unable to find %s size\n", file);
530 exit(1);
532 zero_end = 1;
534 if (block_count < 256 * 1024 * 1024) {
535 fprintf(stderr, "device %s is too small "
536 "(must be at least 256 MB)\n", file);
537 exit(1);
539 ret = zero_dev_start(fd);
540 if (ret) {
541 fprintf(stderr, "failed to zero device start %d\n", ret);
542 exit(1);
545 for (i = 0 ; i < BTRFS_SUPER_MIRROR_MAX; i++) {
546 bytenr = btrfs_sb_offset(i);
547 if (bytenr >= block_count)
548 break;
549 zero_blocks(fd, bytenr, BTRFS_SUPER_INFO_SIZE);
552 if (zero_end) {
553 ret = zero_dev_end(fd, block_count);
554 if (ret) {
555 fprintf(stderr, "failed to zero device end %d\n", ret);
556 exit(1);
559 *block_count_ret = block_count;
560 return 0;
563 int btrfs_make_root_dir(struct btrfs_trans_handle *trans,
564 struct btrfs_root *root, u64 objectid)
566 int ret;
567 struct btrfs_inode_item inode_item;
569 memset(&inode_item, 0, sizeof(inode_item));
570 btrfs_set_stack_inode_generation(&inode_item, trans->transid);
571 btrfs_set_stack_inode_size(&inode_item, 0);
572 btrfs_set_stack_inode_nlink(&inode_item, 1);
573 btrfs_set_stack_inode_nbytes(&inode_item, root->leafsize);
574 btrfs_set_stack_inode_mode(&inode_item, S_IFDIR | 0555);
576 if (root->fs_info->tree_root == root)
577 btrfs_set_super_root_dir(&root->fs_info->super_copy, objectid);
579 ret = btrfs_insert_inode(trans, root, objectid, &inode_item);
580 if (ret)
581 goto error;
583 ret = btrfs_insert_inode_ref(trans, root, "..", 2, objectid, objectid, 0);
584 if (ret)
585 goto error;
587 btrfs_set_root_dirid(&root->root_item, objectid);
588 ret = 0;
589 error:
590 return ret;
593 /* checks if a device is a loop device */
594 int is_loop_device (const char* device) {
595 struct stat statbuf;
597 if(stat(device, &statbuf) < 0)
598 return -errno;
600 return (S_ISBLK(statbuf.st_mode) &&
601 MAJOR(statbuf.st_rdev) == LOOP_MAJOR);
605 /* Takes a loop device path (e.g. /dev/loop0) and returns
606 * the associated file (e.g. /images/my_btrfs.img) */
607 int resolve_loop_device(const char* loop_dev, char* loop_file, int max_len)
609 int loop_fd;
610 int ret_ioctl;
611 struct loop_info loopinfo;
613 if ((loop_fd = open(loop_dev, O_RDONLY)) < 0)
614 return -errno;
616 ret_ioctl = ioctl(loop_fd, LOOP_GET_STATUS, &loopinfo);
617 close(loop_fd);
619 if (ret_ioctl == 0)
620 strncpy(loop_file, loopinfo.lo_name, max_len);
621 else
622 return -errno;
624 return 0;
627 /* Checks whether a and b are identical or device
628 * files associated with the same block device
630 int is_same_blk_file(const char* a, const char* b)
632 struct stat st_buf_a, st_buf_b;
633 char real_a[PATH_MAX];
634 char real_b[PATH_MAX];
636 if(!realpath(a, real_a) ||
637 !realpath(b, real_b))
639 return -errno;
642 /* Identical path? */
643 if(strcmp(real_a, real_b) == 0)
644 return 1;
646 if(stat(a, &st_buf_a) < 0 ||
647 stat(b, &st_buf_b) < 0)
649 return -errno;
652 /* Same blockdevice? */
653 if(S_ISBLK(st_buf_a.st_mode) &&
654 S_ISBLK(st_buf_b.st_mode) &&
655 st_buf_a.st_rdev == st_buf_b.st_rdev)
657 return 1;
660 /* Hardlink? */
661 if (st_buf_a.st_dev == st_buf_b.st_dev &&
662 st_buf_a.st_ino == st_buf_b.st_ino)
664 return 1;
667 return 0;
670 /* checks if a and b are identical or device
671 * files associated with the same block device or
672 * if one file is a loop device that uses the other
673 * file.
675 int is_same_loop_file(const char* a, const char* b)
677 char res_a[PATH_MAX];
678 char res_b[PATH_MAX];
679 const char* final_a;
680 const char* final_b;
681 int ret;
683 /* Resolve a if it is a loop device */
684 if((ret = is_loop_device(a)) < 0) {
685 return ret;
686 } else if(ret) {
687 if((ret = resolve_loop_device(a, res_a, sizeof(res_a))) < 0)
688 return ret;
690 final_a = res_a;
691 } else {
692 final_a = a;
695 /* Resolve b if it is a loop device */
696 if((ret = is_loop_device(b)) < 0) {
697 return ret;
698 } else if(ret) {
699 if((ret = resolve_loop_device(b, res_b, sizeof(res_b))) < 0)
700 return ret;
702 final_b = res_b;
703 } else {
704 final_b = b;
707 return is_same_blk_file(final_a, final_b);
710 /* Checks if a file exists and is a block or regular file*/
711 int is_existing_blk_or_reg_file(const char* filename)
713 struct stat st_buf;
715 if(stat(filename, &st_buf) < 0) {
716 if(errno == ENOENT)
717 return 0;
718 else
719 return -errno;
722 return (S_ISBLK(st_buf.st_mode) || S_ISREG(st_buf.st_mode));
725 /* Checks if a file is used (directly or indirectly via a loop device)
726 * by a device in fs_devices
728 int blk_file_in_dev_list(struct btrfs_fs_devices* fs_devices, const char* file)
730 int ret;
731 struct list_head *head;
732 struct list_head *cur;
733 struct btrfs_device *device;
735 head = &fs_devices->devices;
736 list_for_each(cur, head) {
737 device = list_entry(cur, struct btrfs_device, dev_list);
739 if((ret = is_same_loop_file(device->name, file)))
740 return ret;
743 return 0;
747 * returns 1 if the device was mounted, < 0 on error or 0 if everything
748 * is safe to continue.
750 int check_mounted(const char* file)
752 int ret;
753 int fd;
754 u64 total_devs = 1;
755 int is_btrfs;
756 struct btrfs_fs_devices* fs_devices_mnt = NULL;
757 FILE *f;
758 struct mntent *mnt;
760 fd = open(file, O_RDONLY);
761 if (fd < 0) {
762 fprintf (stderr, "check_mounted(): Could not open %s\n", file);
763 return -errno;
766 /* scan the initial device */
767 ret = btrfs_scan_one_device(fd, file, &fs_devices_mnt,
768 &total_devs, BTRFS_SUPER_INFO_OFFSET);
769 is_btrfs = (ret >= 0);
770 close(fd);
772 /* scan other devices */
773 if (is_btrfs && total_devs > 1) {
774 if((ret = btrfs_scan_for_fsid(fs_devices_mnt, total_devs, 1)))
775 return ret;
778 /* iterate over the list of currently mountes filesystems */
779 if ((f = setmntent ("/proc/mounts", "r")) == NULL)
780 return -errno;
782 while ((mnt = getmntent (f)) != NULL) {
783 if(is_btrfs) {
784 if(strcmp(mnt->mnt_type, "btrfs") != 0)
785 continue;
787 ret = blk_file_in_dev_list(fs_devices_mnt, mnt->mnt_fsname);
788 } else {
789 /* ignore entries in the mount table that are not
790 associated with a file*/
791 if((ret = is_existing_blk_or_reg_file(mnt->mnt_fsname)) < 0)
792 goto out_mntloop_err;
793 else if(!ret)
794 continue;
796 ret = is_same_loop_file(file, mnt->mnt_fsname);
799 if(ret < 0)
800 goto out_mntloop_err;
801 else if(ret)
802 break;
805 /* Did we find an entry in mnt table? */
806 ret = (mnt != NULL);
808 out_mntloop_err:
809 endmntent (f);
811 return ret;
814 struct pending_dir {
815 struct list_head list;
816 char name[256];
819 void btrfs_register_one_device(char *fname)
821 struct btrfs_ioctl_vol_args args;
822 int fd;
823 int ret;
825 fd = open("/dev/btrfs-control", O_RDONLY);
826 if (fd < 0) {
827 fprintf(stderr, "failed to open /dev/btrfs-control "
828 "skipping device registration\n");
829 return;
831 strcpy(args.name, fname);
832 ret = ioctl(fd, BTRFS_IOC_SCAN_DEV, &args);
833 close(fd);
836 int btrfs_scan_one_dir(char *dirname, int run_ioctl)
838 DIR *dirp = NULL;
839 struct dirent *dirent;
840 struct pending_dir *pending;
841 struct stat st;
842 int ret;
843 int fd;
844 int dirname_len;
845 int pathlen;
846 char *fullpath;
847 struct list_head pending_list;
848 struct btrfs_fs_devices *tmp_devices;
849 u64 num_devices;
851 INIT_LIST_HEAD(&pending_list);
853 pending = malloc(sizeof(*pending));
854 if (!pending)
855 return -ENOMEM;
856 strcpy(pending->name, dirname);
858 again:
859 dirname_len = strlen(pending->name);
860 pathlen = 1024;
861 fullpath = malloc(pathlen);
862 dirname = pending->name;
864 if (!fullpath) {
865 ret = -ENOMEM;
866 goto fail;
868 dirp = opendir(dirname);
869 if (!dirp) {
870 fprintf(stderr, "Unable to open /sys/block for scanning\n");
871 return -ENOENT;
873 while(1) {
874 dirent = readdir(dirp);
875 if (!dirent)
876 break;
877 if (dirent->d_name[0] == '.')
878 continue;
879 if (dirname_len + strlen(dirent->d_name) + 2 > pathlen) {
880 ret = -EFAULT;
881 goto fail;
883 snprintf(fullpath, pathlen, "%s/%s", dirname, dirent->d_name);
884 ret = lstat(fullpath, &st);
885 if (ret < 0) {
886 fprintf(stderr, "failed to stat %s\n", fullpath);
887 continue;
889 if (S_ISLNK(st.st_mode))
890 continue;
891 if (S_ISDIR(st.st_mode)) {
892 struct pending_dir *next = malloc(sizeof(*next));
893 if (!next) {
894 ret = -ENOMEM;
895 goto fail;
897 strcpy(next->name, fullpath);
898 list_add_tail(&next->list, &pending_list);
900 if (!S_ISBLK(st.st_mode)) {
901 continue;
903 fd = open(fullpath, O_RDONLY);
904 if (fd < 0) {
905 fprintf(stderr, "failed to read %s\n", fullpath);
906 continue;
908 ret = btrfs_scan_one_device(fd, fullpath, &tmp_devices,
909 &num_devices,
910 BTRFS_SUPER_INFO_OFFSET);
911 if (ret == 0 && run_ioctl > 0) {
912 btrfs_register_one_device(fullpath);
914 close(fd);
916 if (!list_empty(&pending_list)) {
917 free(pending);
918 pending = list_entry(pending_list.next, struct pending_dir,
919 list);
920 list_del(&pending->list);
921 closedir(dirp);
922 goto again;
924 ret = 0;
925 fail:
926 free(pending);
927 if (dirp)
928 closedir(dirp);
929 return ret;
932 int btrfs_scan_for_fsid(struct btrfs_fs_devices *fs_devices, u64 total_devs,
933 int run_ioctls)
935 return btrfs_scan_one_dir("/dev", run_ioctls);
938 int btrfs_device_already_in_root(struct btrfs_root *root, int fd,
939 int super_offset)
941 struct btrfs_super_block *disk_super;
942 char *buf;
943 int ret = 0;
945 buf = malloc(BTRFS_SUPER_INFO_SIZE);
946 if (!buf) {
947 ret = -ENOMEM;
948 goto out;
950 ret = pread(fd, buf, BTRFS_SUPER_INFO_SIZE, super_offset);
951 if (ret != BTRFS_SUPER_INFO_SIZE)
952 goto brelse;
954 ret = 0;
955 disk_super = (struct btrfs_super_block *)buf;
956 if (strncmp((char *)(&disk_super->magic), BTRFS_MAGIC,
957 sizeof(disk_super->magic)))
958 goto brelse;
960 if (!memcmp(disk_super->fsid, root->fs_info->super_copy.fsid,
961 BTRFS_FSID_SIZE))
962 ret = 1;
963 brelse:
964 free(buf);
965 out:
966 return ret;
969 static char *size_strs[] = { "", "KB", "MB", "GB", "TB",
970 "PB", "EB", "ZB", "YB"};
971 char *pretty_sizes(u64 size)
973 int num_divs = 0;
974 u64 last_size = size;
975 u64 fract_size = size;
976 float fraction;
977 char *pretty;
979 while(size > 0) {
980 fract_size = last_size;
981 last_size = size;
982 size /= 1024;
983 num_divs++;
985 if (num_divs == 0)
986 num_divs = 1;
987 if (num_divs > ARRAY_SIZE(size_strs))
988 return NULL;
990 fraction = (float)fract_size / 1024;
991 pretty = malloc(16);
992 sprintf(pretty, "%.2f%s", fraction, size_strs[num_divs-1]);
993 return pretty;