btrfs-progs: defrag: set errno correctly in the callback

In case defrag fails, the errno is not properly reported everywhere but
rather the last value of 'e', which could be 0. Then we get confusing
error messages like:

ERROR: defrag failed on /path/to/file: Success

Reported-by: Adam Mizerski <adam@mizerski.pl>
Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
David Sterba 2016-09-20 16:45:36 +02:00
parent eccba6261a
commit d75e061bcd
1 changed files with 9 additions and 6 deletions

View File

@ -993,32 +993,35 @@ static int defrag_callback(const char *fpath, const struct stat *sb,
int typeflag, struct FTW *ftwbuf) int typeflag, struct FTW *ftwbuf)
{ {
int ret = 0; int ret = 0;
int e = 0; int err = 0;
int fd = 0; int fd = 0;
if ((typeflag == FTW_F) && S_ISREG(sb->st_mode)) { if ((typeflag == FTW_F) && S_ISREG(sb->st_mode)) {
if (defrag_global_verbose) if (defrag_global_verbose)
printf("%s\n", fpath); printf("%s\n", fpath);
fd = open(fpath, O_RDWR); fd = open(fpath, O_RDWR);
if (fd < 0) if (fd < 0) {
err = errno;
goto error; goto error;
}
ret = do_defrag(fd, defrag_global_fancy_ioctl, &defrag_global_range); ret = do_defrag(fd, defrag_global_fancy_ioctl, &defrag_global_range);
e = errno;
close(fd); close(fd);
if (ret && e == ENOTTY && defrag_global_fancy_ioctl) { if (ret && errno == ENOTTY && defrag_global_fancy_ioctl) {
error("defrag range ioctl not " error("defrag range ioctl not "
"supported in this kernel, please try " "supported in this kernel, please try "
"without any options."); "without any options.");
defrag_global_errors++; defrag_global_errors++;
return ENOTTY; return ENOTTY;
} }
if (ret) if (ret) {
err = errno;
goto error; goto error;
}
} }
return 0; return 0;
error: error:
error("defrag failed on %s: %s", fpath, strerror(e)); error("defrag failed on %s: %s", fpath, strerror(err));
defrag_global_errors++; defrag_global_errors++;
return 0; return 0;
} }