int main(int argc, char *argv[]) { struct btrfs_root *root; int success = 0; int extrefs_flag = 0; int seeding_flag = 0; int seeding_value = 0; int ret; while(1) { int c = getopt(argc, argv, "S:r"); if (c < 0) break; switch(c) { case 'S': seeding_flag = 1; seeding_value = atoi(optarg); break; case 'r': extrefs_flag = 1; break; default: print_usage(); return 1; } } argc = argc - optind; device = argv[optind]; if (argc != 1) { print_usage(); return 1; } if (check_mounted(device)) { fprintf(stderr, "%s is mounted\n", device); return 1; } root = open_ctree(device, 0, 1); if (!root) { fprintf(stderr, "Open ctree failed\n"); return 1; } if (seeding_flag) { ret = update_seeding_flag(root, seeding_value); if (!ret) success++; } if (extrefs_flag) { enable_extrefs_flag(root); success++; } if (success > 0) { ret = 0; } else { root->fs_info->readonly = 1; ret = 1; } close_ctree(root); return ret; }
int main(int argc, char *argv[]) { struct btrfs_root *root; unsigned ctree_flags = OPEN_CTREE_WRITES; int success = 0; int total = 0; int seeding_flag = 0; u64 seeding_value = 0; int random_fsid = 0; char *new_fsid_str = NULL; int ret; u64 super_flags = 0; while(1) { static const struct option long_options[] = { { "help", no_argument, NULL, GETOPT_VAL_HELP}, { NULL, 0, NULL, 0 } }; int c = getopt_long(argc, argv, "S:rxfuU:n", long_options, NULL); if (c < 0) break; switch(c) { case 'S': seeding_flag = 1; seeding_value = arg_strtou64(optarg); break; case 'r': super_flags |= BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF; break; case 'x': super_flags |= BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA; break; case 'n': super_flags |= BTRFS_FEATURE_INCOMPAT_NO_HOLES; break; case 'f': force = 1; break; case 'U': ctree_flags |= OPEN_CTREE_IGNORE_FSID_MISMATCH; new_fsid_str = optarg; break; case 'u': ctree_flags |= OPEN_CTREE_IGNORE_FSID_MISMATCH; random_fsid = 1; break; case GETOPT_VAL_HELP: default: print_usage(); return c != GETOPT_VAL_HELP; } } set_argv0(argv); device = argv[optind]; if (check_argc_exact(argc - optind, 1)) { print_usage(); return 1; } if (random_fsid && new_fsid_str) { error("random fsid can't be used with specified fsid"); return 1; } if (!super_flags && !seeding_flag && !(random_fsid || new_fsid_str)) { error("at least one option should be specified"); print_usage(); return 1; } if (new_fsid_str) { uuid_t tmp; ret = uuid_parse(new_fsid_str, tmp); if (ret < 0) { error("could not parse UUID: %s", new_fsid_str); return 1; } if (!test_uuid_unique(new_fsid_str)) { error("fsid %s is not unique", new_fsid_str); return 1; } } ret = check_mounted(device); if (ret < 0) { error("could not check mount status of %s: %s", device, strerror(-ret)); return 1; } else if (ret) { error("%s is mounted", device); return 1; } root = open_ctree(device, 0, ctree_flags); if (!root) { error("open ctree failed"); return 1; } if (seeding_flag) { if (!seeding_value && !force) { warning( "this is dangerous, clearing the seeding flag may cause the derived device not to be mountable!"); ret = ask_user("We are going to clear the seeding flag, are you sure?"); if (!ret) { fprintf(stderr, "Clear seeding flag canceled\n"); ret = 1; goto out; } } ret = update_seeding_flag(root, seeding_value); if (!ret) success++; total++; } if (super_flags) { ret = set_super_incompat_flags(root, super_flags); if (!ret) success++; total++; } if (random_fsid || new_fsid_str) { if (!force) { warning( "it's highly recommended to run 'btrfs check' before this operation"); warning( "also canceling running UUID change progress may cause corruption"); ret = ask_user("We are going to change UUID, are your sure?"); if (!ret) { fprintf(stderr, "UUID change canceled\n"); ret = 1; goto out; } } ret = change_uuid(root->fs_info, new_fsid_str); if (!ret) success++; total++; } if (success == total) { ret = 0; } else { root->fs_info->readonly = 1; ret = 1; error("btrfstune failed"); } out: close_ctree(root); btrfs_close_all_devices(); return ret; }