fprintf(stderr, "unable to update system chunk\n");
goto fail;
}
- root = open_ctree_fd(fd, devname, super_bytenr, O_RDWR);
+ root = open_ctree_fd(fd, devname, super_bytenr, OPEN_CTREE_WRITES);
if (!root) {
fprintf(stderr, "unable to open ctree\n");
goto fail;
goto fail;
}
- root = open_ctree_fd(fd, devname, 0, O_RDWR);
+ root = open_ctree_fd(fd, devname, 0, OPEN_CTREE_WRITES);
if (!root) {
fprintf(stderr, "unable to open ctree\n");
goto fail;
fprintf(stderr, "unable to open %s\n", devname);
goto fail;
}
- root = open_ctree_fd(fd, devname, 0, O_RDWR);
+ root = open_ctree_fd(fd, devname, 0, OPEN_CTREE_WRITES);
if (!root) {
fprintf(stderr, "unable to open ctree\n");
goto fail;
radix_tree_init();
cache_tree_init(&root_cache);
- root = open_ctree(dev, 0, 1);
+ root = open_ctree(dev, 0, OPEN_CTREE_WRITES);
if (!root) {
fprintf(stderr, "Open ctree failed\n");
exit(1);
if (ac != 1)
print_usage();
- info = open_ctree_fs_info(av[optind], 0, 0, 0, 1, 0);
+ info = open_ctree_fs_info(av[optind], 0, 0, OPEN_CTREE_PARTIAL);
if (!info) {
fprintf(stderr, "unable to open %s\n", av[optind]);
exit(1);
/* NOTE: open with write mode */
if (fixup_offset) {
BUG_ON(!target);
- info = open_ctree_fs_info_restore(target, 0, 0, 1, 1);
+ info = open_ctree_fs_info(target, 0, 0,
+ OPEN_CTREE_WRITES |
+ OPEN_CTREE_RESTORE |
+ OPEN_CTREE_PARTIAL);
if (!info) {
fprintf(stderr, "%s: open ctree failed\n", __func__);
ret = -EIO;
u64 total_devs;
int i;
- info = open_ctree_fs_info_restore(target, 0, 0, 0, 1);
+ info = open_ctree_fs_info(target, 0, 0,
+ OPEN_CTREE_PARTIAL |
+ OPEN_CTREE_RESTORE);
if (!info) {
int e = errno;
fprintf(stderr, "unable to open %s error = %s\n",
goto out;
}
- root = open_ctree(av[1], 0, 1);
+ root = open_ctree(av[1], 0, OPEN_CTREE_WRITES);
if (root == NULL)
return 1;
return 1;
}
- root = open_ctree(device, 0, 1);
+ root = open_ctree(device, 0, OPEN_CTREE_WRITES);
if (!root) {
fprintf(stderr, "Open ctree failed\n");
struct btrfs_fs_info *info;
u64 bytenr = 0;
char uuidbuf[37];
- int backup_root = 0;
int ret;
int num;
int option_index = 0;
int init_csum_tree = 0;
int init_extent_tree = 0;
- int rw = 0;
+ enum btrfs_open_ctree_flags ctree_flags = OPEN_CTREE_PARTIAL;
while(1) {
int c;
switch(c) {
case 'a': /* ignored */ break;
case 'b':
- backup_root = 1;
+ ctree_flags |= OPEN_CTREE_BACKUP_ROOT;
break;
case 's':
num = atol(optarg);
if (option_index == 1) {
printf("enabling repair mode\n");
repair = 1;
- rw = 1;
+ ctree_flags |= OPEN_CTREE_WRITES;
} else if (option_index == 2) {
printf("Creating a new CRC tree\n");
init_csum_tree = 1;
- rw = 1;
+ ctree_flags |= OPEN_CTREE_WRITES;
} else if (option_index == 3) {
init_extent_tree = 1;
- rw = 1;
+ ctree_flags |= (OPEN_CTREE_WRITES |
+ OPEN_CTREE_NO_BLOCK_GROUPS);
repair = 1;
}
return -EBUSY;
}
- info = open_ctree_fs_info(argv[optind], bytenr, 0, rw, 1, backup_root);
+ info = open_ctree_fs_info(argv[optind], bytenr, 0, ctree_flags);
if (!info) {
fprintf(stderr, "Couldn't open file system\n");
return -EIO;
if (ret)
goto out_cleanup;
- ret = btrfs_setup_all_roots(fs_info, 0, 0);
+ ret = btrfs_setup_all_roots(fs_info, 0, 0, 0);
if (ret)
goto out_failed;
for (i = super_mirror; i < BTRFS_SUPER_MIRROR_MAX; i++) {
bytenr = btrfs_sb_offset(i);
- fs_info = open_ctree_fs_info(dev, bytenr, root_location, 0, 1, 0);
+ fs_info = open_ctree_fs_info(dev, bytenr, root_location,
+ OPEN_CTREE_PARTIAL);
if (fs_info)
break;
fprintf(stderr, "Could not open root, trying backup super\n");
return best_index;
}
-int btrfs_setup_all_roots(struct btrfs_fs_info *fs_info,
- u64 root_tree_bytenr, int partial, int backup_root)
+int btrfs_setup_all_roots(struct btrfs_fs_info *fs_info, u64 root_tree_bytenr,
+ enum btrfs_open_ctree_flags flags)
{
struct btrfs_super_block *sb = fs_info->super_copy;
struct btrfs_root *root;
blocksize = btrfs_level_size(root, btrfs_super_root_level(sb));
generation = btrfs_super_generation(sb);
- if (!root_tree_bytenr && !backup_root) {
+ if (!root_tree_bytenr && !(flags & OPEN_CTREE_BACKUP_ROOT)) {
root_tree_bytenr = btrfs_super_root(sb);
- } else if (backup_root) {
+ } else if (flags & OPEN_CTREE_BACKUP_ROOT) {
struct btrfs_root_backup *backup;
int index = find_best_backup_root(sb);
if (index >= BTRFS_NUM_BACKUP_ROOTS) {
fs_info->csum_root);
if (ret) {
printk("Couldn't setup csum tree\n");
- if (!partial)
+ if (!(flags & OPEN_CTREE_PARTIAL))
return -EIO;
}
fs_info->csum_root->track_dirty = 1;
fs_info->generation = generation;
fs_info->last_trans_committed = generation;
- btrfs_read_block_groups(fs_info->tree_root);
+ if (extent_buffer_uptodate(fs_info->extent_root->node) &&
+ !(flags & OPEN_CTREE_NO_BLOCK_GROUPS))
+ btrfs_read_block_groups(fs_info->tree_root);
key.objectid = BTRFS_FS_TREE_OBJECTID;
key.type = BTRFS_ROOT_ITEM_KEY;
static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path,
u64 sb_bytenr,
- u64 root_tree_bytenr, int writes,
- int partial, int restore,
- int recover_super,
- int backup_root)
+ u64 root_tree_bytenr,
+ enum btrfs_open_ctree_flags flags)
{
struct btrfs_fs_info *fs_info;
struct btrfs_super_block *disk_super;
if (posix_fadvise(fp, 0, 0, POSIX_FADV_DONTNEED))
fprintf(stderr, "Warning, could not drop caches\n");
- fs_info = btrfs_new_fs_info(writes, sb_bytenr);
+ fs_info = btrfs_new_fs_info(flags & OPEN_CTREE_WRITES, sb_bytenr);
if (!fs_info) {
fprintf(stderr, "Failed to allocate memory for fs_info\n");
return NULL;
}
- if (restore)
+ if (flags & OPEN_CTREE_RESTORE)
fs_info->on_restoring = 1;
ret = btrfs_scan_fs_devices(fp, path, &fs_devices, sb_bytenr,
- !recover_super);
+ !(flags & OPEN_CTREE_RECOVER_SUPER));
if (ret)
goto out;
fs_info->fs_devices = fs_devices;
- if (writes)
+ if (flags & OPEN_CTREE_WRITES)
ret = btrfs_open_devices(fs_devices, O_RDWR);
else
ret = btrfs_open_devices(fs_devices, O_RDONLY);
disk_super = fs_info->super_copy;
- if (!recover_super)
+ if (!(flags & OPEN_CTREE_RECOVER_SUPER))
ret = btrfs_read_dev_super(fs_devices->latest_bdev,
disk_super, sb_bytenr);
else
memcpy(fs_info->fsid, &disk_super->fsid, BTRFS_FSID_SIZE);
- ret = btrfs_check_fs_compatibility(fs_info->super_copy, writes);
+ ret = btrfs_check_fs_compatibility(fs_info->super_copy,
+ flags & OPEN_CTREE_WRITES);
if (ret)
goto out_devices;
(unsigned long)btrfs_header_chunk_tree_uuid(eb),
BTRFS_UUID_SIZE);
- ret = btrfs_setup_all_roots(fs_info, root_tree_bytenr, partial,
- backup_root);
+ ret = btrfs_setup_all_roots(fs_info, root_tree_bytenr, flags);
if (ret)
goto out_failed;
return fs_info;
out_failed:
- if (partial)
+ if (flags & OPEN_CTREE_PARTIAL)
return fs_info;
out_chunk:
btrfs_release_all_roots(fs_info);
return NULL;
}
-struct btrfs_fs_info *open_ctree_fs_info_restore(const char *filename,
- u64 sb_bytenr, u64 root_tree_bytenr,
- int writes, int partial)
-{
- int fp;
- struct btrfs_fs_info *info;
- int flags = O_CREAT | O_RDWR;
- int restore = 1;
-
- if (!writes)
- flags = O_RDONLY;
-
- fp = open(filename, flags, 0600);
- if (fp < 0) {
- fprintf (stderr, "Could not open %s\n", filename);
- return NULL;
- }
- info = __open_ctree_fd(fp, filename, sb_bytenr, root_tree_bytenr,
- writes, partial, restore, 0, 0);
- close(fp);
- return info;
-}
-
struct btrfs_fs_info *open_ctree_fs_info(const char *filename,
u64 sb_bytenr, u64 root_tree_bytenr,
- int writes, int partial,
- int backup_root)
+ enum btrfs_open_ctree_flags flags)
{
int fp;
struct btrfs_fs_info *info;
- int flags = O_CREAT | O_RDWR;
+ int oflags = O_CREAT | O_RDWR;
- if (!writes)
- flags = O_RDONLY;
+ if (!(flags & OPEN_CTREE_WRITES))
+ oflags = O_RDONLY;
- fp = open(filename, flags, 0600);
+ fp = open(filename, oflags, 0600);
if (fp < 0) {
fprintf (stderr, "Could not open %s\n", filename);
return NULL;
}
info = __open_ctree_fd(fp, filename, sb_bytenr, root_tree_bytenr,
- writes, partial, 0, 0, backup_root);
+ flags);
close(fp);
return info;
}
-struct btrfs_root *open_ctree_with_broken_super(const char *filename,
- u64 sb_bytenr, int writes)
-{
- int fp;
- struct btrfs_fs_info *info;
- int flags = O_CREAT | O_RDWR;
-
- if (!writes)
- flags = O_RDONLY;
-
- fp = open(filename, flags, 0600);
- if (fp < 0) {
- fprintf(stderr, "Could not open %s\n", filename);
- return NULL;
- }
- info = __open_ctree_fd(fp, filename, sb_bytenr, 0,
- writes, 0, 0, 1, 0);
- close(fp);
- if (info)
- return info->fs_root;
- return NULL;
-}
-
-struct btrfs_root *open_ctree(const char *filename, u64 sb_bytenr, int writes)
+struct btrfs_root *open_ctree(const char *filename, u64 sb_bytenr,
+ enum btrfs_open_ctree_flags flags)
{
struct btrfs_fs_info *info;
- info = open_ctree_fs_info(filename, sb_bytenr, 0, writes, 0, 0);
+ info = open_ctree_fs_info(filename, sb_bytenr, 0, flags);
if (!info)
return NULL;
return info->fs_root;
}
struct btrfs_root *open_ctree_fd(int fp, const char *path, u64 sb_bytenr,
- int writes)
+ enum btrfs_open_ctree_flags flags)
{
struct btrfs_fs_info *info;
- info = __open_ctree_fd(fp, path, sb_bytenr, 0, writes, 0, 0, 0, 0);
+ info = __open_ctree_fd(fp, path, sb_bytenr, 0, flags);
if (!info)
return NULL;
return info->fs_root;
#define BTRFS_SUPER_MIRROR_MAX 3
#define BTRFS_SUPER_MIRROR_SHIFT 12
+enum btrfs_open_ctree_flags {
+ OPEN_CTREE_WRITES = 1,
+ OPEN_CTREE_PARTIAL = 2,
+ OPEN_CTREE_BACKUP_ROOT = 4,
+ OPEN_CTREE_RECOVER_SUPER = 8,
+ OPEN_CTREE_RESTORE = 16,
+ OPEN_CTREE_NO_BLOCK_GROUPS = 32,
+};
+
static inline u64 btrfs_sb_offset(int mirror)
{
u64 start = 16 * 1024;
void btrfs_free_fs_info(struct btrfs_fs_info *fs_info);
struct btrfs_fs_info *btrfs_new_fs_info(int writable, u64 sb_bytenr);
int btrfs_check_fs_compatibility(struct btrfs_super_block *sb, int writable);
-int btrfs_setup_all_roots(struct btrfs_fs_info *fs_info,
- u64 root_tree_bytenr, int partial, int backup_root);
+int btrfs_setup_all_roots(struct btrfs_fs_info *fs_info, u64 root_tree_bytenr,
+ enum btrfs_open_ctree_flags flags);
void btrfs_release_all_roots(struct btrfs_fs_info *fs_info);
void btrfs_cleanup_all_caches(struct btrfs_fs_info *fs_info);
int btrfs_scan_fs_devices(int fd, const char *path,
int run_ioctl);
int btrfs_setup_chunk_tree_and_device_map(struct btrfs_fs_info *fs_info);
-struct btrfs_root *open_ctree(const char *filename, u64 sb_bytenr, int writes);
+struct btrfs_root *open_ctree(const char *filename, u64 sb_bytenr,
+ enum btrfs_open_ctree_flags flags);
struct btrfs_root *open_ctree_fd(int fp, const char *path, u64 sb_bytenr,
- int writes);
-struct btrfs_fs_info *open_ctree_fs_info_restore(const char *filename,
- u64 sb_bytenr, u64 root_tree_bytenr,
- int writes, int partial);
+ enum btrfs_open_ctree_flags flags);
struct btrfs_fs_info *open_ctree_fs_info(const char *filename,
u64 sb_bytenr, u64 root_tree_bytenr,
- int writes, int partial,
- int backup_root);
-struct btrfs_root *open_ctree_with_broken_super(const char *filename,
- u64 sb_bytenr, int writes);
+ enum btrfs_open_ctree_flags flags);
int close_ctree(struct btrfs_root *root);
int write_all_supers(struct btrfs_root *root);
int write_ctree_super(struct btrfs_trans_handle *trans,
exit(1);
}
- root = open_ctree(file, 0, O_RDWR);
+ root = open_ctree(file, 0, OPEN_CTREE_WRITES);
if (!root) {
fprintf(stderr, "Open ctree failed\n");
close(fd);
radix_tree_init();
- root = open_ctree(av[1], BTRFS_SUPER_INFO_OFFSET, O_RDWR);
+ root = open_ctree(av[1], BTRFS_SUPER_INFO_OFFSET, OPEN_CTREE_WRITES);
if (!root) {
fprintf(stderr, "Open ctree failed\n");
exit(1);
btrfs_commit_transaction(trans, root);
close_ctree(root);
exit(1);
- root = open_ctree(av[1], BTRFS_SUPER_INFO_OFFSET, O_RDWR);
+ root = open_ctree(av[1], BTRFS_SUPER_INFO_OFFSET, OPEN_CTREE_WRITES);
if (!root) {
fprintf(stderr, "Open ctree failed\n");
exit(1);
}
close_ctree(root);
- root = open_ctree(av[1], BTRFS_SUPER_INFO_OFFSET, O_RDWR);
+ root = open_ctree(av[1], BTRFS_SUPER_INFO_OFFSET, OPEN_CTREE_WRITES);
if (!root) {
fprintf(stderr, "Open ctree failed\n");
exit(1);
btrfs_commit_transaction(trans, root);
close_ctree(root);
- root = open_ctree(av[1], BTRFS_SUPER_INFO_OFFSET, O_RDWR);
+ root = open_ctree(av[1], BTRFS_SUPER_INFO_OFFSET, OPEN_CTREE_WRITES);
if (!root) {
fprintf(stderr, "Open ctree failed\n");
exit(1);
btrfs_commit_transaction(trans, root);
close_ctree(root);
- root = open_ctree(av[1], BTRFS_SUPER_INFO_OFFSET, O_RDWR);
+ root = open_ctree(av[1], BTRFS_SUPER_INFO_OFFSET, OPEN_CTREE_WRITES);
if (!root) {
fprintf(stderr, "Open ctree failed\n");
exit(1);
}
}
record = recover_get_good_super(&recover);
- root = open_ctree_with_broken_super(record->device_name,
- record->bytenr, 1);
+ root = open_ctree(record->device_name, record->bytenr,
+ OPEN_CTREE_RECOVER_SUPER | OPEN_CTREE_WRITES);
if (!root) {
ret = 3;
goto no_recover;
/* Open the super_block at the default location
* and as read-write.
*/
- root = open_ctree(dev, 0, 1);
+ root = open_ctree(dev, 0, OPEN_CTREE_WRITES);
if (!root) /* errors are printed by open_ctree() */
return -1;