int main(int argc, char **argv) { int c; unsigned long checksum = 0; char *str; char *buf; int length = 10; u64 seed = 0; int loop = 0; int i; while ((c = getopt(argc, argv, "l:c:s:h")) != -1) { switch (c) { case 'l': length = atol(optarg); break; case 'c': sscanf(optarg, "%li", &checksum); loop = 1; break; case 's': seed = atoll(optarg); break; case 'h': print_usage(1); case '?': print_usage(255); } } set_argv0(argv); str = argv[optind]; if (!loop) { if (check_argc_exact(argc - optind, 1)) print_usage(255); printf("%12u - %s\n", crc32c(~1, str, strlen(str)), str); return 0; } if (check_argc_exact(argc - optind, 0)) print_usage(255); buf = malloc(length); if (!buf) return -ENOMEM; if (seed) init_rand_seed(seed); while (1) { for (i = 0; i < length; i++) buf[i] = rand_range(94) + 33; if (crc32c(~1, buf, length) == checksum) printf("%12lu - %.*s\n", checksum, length, buf); } return 0; }
static int cmd_balance_pause(int argc, char **argv) { const char *path; int fd; int ret; int e; DIR *dirstream = NULL; if (check_argc_exact(argc, 2)) usage(cmd_balance_pause_usage); path = argv[1]; fd = open_file_or_dir(path, &dirstream); if (fd < 0) { fprintf(stderr, "ERROR: can't access '%s'\n", path); return 1; } ret = ioctl(fd, BTRFS_IOC_BALANCE_CTL, BTRFS_BALANCE_CTL_PAUSE); e = errno; close_file_or_dir(fd, dirstream); if (ret < 0) { fprintf(stderr, "ERROR: balance pause on '%s' failed - %s\n", path, (e == ENOTCONN) ? "Not running" : strerror(e)); if (e == ENOTCONN) return 2; else return 1; } return 0; }
static int cmd_inspect_subvolid_resolve(int argc, char **argv) { int ret; int fd = -1; u64 subvol_id; char path[PATH_MAX]; DIR *dirstream = NULL; clean_args_no_options(argc, argv, cmd_inspect_subvolid_resolve_usage); if (check_argc_exact(argc - optind, 2)) usage(cmd_inspect_subvolid_resolve_usage); fd = btrfs_open_dir(argv[optind + 1], &dirstream, 1); if (fd < 0) { ret = -ENOENT; goto out; } subvol_id = arg_strtou64(argv[optind]); ret = btrfs_subvolid_resolve(fd, path, sizeof(path), subvol_id); if (ret) { error("resolving subvolid %llu error %d", (unsigned long long)subvol_id, ret); goto out; } path[PATH_MAX - 1] = '\0'; printf("%s\n", path); out: close_file_or_dir(fd, dirstream); return ret ? 1 : 0; }
static int qgroup_create(int create, int argc, char **argv) { int ret = 0; int fd; int e; char *path = argv[2]; struct btrfs_ioctl_qgroup_create_args args; DIR *dirstream = NULL; if (check_argc_exact(argc, 3)) return -1; memset(&args, 0, sizeof(args)); args.create = create; args.qgroupid = parse_qgroupid(argv[1]); fd = open_file_or_dir(path, &dirstream); if (fd < 0) { fprintf(stderr, "ERROR: can't access '%s'\n", path); return 1; } ret = ioctl(fd, BTRFS_IOC_QGROUP_CREATE, &args); e = errno; close_file_or_dir(fd, dirstream); if (ret < 0) { fprintf(stderr, "ERROR: unable to %s quota group: %s\n", create ? "create":"destroy", strerror(e)); return 1; } return 0; }
static int cmd_subvol_set_default(int argc, char **argv) { int ret=0, fd, e; u64 objectid; char *path; char *subvolid; DIR *dirstream = NULL; clean_args_no_options(argc, argv, cmd_subvol_set_default_usage); if (check_argc_exact(argc - optind, 2)) usage(cmd_subvol_set_default_usage); subvolid = argv[optind]; path = argv[optind + 1]; objectid = arg_strtou64(subvolid); fd = btrfs_open_dir(path, &dirstream, 1); if (fd < 0) return 1; ret = ioctl(fd, BTRFS_IOC_DEFAULT_SUBVOL, &objectid); e = errno; close_file_or_dir(fd, dirstream); if (ret < 0) { error("unable to set a new default subvolume: %s", strerror(e)); return 1; } return 0; }
static int cmd_inspect_rootid(int argc, char **argv) { int ret; int fd = -1; u64 rootid; DIR *dirstream = NULL; clean_args_no_options(argc, argv, cmd_inspect_rootid_usage); if (check_argc_exact(argc - optind, 1)) usage(cmd_inspect_rootid_usage); fd = btrfs_open_dir(argv[optind], &dirstream, 1); if (fd < 0) { ret = -ENOENT; goto out; } ret = lookup_ino_rootid(fd, &rootid); if (ret) { error("rootid failed with ret=%d", ret); goto out; } printf("%llu\n", (unsigned long long)rootid); out: close_file_or_dir(fd, dirstream); return !!ret; }
static int cmd_inspect_inode_resolve(int argc, char **argv) { int fd; int verbose = 0; int ret; DIR *dirstream = NULL; optind = 1; while (1) { int c = getopt(argc, argv, "v"); if (c < 0) break; switch (c) { case 'v': verbose = 1; break; default: usage(cmd_inspect_inode_resolve_usage); } } if (check_argc_exact(argc - optind, 2)) usage(cmd_inspect_inode_resolve_usage); fd = btrfs_open_dir(argv[optind + 1], &dirstream, 1); if (fd < 0) return 1; ret = __ino_to_path_fd(arg_strtou64(argv[optind]), fd, verbose, argv[optind+1]); close_file_or_dir(fd, dirstream); return !!ret; }
static int cmd_balance_cancel(int argc, char **argv) { const char *path; int fd; int ret; int e; if (check_argc_exact(argc, 2)) usage(cmd_balance_cancel_usage); path = argv[1]; fd = open_file_or_dir(path); if (fd < 0) { fprintf(stderr, "ERROR: can't access to '%s'\n", path); return 12; } ret = ioctl(fd, BTRFS_IOC_BALANCE_CTL, BTRFS_BALANCE_CTL_CANCEL); e = errno; close(fd); if (ret < 0) { fprintf(stderr, "ERROR: balance cancel on '%s' failed - %s\n", path, (e == ENOTCONN) ? "Not in progress" : strerror(e)); return 19; } return 0; }
static int _cmd_qgroup_create(int create, int argc, char **argv) { int ret = 0; int fd; int e; char *path; struct btrfs_ioctl_qgroup_create_args args; DIR *dirstream = NULL; if (check_argc_exact(argc - optind, 2)) return -1; memset(&args, 0, sizeof(args)); args.create = create; args.qgroupid = parse_qgroupid(argv[optind]); path = argv[optind + 1]; fd = btrfs_open_dir(path, &dirstream, 1); if (fd < 0) return 1; ret = ioctl(fd, BTRFS_IOC_QGROUP_CREATE, &args); e = errno; close_file_or_dir(fd, dirstream); if (ret < 0) { error("unable to %s quota group: %s", create ? "create":"destroy", strerror(e)); return 1; } return 0; }
static int quota_ctl(int cmd, int argc, char **argv) { int ret = 0; int fd; int e; char *path = argv[1]; struct btrfs_ioctl_quota_ctl_args args; DIR *dirstream = NULL; if (check_argc_exact(argc, 2)) return -1; memset(&args, 0, sizeof(args)); args.cmd = cmd; fd = open_file_or_dir(path, &dirstream); if (fd < 0) { fprintf(stderr, "ERROR: can't access '%s'\n", path); return 1; } ret = ioctl(fd, BTRFS_IOC_QUOTA_CTL, &args); e = errno; close_file_or_dir(fd, dirstream); if (ret < 0) { fprintf(stderr, "ERROR: quota command failed: %s\n", strerror(e)); return 1; } return 0; }
static int cmd_subvol_set_default(int argc, char **argv) { int ret=0, fd, e; u64 objectid; char *path; char *subvolid; DIR *dirstream = NULL; if (check_argc_exact(argc, 3)) usage(cmd_subvol_set_default_usage); subvolid = argv[1]; path = argv[2]; objectid = arg_strtou64(subvolid); fd = open_file_or_dir(path, &dirstream); if (fd < 0) { fprintf(stderr, "ERROR: can't access '%s'\n", path); return 1; } ret = ioctl(fd, BTRFS_IOC_DEFAULT_SUBVOL, &objectid); e = errno; close_file_or_dir(fd, dirstream); if (ret < 0) { fprintf(stderr, "ERROR: unable to set a new default subvolume - %s\n", strerror(e)); return 1; } return 0; }
static int cmd_balance_pause(int argc, char **argv) { const char *path; int fd; int ret; DIR *dirstream = NULL; clean_args_no_options(argc, argv, cmd_balance_pause_usage); if (check_argc_exact(argc - optind, 1)) return 1; path = argv[optind]; fd = btrfs_open_dir(path, &dirstream, 1); if (fd < 0) return 1; ret = ioctl(fd, BTRFS_IOC_BALANCE_CTL, BTRFS_BALANCE_CTL_PAUSE); if (ret < 0) { error("balance pause on '%s' failed: %s", path, (errno == ENOTCONN) ? "Not running" : strerror(errno)); if (errno == ENOTCONN) ret = 2; else ret = 1; } close_file_or_dir(fd, dirstream); return ret; }
int main(int ac, char **av) { struct btrfs_root *root; struct btrfs_trans_handle *trans; int ret; set_argv0(av); if (check_argc_exact(ac, 2)) print_usage(); radix_tree_init(); if((ret = check_mounted(av[1])) < 0) { fprintf(stderr, "Could not check mount status: %s\n", strerror(-ret)); goto out; } else if(ret) { fprintf(stderr, "%s is currently mounted. Aborting.\n", av[1]); ret = -EBUSY; goto out; } root = open_ctree(av[1], 0, OPEN_CTREE_WRITES); if (root == NULL) return 1; trans = btrfs_start_transaction(root, 1); btrfs_set_super_log_root(root->fs_info->super_copy, 0); btrfs_set_super_log_root_level(root->fs_info->super_copy, 0); btrfs_commit_transaction(trans, root); close_ctree(root); out: return !!ret; }
static int cmd_balance_cancel(int argc, char **argv) { const char *path; int fd; int ret; int e; DIR *dirstream = NULL; clean_args_no_options(argc, argv, cmd_balance_cancel_usage); if (check_argc_exact(argc - optind, 1)) usage(cmd_balance_cancel_usage); path = argv[optind]; fd = btrfs_open_dir(path, &dirstream, 1); if (fd < 0) return 1; ret = ioctl(fd, BTRFS_IOC_BALANCE_CTL, BTRFS_BALANCE_CTL_CANCEL); e = errno; close_file_or_dir(fd, dirstream); if (ret < 0) { error("balance cancel on '%s' failed: %s", path, (e == ENOTCONN) ? "Not in progress" : strerror(e)); if (e == ENOTCONN) return 2; else return 1; } return 0; }
static int cmd_subvol_get_default(int argc, char **argv) { int fd = -1; int ret; char *subvol; struct btrfs_list_filter_set *filter_set; u64 default_id; DIR *dirstream = NULL; if (check_argc_exact(argc, 2)) usage(cmd_subvol_get_default_usage); subvol = argv[1]; fd = open_file_or_dir(subvol, &dirstream); if (fd < 0) { fprintf(stderr, "ERROR: can't access '%s'\n", subvol); return 1; } ret = btrfs_list_get_default_subvolume(fd, &default_id); if (ret) { fprintf(stderr, "ERROR: can't perform the search - %s\n", strerror(errno)); goto out; } ret = 1; if (default_id == 0) { fprintf(stderr, "ERROR: 'default' dir item not found\n"); goto out; } /* no need to resolve roots if FS_TREE is default */ if (default_id == BTRFS_FS_TREE_OBJECTID) { printf("ID 5 (FS_TREE)\n"); ret = 0; goto out; } filter_set = btrfs_list_alloc_filter_set(); btrfs_list_setup_filter(&filter_set, BTRFS_LIST_FILTER_ROOTID, default_id); /* by default we shall print the following columns*/ btrfs_list_setup_print_column(BTRFS_LIST_OBJECTID); btrfs_list_setup_print_column(BTRFS_LIST_GENERATION); btrfs_list_setup_print_column(BTRFS_LIST_TOP_LEVEL); btrfs_list_setup_print_column(BTRFS_LIST_PATH); ret = btrfs_list_subvols_print(fd, filter_set, NULL, BTRFS_LIST_LAYOUT_DEFAULT, 1, NULL); if (filter_set) btrfs_list_free_filter_set(filter_set); out: close_file_or_dir(fd, dirstream); return !!ret; }
static int cmd_subvol_get_default(int argc, char **argv) { int fd = -1; int ret; char *subvol; struct btrfs_list_filter_set *filter_set; u64 default_id; DIR *dirstream = NULL; clean_args_no_options(argc, argv, cmd_subvol_get_default_usage); if (check_argc_exact(argc - optind, 1)) usage(cmd_subvol_get_default_usage); subvol = argv[1]; fd = btrfs_open_dir(subvol, &dirstream, 1); if (fd < 0) return 1; ret = btrfs_list_get_default_subvolume(fd, &default_id); if (ret) { error("failed to look up default subvolume: %s", strerror(errno)); goto out; } ret = 1; if (default_id == 0) { error("'default' dir item not found"); goto out; } /* no need to resolve roots if FS_TREE is default */ if (default_id == BTRFS_FS_TREE_OBJECTID) { printf("ID 5 (FS_TREE)\n"); ret = 0; goto out; } filter_set = btrfs_list_alloc_filter_set(); btrfs_list_setup_filter(&filter_set, BTRFS_LIST_FILTER_ROOTID, default_id); /* by default we shall print the following columns*/ btrfs_list_setup_print_column(BTRFS_LIST_OBJECTID); btrfs_list_setup_print_column(BTRFS_LIST_GENERATION); btrfs_list_setup_print_column(BTRFS_LIST_TOP_LEVEL); btrfs_list_setup_print_column(BTRFS_LIST_PATH); ret = btrfs_list_subvols_print(fd, filter_set, NULL, BTRFS_LIST_LAYOUT_DEFAULT, 1, NULL); if (filter_set) free(filter_set); out: close_file_or_dir(fd, dirstream); return !!ret; }
static int cmd_balance_resume(int argc, char **argv) { struct btrfs_ioctl_balance_args args; const char *path; DIR *dirstream = NULL; int fd; int ret; int e; if (check_argc_exact(argc, 2)) usage(cmd_balance_resume_usage); path = argv[1]; fd = open_file_or_dir(path, &dirstream); if (fd < 0) { fprintf(stderr, "ERROR: can't access '%s'\n", path); return 1; } memset(&args, 0, sizeof(args)); args.flags |= BTRFS_BALANCE_RESUME; ret = ioctl(fd, BTRFS_IOC_BALANCE_V2, &args); e = errno; close_file_or_dir(fd, dirstream); if (ret < 0) { if (e == ECANCELED) { if (args.state & BTRFS_BALANCE_STATE_PAUSE_REQ) fprintf(stderr, "balance paused by user\n"); if (args.state & BTRFS_BALANCE_STATE_CANCEL_REQ) fprintf(stderr, "balance canceled by user\n"); } else if (e == ENOTCONN || e == EINPROGRESS) { fprintf(stderr, "ERROR: balance resume on '%s' " "failed - %s\n", path, (e == ENOTCONN) ? "Not in progress" : "Already running"); if (e == ENOTCONN) return 2; else return 1; } else { fprintf(stderr, "ERROR: error during balancing '%s' - %s\n" "There may be more info in syslog - try dmesg | tail\n", path, strerror(e)); return 1; } } else { printf("Done, had to relocate %llu out of %llu chunks\n", (unsigned long long)args.stat.completed, (unsigned long long)args.stat.considered); } return 0; }
int cmd_receive(int argc, char **argv) { int c; char *tomnt = NULL; char *fromfile = NULL; struct btrfs_receive r; int receive_fd = fileno(stdin); u64 max_errors = 1; int ret; memset(&r, 0, sizeof(r)); r.mnt_fd = -1; r.write_fd = -1; r.dest_dir_fd = -1; while ((c = getopt_long(argc, argv, "evf:", long_opts, NULL)) != -1) { switch (c) { case 'v': g_verbose++; break; case 'f': fromfile = optarg; break; case 'e': r.honor_end_cmd = 1; break; case 'E': max_errors = arg_strtou64(optarg); break; case '?': default: fprintf(stderr, "ERROR: receive args invalid.\n"); return 1; } } if (check_argc_exact(argc - optind, 1)) usage(cmd_receive_usage); tomnt = argv[optind]; if (fromfile) { receive_fd = open(fromfile, O_RDONLY | O_NOATIME); if (receive_fd < 0) { fprintf(stderr, "ERROR: failed to open %s\n", fromfile); return 1; } } ret = do_receive(&r, tomnt, receive_fd, max_errors); return !!ret; }
static int cmd_balance_resume(int argc, char **argv) { struct btrfs_ioctl_balance_args args; const char *path; DIR *dirstream = NULL; int fd; int ret; clean_args_no_options(argc, argv, cmd_balance_resume_usage); if (check_argc_exact(argc - optind, 1)) return 1; path = argv[optind]; fd = btrfs_open_dir(path, &dirstream, 1); if (fd < 0) return 1; memset(&args, 0, sizeof(args)); args.flags |= BTRFS_BALANCE_RESUME; ret = ioctl(fd, BTRFS_IOC_BALANCE_V2, &args); if (ret < 0) { if (errno == ECANCELED) { if (args.state & BTRFS_BALANCE_STATE_PAUSE_REQ) fprintf(stderr, "balance paused by user\n"); if (args.state & BTRFS_BALANCE_STATE_CANCEL_REQ) fprintf(stderr, "balance canceled by user\n"); } else if (errno == ENOTCONN || errno == EINPROGRESS) { error("balance resume on '%s' failed: %s", path, (errno == ENOTCONN) ? "Not in progress" : "Already running"); if (errno == ENOTCONN) ret = 2; else ret = 1; } else { error("error during balancing '%s': %m\n" "There may be more info in syslog - try dmesg | tail", path); ret = 1; } } else { printf("Done, had to relocate %llu out of %llu chunks\n", (unsigned long long)args.stat.completed, (unsigned long long)args.stat.considered); } close_file_or_dir(fd, dirstream); return ret; }
int cmd_rescue_chunk_recover(int argc, char *argv[]) { int ret = 0; char *file; int yes = 0; int verbose = 0; while (1) { int c = getopt(argc, argv, "yvh"); if (c < 0) break; switch (c) { case 'y': yes = 1; break; case 'v': verbose = 1; break; case 'h': default: usage(cmd_rescue_chunk_recover_usage); } } argc = argc - optind; if (check_argc_exact(argc, 1)) usage(cmd_rescue_chunk_recover_usage); file = argv[optind]; ret = check_mounted(file); if (ret < 0) { fprintf(stderr, "Could not check mount status: %s\n", strerror(-ret)); return 1; } else if (ret) { fprintf(stderr, "the device is busy\n"); return 1; } ret = btrfs_recover_chunk_tree(file, verbose, yes); if (!ret) { fprintf(stdout, "Recover the chunk tree successfully.\n"); } else if (ret > 0) { ret = 0; fprintf(stdout, "Abort to rebuild the on-disk chunk tree.\n"); } else { fprintf(stdout, "Fail to recover the chunk tree.\n"); } return ret; }
static int cmd_rescue_chunk_recover(int argc, char *argv[]) { int ret = 0; char *file; int yes = 0; int verbose = 0; optind = 0; while (1) { int c = getopt(argc, argv, "yvh"); if (c < 0) break; switch (c) { case 'y': yes = 1; break; case 'v': verbose = 1; break; case 'h': default: usage(cmd_rescue_chunk_recover_usage); } } if (check_argc_exact(argc - optind, 1)) usage(cmd_rescue_chunk_recover_usage); file = argv[optind]; ret = check_mounted(file); if (ret < 0) { errno = -ret; error("could not check mount status: %m"); return 1; } else if (ret) { error("the device is busy"); return 1; } ret = btrfs_recover_chunk_tree(file, verbose, yes); if (!ret) { fprintf(stdout, "Chunk tree recovered successfully\n"); } else if (ret > 0) { ret = 0; fprintf(stdout, "Chunk tree recovery aborted\n"); } else { fprintf(stdout, "Chunk tree recovery failed\n"); } return ret; }
static int cmd_replace_cancel(int argc, char **argv) { struct btrfs_ioctl_dev_replace_args args = {0}; int ret; int c; int fd; int e; char *path; DIR *dirstream = NULL; while ((c = getopt(argc, argv, "")) != -1) { switch (c) { case '?': default: usage(cmd_replace_cancel_usage); } } if (check_argc_exact(argc - optind, 1)) usage(cmd_replace_cancel_usage); path = argv[optind]; fd = open_file_or_dir(path, &dirstream); if (fd < 0) { fprintf(stderr, "ERROR: can't access \"%s\": %s\n", path, strerror(errno)); return 1; } args.cmd = BTRFS_IOCTL_DEV_REPLACE_CMD_CANCEL; args.result = BTRFS_IOCTL_DEV_REPLACE_RESULT_NO_RESULT; ret = ioctl(fd, BTRFS_IOC_DEV_REPLACE, &args); e = errno; close_file_or_dir(fd, dirstream); if (ret) { fprintf(stderr, "ERROR: ioctl(DEV_REPLACE_CANCEL) failed on \"%s\": %s", path, strerror(e)); if (args.result != BTRFS_IOCTL_DEV_REPLACE_RESULT_NO_RESULT) fprintf(stderr, ", %s\n", replace_dev_result2string(args.result)); else fprintf(stderr, "\n"); return 1; } if (args.result == BTRFS_IOCTL_DEV_REPLACE_RESULT_NOT_STARTED) { printf("INFO: ioctl(DEV_REPLACE_CANCEL)\"%s\": %s\n", path, replace_dev_result2string(args.result)); return 2; } return 0; }
static int cmd_scrub_cancel(int argc, char **argv) { char *path; int ret; int fdmnt; int err; char mp[BTRFS_PATH_NAME_MAX + 1]; struct btrfs_fs_devices *fs_devices_mnt = NULL; if (check_argc_exact(argc, 2)) usage(cmd_scrub_cancel_usage); path = argv[1]; fdmnt = open_file_or_dir(path); if (fdmnt < 0) { fprintf(stderr, "ERROR: scrub cancel failed\n"); return 12; } again: ret = ioctl(fdmnt, BTRFS_IOC_SCRUB_CANCEL, NULL); err = errno; close(fdmnt); if (ret && err == EINVAL) { /* path is no mounted btrfs. try if it's a device */ ret = check_mounted_where(fdmnt, path, mp, sizeof(mp), &fs_devices_mnt); close(fdmnt); if (ret) { fdmnt = open_file_or_dir(mp); if (fdmnt >= 0) { path = mp; goto again; } } } if (ret) { fprintf(stderr, "ERROR: scrub cancel failed on %s: %s\n", path, err == ENOTCONN ? "not running" : strerror(errno)); return 1; } printf("scrub cancelled\n"); return 0; }
static int cmd_rescue_zero_log(int argc, char **argv) { struct btrfs_root *root; struct btrfs_trans_handle *trans; struct btrfs_super_block *sb; char *devname; int ret; clean_args_no_options(argc, argv, cmd_rescue_zero_log_usage); if (check_argc_exact(argc, 2)) usage(cmd_rescue_zero_log_usage); devname = argv[optind]; ret = check_mounted(devname); if (ret < 0) { errno = -ret; error("could not check mount status: %m"); goto out; } else if (ret) { error("%s is currently mounted", devname); ret = -EBUSY; goto out; } root = open_ctree(devname, 0, OPEN_CTREE_WRITES | OPEN_CTREE_PARTIAL); if (!root) { error("could not open ctree"); return 1; } sb = root->fs_info->super_copy; printf("Clearing log on %s, previous log_root %llu, level %u\n", devname, (unsigned long long)btrfs_super_log_root(sb), (unsigned)btrfs_super_log_root_level(sb)); trans = btrfs_start_transaction(root, 1); BUG_ON(IS_ERR(trans)); btrfs_set_super_log_root(sb, 0); btrfs_set_super_log_root_level(sb, 0); btrfs_commit_transaction(trans, root); close_ctree(root); out: return !!ret; }
static int cmd_device_ready(int argc, char **argv) { struct btrfs_ioctl_vol_args args; int fd; int ret; char *path; clean_args_no_options(argc, argv, cmd_device_ready_usage); if (check_argc_exact(argc - optind, 1)) usage(cmd_device_ready_usage); fd = open("/dev/btrfs-control", O_RDWR); if (fd < 0) { perror("failed to open /dev/btrfs-control"); return 1; } path = canonicalize_path(argv[optind]); if (!path) { error("could not canonicalize pathname '%s': %m", argv[optind]); ret = 1; goto out; } if (is_block_device(path) != 1) { error("not a block device: %s", path); ret = 1; goto out; } memset(&args, 0, sizeof(args)); strncpy_null(args.name, path); ret = ioctl(fd, BTRFS_IOC_DEVICES_READY, &args); if (ret < 0) { error("unable to determine if device '%s' is ready for mount: %m", path); ret = 1; } out: free(path); close(fd); return ret; }
static int cmd_scrub_cancel(int argc, char **argv) { char *path; int ret; int fdmnt = -1; DIR *dirstream = NULL; if (check_argc_exact(argc, 2)) usage(cmd_scrub_cancel_usage); path = argv[1]; fdmnt = open_path_or_dev_mnt(path, &dirstream); if (fdmnt < 0) { if (errno == EINVAL) fprintf(stderr, "ERROR: '%s' is not a mounted btrfs device\n", path); else fprintf(stderr, "ERROR: can't access '%s': %s\n", path, strerror(errno)); ret = 1; goto out; } ret = ioctl(fdmnt, BTRFS_IOC_SCRUB_CANCEL, NULL); if (ret < 0) { fprintf(stderr, "ERROR: scrub cancel failed on %s: %s\n", path, errno == ENOTCONN ? "not running" : strerror(errno)); if (errno == ENOTCONN) ret = 2; else ret = 1; goto out; } ret = 0; printf("scrub cancelled\n"); out: close_file_or_dir(fdmnt, dirstream); return ret; }
int main(int ac, char **av) { struct btrfs_root *root; struct btrfs_trans_handle *trans; struct btrfs_super_block *sb; int ret; set_argv0(av); if (check_argc_exact(ac, 2)) print_usage(); radix_tree_init(); printf("WARNING: this utility is deprecated, please use 'btrfs rescue zero-log'\n\n"); if ((ret = check_mounted(av[1])) < 0) { fprintf(stderr, "ERROR: could not check mount status: %s\n", strerror(-ret)); goto out; } else if (ret) { fprintf(stderr, "ERROR: %s is currently mounted\n", av[1]); ret = -EBUSY; goto out; } root = open_ctree(av[1], 0, OPEN_CTREE_WRITES | OPEN_CTREE_PARTIAL); if (!root) { fprintf(stderr, "ERROR: cannot open ctree\n"); return 1; } sb = root->fs_info->super_copy; printf("Clearing log on %s, previous log_root %llu, level %u\n", av[1], (unsigned long long)btrfs_super_log_root(sb), (unsigned)btrfs_super_log_root_level(sb)); trans = btrfs_start_transaction(root, 1); btrfs_set_super_log_root(root->fs_info->super_copy, 0); btrfs_set_super_log_root_level(root->fs_info->super_copy, 0); btrfs_commit_transaction(trans, root); close_ctree(root); out: return !!ret; }
static int cmd_find_new(int argc, char **argv) { int fd; int ret; char *subvol; u64 last_gen; DIR *dirstream = NULL; if (check_argc_exact(argc, 3)) usage(cmd_find_new_usage); subvol = argv[1]; last_gen = arg_strtou64(argv[2]); ret = test_issubvolume(subvol); if (ret < 0) { fprintf(stderr, "ERROR: error accessing '%s'\n", subvol); return 1; } if (!ret) { fprintf(stderr, "ERROR: '%s' is not a subvolume\n", subvol); return 1; } fd = open_file_or_dir(subvol, &dirstream); if (fd < 0) { fprintf(stderr, "ERROR: can't access '%s'\n", subvol); return 1; } ret = ioctl(fd, BTRFS_IOC_SYNC); if (ret < 0) { fprintf(stderr, "ERROR: unable to fs-syncing '%s' - %s\n", subvol, strerror(errno)); close_file_or_dir(fd, dirstream); return 1; } ret = btrfs_list_find_updated_files(fd, 0, last_gen); close_file_or_dir(fd, dirstream); return !!ret; }
static int cmd_subvol_find_new(int argc, char **argv) { int fd; int ret; char *subvol; u64 last_gen; DIR *dirstream = NULL; clean_args_no_options(argc, argv, cmd_subvol_find_new_usage); if (check_argc_exact(argc - optind, 2)) usage(cmd_subvol_find_new_usage); subvol = argv[optind]; last_gen = arg_strtou64(argv[optind + 1]); ret = test_issubvolume(subvol); if (ret < 0) { error("cannot access subvolume %s: %s", subvol, strerror(-ret)); return 1; } if (!ret) { error("not a subvolume: %s", subvol); return 1; } fd = btrfs_open_dir(subvol, &dirstream, 1); if (fd < 0) return 1; ret = ioctl(fd, BTRFS_IOC_SYNC); if (ret < 0) { error("sync ioctl failed on '%s': %s", subvol, strerror(errno)); close_file_or_dir(fd, dirstream); return 1; } ret = btrfs_list_find_updated_files(fd, 0, last_gen); close_file_or_dir(fd, dirstream); return !!ret; }
static int cmd_cancel_replace(int argc, char **argv) { struct btrfs_ioctl_dev_replace_args args = {0}; int ret; int c; int fd; int e; char *path; while ((c = getopt(argc, argv, "")) != -1) { switch (c) { case '?': default: usage(cmd_cancel_replace_usage); } } if (check_argc_exact(argc - optind, 1)) usage(cmd_cancel_replace_usage); path = argv[optind]; fd = open_file_or_dir(path); if (fd < 0) { fprintf(stderr, "ERROR: can't access \"%s\": %s\n", path, strerror(errno)); return -1; } args.cmd = BTRFS_IOCTL_DEV_REPLACE_CMD_CANCEL; ret = ioctl(fd, BTRFS_IOC_DEV_REPLACE, &args); e = errno; close(fd); if (ret) { fprintf(stderr, "ERROR: ioctl(DEV_REPLACE_CANCEL) failed on \"%s\": %s, %s\n", path, strerror(e), replace_dev_result2string(args.result)); return ret; } return 0; }