X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=cmds-filesystem.c;h=e2e41e911df3de52db75a56a67c190e2914c0df5;hb=4b54ca8ba44ac7cee29cdf7f75c6ac472cfe59ef;hp=26b70e13a41a03d0982c33e0959e311ea4eb519a;hpb=1ed3426d3f74bbbfaab2b77991596644e2e6321d;p=platform%2Fupstream%2Fbtrfs-progs.git diff --git a/cmds-filesystem.c b/cmds-filesystem.c index 26b70e1..e2e41e9 100644 --- a/cmds-filesystem.c +++ b/cmds-filesystem.c @@ -38,6 +38,7 @@ #include "list_sort.h" #include "disk-io.h" #include "cmds-fi-du.h" +#include "help.h" /* * for btrfs fi show, we maintain a hash of fsids we've already printed. @@ -149,7 +150,7 @@ static int get_df(int fd, struct btrfs_ioctl_space_args **sargs_ret) ret = ioctl(fd, BTRFS_IOC_SPACE_INFO, sargs); if (ret < 0) { - error("cannot get space info: %s\n", strerror(errno)); + error("cannot get space info: %s", strerror(errno)); free(sargs); return -errno; } @@ -248,7 +249,7 @@ static int match_search_item_kernel(__u8 *fsid, char *mnt, char *label, return 0; } -static int uuid_search(struct btrfs_fs_devices *fs_devices, char *search) +static int uuid_search(struct btrfs_fs_devices *fs_devices, const char *search) { char uuidbuf[BTRFS_UUID_UNPARSED_SIZE]; struct list_head *cur; @@ -509,7 +510,7 @@ out: return !found; } -static int dev_to_fsid(char *dev, __u8 *fsid) +static int dev_to_fsid(const char *dev, __u8 *fsid) { struct btrfs_super_block *disk_super; char buf[BTRFS_SUPER_INFO_SIZE]; @@ -872,10 +873,10 @@ static int cmd_filesystem_show(int argc, char **argv) goto out; devs_only: - ret = btrfs_scan_lblkid(); + ret = btrfs_scan_devices(); if (ret) { - error("blkid device scan returned %d\n", ret); + error("blkid device scan returned %d", ret); return 1; } @@ -972,20 +973,6 @@ static const char * const cmd_filesystem_defrag_usage[] = { NULL }; -static int do_defrag(int fd, int fancy_ioctl, - struct btrfs_ioctl_defrag_range_args *range) -{ - int ret; - - if (!fancy_ioctl) - ret = ioctl(fd, BTRFS_IOC_DEFRAG, NULL); - else - ret = ioctl(fd, BTRFS_IOC_DEFRAG_RANGE, range); - - return ret; -} - -static int defrag_global_fancy_ioctl; static struct btrfs_ioctl_defrag_range_args defrag_global_range; static int defrag_global_verbose; static int defrag_global_errors; @@ -1004,12 +991,11 @@ static int defrag_callback(const char *fpath, const struct stat *sb, err = errno; goto error; } - ret = do_defrag(fd, defrag_global_fancy_ioctl, &defrag_global_range); + ret = ioctl(fd, BTRFS_IOC_DEFRAG_RANGE, &defrag_global_range); close(fd); - if (ret && errno == ENOTTY && defrag_global_fancy_ioctl) { - error("defrag range ioctl not " - "supported in this kernel, please try " - "without any options."); + if (ret && errno == ENOTTY) { + error( +"defrag range ioctl not supported in this kernel version, 2.6.33 and newer is required"); defrag_global_errors++; return ENOTTY; } @@ -1036,21 +1022,20 @@ static int cmd_filesystem_defrag(int argc, char **argv) int i; int recursive = 0; int ret = 0; - int e = 0; int compress_type = BTRFS_COMPRESS_NONE; DIR *dirstream; /* * Kernel has a different default (256K) that is supposed to be safe, * but it does not defragment very well. The 32M will likely lead to - * better results and is independent of the kernel default. + * better results and is independent of the kernel default. We have to + * use the v2 defrag ioctl. */ - thresh = 32 * 1024 * 1024; + thresh = SZ_32M; defrag_global_errors = 0; defrag_global_verbose = 0; defrag_global_errors = 0; - defrag_global_fancy_ioctl = 0; while(1) { int c = getopt(argc, argv, "vrc::fs:l:t:"); if (c < 0) @@ -1061,22 +1046,18 @@ static int cmd_filesystem_defrag(int argc, char **argv) compress_type = BTRFS_COMPRESS_ZLIB; if (optarg) compress_type = parse_compress_type(optarg); - defrag_global_fancy_ioctl = 1; break; case 'f': flush = 1; - defrag_global_fancy_ioctl = 1; break; case 'v': defrag_global_verbose = 1; break; case 's': start = parse_size(optarg); - defrag_global_fancy_ioctl = 1; break; case 'l': len = parse_size(optarg); - defrag_global_fancy_ioctl = 1; break; case 't': thresh = parse_size(optarg); @@ -1086,7 +1067,6 @@ static int cmd_filesystem_defrag(int argc, char **argv) thresh, (u32)-1); thresh = (u32)-1; } - defrag_global_fancy_ioctl = 1; break; case 'r': recursive = 1; @@ -1110,13 +1090,43 @@ static int cmd_filesystem_defrag(int argc, char **argv) if (flush) defrag_global_range.flags |= BTRFS_DEFRAG_RANGE_START_IO; + /* + * Look for directory arguments and warn if the recursive mode is not + * requested, as this is not implemented as recursive defragmentation + * in kernel. The stat errors are silent here as we check them below. + */ + if (!recursive) { + int found = 0; + + for (i = optind; i < argc; i++) { + struct stat st; + + if (stat(argv[i], &st)) + continue; + + if (S_ISDIR(st.st_mode)) { + warning( + "directory specified but recursive mode not requested: %s", + argv[i]); + found = 1; + } + } + if (found) { + warning( +"a directory passed to the defrag ioctl will not process the files\n" +"recursively but will defragment the subvolume tree and the extent tree.\n" +"If this is not intended, please use option -r ."); + } + } + for (i = optind; i < argc; i++) { struct stat st; + int defrag_err = 0; dirstream = NULL; fd = open_file_or_dir(argv[i], &dirstream); if (fd < 0) { - error("cannot open %s: %s\n", argv[i], + error("cannot open %s: %s", argv[i], strerror(errno)); defrag_global_errors++; close_file_or_dir(fd, dirstream); @@ -1130,44 +1140,36 @@ static int cmd_filesystem_defrag(int argc, char **argv) continue; } if (!(S_ISDIR(st.st_mode) || S_ISREG(st.st_mode))) { - error("%s is not a directory or a regular file\n", + error("%s is not a directory or a regular file", argv[i]); defrag_global_errors++; close_file_or_dir(fd, dirstream); continue; } - if (recursive) { - if (S_ISDIR(st.st_mode)) { - ret = nftw(argv[i], defrag_callback, 10, + if (recursive && S_ISDIR(st.st_mode)) { + ret = nftw(argv[i], defrag_callback, 10, FTW_MOUNT | FTW_PHYS); - if (ret == ENOTTY) - exit(1); - /* errors are handled in the callback */ - ret = 0; - } else { - if (defrag_global_verbose) - printf("%s\n", argv[i]); - ret = do_defrag(fd, defrag_global_fancy_ioctl, - &defrag_global_range); - e = errno; - } + if (ret == ENOTTY) + exit(1); + /* errors are handled in the callback */ + ret = 0; } else { if (defrag_global_verbose) printf("%s\n", argv[i]); - ret = do_defrag(fd, defrag_global_fancy_ioctl, + ret = ioctl(fd, BTRFS_IOC_DEFRAG_RANGE, &defrag_global_range); - e = errno; + defrag_err = errno; } close_file_or_dir(fd, dirstream); - if (ret && e == ENOTTY && defrag_global_fancy_ioctl) { - error("defrag range ioctl not " - "supported in this kernel, please try " - "without any options."); + if (ret && defrag_err == ENOTTY) { + error( +"defrag range ioctl not supported in this kernel version, 2.6.33 and newer is required"); defrag_global_errors++; break; } if (ret) { - error("defrag failed on %s: %s", argv[i], strerror(e)); + error("defrag failed on %s: %s", argv[i], + strerror(defrag_err)); defrag_global_errors++; } }