Hi David, all kindly review/accept this patch set to fix various bugs as in the patch. This patch set is on top David''s integration-20130321 branch and would apply nicely on top the backup sb fixes which was sent separately. Thanks Anand Anand Jain (9): btrfs-progs: root_item generation_v2 is out of sync after btrfsck btrfs-progs: no pending balance is not an error btrfs-progs: mkfs should first check all disks before writing to a disk btrfs-progs: check if btrfs kernel module is loaded btrfs-progs: delete unused function get_mountpt btrfs-progs: mkfs stdout print to match chronology btrfs-progs: cmd replace should check target-dev fully btrfs-progs: btrfs-select-super output is confusing when it fails btrfs-progs: fix btrfs scrub start help btrfs-select-super.c | 6 +- cmds-balance.c | 6 +- cmds-device.c | 56 +++++++++---- cmds-replace.c | 24 +----- cmds-scrub.c | 2 +- mkfs.c | 216 +++++++++++---------------------------------------- root-tree.c | 13 ++++ utils.c | 178 +++++++++++++++++++++++++++++++++--------- utils.h | 2 + 9 files changed, 260 insertions(+), 243 deletions(-) -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Apr-05 05:54 UTC
[PATCH 1/9] [RESEND] btrfs-progs: root_item generation_v2 is out of sync after btrfsck
reproducing steps: mkfs.btrfs /dev/dm-2 -f mount /dev/dm-2 /btrfs umount /btrfs btrfs check /dev/dm-2 --repair mount /dev/dm-2 /btrfs ---- btrfs: mismatching generation and generation_v2 found in root item. This root was probably mounted with an older kernel. Resetting all new fields. ---- btrfs-debug-tree shows change in uuid < root data bytenr 29425664 level 0 dirid 0 refs 1 gen 43 < uuid 293596e8-7888-eb4c-9134-6df9db996fe5 Signed-off-by: Anand Jain <anand.jain@oracle.com> --- root-tree.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/root-tree.c b/root-tree.c index c10d068..4454147 100644 --- a/root-tree.c +++ b/root-tree.c @@ -69,6 +69,7 @@ int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root int ret; int slot; unsigned long ptr; + u32 old_size; path = btrfs_alloc_path(); BUG_ON(!path); @@ -79,6 +80,18 @@ int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root l = path->nodes[0]; slot = path->slots[0]; ptr = btrfs_item_ptr_offset(l, slot); + /* + * If the btrfs-progs is newer and kernel is at + * generation_v1 then we don''t touch v2 items + * otherwise when kernel is at same or greater + * version compared with btrfs-progs then update + * the needed + */ + old_size = btrfs_item_size_nr(l, slot); + if (old_size >= sizeof(*item)) { + btrfs_set_root_generation_v2(item, + btrfs_root_generation(item)); + } write_extent_buffer(l, item, ptr, sizeof(*item)); btrfs_mark_buffer_dirty(path->nodes[0]); out: -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Apr-05 05:54 UTC
[PATCH 2/9] btrfs-progs: no pending balance is not an error
Having no balance running/ paused/completed is a normal situation, so the current output message should be positive with return val zero. As of now: Signed-off-by: Anand Jain <anand.jain@oracle.com> --- cmds-balance.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cmds-balance.c b/cmds-balance.c index f5dc317..a690301 100644 --- a/cmds-balance.c +++ b/cmds-balance.c @@ -662,8 +662,12 @@ static int cmd_balance_status(int argc, char **argv) close(fd); if (ret < 0) { + if (e == ENOTCONN) { + printf("No balance found on ''%s''\n", path); + return 0; + } fprintf(stderr, "ERROR: balance status on ''%s'' failed - %s\n", - path, (e == ENOTCONN) ? "Not in progress" : strerror(e)); + path, strerror(e)); return 19; } -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Apr-05 05:54 UTC
[PATCH 3/9] btrfs-progs: mkfs should first check all disks before writing to a disk
In the cases where one of the disk is not suitable for btrfs, then we would fail the mkfs, however we determine that after we have written btrfs to the preceding disks. At this time if user changes mind for not to use btrfs will left with no choice. So this patch will check if all the provided disks are suitable for the btrfs at once before proceeding to create btrfs on a disk. Further this patch also removed duplicate code to check device suitability for the btrfs. Next, there is an existing bug about the -r mkfs option, which this patch would carry forward most of it. Ref: [PATCH 2/2, RFC] btrfs-progs: overhaul mkfs.btrfs -r option Signed-off-by: Anand Jain <anand.jain@oracle.com> merge with prev Signed-off-by: Anand Jain <anand.jain@oracle.com> --- mkfs.c | 149 ++++++++++++++++++++++++++++++----------------------------------- 1 file changed, 69 insertions(+), 80 deletions(-) diff --git a/mkfs.c b/mkfs.c index c8cb395..7d23520 100644 --- a/mkfs.c +++ b/mkfs.c @@ -1341,6 +1341,46 @@ out: return ret; } +void __test_dev_for_mkfs(char *file, int force_overwrite) +{ + int ret, fd; + + ret = is_swap_device(file); + if (ret < 0) { + fprintf(stderr, "error checking %s status: %s\n", file, + strerror(-ret)); + exit(1); + } + if (ret == 1) { + fprintf(stderr, "%s is a swap device\n", file); + exit(1); + } + if (!force_overwrite) { + if (check_overwrite(file)) { + fprintf(stderr, "Use the -f option to force overwrite.\n"); + exit(1); + } + } + ret = check_mounted(file); + if (ret < 0) { + fprintf(stderr, "error checking %s mount status\n", + file); + exit(1); + } + if (ret == 1) { + fprintf(stderr, "%s is mounted\n", file); + exit(1); + } + /* check if the device is busy */ + fd = open(file, O_RDWR|O_EXCL); + if (fd < 0) { + fprintf(stderr, "unable to open %s: %s\n", file, + strerror(errno)); + exit(1); + } + close(fd); +} + int main(int ac, char **av) { char *file; @@ -1378,6 +1418,8 @@ int main(int ac, char **av) char *pretty_buf; struct btrfs_super_block *super; u64 flags; + int dev_cnt=0; + int saved_optind; while(1) { int c; @@ -1442,51 +1484,36 @@ int main(int ac, char **av) exit(1); if (check_leaf_or_node_size(nodesize, sectorsize)) exit(1); - ac = ac - optind; - if (ac == 0) + saved_optind = optind; + dev_cnt = ac - optind; + if (dev_cnt == 0) print_usage(); + if (source_dir_set && dev_cnt > 1) { + fprintf(stderr, + "The -r option is limited to a single device\n"); + exit(1); + } + while (dev_cnt-- > 0) { + file = av[optind++]; + /* following func would exit on error */ + if (is_block_device(file)) + __test_dev_for_mkfs(file, force_overwrite); + } + + /* if we are here that means all devs are good to btrfsify*/ + optind = saved_optind; + dev_cnt = ac - optind; + printf("\nWARNING! - %s IS EXPERIMENTAL\n", BTRFS_BUILD_VERSION); printf("WARNING! - see http://btrfs.wiki.kernel.org before using\n\n"); - if (source_dir == 0) { - file = av[optind++]; - ret = is_swap_device(file); - if (ret < 0) { - fprintf(stderr, "error checking %s status: %s\n", file, - strerror(-ret)); - exit(1); - } - if (ret == 1) { - fprintf(stderr, "%s is a swap device\n", file); - exit(1); - } - if (!force_overwrite) { - if (check_overwrite(file)) { - fprintf(stderr, "Use the -f option to force overwrite.\n"); - exit(1); - } - } - ret = check_mounted(file); - if (ret < 0) { - fprintf(stderr, "error checking %s mount status\n", file); - exit(1); - } - if (ret == 1) { - fprintf(stderr, "%s is mounted\n", file); - exit(1); - } - ac--; - /* check if the device is busy */ - fd = open(file, O_RDWR|O_EXCL); - if (fd < 0) { - fprintf(stderr, "unable to open %s: %s\n", file, - strerror(errno)); - exit(1); - } - close(fd); + file = av[optind++]; + dev_cnt--; + + if (!source_dir_set) { /* - * open again without O_EXCL so that the problem should not + * open without O_EXCL so that the problem should not * occur by the following processing. * (btrfs_register_one_device() fails if O_EXCL is on) */ @@ -1504,8 +1531,6 @@ int main(int ac, char **av) exit(1); } } else { - ac = 0; - file = av[optind++]; fd = open_target(file); if (fd < 0) { fprintf(stderr, "unable to open the %s\n", file); @@ -1566,53 +1591,19 @@ int main(int ac, char **av) trans = btrfs_start_transaction(root, 1); - if (ac == 0) + if (dev_cnt == 0) goto raid_groups; btrfs_register_one_device(file); zero_end = 1; - while(ac-- > 0) { + while(dev_cnt-- > 0) { int old_mixed = mixed; file = av[optind++]; - if (!force_overwrite) { - if (check_overwrite(file)) { - fprintf(stderr, "Use the -f option to force overwrite.\n"); - exit(1); - } - } - ret = is_swap_device(file); - if (ret < 0) { - fprintf(stderr, "error checking %s status: %s\n", file, - strerror(-ret)); - exit(1); - } - if (ret == 1) { - fprintf(stderr, "%s is a swap device\n", file); - exit(1); - } - ret = check_mounted(file); - if (ret < 0) { - fprintf(stderr, "error checking %s mount status\n", - file); - exit(1); - } - if (ret == 1) { - fprintf(stderr, "%s is mounted\n", file); - exit(1); - } - /* check if the device is busy */ - fd = open(file, O_RDWR|O_EXCL); - if (fd < 0) { - fprintf(stderr, "unable to open %s: %s\n", file, - strerror(errno)); - exit(1); - } - close(fd); /* - * open again without O_EXCL so that the problem should not + * open without O_EXCL so that the problem should not * occur by the following processing. * (btrfs_register_one_device() fails if O_EXCL is on) */ @@ -1693,8 +1684,6 @@ raid_groups: ret = close_ctree(root); BUG_ON(ret); - free(label); return 0; } - -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Apr-05 05:54 UTC
[PATCH 4/9] btrfs-progs: check if btrfs kernel module is loaded
when we have to report no such file error for /dev/btrfs-control we could confirm if btrfs kernel module is loaded and report it and skip registration where appropriate Further this patch pretty prints the dev scan results. Signed-off-by: Anand Jain <anand.jain@oracle.com> --- cmds-device.c | 56 +++++++++++++++++++++++++++++++++++++++++++------------- mkfs.c | 13 +++++++++++-- utils.c | 22 ++++++++++++++++++++++ utils.h | 1 + 4 files changed, 77 insertions(+), 15 deletions(-) diff --git a/cmds-device.c b/cmds-device.c index a90fb67..0e1e6de 100644 --- a/cmds-device.c +++ b/cmds-device.c @@ -185,9 +185,10 @@ static const char * const cmd_scan_dev_usage[] = { static int cmd_scan_dev(int argc, char **argv) { - int i, fd, e; + int i, fd = -1, e, ret = 0; int checklist = 1; int devstart = 1; + u64 flag_reg = 0ull; if( argc > 1 && !strcmp(argv[1],"--all-devices")){ if (check_argc_max(argc, 2)) @@ -197,11 +198,16 @@ static int cmd_scan_dev(int argc, char **argv) devstart += 1; } + if (is_btrfs_kernel_loaded()) + flag_reg = BTRFS_SCAN_REGISTER; + else + fprintf(stderr, "btrfs kernel module is not loaded\n"); + if(argc<=devstart){ int ret; - printf("Scanning for Btrfs filesystems\n"); + printf("Scanning for Btrfs filesystems "); if(checklist) ret = btrfs_scan_block_devices(BTRFS_SCAN_REGISTER); else @@ -210,20 +216,39 @@ static int cmd_scan_dev(int argc, char **argv) fprintf(stderr, "ERROR: error %d while scanning\n", ret); return 18; } + printf("..done\n"); return 0; } - fd = open("/dev/btrfs-control", O_RDWR); - if (fd < 0) { - perror("failed to open /dev/btrfs-control"); - return 10; + if (!flag_reg) + return -1; + + if ((fd = open("/dev/btrfs-control", O_RDWR)) < 0) { + fprintf(stderr, "ERROR: failed to open "\ + "/dev/btrfs-control - %s\n", strerror(errno)); + return -1; } + printf("Scanning for Btrfs in\n"); for( i = devstart ; i < argc ; i++ ){ + int fdt; struct btrfs_ioctl_vol_args args; - int ret; + printf(" %s ", argv[i]); + fflush(stdout); - printf("Scanning for Btrfs filesystems in ''%s''\n", argv[i]); + /* + * If for a multipath (mp) disk user provides the + * non-mp path then open with flag O_EXCL will fail, + * (also ioctl opens with O_EXCL), So test it before + * calling ioctl. + */ + fdt = open(argv[i], O_RDONLY|O_EXCL); + if (fdt < 0) { + perror("ERROR"); + ret = -1; + continue; + } + close(fdt); strncpy_null(args.name, argv[i]); /* @@ -235,15 +260,16 @@ static int cmd_scan_dev(int argc, char **argv) e = errno; if( ret < 0 ){ - close(fd); - fprintf(stderr, "ERROR: unable to scan the device ''%s'' - %s\n", - argv[i], strerror(e)); - return 11; + fprintf(stderr, "ERROR: unable to scan - %s\n", + strerror(e)); + ret = -1; + } else { + printf("found\n"); } } close(fd); - return 0; + return ret; } static const char * const cmd_ready_dev_usage[] = { @@ -261,6 +287,10 @@ static int cmd_ready_dev(int argc, char **argv) if (check_argc_min(argc, 2)) usage(cmd_ready_dev_usage); + if (!is_btrfs_kernel_loaded()) { + fprintf(stderr, "btrfs kernel module is not loaded\n"); + return 10; + } fd = open("/dev/btrfs-control", O_RDWR); if (fd < 0) { perror("failed to open /dev/btrfs-control"); diff --git a/mkfs.c b/mkfs.c index 7d23520..dc4120a 100644 --- a/mkfs.c +++ b/mkfs.c @@ -1420,6 +1420,7 @@ int main(int ac, char **av) u64 flags; int dev_cnt=0; int saved_optind; + int flag_reg=1; while(1) { int c; @@ -1508,6 +1509,12 @@ int main(int ac, char **av) printf("\nWARNING! - %s IS EXPERIMENTAL\n", BTRFS_BUILD_VERSION); printf("WARNING! - see http://btrfs.wiki.kernel.org before using\n\n"); + if (!is_btrfs_kernel_loaded()) { + printf("btrfs kernel module is not loaded, " + "would skip device registration\n"); + flag_reg = 0; + } + file = av[optind++]; dev_cnt--; @@ -1594,7 +1601,8 @@ int main(int ac, char **av) if (dev_cnt == 0) goto raid_groups; - btrfs_register_one_device(file); + if (flag_reg) + btrfs_register_one_device(file); zero_end = 1; while(dev_cnt-- > 0) { @@ -1629,7 +1637,8 @@ int main(int ac, char **av) ret = btrfs_add_to_fsid(trans, root, fd, file, dev_block_count, sectorsize, sectorsize, sectorsize); BUG_ON(ret); - btrfs_register_one_device(file); + if (flag_reg) + btrfs_register_one_device(file); } raid_groups: diff --git a/utils.c b/utils.c index 27574a0..21483b8 100644 --- a/utils.c +++ b/utils.c @@ -1016,6 +1016,23 @@ struct pending_dir { char name[PATH_MAX]; }; +/* + * return 1 for btrfs kernel module loaded + * return 0 for not + */ +int is_btrfs_kernel_loaded() +{ + FILE *mfd = popen("lsmod | grep btrfs", "r"); + char buf[16]; + + if (fread (buf, 1, sizeof (buf), mfd) > 0) { + pclose(mfd); + return 1; + } + pclose(mfd); + return 0; +} + void btrfs_register_one_device(char *fname) { struct btrfs_ioctl_vol_args args; @@ -1023,6 +1040,11 @@ void btrfs_register_one_device(char *fname) int ret; int e; + if (!is_btrfs_kernel_loaded()) { + fprintf(stderr, "btrfs kernel module is not loaded, " + "skipping device registration\n"); + return; + } fd = open("/dev/btrfs-control", O_RDONLY); if (fd < 0) { fprintf(stderr, "failed to open /dev/btrfs-control " diff --git a/utils.h b/utils.h index ab22b02..50957b7 100644 --- a/utils.h +++ b/utils.h @@ -64,6 +64,7 @@ int get_btrfs_mount(const char *path, char *mp, size_t mp_size); int open_path_or_dev_mnt(const char *path); int is_swap_device(const char *file); u64 btrfs_device_size(int fd, struct stat *st); +int is_btrfs_kernel_loaded(); /* Helper to always get proper size of the destination string */ #define strncpy_null(dest, src) __strncpy__null(dest, src, sizeof(dest)) -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Apr-05 05:54 UTC
[PATCH 5/9] [RESEND] btrfs-progs: delete unused function get_mountpt
and get_btrfs_mount has replaced it Signed-off-by: Anand Jain <anand.jain@oracle.com> --- utils.c | 35 ----------------------------------- 1 file changed, 35 deletions(-) diff --git a/utils.c b/utils.c index 21483b8..9c5dbf4 100644 --- a/utils.c +++ b/utils.c @@ -976,41 +976,6 @@ out_mntloop_err: return ret; } -/* Gets the mount point of btrfs filesystem that is using the specified device. - * Returns 0 is everything is good, <0 if we have an error. - * TODO: Fix this fucntion and check_mounted to work with multiple drive BTRFS - * setups. - */ -int get_mountpt(char *dev, char *mntpt, size_t size) -{ - struct mntent *mnt; - FILE *f; - int ret = 0; - - f = setmntent("/proc/mounts", "r"); - if (f == NULL) - return -errno; - - while ((mnt = getmntent(f)) != NULL ) - { - if (strcmp(dev, mnt->mnt_fsname) == 0) - { - strncpy(mntpt, mnt->mnt_dir, size); - if (size) - mntpt[size-1] = 0; - break; - } - } - - if (mnt == NULL) - { - /* We didn''t find an entry so lets report an error */ - ret = -1; - } - - return ret; -} - struct pending_dir { struct list_head list; char name[PATH_MAX]; -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Apr-05 05:55 UTC
[PATCH 6/9] btrfs-progs: mkfs stdout print to match chronology
A trivial fix: To match the events inside to what being printed out before: ---- :: adding device /dev/dm-3 id 2 adding device /dev/dm-4 id 3 adding device /dev/dm-5 id 4 fs created label (null) on /dev/dm-2 nodesize 4096 leafsize 4096 sectorsize 4096 size 213.20GB Btrfs v0.20-rc1-235-gdd21bc1 ---- After: ---- :: fs created label (null) on /dev/dm-2 id 1 nodesize 4096 leafsize 4096 sectorsize 4096 size 59.99GB adding device /dev/dm-3 id 2 adding device /dev/dm-4 id 3 adding device /dev/dm-5 id 4 Btrfs v0.20-rc1-235-gdd21bc1 ---- Signed-off-by: Anand Jain <anand.jain@oracle.com> --- mkfs.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/mkfs.c b/mkfs.c index dc4120a..de83cc8 100644 --- a/mkfs.c +++ b/mkfs.c @@ -1596,6 +1596,12 @@ int main(int ac, char **av) exit(1); } + printf("fs created label %s on %s id 1\n\tnodesize %u leafsize %u " + "sectorsize %u size %s\n", + label, first_file, nodesize, leafsize, sectorsize, + pretty_buf = pretty_sizes(btrfs_super_total_bytes(root->fs_info->super_copy))); + free(pretty_buf); + trans = btrfs_start_transaction(root, 1); if (dev_cnt == 0) @@ -1671,13 +1677,7 @@ raid_groups: printf("Setting RAID5/6 feature flag\n"); } - printf("fs created label %s on %s\n\tnodesize %u leafsize %u " - "sectorsize %u size %s\n", - label, first_file, nodesize, leafsize, sectorsize, - pretty_buf = pretty_sizes(btrfs_super_total_bytes(root->fs_info->super_copy))); - free(pretty_buf); - - printf("%s\n", BTRFS_BUILD_VERSION); + printf("\n%s\n", BTRFS_BUILD_VERSION); btrfs_commit_transaction(trans, root); if (source_dir_set) { -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Apr-05 05:55 UTC
[PATCH 7/9] btrfs-progs: cmd replace should check target-dev fully
as of now in replace command target dev is being checked for mounted and for existing fs, however there is newly introduced __test_dev_for_mkfs in mkfs.c which is suitable for this job, and further it also checks if dev can be opened for with O_EXCL. Its better to use __test_dev_for_mkfs So for this purpose __test_dev_for_mkfs is moved to utils.c and renamed to test_dev_for_mkfs Signed-off-by: Anand Jain <anand.jain@oracle.com> --- cmds-replace.c | 24 ++---------- mkfs.c | 122 +-------------------------------------------------------- utils.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ utils.h | 1 + 4 files changed, 126 insertions(+), 142 deletions(-) diff --git a/cmds-replace.c b/cmds-replace.c index ab34388..abf6307 100644 --- a/cmds-replace.c +++ b/cmds-replace.c @@ -137,8 +137,6 @@ static int cmd_start_replace(int argc, char **argv) char *dstdev; int avoid_reading_from_srcdev = 0; int force_using_targetdev = 0; - u64 total_devs = 1; - struct btrfs_fs_devices *fs_devices_mnt = NULL; struct stat st; u64 dstdev_block_count; int do_not_background = 0; @@ -263,30 +261,14 @@ static int cmd_start_replace(int argc, char **argv) start_args.start.srcdevid = 0; } - ret = check_mounted(dstdev); - if (ret < 0) { - fprintf(stderr, "Error checking %s mount status\n", dstdev); - goto leave_with_error; - } - if (ret == 1) { - fprintf(stderr, - "Error, target device %s is in use and currently mounted!\n", - dstdev); - goto leave_with_error; - } + /* this below func will exit if there is any error */ + test_dev_for_mkfs(dstdev, force_using_targetdev); + fddstdev = open(dstdev, O_RDWR); if (fddstdev < 0) { fprintf(stderr, "Unable to open %s\n", dstdev); goto leave_with_error; } - ret = btrfs_scan_one_device(fddstdev, dstdev, &fs_devices_mnt, - &total_devs, BTRFS_SUPER_INFO_OFFSET, 0ull); - if (ret >= 0 && !force_using_targetdev) { - fprintf(stderr, - "Error, target device %s contains filesystem, use ''-f'' to force overwriting.\n", - dstdev); - goto leave_with_error; - } ret = fstat(fddstdev, &st); if (ret) { fprintf(stderr, "Error: Unable to stat ''%s''\n", dstdev); diff --git a/mkfs.c b/mkfs.c index de83cc8..315b6e3 100644 --- a/mkfs.c +++ b/mkfs.c @@ -1261,126 +1261,6 @@ static int is_ssd(const char *file) return !atoi((const char *)&rotational); } -/* - * Check for existing filesystem or partition table on device. - * Returns: - * 1 for existing fs or partition - * 0 for nothing found - * -1 for internal error - */ -static int -check_overwrite( - char *device) -{ - const char *type; - blkid_probe pr = NULL; - int ret; - blkid_loff_t size; - - if (!device || !*device) - return 0; - - ret = -1; /* will reset on success of all setup calls */ - - pr = blkid_new_probe_from_filename(device); - if (!pr) - goto out; - - size = blkid_probe_get_size(pr); - if (size < 0) - goto out; - - /* nothing to overwrite on a 0-length device */ - if (size == 0) { - ret = 0; - goto out; - } - - ret = blkid_probe_enable_partitions(pr, 1); - if (ret < 0) - goto out; - - ret = blkid_do_fullprobe(pr); - if (ret < 0) - goto out; - - /* - * Blkid returns 1 for nothing found and 0 when it finds a signature, - * but we want the exact opposite, so reverse the return value here. - * - * In addition print some useful diagnostics about what actually is - * on the device. - */ - if (ret) { - ret = 0; - goto out; - } - - if (!blkid_probe_lookup_value(pr, "TYPE", &type, NULL)) { - fprintf(stderr, - "%s appears to contain an existing " - "filesystem (%s).\n", device, type); - } else if (!blkid_probe_lookup_value(pr, "PTTYPE", &type, NULL)) { - fprintf(stderr, - "%s appears to contain a partition " - "table (%s).\n", device, type); - } else { - fprintf(stderr, - "%s appears to contain something weird " - "according to blkid\n", device); - } - ret = 1; - -out: - if (pr) - blkid_free_probe(pr); - if (ret == -1) - fprintf(stderr, - "probe of %s failed, cannot detect " - "existing filesystem.\n", device); - return ret; -} - -void __test_dev_for_mkfs(char *file, int force_overwrite) -{ - int ret, fd; - - ret = is_swap_device(file); - if (ret < 0) { - fprintf(stderr, "error checking %s status: %s\n", file, - strerror(-ret)); - exit(1); - } - if (ret == 1) { - fprintf(stderr, "%s is a swap device\n", file); - exit(1); - } - if (!force_overwrite) { - if (check_overwrite(file)) { - fprintf(stderr, "Use the -f option to force overwrite.\n"); - exit(1); - } - } - ret = check_mounted(file); - if (ret < 0) { - fprintf(stderr, "error checking %s mount status\n", - file); - exit(1); - } - if (ret == 1) { - fprintf(stderr, "%s is mounted\n", file); - exit(1); - } - /* check if the device is busy */ - fd = open(file, O_RDWR|O_EXCL); - if (fd < 0) { - fprintf(stderr, "unable to open %s: %s\n", file, - strerror(errno)); - exit(1); - } - close(fd); -} - int main(int ac, char **av) { char *file; @@ -1499,7 +1379,7 @@ int main(int ac, char **av) file = av[optind++]; /* following func would exit on error */ if (is_block_device(file)) - __test_dev_for_mkfs(file, force_overwrite); + test_dev_for_mkfs(file, force_overwrite); } /* if we are here that means all devs are good to btrfsify*/ diff --git a/utils.c b/utils.c index 9c5dbf4..f4cac96 100644 --- a/utils.c +++ b/utils.c @@ -40,6 +40,7 @@ #include <linux/major.h> #include <linux/kdev_t.h> #include <limits.h> +#include <blkid/blkid.h> #include "kerncompat.h" #include "radix-tree.h" #include "ctree.h" @@ -1706,3 +1707,123 @@ out: return ret; } + +/* + * Check for existing filesystem or partition table on device. + * Returns: + * 1 for existing fs or partition + * 0 for nothing found + * -1 for internal error + */ +static int +check_overwrite( + char *device) +{ + const char *type; + blkid_probe pr = NULL; + int ret; + blkid_loff_t size; + + if (!device || !*device) + return 0; + + ret = -1; /* will reset on success of all setup calls */ + + pr = blkid_new_probe_from_filename(device); + if (!pr) + goto out; + + size = blkid_probe_get_size(pr); + if (size < 0) + goto out; + + /* nothing to overwrite on a 0-length device */ + if (size == 0) { + ret = 0; + goto out; + } + + ret = blkid_probe_enable_partitions(pr, 1); + if (ret < 0) + goto out; + + ret = blkid_do_fullprobe(pr); + if (ret < 0) + goto out; + + /* + * Blkid returns 1 for nothing found and 0 when it finds a signature, + * but we want the exact opposite, so reverse the return value here. + * + * In addition print some useful diagnostics about what actually is + * on the device. + */ + if (ret) { + ret = 0; + goto out; + } + + if (!blkid_probe_lookup_value(pr, "TYPE", &type, NULL)) { + fprintf(stderr, + "%s appears to contain an existing " + "filesystem (%s).\n", device, type); + } else if (!blkid_probe_lookup_value(pr, "PTTYPE", &type, NULL)) { + fprintf(stderr, + "%s appears to contain a partition " + "table (%s).\n", device, type); + } else { + fprintf(stderr, + "%s appears to contain something weird " + "according to blkid\n", device); + } + ret = 1; + +out: + if (pr) + blkid_free_probe(pr); + if (ret == -1) + fprintf(stderr, + "probe of %s failed, cannot detect " + "existing filesystem.\n", device); + return ret; +} + +void test_dev_for_mkfs(char *file, int force_overwrite) +{ + int ret, fd; + + ret = is_swap_device(file); + if (ret < 0) { + fprintf(stderr, "error checking %s status: %s\n", file, + strerror(-ret)); + exit(1); + } + if (ret == 1) { + fprintf(stderr, "%s is a swap device\n", file); + exit(1); + } + if (!force_overwrite) { + if (check_overwrite(file)) { + fprintf(stderr, "Use the -f option to force overwrite.\n"); + exit(1); + } + } + ret = check_mounted(file); + if (ret < 0) { + fprintf(stderr, "error checking %s mount status\n", + file); + exit(1); + } + if (ret == 1) { + fprintf(stderr, "%s is mounted\n", file); + exit(1); + } + /* check if the device is busy */ + fd = open(file, O_RDWR|O_EXCL); + if (fd < 0) { + fprintf(stderr, "unable to open %s: %s\n", file, + strerror(errno)); + exit(1); + } + close(fd); +} diff --git a/utils.h b/utils.h index 50957b7..1e051b5 100644 --- a/utils.h +++ b/utils.h @@ -67,5 +67,6 @@ u64 btrfs_device_size(int fd, struct stat *st); int is_btrfs_kernel_loaded(); /* Helper to always get proper size of the destination string */ #define strncpy_null(dest, src) __strncpy__null(dest, src, sizeof(dest)) +void test_dev_for_mkfs(char *file, int force_overwrite); #endif -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Apr-05 05:55 UTC
[PATCH 8/9] btrfs-progs: btrfs-select-super output is confusing when it fails
Trivial patch: ./btrfs-progs/btrfs-select-super -s 0 /dev/sdc using SB copy 0, bytenr 65536 No valid Btrfs found on /dev/sdc Open ctree failed The line ''using..'' is confusing which gives an indication that command is successful This patch will avoid that when command fails Signed-off-by: Anand Jain <anand.jain@oracle.com> --- btrfs-select-super.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/btrfs-select-super.c b/btrfs-select-super.c index 0c4f5c0..6a458b8 100644 --- a/btrfs-select-super.c +++ b/btrfs-select-super.c @@ -43,7 +43,7 @@ int main(int ac, char **av) { struct btrfs_root *root; int ret; - int num; + int num = 0; u64 bytenr = 0; while(1) { @@ -55,8 +55,6 @@ int main(int ac, char **av) case ''s'': num = atol(optarg); bytenr = btrfs_sb_offset(num); - printf("using SB copy %d, bytenr %llu\n", num, - (unsigned long long)bytenr); break; default: print_usage(); @@ -97,5 +95,7 @@ int main(int ac, char **av) * transaction commit. We just want the super copy we pulled off the * disk to overwrite all the other copies */ + printf("using SB copy %d, bytenr %llu\n", num, + (unsigned long long)bytenr); return ret; } -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
a very trivial fix Signed-off-by: Anand Jain <anand.jain@oracle.com> --- cmds-scrub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmds-scrub.c b/cmds-scrub.c index 5922361..ebb0dc9 100644 --- a/cmds-scrub.c +++ b/cmds-scrub.c @@ -1465,7 +1465,7 @@ out: } static const char * const cmd_scrub_start_usage[] = { - "btrfs scrub start Bdqr] [-c ioprio_class -n ioprio_classdata] <path>|<device>\n", + "btrfs scrub start [Bdqr] [-c ioprio_class -n ioprio_classdata] <path>|<device>\n", "Start a new scrub", "", "-B do not background", -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Stefan Behrens
2013-Apr-05 09:05 UTC
Re: [PATCH 9/9] btrfs-progs: fix btrfs scrub start help
On Fri, 5 Apr 2013 13:55:03 +0800, Anand Jain wrote:> a very trivial fix > > Signed-off-by: Anand Jain <anand.jain@oracle.com> > --- > cmds-scrub.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/cmds-scrub.c b/cmds-scrub.c > index 5922361..ebb0dc9 100644 > --- a/cmds-scrub.c > +++ b/cmds-scrub.c > @@ -1465,7 +1465,7 @@ out: > } > > static const char * const cmd_scrub_start_usage[] = { > - "btrfs scrub start Bdqr] [-c ioprio_class -n ioprio_classdata] <path>|<device>\n", > + "btrfs scrub start [Bdqr] [-c ioprio_class -n ioprio_classdata] <path>|<device>\n", > "Start a new scrub", > "", > "-B do not background", >The ''\n'' at the end is also wrong. In cmd_scrub_resume_usage[] as well. If you happen to send a V2, you could fix these two ''\n'' merge issues, too. -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
a very trivial fix Signed-off-by: Anand Jain <anand.jain@oracle.com> --- cmds-scrub.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmds-scrub.c b/cmds-scrub.c index 5922361..32fcc20 100644 --- a/cmds-scrub.c +++ b/cmds-scrub.c @@ -1465,7 +1465,7 @@ out: } static const char * const cmd_scrub_start_usage[] = { - "btrfs scrub start Bdqr] [-c ioprio_class -n ioprio_classdata] <path>|<device>\n", + "btrfs scrub start [Bdqr] [-c ioprio_class -n ioprio_classdata] <path>|<device>", "Start a new scrub", "", "-B do not background", @@ -1526,7 +1526,7 @@ out: } static const char * const cmd_scrub_resume_usage[] = { - "btrfs scrub resume [-Bdqr] [-c ioprio_class -n ioprio_classdata] <path>|<device>\n", + "btrfs scrub resume [-Bdqr] [-c ioprio_class -n ioprio_classdata] <path>|<device>", "Resume previously canceled or interrupted scrub", "", "-B do not background", -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
a very trivial fix Signed-off-by: Anand Jain <anand.jain@oracle.com> --- cmds-scrub.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmds-scrub.c b/cmds-scrub.c index 5922361..c0dc584 100644 --- a/cmds-scrub.c +++ b/cmds-scrub.c @@ -1465,7 +1465,7 @@ out: } static const char * const cmd_scrub_start_usage[] = { - "btrfs scrub start Bdqr] [-c ioprio_class -n ioprio_classdata] <path>|<device>\n", + "btrfs scrub start [-Bdqr] [-c ioprio_class -n ioprio_classdata] <path>|<device>", "Start a new scrub", "", "-B do not background", @@ -1526,7 +1526,7 @@ out: } static const char * const cmd_scrub_resume_usage[] = { - "btrfs scrub resume [-Bdqr] [-c ioprio_class -n ioprio_classdata] <path>|<device>\n", + "btrfs scrub resume [-Bdqr] [-c ioprio_class -n ioprio_classdata] <path>|<device>", "Resume previously canceled or interrupted scrub", "", "-B do not background", -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Apr-10 08:23 UTC
[PATCH 4/9 v2] btrfs-progs: check if btrfs kernel module is loaded
when we have to report no such file error for /dev/btrfs-control we could confirm if btrfs kernel is present and report it and skip registration where appropriate v1->v2: use /proc/filesystems to check if the btrfs is present Signed-off-by: Anand Jain <anand.jain@oracle.com> --- cmds-device.c | 56 +++++++++++++++++++++++++++++++++++++++++++------------- mkfs.c | 13 +++++++++++-- utils.c | 32 ++++++++++++++++++++++++++++++++ utils.h | 1 + 4 files changed, 87 insertions(+), 15 deletions(-) diff --git a/cmds-device.c b/cmds-device.c index a90fb67..0e1e6de 100644 --- a/cmds-device.c +++ b/cmds-device.c @@ -185,9 +185,10 @@ static const char * const cmd_scan_dev_usage[] = { static int cmd_scan_dev(int argc, char **argv) { - int i, fd, e; + int i, fd = -1, e, ret = 0; int checklist = 1; int devstart = 1; + u64 flag_reg = 0ull; if( argc > 1 && !strcmp(argv[1],"--all-devices")){ if (check_argc_max(argc, 2)) @@ -197,11 +198,16 @@ static int cmd_scan_dev(int argc, char **argv) devstart += 1; } + if (is_btrfs_kernel_loaded()) + flag_reg = BTRFS_SCAN_REGISTER; + else + fprintf(stderr, "btrfs kernel module is not loaded\n"); + if(argc<=devstart){ int ret; - printf("Scanning for Btrfs filesystems\n"); + printf("Scanning for Btrfs filesystems "); if(checklist) ret = btrfs_scan_block_devices(BTRFS_SCAN_REGISTER); else @@ -210,20 +216,39 @@ static int cmd_scan_dev(int argc, char **argv) fprintf(stderr, "ERROR: error %d while scanning\n", ret); return 18; } + printf("..done\n"); return 0; } - fd = open("/dev/btrfs-control", O_RDWR); - if (fd < 0) { - perror("failed to open /dev/btrfs-control"); - return 10; + if (!flag_reg) + return -1; + + if ((fd = open("/dev/btrfs-control", O_RDWR)) < 0) { + fprintf(stderr, "ERROR: failed to open "\ + "/dev/btrfs-control - %s\n", strerror(errno)); + return -1; } + printf("Scanning for Btrfs in\n"); for( i = devstart ; i < argc ; i++ ){ + int fdt; struct btrfs_ioctl_vol_args args; - int ret; + printf(" %s ", argv[i]); + fflush(stdout); - printf("Scanning for Btrfs filesystems in ''%s''\n", argv[i]); + /* + * If for a multipath (mp) disk user provides the + * non-mp path then open with flag O_EXCL will fail, + * (also ioctl opens with O_EXCL), So test it before + * calling ioctl. + */ + fdt = open(argv[i], O_RDONLY|O_EXCL); + if (fdt < 0) { + perror("ERROR"); + ret = -1; + continue; + } + close(fdt); strncpy_null(args.name, argv[i]); /* @@ -235,15 +260,16 @@ static int cmd_scan_dev(int argc, char **argv) e = errno; if( ret < 0 ){ - close(fd); - fprintf(stderr, "ERROR: unable to scan the device ''%s'' - %s\n", - argv[i], strerror(e)); - return 11; + fprintf(stderr, "ERROR: unable to scan - %s\n", + strerror(e)); + ret = -1; + } else { + printf("found\n"); } } close(fd); - return 0; + return ret; } static const char * const cmd_ready_dev_usage[] = { @@ -261,6 +287,10 @@ static int cmd_ready_dev(int argc, char **argv) if (check_argc_min(argc, 2)) usage(cmd_ready_dev_usage); + if (!is_btrfs_kernel_loaded()) { + fprintf(stderr, "btrfs kernel module is not loaded\n"); + return 10; + } fd = open("/dev/btrfs-control", O_RDWR); if (fd < 0) { perror("failed to open /dev/btrfs-control"); diff --git a/mkfs.c b/mkfs.c index 7d23520..dc4120a 100644 --- a/mkfs.c +++ b/mkfs.c @@ -1420,6 +1420,7 @@ int main(int ac, char **av) u64 flags; int dev_cnt=0; int saved_optind; + int flag_reg=1; while(1) { int c; @@ -1508,6 +1509,12 @@ int main(int ac, char **av) printf("\nWARNING! - %s IS EXPERIMENTAL\n", BTRFS_BUILD_VERSION); printf("WARNING! - see http://btrfs.wiki.kernel.org before using\n\n"); + if (!is_btrfs_kernel_loaded()) { + printf("btrfs kernel module is not loaded, " + "would skip device registration\n"); + flag_reg = 0; + } + file = av[optind++]; dev_cnt--; @@ -1594,7 +1601,8 @@ int main(int ac, char **av) if (dev_cnt == 0) goto raid_groups; - btrfs_register_one_device(file); + if (flag_reg) + btrfs_register_one_device(file); zero_end = 1; while(dev_cnt-- > 0) { @@ -1629,7 +1637,8 @@ int main(int ac, char **av) ret = btrfs_add_to_fsid(trans, root, fd, file, dev_block_count, sectorsize, sectorsize, sectorsize); BUG_ON(ret); - btrfs_register_one_device(file); + if (flag_reg) + btrfs_register_one_device(file); } raid_groups: diff --git a/utils.c b/utils.c index 27574a0..0b10316 100644 --- a/utils.c +++ b/utils.c @@ -1016,6 +1016,33 @@ struct pending_dir { char name[PATH_MAX]; }; +/* + * return 1 if btrfs kernel is present + * return 0 for not + */ +int is_btrfs_kernel_loaded() +{ + FILE *pfs; + char fsname[100]; + int ret = -1; + char line[100]; + + pfs = fopen("/proc/filesystems", "r"); + if (pfs) { + ret = 0; + while (fgets(line, sizeof(line), pfs)) { + if (sscanf(line, "nodev %[^#\n]\n", fsname) == 1) continue; + if (sscanf(line, " %[^# \n]\n", fsname) != 1) continue; + if (!strcmp(fsname, "btrfs")) { + ret = 1; + break; + } + } + fclose(pfs); + } + return ret; +} + void btrfs_register_one_device(char *fname) { struct btrfs_ioctl_vol_args args; @@ -1023,6 +1050,11 @@ void btrfs_register_one_device(char *fname) int ret; int e; + if (!is_btrfs_kernel_loaded()) { + fprintf(stderr, "btrfs kernel module is not loaded, " + "skipping device registration\n"); + return; + } fd = open("/dev/btrfs-control", O_RDONLY); if (fd < 0) { fprintf(stderr, "failed to open /dev/btrfs-control " diff --git a/utils.h b/utils.h index ab22b02..50957b7 100644 --- a/utils.h +++ b/utils.h @@ -64,6 +64,7 @@ int get_btrfs_mount(const char *path, char *mp, size_t mp_size); int open_path_or_dev_mnt(const char *path); int is_swap_device(const char *file); u64 btrfs_device_size(int fd, struct stat *st); +int is_btrfs_kernel_loaded(); /* Helper to always get proper size of the destination string */ #define strncpy_null(dest, src) __strncpy__null(dest, src, sizeof(dest)) -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Apr-11 09:58 UTC
[PATCH] btrfs-progs: avoid ioctl for multipath-dev with its non-multipath path
We should avoid using non multi-path (mp) path for mp disks As of now there is no good way (like api) to check that. A workaround way is to check if the O_EXCL open is unsuccessful. This is safe since otherwise the BTRFS_IOC_SCAN_DEV ioctl would fail if the disk-path can not be opened with the flag O_EXCL set. Signed-off-by: Anand Jain <anand.jain@oracle.com> --- utils.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/utils.c b/utils.c index 3308668..0231677 100644 --- a/utils.c +++ b/utils.c @@ -1105,6 +1105,13 @@ again: if (!S_ISBLK(st.st_mode)) { continue; } + + /* Do not test for O_EXCL here since btrfs when + * mounted will open with O_EXCL, and if we don''t + * allow btrfs_scan_one_device pass thru + * btrfs fi show will not show the btrfs fs which + * are mounted + */ fd = open(fullpath, O_RDONLY); if (fd < 0) { /* ignore the following errors: @@ -1122,10 +1129,18 @@ again: &num_devices, BTRFS_SUPER_INFO_OFFSET, 0ull); + close(fd); + if (ret == 0 && flags & BTRFS_SCAN_REGISTER) { + /* Test if the dev is already opened with O_EXCL flag + * if yes then no need to call ioctl since the + * ioctl will anyway fail. + */ + fd = open(fullpath, O_RDONLY|O_EXCL); + if (fd < 0) continue; + close(fd); btrfs_register_one_device(fullpath); } - close(fd); } if (!list_empty(&pending_list)) { free(pending); @@ -1444,6 +1459,12 @@ scan_again: continue; } + /* Do not test for O_EXCL here since btrfs when + * mounted will open with O_EXCL, and if we don''t + * allow btrfs_scan_one_device pass thru + * btrfs fi show will not show the btrfs fs which + * are mounted + */ fd = open(fullpath, O_RDONLY); if (fd < 0) { fprintf(stderr, "failed to open %s: %s\n", @@ -1455,6 +1476,13 @@ scan_again: BTRFS_SUPER_INFO_OFFSET, 0ull); if (ret == 0 && flags & BTRFS_SCAN_REGISTER) { + /* Test if the dev is already opened with O_EXCL flag + * if yes then no need to call ioctl since the + * ioctl will anyway fail. + */ + fd = open(fullpath, O_RDONLY|O_EXCL); + if (fd < 0) continue; + close(fd); btrfs_register_one_device(fullpath); } close(fd); -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
David Sterba
2013-Apr-12 15:57 UTC
Re: [PATCH 2/9] btrfs-progs: no pending balance is not an error
On Fri, Apr 05, 2013 at 01:54:56PM +0800, Anand Jain wrote:> --- a/cmds-balance.c > +++ b/cmds-balance.c > @@ -662,8 +662,12 @@ static int cmd_balance_status(int argc, char **argv) > close(fd); > > if (ret < 0) { > + if (e == ENOTCONN) { > + printf("No balance found on ''%s''\n", path); > + return 0; > + } > fprintf(stderr, "ERROR: balance status on ''%s'' failed - %s\n", > - path, (e == ENOTCONN) ? "Not in progress" : strerror(e));I''m not sure if we want to change the error code if balance is not in progress. That''s the only way to find out if it is so. Let''s say that I have this shell code as a balance monitor and expect it to finish when the balance finishes: while btrfs fi balance status; do sleep 5; done not possible after your change. What we can do is to differentiate the status by a different error code number, let''s say 1 for an error and 2 for ''not in progress''.> + path, strerror(e)); > return 19; > }-- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
David Sterba
2013-Apr-12 16:06 UTC
Re: [PATCH 3/9] btrfs-progs: mkfs should first check all disks before writing to a disk
On Fri, Apr 05, 2013 at 01:54:57PM +0800, Anand Jain wrote:> In the cases where one of the disk is not suitable for > btrfs, then we would fail the mkfs, however we determine > that after we have written btrfs to the preceding disks. > At this time if user changes mind for not to use btrfs > will left with no choice. > > So this patch will check if all the provided disks are > suitable for the btrfs at once before proceeding to > create btrfs on a disk.Good fix and cleanup.> +void __test_dev_for_mkfs(char *file, int force_overwrite) > +{ > + int ret, fd; > + > + ret = is_swap_device(file); > + if (ret < 0) { > + fprintf(stderr, "error checking %s status: %s\n", file, > + strerror(-ret)); > + exit(1);The exit()s were ok when this code was in main(), but should be converted to return for a helper function.> + } > int main(int ac, char **av) > { > char *file; > @@ -1378,6 +1418,8 @@ int main(int ac, char **av) > char *pretty_buf; > struct btrfs_super_block *super; > u64 flags; > + int dev_cnt=0;int dev_cnt = 0;> + int saved_optind; > > while(1) { > int c; > + dev_cnt = ac - optind; > + if (dev_cnt == 0) > print_usage(); > > + if (source_dir_set && dev_cnt > 1) { > + fprintf(stderr, > + "The -r option is limited to a single device\n"); > + exit(1); > + } > + while (dev_cnt-- > 0) { > + file = av[optind++]; > + /* following func would exit on error */ > + if (is_block_device(file)) > + __test_dev_for_mkfs(file, force_overwrite);Catch errors here and exit() eventually.> + } > +-- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
David Sterba
2013-Apr-12 16:23 UTC
Re: [PATCH 4/9 v2] btrfs-progs: check if btrfs kernel module is loaded
On Wed, Apr 10, 2013 at 04:23:21PM +0800, Anand Jain wrote:> diff --git a/cmds-device.c b/cmds-device.c > index a90fb67..0e1e6de 100644 > --- a/cmds-device.c > +++ b/cmds-device.c > @@ -185,9 +185,10 @@ static const char * const cmd_scan_dev_usage[] = { > > static int cmd_scan_dev(int argc, char **argv) > { > - int i, fd, e; > + int i, fd = -1, e, ret = 0; > int checklist = 1; > int devstart = 1; > + u64 flag_reg = 0ull;Do you need it to be u64? I see it''s used only as a bool flag.> + if (is_btrfs_kernel_loaded()) > + flag_reg = BTRFS_SCAN_REGISTER;flag_reg = 1; would work the same, so it should be fine with int.> } > > + printf("Scanning for Btrfs in\n");...> - printf("Scanning for Btrfs filesystems in ''%s''\n", argv[i]);Please keep the word ''filesystem'' in the message> @@ -261,6 +287,10 @@ static int cmd_ready_dev(int argc, char **argv) > if (check_argc_min(argc, 2)) > usage(cmd_ready_dev_usage); > > + if (!is_btrfs_kernel_loaded()) { > + fprintf(stderr, "btrfs kernel module is not loaded\n"); > + return 10;return 1 or -1> --- a/mkfs.c > +++ b/mkfs.c > @@ -1420,6 +1420,7 @@ int main(int ac, char **av) > u64 flags; > int dev_cnt=0; > int saved_optind; > + int flag_reg=1;ah, here it is an ''int''> --- a/utils.c > +++ b/utils.c > @@ -1016,6 +1016,33 @@ struct pending_dir { > +/* > + * return 1 if btrfs kernel is present > + * return 0 for not > + */ > +int is_btrfs_kernel_loaded() > +{ > + FILE *pfs; > + char fsname[100]; > + int ret = -1; > + char line[100]; > + > + pfs = fopen("/proc/filesystems", "r"); > + if (pfs) { > + ret = 0; > + while (fgets(line, sizeof(line), pfs)) { > + if (sscanf(line, "nodev %[^#\n]\n", fsname) == 1) continue;if (!strncmp("nodev", line, 5)) continue;> + if (sscanf(line, " %[^# \n]\n", fsname) != 1) continue; > + if (!strcmp(fsname, "btrfs")) { > + ret = 1; > + break; > + } > + } > + fclose(pfs); > + } > + return ret; > +} > + > void btrfs_register_one_device(char *fname) > { > struct btrfs_ioctl_vol_args args; > @@ -1023,6 +1050,11 @@ void btrfs_register_one_device(char *fname) > int ret; > int e; > > + if (!is_btrfs_kernel_loaded()) { > + fprintf(stderr, "btrfs kernel module is not loaded, " > + "skipping device registration\n"); > + return; > + } > fd = open("/dev/btrfs-control", O_RDONLY); > if (fd < 0) { > fprintf(stderr, "failed to open /dev/btrfs-control "Otherwise ok. david -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Apr-15 02:22 UTC
Re: [PATCH 2/9] btrfs-progs: no pending balance is not an error
On 04/12/2013 11:57 PM, David Sterba wrote:> On Fri, Apr 05, 2013 at 01:54:56PM +0800, Anand Jain wrote: >> --- a/cmds-balance.c >> +++ b/cmds-balance.c >> @@ -662,8 +662,12 @@ static int cmd_balance_status(int argc, char **argv) >> close(fd); >> >> if (ret < 0) { >> + if (e == ENOTCONN) { >> + printf("No balance found on ''%s''\n", path); >> + return 0; >> + } >> fprintf(stderr, "ERROR: balance status on ''%s'' failed - %s\n", >> - path, (e == ENOTCONN) ? "Not in progress" : strerror(e)); > > I''m not sure if we want to change the error code if balance is not in > progress. That''s the only way to find out if it is so. > > Let''s say that I have this shell code as a balance monitor and expect it > to finish when the balance finishes: > > while btrfs fi balance status; do > sleep 5; > done > > not possible after your change. What we can do is to differentiate the > status by a different error code number, let''s say 1 for an error and 2 > for ''not in progress''. > >> + path, strerror(e)); >> return 19; >> }Thanks for the review. good point. Hope the below return code will suffice /* * return codes: * -1 : Error, failed to know if there is any pending balance * 1 : Successful to know status of a pending balance * 0 : when there is no pending balance or completed */ OR do we prefer /* * return codes: * -1 : Error, failed to know if there is any pending balance * 0 : Successful to know status of a pending balance * 1 : when there is no pending balance or completed */ I am fine with either. Thanks, Anand -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
v1->v2: Accepts the review comments from David Accepts the review comments from Stefan Rebase changes Adds the 10/11 and 11/11 which was outside this patch-set Anand Jain (11): btrfs-progs: root_item generation_v2 is out of sync after btrfsck btrfs-progs: no pending balance is not an error btrfs-progs: mkfs should first check all disks before writing to a disk btrfs-progs: cmd replace should check target-dev fully btrfs-progs: mkfs stdout print to match chronology btrfs-progs: check if btrfs kernel module is loaded btrfs-progs: delete unused function get_mountpt btrfs-progs: btrfs-select-super output is confusing when it fails btrfs-progs: fix btrfs scrub start help btrfs-progs: avoid ioctl for multipath-dev with its non-multipath path btrfs-progs: a copy of superblock is zero may not mean btrfs is not there btrfs-select-super.c | 6 +- cmds-balance.c | 16 +++- cmds-device.c | 60 ++++++++++---- cmds-replace.c | 23 +----- cmds-scrub.c | 4 +- disk-io.c | 9 ++- mkfs.c | 219 ++++++++++++------------------------------------- root-tree.c | 13 +++ utils.c | 225 ++++++++++++++++++++++++++++++++++++++++++--------- utils.h | 3 +- 10 files changed, 327 insertions(+), 251 deletions(-) -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Apr-15 06:38 UTC
[PATCH 01/11, RESEND] btrfs-progs: root_item generation_v2 is out of sync after btrfsck
reproducing steps: mkfs.btrfs /dev/dm-2 -f mount /dev/dm-2 /btrfs umount /btrfs btrfs check /dev/dm-2 --repair mount /dev/dm-2 /btrfs ---- btrfs: mismatching generation and generation_v2 found in root item. This root was probably mounted with an older kernel. Resetting all new fields. ---- btrfs-debug-tree shows change in uuid < root data bytenr 29425664 level 0 dirid 0 refs 1 gen 43 < uuid 293596e8-7888-eb4c-9134-6df9db996fe5 Signed-off-by: Anand Jain <anand.jain@oracle.com> --- root-tree.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/root-tree.c b/root-tree.c index c10d068..4454147 100644 --- a/root-tree.c +++ b/root-tree.c @@ -69,6 +69,7 @@ int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root int ret; int slot; unsigned long ptr; + u32 old_size; path = btrfs_alloc_path(); BUG_ON(!path); @@ -79,6 +80,18 @@ int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root l = path->nodes[0]; slot = path->slots[0]; ptr = btrfs_item_ptr_offset(l, slot); + /* + * If the btrfs-progs is newer and kernel is at + * generation_v1 then we don''t touch v2 items + * otherwise when kernel is at same or greater + * version compared with btrfs-progs then update + * the needed + */ + old_size = btrfs_item_size_nr(l, slot); + if (old_size >= sizeof(*item)) { + btrfs_set_root_generation_v2(item, + btrfs_root_generation(item)); + } write_extent_buffer(l, item, ptr, sizeof(*item)); btrfs_mark_buffer_dirty(path->nodes[0]); out: -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Apr-15 06:38 UTC
[PATCH 02/11, RESEND] btrfs-progs: no pending balance is not an error
Having no balance running/ paused/completed is a normal situation, so the current output message should be positive with return val zero. Signed-off-by: Anand Jain <anand.jain@oracle.com> --- cmds-balance.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/cmds-balance.c b/cmds-balance.c index f5dc317..a968e0d 100644 --- a/cmds-balance.c +++ b/cmds-balance.c @@ -616,6 +616,12 @@ static const char * const cmd_balance_status_usage[] = { NULL }; +/* Checks the status of the balance if any + * return codes: + * -1 : Error failed to know if there is any pending balance + * 1 : Successful to know status of a pending balance + * 0 : When there is no pending balance or completed + */ static int cmd_balance_status(int argc, char **argv) { struct btrfs_ioctl_balance_args args; @@ -662,9 +668,13 @@ static int cmd_balance_status(int argc, char **argv) close(fd); if (ret < 0) { + if (e == ENOTCONN) { + printf("No balance found on ''%s''\n", path); + return 0; + } fprintf(stderr, "ERROR: balance status on ''%s'' failed - %s\n", - path, (e == ENOTCONN) ? "Not in progress" : strerror(e)); - return 19; + path, strerror(e)); + return -1; } if (args.state & BTRFS_BALANCE_STATE_RUNNING) { @@ -688,7 +698,7 @@ static int cmd_balance_status(int argc, char **argv) if (verbose) dump_ioctl_balance_args(&args); - return 0; + return 1; } const struct cmd_group balance_cmd_group = { -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Apr-15 06:38 UTC
[PATCH 03/11 v2] btrfs-progs: mkfs should first check all disks before writing to a disk
In the cases where one of the disk is not suitable for btrfs, then we would fail the mkfs, however we determine that after we have written btrfs to the preceding disks. At this time if user changes mind for not to use btrfs will left with no choice. So this patch will check if all the provided disks are suitable for the btrfs at once before proceeding to create btrfs on a disk. Further this patch also removed duplicate code to check device suitability for the btrfs. Next, there is an existing bug about the -r mkfs option, which this patch would carry forward most of it. Ref: [PATCH 2/2, RFC] btrfs-progs: overhaul mkfs.btrfs -r option Signed-off-by: Anand Jain <anand.jain@oracle.com> to merg prev Signed-off-by: Anand Jain <anand.jain@oracle.com> --- mkfs.c | 192 +++++++++++----------------------------------------------------- utils.c | 128 +++++++++++++++++++++++++++++++++++++++++++ utils.h | 1 + 3 files changed, 161 insertions(+), 160 deletions(-) diff --git a/mkfs.c b/mkfs.c index c8cb395..a58b313 100644 --- a/mkfs.c +++ b/mkfs.c @@ -1261,86 +1261,6 @@ static int is_ssd(const char *file) return !atoi((const char *)&rotational); } -/* - * Check for existing filesystem or partition table on device. - * Returns: - * 1 for existing fs or partition - * 0 for nothing found - * -1 for internal error - */ -static int -check_overwrite( - char *device) -{ - const char *type; - blkid_probe pr = NULL; - int ret; - blkid_loff_t size; - - if (!device || !*device) - return 0; - - ret = -1; /* will reset on success of all setup calls */ - - pr = blkid_new_probe_from_filename(device); - if (!pr) - goto out; - - size = blkid_probe_get_size(pr); - if (size < 0) - goto out; - - /* nothing to overwrite on a 0-length device */ - if (size == 0) { - ret = 0; - goto out; - } - - ret = blkid_probe_enable_partitions(pr, 1); - if (ret < 0) - goto out; - - ret = blkid_do_fullprobe(pr); - if (ret < 0) - goto out; - - /* - * Blkid returns 1 for nothing found and 0 when it finds a signature, - * but we want the exact opposite, so reverse the return value here. - * - * In addition print some useful diagnostics about what actually is - * on the device. - */ - if (ret) { - ret = 0; - goto out; - } - - if (!blkid_probe_lookup_value(pr, "TYPE", &type, NULL)) { - fprintf(stderr, - "%s appears to contain an existing " - "filesystem (%s).\n", device, type); - } else if (!blkid_probe_lookup_value(pr, "PTTYPE", &type, NULL)) { - fprintf(stderr, - "%s appears to contain a partition " - "table (%s).\n", device, type); - } else { - fprintf(stderr, - "%s appears to contain something weird " - "according to blkid\n", device); - } - ret = 1; - -out: - if (pr) - blkid_free_probe(pr); - if (ret == -1) - fprintf(stderr, - "probe of %s failed, cannot detect " - "existing filesystem.\n", device); - return ret; -} - int main(int ac, char **av) { char *file; @@ -1378,6 +1298,9 @@ int main(int ac, char **av) char *pretty_buf; struct btrfs_super_block *super; u64 flags; + int dev_cnt = 0; + int saved_optind; + char estr[100]; while(1) { int c; @@ -1442,51 +1365,38 @@ int main(int ac, char **av) exit(1); if (check_leaf_or_node_size(nodesize, sectorsize)) exit(1); - ac = ac - optind; - if (ac == 0) + saved_optind = optind; + dev_cnt = ac - optind; + if (dev_cnt == 0) print_usage(); - printf("\nWARNING! - %s IS EXPERIMENTAL\n", BTRFS_BUILD_VERSION); - printf("WARNING! - see http://btrfs.wiki.kernel.org before using\n\n"); - - if (source_dir == 0) { + if (source_dir_set && dev_cnt > 1) { + fprintf(stderr, + "The -r option is limited to a single device\n"); + exit(1); + } + while (dev_cnt-- > 0) { file = av[optind++]; - ret = is_swap_device(file); - if (ret < 0) { - fprintf(stderr, "error checking %s status: %s\n", file, - strerror(-ret)); - exit(1); - } - if (ret == 1) { - fprintf(stderr, "%s is a swap device\n", file); - exit(1); - } - if (!force_overwrite) { - if (check_overwrite(file)) { - fprintf(stderr, "Use the -f option to force overwrite.\n"); + if (is_block_device(file)) + if (test_dev_for_mkfs(file, force_overwrite, estr)) { + fprintf(stderr, "Error: %s", estr); exit(1); } - } - ret = check_mounted(file); - if (ret < 0) { - fprintf(stderr, "error checking %s mount status\n", file); - exit(1); - } - if (ret == 1) { - fprintf(stderr, "%s is mounted\n", file); - exit(1); - } - ac--; - /* check if the device is busy */ - fd = open(file, O_RDWR|O_EXCL); - if (fd < 0) { - fprintf(stderr, "unable to open %s: %s\n", file, - strerror(errno)); - exit(1); - } - close(fd); + } + + /* if we are here that means all devs are good to btrfsify*/ + optind = saved_optind; + dev_cnt = ac - optind; + + printf("\nWARNING! - %s IS EXPERIMENTAL\n", BTRFS_BUILD_VERSION); + printf("WARNING! - see http://btrfs.wiki.kernel.org before using\n\n"); + + file = av[optind++]; + dev_cnt--; + + if (!source_dir_set) { /* - * open again without O_EXCL so that the problem should not + * open without O_EXCL so that the problem should not * occur by the following processing. * (btrfs_register_one_device() fails if O_EXCL is on) */ @@ -1504,8 +1414,6 @@ int main(int ac, char **av) exit(1); } } else { - ac = 0; - file = av[optind++]; fd = open_target(file); if (fd < 0) { fprintf(stderr, "unable to open the %s\n", file); @@ -1566,53 +1474,19 @@ int main(int ac, char **av) trans = btrfs_start_transaction(root, 1); - if (ac == 0) + if (dev_cnt == 0) goto raid_groups; btrfs_register_one_device(file); zero_end = 1; - while(ac-- > 0) { + while(dev_cnt-- > 0) { int old_mixed = mixed; file = av[optind++]; - if (!force_overwrite) { - if (check_overwrite(file)) { - fprintf(stderr, "Use the -f option to force overwrite.\n"); - exit(1); - } - } - ret = is_swap_device(file); - if (ret < 0) { - fprintf(stderr, "error checking %s status: %s\n", file, - strerror(-ret)); - exit(1); - } - if (ret == 1) { - fprintf(stderr, "%s is a swap device\n", file); - exit(1); - } - ret = check_mounted(file); - if (ret < 0) { - fprintf(stderr, "error checking %s mount status\n", - file); - exit(1); - } - if (ret == 1) { - fprintf(stderr, "%s is mounted\n", file); - exit(1); - } - /* check if the device is busy */ - fd = open(file, O_RDWR|O_EXCL); - if (fd < 0) { - fprintf(stderr, "unable to open %s: %s\n", file, - strerror(errno)); - exit(1); - } - close(fd); /* - * open again without O_EXCL so that the problem should not + * open without O_EXCL so that the problem should not * occur by the following processing. * (btrfs_register_one_device() fails if O_EXCL is on) */ @@ -1693,8 +1567,6 @@ raid_groups: ret = close_ctree(root); BUG_ON(ret); - free(label); return 0; } - diff --git a/utils.c b/utils.c index 27574a0..53ee919 100644 --- a/utils.c +++ b/utils.c @@ -40,6 +40,7 @@ #include <linux/major.h> #include <linux/kdev_t.h> #include <limits.h> +#include <blkid/blkid.h> #include "kerncompat.h" #include "radix-tree.h" #include "ctree.h" @@ -1719,3 +1720,130 @@ out: return ret; } + +/* + * Check for existing filesystem or partition table on device. + * Returns: + * 1 for existing fs or partition + * 0 for nothing found + * -1 for internal error + */ +static int +check_overwrite( + char *device) +{ + const char *type; + blkid_probe pr = NULL; + int ret; + blkid_loff_t size; + + if (!device || !*device) + return 0; + + ret = -1; /* will reset on success of all setup calls */ + + pr = blkid_new_probe_from_filename(device); + if (!pr) + goto out; + + size = blkid_probe_get_size(pr); + if (size < 0) + goto out; + + /* nothing to overwrite on a 0-length device */ + if (size == 0) { + ret = 0; + goto out; + } + + ret = blkid_probe_enable_partitions(pr, 1); + if (ret < 0) + goto out; + + ret = blkid_do_fullprobe(pr); + if (ret < 0) + goto out; + + /* + * Blkid returns 1 for nothing found and 0 when it finds a signature, + * but we want the exact opposite, so reverse the return value here. + * + * In addition print some useful diagnostics about what actually is + * on the device. + */ + if (ret) { + ret = 0; + goto out; + } + + if (!blkid_probe_lookup_value(pr, "TYPE", &type, NULL)) { + fprintf(stderr, + "%s appears to contain an existing " + "filesystem (%s).\n", device, type); + } else if (!blkid_probe_lookup_value(pr, "PTTYPE", &type, NULL)) { + fprintf(stderr, + "%s appears to contain a partition " + "table (%s).\n", device, type); + } else { + fprintf(stderr, + "%s appears to contain something weird " + "according to blkid\n", device); + } + ret = 1; + +out: + if (pr) + blkid_free_probe(pr); + if (ret == -1) + fprintf(stderr, + "probe of %s failed, cannot detect " + "existing filesystem.\n", device); + return ret; +} + +/* Check if disk is suitable for btrfs + * returns: + * 1: something is wrong, estr provides the error + * 0: all is fine + */ +int test_dev_for_mkfs(char *file, int force_overwrite, char *estr) +{ + int ret, fd; + size_t sz = 100; + + ret = is_swap_device(file); + if (ret < 0) { + snprintf(estr, sz, "error checking %s status: %s\n", file, + strerror(-ret)); + return 1; + } + if (ret == 1) { + snprintf(estr, sz, "%s is a swap device\n", file); + return 1; + } + if (!force_overwrite) { + if (check_overwrite(file)) { + snprintf(estr, sz, "Use the -f option to force overwrite.\n"); + return 1; + } + } + ret = check_mounted(file); + if (ret < 0) { + snprintf(estr, sz, "error checking %s mount status\n", + file); + return 1; + } + if (ret == 1) { + snprintf(estr, sz, "%s is mounted\n", file); + return 1; + } + /* check if the device is busy */ + fd = open(file, O_RDWR|O_EXCL); + if (fd < 0) { + snprintf(estr, sz, "unable to open %s: %s\n", file, + strerror(errno)); + return 1; + } + close(fd); + return 0; +} diff --git a/utils.h b/utils.h index ab22b02..989c4e5 100644 --- a/utils.h +++ b/utils.h @@ -66,5 +66,6 @@ int is_swap_device(const char *file); u64 btrfs_device_size(int fd, struct stat *st); /* Helper to always get proper size of the destination string */ #define strncpy_null(dest, src) __strncpy__null(dest, src, sizeof(dest)) +int test_dev_for_mkfs(char *file, int force_overwrite, char *estr); #endif -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Apr-15 06:38 UTC
[PATCH 04/11 v2] btrfs-progs: cmd replace should check target-dev fully
as of now in replace command target dev is being checked for mounted and for existing fs, however there is newly introduced test_dev_for_mkfs in mkfs.c which is suitable for this job, and further it also checks if dev can be opened for with O_EXCL. Its better to use test_dev_for_mkfs Signed-off-by: Anand Jain <anand.jain@oracle.com> --- cmds-replace.c | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/cmds-replace.c b/cmds-replace.c index ab34388..4e881b7 100644 --- a/cmds-replace.c +++ b/cmds-replace.c @@ -137,12 +137,11 @@ static int cmd_start_replace(int argc, char **argv) char *dstdev; int avoid_reading_from_srcdev = 0; int force_using_targetdev = 0; - u64 total_devs = 1; - struct btrfs_fs_devices *fs_devices_mnt = NULL; struct stat st; u64 dstdev_block_count; int do_not_background = 0; int mixed = 0; + char estr[100]; while ((c = getopt(argc, argv, "Brf")) != -1) { switch (c) { @@ -263,30 +262,16 @@ static int cmd_start_replace(int argc, char **argv) start_args.start.srcdevid = 0; } - ret = check_mounted(dstdev); - if (ret < 0) { - fprintf(stderr, "Error checking %s mount status\n", dstdev); - goto leave_with_error; - } - if (ret == 1) { - fprintf(stderr, - "Error, target device %s is in use and currently mounted!\n", - dstdev); + if (test_dev_for_mkfs(dstdev, force_using_targetdev, estr)) { + fprintf(stderr, "Error: %s", estr); goto leave_with_error; } + fddstdev = open(dstdev, O_RDWR); if (fddstdev < 0) { fprintf(stderr, "Unable to open %s\n", dstdev); goto leave_with_error; } - ret = btrfs_scan_one_device(fddstdev, dstdev, &fs_devices_mnt, - &total_devs, BTRFS_SUPER_INFO_OFFSET, 0ull); - if (ret >= 0 && !force_using_targetdev) { - fprintf(stderr, - "Error, target device %s contains filesystem, use ''-f'' to force overwriting.\n", - dstdev); - goto leave_with_error; - } ret = fstat(fddstdev, &st); if (ret) { fprintf(stderr, "Error: Unable to stat ''%s''\n", dstdev); -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Apr-15 06:38 UTC
[PATCH 05/11, RESEND] btrfs-progs: mkfs stdout print to match chronology
A trivial fix: To match the events inside to what being printed out before: ---- :: adding device /dev/dm-3 id 2 adding device /dev/dm-4 id 3 adding device /dev/dm-5 id 4 fs created label (null) on /dev/dm-2 nodesize 4096 leafsize 4096 sectorsize 4096 size 213.20GB Btrfs v0.20-rc1-235-gdd21bc1 ---- After: ---- :: fs created label (null) on /dev/dm-2 id 1 nodesize 4096 leafsize 4096 sectorsize 4096 size 59.99GB adding device /dev/dm-3 id 2 adding device /dev/dm-4 id 3 adding device /dev/dm-5 id 4 Btrfs v0.20-rc1-235-gdd21bc1 ---- Signed-off-by: Anand Jain <anand.jain@oracle.com> --- mkfs.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/mkfs.c b/mkfs.c index a58b313..2eb3087 100644 --- a/mkfs.c +++ b/mkfs.c @@ -1472,6 +1472,12 @@ int main(int ac, char **av) exit(1); } + printf("fs created label %s on %s id 1\n\tnodesize %u leafsize %u " + "sectorsize %u size %s\n", + label, first_file, nodesize, leafsize, sectorsize, + pretty_buf = pretty_sizes(btrfs_super_total_bytes(root->fs_info->super_copy))); + free(pretty_buf); + trans = btrfs_start_transaction(root, 1); if (dev_cnt == 0) @@ -1545,13 +1551,7 @@ raid_groups: printf("Setting RAID5/6 feature flag\n"); } - printf("fs created label %s on %s\n\tnodesize %u leafsize %u " - "sectorsize %u size %s\n", - label, first_file, nodesize, leafsize, sectorsize, - pretty_buf = pretty_sizes(btrfs_super_total_bytes(root->fs_info->super_copy))); - free(pretty_buf); - - printf("%s\n", BTRFS_BUILD_VERSION); + printf("\n%s\n", BTRFS_BUILD_VERSION); btrfs_commit_transaction(trans, root); if (source_dir_set) { -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Apr-15 06:38 UTC
[PATCH 06/11, v2] btrfs-progs: check if btrfs kernel module is loaded
when we have to report no such file error for /dev/btrfs-control we could confirm if btrfs kernel is present and report it and skip registration where appropriate v1->v2: use /proc/filesystems to check if the btrfs is present Signed-off-by: Anand Jain <anand.jain@oracle.com> --- cmds-device.c | 60 ++++++++++++++++++++++++++++++++++++++++++++--------------- mkfs.c | 13 +++++++++++-- utils.c | 32 +++++++++++++++++++++++++++++++ utils.h | 2 +- 4 files changed, 89 insertions(+), 18 deletions(-) diff --git a/cmds-device.c b/cmds-device.c index a90fb67..4a134fa 100644 --- a/cmds-device.c +++ b/cmds-device.c @@ -185,9 +185,10 @@ static const char * const cmd_scan_dev_usage[] = { static int cmd_scan_dev(int argc, char **argv) { - int i, fd, e; + int i, fd = -1, e, ret = 0; int checklist = 1; int devstart = 1; + u64 flag_reg = 0ull; if( argc > 1 && !strcmp(argv[1],"--all-devices")){ if (check_argc_max(argc, 2)) @@ -197,33 +198,57 @@ static int cmd_scan_dev(int argc, char **argv) devstart += 1; } + if (is_btrfs_kernel_loaded()) + flag_reg = BTRFS_SCAN_REGISTER; + else + fprintf(stderr, "btrfs kernel module is not loaded\n"); + if(argc<=devstart){ int ret; - printf("Scanning for Btrfs filesystems\n"); + printf("Scanning for Btrfs filesystems "); if(checklist) - ret = btrfs_scan_block_devices(BTRFS_SCAN_REGISTER); + ret = btrfs_scan_block_devices(flag_reg); else - ret = btrfs_scan_one_dir("/dev", BTRFS_SCAN_REGISTER); + ret = btrfs_scan_one_dir("/dev", flag_reg); if (ret){ fprintf(stderr, "ERROR: error %d while scanning\n", ret); return 18; } + printf("..done\n"); return 0; } - fd = open("/dev/btrfs-control", O_RDWR); - if (fd < 0) { - perror("failed to open /dev/btrfs-control"); - return 10; + if (!flag_reg) + return -1; + + if ((fd = open("/dev/btrfs-control", O_RDWR)) < 0) { + fprintf(stderr, "ERROR: failed to open "\ + "/dev/btrfs-control - %s\n", strerror(errno)); + return -1; } + printf("Scanning for Btrfs in\n"); for( i = devstart ; i < argc ; i++ ){ + int fdt; struct btrfs_ioctl_vol_args args; - int ret; + printf(" %s ", argv[i]); + fflush(stdout); - printf("Scanning for Btrfs filesystems in ''%s''\n", argv[i]); + /* + * If for a multipath (mp) disk user provides the + * non-mp path then open with flag O_EXCL will fail, + * (also ioctl opens with O_EXCL), So test it before + * calling ioctl. + */ + fdt = open(argv[i], O_RDONLY|O_EXCL); + if (fdt < 0) { + perror("ERROR"); + ret = -1; + continue; + } + close(fdt); strncpy_null(args.name, argv[i]); /* @@ -235,15 +260,16 @@ static int cmd_scan_dev(int argc, char **argv) e = errno; if( ret < 0 ){ - close(fd); - fprintf(stderr, "ERROR: unable to scan the device ''%s'' - %s\n", - argv[i], strerror(e)); - return 11; + fprintf(stderr, "ERROR: unable to scan - %s\n", + strerror(e)); + ret = -1; + } else { + printf("found\n"); } } close(fd); - return 0; + return ret; } static const char * const cmd_ready_dev_usage[] = { @@ -261,6 +287,10 @@ static int cmd_ready_dev(int argc, char **argv) if (check_argc_min(argc, 2)) usage(cmd_ready_dev_usage); + if (!is_btrfs_kernel_loaded()) { + fprintf(stderr, "btrfs kernel module is not loaded\n"); + return 10; + } fd = open("/dev/btrfs-control", O_RDWR); if (fd < 0) { perror("failed to open /dev/btrfs-control"); diff --git a/mkfs.c b/mkfs.c index 2eb3087..e8b22cc 100644 --- a/mkfs.c +++ b/mkfs.c @@ -1301,6 +1301,7 @@ int main(int ac, char **av) int dev_cnt = 0; int saved_optind; char estr[100]; + int flag_reg = 1; while(1) { int c; @@ -1391,6 +1392,12 @@ int main(int ac, char **av) printf("\nWARNING! - %s IS EXPERIMENTAL\n", BTRFS_BUILD_VERSION); printf("WARNING! - see http://btrfs.wiki.kernel.org before using\n\n"); + if (!is_btrfs_kernel_loaded()) { + printf("btrfs kernel module is not loaded, " + "would skip device registration\n"); + flag_reg = 0; + } + file = av[optind++]; dev_cnt--; @@ -1483,7 +1490,8 @@ int main(int ac, char **av) if (dev_cnt == 0) goto raid_groups; - btrfs_register_one_device(file); + if (flag_reg) + btrfs_register_one_device(file); zero_end = 1; while(dev_cnt-- > 0) { @@ -1518,7 +1526,8 @@ int main(int ac, char **av) ret = btrfs_add_to_fsid(trans, root, fd, file, dev_block_count, sectorsize, sectorsize, sectorsize); BUG_ON(ret); - btrfs_register_one_device(file); + if (flag_reg) + btrfs_register_one_device(file); } raid_groups: diff --git a/utils.c b/utils.c index 53ee919..67419da 100644 --- a/utils.c +++ b/utils.c @@ -1017,6 +1017,33 @@ struct pending_dir { char name[PATH_MAX]; }; +/* + * return 1 if btrfs kernel is present + * return 0 for not + */ +int is_btrfs_kernel_loaded() +{ + FILE *pfs; + char fsname[100]; + int ret = -1; + char line[100]; + + pfs = fopen("/proc/filesystems", "r"); + if (pfs) { + ret = 0; + while (fgets(line, sizeof(line), pfs)) { + if (sscanf(line, "nodev %[^#\n]\n", fsname) == 1) continue; + if (sscanf(line, " %[^# \n]\n", fsname) != 1) continue; + if (!strcmp(fsname, "btrfs")) { + ret = 1; + break; + } + } + fclose(pfs); + } + return ret; +} + void btrfs_register_one_device(char *fname) { struct btrfs_ioctl_vol_args args; @@ -1024,6 +1051,11 @@ void btrfs_register_one_device(char *fname) int ret; int e; + if (!is_btrfs_kernel_loaded()) { + fprintf(stderr, "btrfs kernel module is not loaded, " + "skipping device registration\n"); + return; + } fd = open("/dev/btrfs-control", O_RDONLY); if (fd < 0) { fprintf(stderr, "failed to open /dev/btrfs-control " diff --git a/utils.h b/utils.h index 989c4e5..b383057 100644 --- a/utils.h +++ b/utils.h @@ -67,5 +67,5 @@ u64 btrfs_device_size(int fd, struct stat *st); /* Helper to always get proper size of the destination string */ #define strncpy_null(dest, src) __strncpy__null(dest, src, sizeof(dest)) int test_dev_for_mkfs(char *file, int force_overwrite, char *estr); - +int is_btrfs_kernel_loaded(); #endif -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Apr-15 06:38 UTC
[PATCH 07/11, RESEND] btrfs-progs: delete unused function get_mountpt
and get_btrfs_mount has replaced it Signed-off-by: Anand Jain <anand.jain@oracle.com> --- utils.c | 35 ----------------------------------- 1 file changed, 35 deletions(-) diff --git a/utils.c b/utils.c index 67419da..926421c 100644 --- a/utils.c +++ b/utils.c @@ -977,41 +977,6 @@ out_mntloop_err: return ret; } -/* Gets the mount point of btrfs filesystem that is using the specified device. - * Returns 0 is everything is good, <0 if we have an error. - * TODO: Fix this fucntion and check_mounted to work with multiple drive BTRFS - * setups. - */ -int get_mountpt(char *dev, char *mntpt, size_t size) -{ - struct mntent *mnt; - FILE *f; - int ret = 0; - - f = setmntent("/proc/mounts", "r"); - if (f == NULL) - return -errno; - - while ((mnt = getmntent(f)) != NULL ) - { - if (strcmp(dev, mnt->mnt_fsname) == 0) - { - strncpy(mntpt, mnt->mnt_dir, size); - if (size) - mntpt[size-1] = 0; - break; - } - } - - if (mnt == NULL) - { - /* We didn''t find an entry so lets report an error */ - ret = -1; - } - - return ret; -} - struct pending_dir { struct list_head list; char name[PATH_MAX]; -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Apr-15 06:38 UTC
[PATCH 08/11, RESEND] btrfs-progs: btrfs-select-super output is confusing when it fails
Trivial patch: ./btrfs-progs/btrfs-select-super -s 0 /dev/sdc using SB copy 0, bytenr 65536 No valid Btrfs found on /dev/sdc Open ctree failed The line ''using..'' is confusing which gives an indication that command is successful This patch will avoid that when command fails Signed-off-by: Anand Jain <anand.jain@oracle.com> --- btrfs-select-super.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/btrfs-select-super.c b/btrfs-select-super.c index 0c4f5c0..6a458b8 100644 --- a/btrfs-select-super.c +++ b/btrfs-select-super.c @@ -43,7 +43,7 @@ int main(int ac, char **av) { struct btrfs_root *root; int ret; - int num; + int num = 0; u64 bytenr = 0; while(1) { @@ -55,8 +55,6 @@ int main(int ac, char **av) case ''s'': num = atol(optarg); bytenr = btrfs_sb_offset(num); - printf("using SB copy %d, bytenr %llu\n", num, - (unsigned long long)bytenr); break; default: print_usage(); @@ -97,5 +95,7 @@ int main(int ac, char **av) * transaction commit. We just want the super copy we pulled off the * disk to overwrite all the other copies */ + printf("using SB copy %d, bytenr %llu\n", num, + (unsigned long long)bytenr); return ret; } -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Apr-15 06:38 UTC
[PATCH 09/11, RESEND] btrfs-progs: fix btrfs scrub start help
a very trivial fix Signed-off-by: Anand Jain <anand.jain@oracle.com> --- cmds-scrub.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmds-scrub.c b/cmds-scrub.c index 5922361..c0dc584 100644 --- a/cmds-scrub.c +++ b/cmds-scrub.c @@ -1465,7 +1465,7 @@ out: } static const char * const cmd_scrub_start_usage[] = { - "btrfs scrub start Bdqr] [-c ioprio_class -n ioprio_classdata] <path>|<device>\n", + "btrfs scrub start [-Bdqr] [-c ioprio_class -n ioprio_classdata] <path>|<device>", "Start a new scrub", "", "-B do not background", @@ -1526,7 +1526,7 @@ out: } static const char * const cmd_scrub_resume_usage[] = { - "btrfs scrub resume [-Bdqr] [-c ioprio_class -n ioprio_classdata] <path>|<device>\n", + "btrfs scrub resume [-Bdqr] [-c ioprio_class -n ioprio_classdata] <path>|<device>", "Resume previously canceled or interrupted scrub", "", "-B do not background", -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Apr-15 06:38 UTC
[PATCH 10/11, RESEND] btrfs-progs: avoid ioctl for multipath-dev with its non-multipath path
We should avoid using non multi-path (mp) path for mp disks As of now there is no good way (like api) to check that. A workaround way is to check if the O_EXCL open is unsuccessful. This is safe since otherwise the BTRFS_IOC_SCAN_DEV ioctl would fail if the disk-path can not be opened with the flag O_EXCL set. Signed-off-by: Anand Jain <anand.jain@oracle.com> --- utils.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/utils.c b/utils.c index 926421c..158912c 100644 --- a/utils.c +++ b/utils.c @@ -1105,6 +1105,13 @@ again: if (!S_ISBLK(st.st_mode)) { continue; } + + /* Do not test for O_EXCL here since btrfs when + * mounted will open with O_EXCL, and if we don''t + * allow btrfs_scan_one_device pass thru + * btrfs fi show will not show the btrfs fs which + * are mounted + */ fd = open(fullpath, O_RDONLY); if (fd < 0) { /* ignore the following errors: @@ -1122,10 +1129,18 @@ again: &num_devices, BTRFS_SUPER_INFO_OFFSET, 0ull); + close(fd); + if (ret == 0 && flags & BTRFS_SCAN_REGISTER) { + /* Test if the dev is already opened with O_EXCL flag + * if yes then no need to call ioctl since the + * ioctl will anyway fail. + */ + fd = open(fullpath, O_RDONLY|O_EXCL); + if (fd < 0) continue; + close(fd); btrfs_register_one_device(fullpath); } - close(fd); } if (!list_empty(&pending_list)) { free(pending); @@ -1444,6 +1459,12 @@ scan_again: continue; } + /* Do not test for O_EXCL here since btrfs when + * mounted will open with O_EXCL, and if we don''t + * allow btrfs_scan_one_device pass thru + * btrfs fi show will not show the btrfs fs which + * are mounted + */ fd = open(fullpath, O_RDONLY); if (fd < 0) { fprintf(stderr, "failed to open %s: %s\n", @@ -1455,6 +1476,13 @@ scan_again: BTRFS_SUPER_INFO_OFFSET, 0ull); if (ret == 0 && flags & BTRFS_SCAN_REGISTER) { + /* Test if the dev is already opened with O_EXCL flag + * if yes then no need to call ioctl since the + * ioctl will anyway fail. + */ + fd = open(fullpath, O_RDONLY|O_EXCL); + if (fd < 0) continue; + close(fd); btrfs_register_one_device(fullpath); } close(fd); -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Apr-15 06:38 UTC
[PATCH 11/11, RESEND] btrfs-progs: a copy of superblock is zero may not mean btrfs is not there
If one of the copy of the superblock is zero it does not confirm to us that btrfs isn''t there on that disk. When we are having more than one copy of superblock we should rather let the for loop to continue to check other copies. the following test case and results would justify the fix mkfs.btrfs /dev/sdb /dev/sdc -f mount /dev/sdb /btrfs dd if=/dev/zero bs=1 count=8 of=/dev/sdc seek=$((64*1024+64)) ~/before/btrfs-select-super -s 1 /dev/sdc using SB copy 1, bytenr 67108864 here btrfs-select-super just wrote superblock to a mounted btrfs with the fix: ./btrfs-select-super -s 1 /dev/sdc /dev/sdc is currently mounted. Aborting. Signed-off-by: Anand Jain <anand.jain@oracle.com> --- disk-io.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/disk-io.c b/disk-io.c index 589b37a..3f85c21 100644 --- a/disk-io.c +++ b/disk-io.c @@ -1138,9 +1138,12 @@ int btrfs_read_dev_super(int fd, struct btrfs_super_block *sb, u64 sb_bytenr, if (btrfs_super_bytenr(&buf) != bytenr ) continue; - /* if magic is NULL, the device was removed */ - if (buf.magic == 0 && i == 0) - return -1; + /* if magic is NULL, either the device was removed + * OR user / application inflected the disk albeit + * with the most common zeros. + * so only this doesn''t confirm that this disk + * isn''t part of btrfs + */ if (buf.magic != cpu_to_le64(BTRFS_MAGIC)) continue; -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Apr-15 06:44 UTC
Re: [PATCH 02/11, v2] btrfs-progs: no pending balance is not an error
Oh. this title prefix should be v2 not RESEND. v1->v2 Accepts David review comments Thanks, Anand On 04/15/2013 02:38 PM, Anand Jain wrote:> Having no balance running/ paused/completed is a normal > situation, so the current output message should be positive > with return val zero. > > Signed-off-by: Anand Jain <anand.jain@oracle.com> > --- > cmds-balance.c | 16 +++++++++++++--- > 1 file changed, 13 insertions(+), 3 deletions(-) > > diff --git a/cmds-balance.c b/cmds-balance.c > index f5dc317..a968e0d 100644 > --- a/cmds-balance.c > +++ b/cmds-balance.c > @@ -616,6 +616,12 @@ static const char * const cmd_balance_status_usage[] = { > NULL > }; > > +/* Checks the status of the balance if any > + * return codes: > + * -1 : Error failed to know if there is any pending balance > + * 1 : Successful to know status of a pending balance > + * 0 : When there is no pending balance or completed > + */ > static int cmd_balance_status(int argc, char **argv) > { > struct btrfs_ioctl_balance_args args; > @@ -662,9 +668,13 @@ static int cmd_balance_status(int argc, char **argv) > close(fd); > > if (ret < 0) { > + if (e == ENOTCONN) { > + printf("No balance found on ''%s''\n", path); > + return 0; > + } > fprintf(stderr, "ERROR: balance status on ''%s'' failed - %s\n", > - path, (e == ENOTCONN) ? "Not in progress" : strerror(e)); > - return 19; > + path, strerror(e)); > + return -1; > } > > if (args.state & BTRFS_BALANCE_STATE_RUNNING) { > @@ -688,7 +698,7 @@ static int cmd_balance_status(int argc, char **argv) > if (verbose) > dump_ioctl_balance_args(&args); > > - return 0; > + return 1; > } > > const struct cmd_group balance_cmd_group = { >-- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Apr-15 06:47 UTC
Re: [PATCH 3/9] btrfs-progs: mkfs should first check all disks before writing to a disk
On 04/13/2013 12:06 AM, David Sterba wrote:> On Fri, Apr 05, 2013 at 01:54:57PM +0800, Anand Jain wrote: >> In the cases where one of the disk is not suitable for >> btrfs, then we would fail the mkfs, however we determine >> that after we have written btrfs to the preceding disks. >> At this time if user changes mind for not to use btrfs >> will left with no choice. >> >> So this patch will check if all the provided disks are >> suitable for the btrfs at once before proceeding to >> create btrfs on a disk. > > Good fix and cleanup. > >> +void __test_dev_for_mkfs(char *file, int force_overwrite) >> +{ >> + int ret, fd; >> + >> + ret = is_swap_device(file); >> + if (ret < 0) { >> + fprintf(stderr, "error checking %s status: %s\n", file, >> + strerror(-ret)); >> + exit(1); > > The exit()s were ok when this code was in main(), but should be > converted to return for a helper function.I got this integrated in v2.>> + } >> int main(int ac, char **av) >> { >> char *file; >> @@ -1378,6 +1418,8 @@ int main(int ac, char **av) >> char *pretty_buf; >> struct btrfs_super_block *super; >> u64 flags; >> + int dev_cnt=0; > > int dev_cnt = 0; > >> + int saved_optind; >> >> while(1) { >> int c; >> + dev_cnt = ac - optind; >> + if (dev_cnt == 0) >> print_usage(); >> >> + if (source_dir_set && dev_cnt > 1) { >> + fprintf(stderr, >> + "The -r option is limited to a single device\n"); >> + exit(1); >> + } >> + while (dev_cnt-- > 0) { >> + file = av[optind++]; >> + /* following func would exit on error */ >> + if (is_block_device(file)) >> + __test_dev_for_mkfs(file, force_overwrite); > > Catch errors here and exit() eventually. > >> + } >> + > -- > To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html >-- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Apr-15 07:11 UTC
[PATCH 06/11 v3] btrfs-progs: check if btrfs kernel module is loaded
when we have to report no such file error for /dev/btrfs-control we could confirm if btrfs kernel is present and report it and skip registration where appropriate v2->v3: accept review comments from David v1->v2: use /proc/filesystems to check if the btrfs is present Signed-off-by: Anand Jain <anand.jain@oracle.com> --- cmds-device.c | 62 ++++++++++++++++++++++++++++++++++++++++++++--------------- mkfs.c | 13 +++++++++++-- utils.c | 34 ++++++++++++++++++++++++++++++++ utils.h | 2 +- 4 files changed, 92 insertions(+), 19 deletions(-) diff --git a/cmds-device.c b/cmds-device.c index a90fb67..f5dce8d 100644 --- a/cmds-device.c +++ b/cmds-device.c @@ -185,9 +185,10 @@ static const char * const cmd_scan_dev_usage[] = { static int cmd_scan_dev(int argc, char **argv) { - int i, fd, e; + int i, fd = -1, e, ret = 0; int checklist = 1; int devstart = 1; + u64 flag_reg = 0ull; if( argc > 1 && !strcmp(argv[1],"--all-devices")){ if (check_argc_max(argc, 2)) @@ -197,33 +198,57 @@ static int cmd_scan_dev(int argc, char **argv) devstart += 1; } + if (is_btrfs_kernel_loaded()) + flag_reg = BTRFS_SCAN_REGISTER; + else + fprintf(stderr, "btrfs kernel module is not loaded\n"); + if(argc<=devstart){ int ret; - printf("Scanning for Btrfs filesystems\n"); + printf("Scanning for Btrfs filesystems "); if(checklist) - ret = btrfs_scan_block_devices(BTRFS_SCAN_REGISTER); + ret = btrfs_scan_block_devices(flag_reg); else - ret = btrfs_scan_one_dir("/dev", BTRFS_SCAN_REGISTER); + ret = btrfs_scan_one_dir("/dev", flag_reg); if (ret){ fprintf(stderr, "ERROR: error %d while scanning\n", ret); return 18; } + printf("..done\n"); return 0; } - fd = open("/dev/btrfs-control", O_RDWR); - if (fd < 0) { - perror("failed to open /dev/btrfs-control"); - return 10; + if (!flag_reg) + return -1; + + if ((fd = open("/dev/btrfs-control", O_RDWR)) < 0) { + fprintf(stderr, "ERROR: failed to open "\ + "/dev/btrfs-control - %s\n", strerror(errno)); + return -1; } + printf("Scanning for Btrfs filesystem in\n"); for( i = devstart ; i < argc ; i++ ){ + int fdt; struct btrfs_ioctl_vol_args args; - int ret; + printf(" %s ", argv[i]); + fflush(stdout); - printf("Scanning for Btrfs filesystems in ''%s''\n", argv[i]); + /* + * If for a multipath (mp) disk user provides the + * non-mp path then open with flag O_EXCL will fail, + * (also ioctl opens with O_EXCL), So test it before + * calling ioctl. + */ + fdt = open(argv[i], O_RDONLY|O_EXCL); + if (fdt < 0) { + perror("ERROR"); + ret = -1; + continue; + } + close(fdt); strncpy_null(args.name, argv[i]); /* @@ -235,15 +260,16 @@ static int cmd_scan_dev(int argc, char **argv) e = errno; if( ret < 0 ){ - close(fd); - fprintf(stderr, "ERROR: unable to scan the device ''%s'' - %s\n", - argv[i], strerror(e)); - return 11; + fprintf(stderr, "ERROR: unable to scan - %s\n", + strerror(e)); + ret = -1; + } else { + printf("found\n"); } } close(fd); - return 0; + return ret; } static const char * const cmd_ready_dev_usage[] = { @@ -261,10 +287,14 @@ static int cmd_ready_dev(int argc, char **argv) if (check_argc_min(argc, 2)) usage(cmd_ready_dev_usage); + if (!is_btrfs_kernel_loaded()) { + fprintf(stderr, "Error: btrfs kernel module is not loaded\n"); + return -1; + } fd = open("/dev/btrfs-control", O_RDWR); if (fd < 0) { perror("failed to open /dev/btrfs-control"); - return 10; + return -1; } strncpy(args.name, argv[argc - 1], BTRFS_PATH_NAME_MAX); diff --git a/mkfs.c b/mkfs.c index 2eb3087..e8b22cc 100644 --- a/mkfs.c +++ b/mkfs.c @@ -1301,6 +1301,7 @@ int main(int ac, char **av) int dev_cnt = 0; int saved_optind; char estr[100]; + int flag_reg = 1; while(1) { int c; @@ -1391,6 +1392,12 @@ int main(int ac, char **av) printf("\nWARNING! - %s IS EXPERIMENTAL\n", BTRFS_BUILD_VERSION); printf("WARNING! - see http://btrfs.wiki.kernel.org before using\n\n"); + if (!is_btrfs_kernel_loaded()) { + printf("btrfs kernel module is not loaded, " + "would skip device registration\n"); + flag_reg = 0; + } + file = av[optind++]; dev_cnt--; @@ -1483,7 +1490,8 @@ int main(int ac, char **av) if (dev_cnt == 0) goto raid_groups; - btrfs_register_one_device(file); + if (flag_reg) + btrfs_register_one_device(file); zero_end = 1; while(dev_cnt-- > 0) { @@ -1518,7 +1526,8 @@ int main(int ac, char **av) ret = btrfs_add_to_fsid(trans, root, fd, file, dev_block_count, sectorsize, sectorsize, sectorsize); BUG_ON(ret); - btrfs_register_one_device(file); + if (flag_reg) + btrfs_register_one_device(file); } raid_groups: diff --git a/utils.c b/utils.c index 53ee919..0755102 100644 --- a/utils.c +++ b/utils.c @@ -1017,6 +1017,35 @@ struct pending_dir { char name[PATH_MAX]; }; +/* + * return 1 if btrfs kernel is present + * return 0 for not + */ +int is_btrfs_kernel_loaded() +{ + FILE *pfs; + char fsname[100]; + int ret = -1; + char line[100]; + + pfs = fopen("/proc/filesystems", "r"); + if (pfs) { + ret = 0; + while (fgets(line, sizeof(line), pfs)) { + if (!strncmp("nodev", line, 5)) + continue; + if (sscanf(line, " %[^# \n]\n", fsname) != 1) + continue; + if (!strcmp(fsname, "btrfs")) { + ret = 1; + break; + } + } + fclose(pfs); + } + return ret; +} + void btrfs_register_one_device(char *fname) { struct btrfs_ioctl_vol_args args; @@ -1024,6 +1053,11 @@ void btrfs_register_one_device(char *fname) int ret; int e; + if (!is_btrfs_kernel_loaded()) { + fprintf(stderr, "btrfs kernel module is not loaded, " + "skipping device registration\n"); + return; + } fd = open("/dev/btrfs-control", O_RDONLY); if (fd < 0) { fprintf(stderr, "failed to open /dev/btrfs-control " diff --git a/utils.h b/utils.h index 989c4e5..b383057 100644 --- a/utils.h +++ b/utils.h @@ -67,5 +67,5 @@ u64 btrfs_device_size(int fd, struct stat *st); /* Helper to always get proper size of the destination string */ #define strncpy_null(dest, src) __strncpy__null(dest, src, sizeof(dest)) int test_dev_for_mkfs(char *file, int force_overwrite, char *estr); - +int is_btrfs_kernel_loaded(); #endif -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Apr-15 07:14 UTC
Re: [PATCH 4/9 v2] btrfs-progs: check if btrfs kernel module is loaded
On 04/13/2013 12:23 AM, David Sterba wrote:> On Wed, Apr 10, 2013 at 04:23:21PM +0800, Anand Jain wrote: >> diff --git a/cmds-device.c b/cmds-device.c >> index a90fb67..0e1e6de 100644 >> --- a/cmds-device.c >> +++ b/cmds-device.c >> @@ -185,9 +185,10 @@ static const char * const cmd_scan_dev_usage[] = { >> >> static int cmd_scan_dev(int argc, char **argv) >> { >> - int i, fd, e; >> + int i, fd = -1, e, ret = 0; >> int checklist = 1; >> int devstart = 1; >> + u64 flag_reg = 0ull; > > Do you need it to be u64? I see it''s used only as a bool flag.Yes. more below..>> + if (is_btrfs_kernel_loaded()) >> + flag_reg = BTRFS_SCAN_REGISTER; > > flag_reg = 1; > > would work the same, so it should be fine with int.actually no. The intention was to use it as the parameter for btrfs_scan_block_devices, v2 fixes this. Thanks for the catch. --- - ret = btrfs_scan_block_devices(BTRFS_SCAN_REGISTER); + ret = btrfs_scan_block_devices(flag_reg); --->> } >> >> + printf("Scanning for Btrfs in\n"); > ... >> - printf("Scanning for Btrfs filesystems in ''%s''\n", argv[i]); > > Please keep the word ''filesystem'' in the messagegot this in v3>> @@ -261,6 +287,10 @@ static int cmd_ready_dev(int argc, char **argv) >> if (check_argc_min(argc, 2)) >> usage(cmd_ready_dev_usage); >> >> + if (!is_btrfs_kernel_loaded()) { >> + fprintf(stderr, "btrfs kernel module is not loaded\n"); >> + return 10; > > return 1 or -1got this into v3>> --- a/mkfs.c >> +++ b/mkfs.c >> @@ -1420,6 +1420,7 @@ int main(int ac, char **av) >> u64 flags; >> int dev_cnt=0; >> int saved_optind; >> + int flag_reg=1; > > ah, here it is an ''int'' > >> --- a/utils.c >> +++ b/utils.c >> @@ -1016,6 +1016,33 @@ struct pending_dir { >> +/* >> + * return 1 if btrfs kernel is present >> + * return 0 for not >> + */ >> +int is_btrfs_kernel_loaded() >> +{ >> + FILE *pfs; >> + char fsname[100]; >> + int ret = -1; >> + char line[100]; >> + >> + pfs = fopen("/proc/filesystems", "r"); >> + if (pfs) { >> + ret = 0; >> + while (fgets(line, sizeof(line), pfs)) { >> + if (sscanf(line, "nodev %[^#\n]\n", fsname) == 1) continue; > > if (!strncmp("nodev", line, 5)) > continue;got this into v3>> + if (sscanf(line, " %[^# \n]\n", fsname) != 1) continue; >> + if (!strcmp(fsname, "btrfs")) { >> + ret = 1; >> + break; >> + } >> + } >> + fclose(pfs); >> + } >> + return ret; >> +} >> + >> void btrfs_register_one_device(char *fname) >> { >> struct btrfs_ioctl_vol_args args; >> @@ -1023,6 +1050,11 @@ void btrfs_register_one_device(char *fname) >> int ret; >> int e; >> >> + if (!is_btrfs_kernel_loaded()) { >> + fprintf(stderr, "btrfs kernel module is not loaded, " >> + "skipping device registration\n"); >> + return; >> + } >> fd = open("/dev/btrfs-control", O_RDONLY); >> if (fd < 0) { >> fprintf(stderr, "failed to open /dev/btrfs-control " > > Otherwise ok. > david > -- > To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html >-- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
David Sterba
2013-Apr-15 16:21 UTC
Re: [PATCH 02/11, RESEND] btrfs-progs: no pending balance is not an error
On Mon, Apr 15, 2013 at 02:38:08PM +0800, Anand Jain wrote:> +/* Checks the status of the balance if any > + * return codes: > + * -1 : Error failed to know if there is any pending balance > + * 1 : Successful to know status of a pending balance > + * 0 : When there is no pending balance or completedThe error code will become the return code of the ''btrfs balance status'' command in the end: btrfs.c:main() 295 exit(cmd->fn(argc, argv)); and that''s why I''ve suggested to return 1 or 2, though -1 matches shell error code 255 but I''d rathe avoid using it. david -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Apr-16 04:58 UTC
[PATCH 02/11 v3] btrfs-progs: no pending balance is not an error
Having no balance running/ paused/completed is a normal situation, so the current output message should be positive with return val zero. Signed-off-by: Anand Jain <anand.jain@oracle.com> --- cmds-balance.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/cmds-balance.c b/cmds-balance.c index f5dc317..cffa807 100644 --- a/cmds-balance.c +++ b/cmds-balance.c @@ -616,6 +616,12 @@ static const char * const cmd_balance_status_usage[] = { NULL }; +/* Checks the status of the balance if any + * return codes: + * 2 : Error failed to know if there is any pending balance + * 1 : Successful to know status of a pending balance + * 0 : When there is no pending balance or completed + */ static int cmd_balance_status(int argc, char **argv) { struct btrfs_ioctl_balance_args args; @@ -654,7 +660,7 @@ static int cmd_balance_status(int argc, char **argv) fd = open_file_or_dir(path); if (fd < 0) { fprintf(stderr, "ERROR: can''t access to ''%s''\n", path); - return 12; + return 2; } ret = ioctl(fd, BTRFS_IOC_BALANCE_PROGRESS, &args); @@ -662,9 +668,13 @@ static int cmd_balance_status(int argc, char **argv) close(fd); if (ret < 0) { + if (e == ENOTCONN) { + printf("No balance found on ''%s''\n", path); + return 0; + } fprintf(stderr, "ERROR: balance status on ''%s'' failed - %s\n", - path, (e == ENOTCONN) ? "Not in progress" : strerror(e)); - return 19; + path, strerror(e)); + return 2; } if (args.state & BTRFS_BALANCE_STATE_RUNNING) { @@ -688,7 +698,7 @@ static int cmd_balance_status(int argc, char **argv) if (verbose) dump_ioctl_balance_args(&args); - return 0; + return 1; } const struct cmd_group balance_cmd_group = { -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Apr-16 05:02 UTC
Re: [PATCH 02/11, RESEND] btrfs-progs: no pending balance is not an error
On 04/16/2013 12:21 AM, David Sterba wrote:> On Mon, Apr 15, 2013 at 02:38:08PM +0800, Anand Jain wrote: >> +/* Checks the status of the balance if any >> + * return codes: >> + * -1 : Error failed to know if there is any pending balance >> + * 1 : Successful to know status of a pending balance >> + * 0 : When there is no pending balance or completed > > The error code will become the return code of the ''btrfs balance status'' > command in the end: > > btrfs.c:main() > > 295 exit(cmd->fn(argc, argv)); > > and that''s why I''ve suggested to return 1 or 2, though -1 matches shell > error code 255 but I''d rathe avoid using it.makes sense. v3 is out. -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
David Sterba
2013-Apr-16 12:15 UTC
Re: [PATCH 00/11 v2] a bunch of miscellaneous bug fixes
Hi, On Mon, Apr 15, 2013 at 02:38:06PM +0800, Anand Jain wrote:> Anand Jain (11): > btrfs-progs: root_item generation_v2 is out of sync after btrfsck > btrfs-progs: no pending balance is not an error > btrfs-progs: mkfs should first check all disks before writing to a > disk > btrfs-progs: cmd replace should check target-dev fully > btrfs-progs: mkfs stdout print to match chronology > btrfs-progs: check if btrfs kernel module is loaded > btrfs-progs: delete unused function get_mountpt > btrfs-progs: btrfs-select-super output is confusing when it fails > btrfs-progs: fix btrfs scrub start help > btrfs-progs: avoid ioctl for multipath-dev with its non-multipath path > btrfs-progs: a copy of superblock is zero may not mean btrfs is not > thereI''ve merged some of the patches from this series, ones that apply without dependencies (mostly the device scan rework which I''ll process next). No need to resend patches that do not change, the easy ones get merged and I''m trying to review the rest. david -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Eric Sandeen
2013-Apr-21 23:09 UTC
Re: [PATCH 01/11, RESEND] btrfs-progs: root_item generation_v2 is out of sync after btrfsck
On 4/15/13 1:38 AM, Anand Jain wrote:> reproducing steps: > mkfs.btrfs /dev/dm-2 -f > mount /dev/dm-2 /btrfs > umount /btrfs > btrfs check /dev/dm-2 --repair > mount /dev/dm-2 /btrfs > > ---- > btrfs: mismatching generation and generation_v2 found in root item. This root was probably mounted with an older kernel. Resetting all new fields. > ----After this patch (on the integration branch), I''m getting: [61371.570449] btrfs: mismatching generation and generation_v2 found in root item. This root was probably mounted with an older kernel. Resetting all new fields. when I run xfstests on my box... Reverting to an older mkfs.btrfs makes it go away. -Eric> btrfs-debug-tree shows change in uuid > > < root data bytenr 29425664 level 0 dirid 0 refs 1 gen 43 > < uuid 293596e8-7888-eb4c-9134-6df9db996fe5 > > Signed-off-by: Anand Jain <anand.jain@oracle.com> > --- > root-tree.c | 13 +++++++++++++ > 1 file changed, 13 insertions(+) > > diff --git a/root-tree.c b/root-tree.c > index c10d068..4454147 100644 > --- a/root-tree.c > +++ b/root-tree.c > @@ -69,6 +69,7 @@ int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root > int ret; > int slot; > unsigned long ptr; > + u32 old_size; > > path = btrfs_alloc_path(); > BUG_ON(!path); > @@ -79,6 +80,18 @@ int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root > l = path->nodes[0]; > slot = path->slots[0]; > ptr = btrfs_item_ptr_offset(l, slot); > + /* > + * If the btrfs-progs is newer and kernel is at > + * generation_v1 then we don''t touch v2 items > + * otherwise when kernel is at same or greater > + * version compared with btrfs-progs then update > + * the needed > + */ > + old_size = btrfs_item_size_nr(l, slot); > + if (old_size >= sizeof(*item)) { > + btrfs_set_root_generation_v2(item, > + btrfs_root_generation(item)); > + } > write_extent_buffer(l, item, ptr, sizeof(*item)); > btrfs_mark_buffer_dirty(path->nodes[0]); > out: >-- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html