mirror of
https://github.com/kdave/btrfs-progs
synced 2025-03-03 17:27:50 +00:00
btrfs-progs: defrag: open files RO on new enough kernels
Defragging an executable conflicts both way with it being run, resulting in ETXTBSY. This either makes defrag fail or prevents the program from being executed. Kernels 4.19-rc1 and later allow defragging files you could have possibly opened rw, even if the passed descriptor is ro (commit 616d374efa23 "btrfs: allow defrag on a file opened read-only that has rw permissions"). Signed-off-by: Adam Borowski <kilobyte@angband.pl> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
3da12f3d5f
commit
5ebf288875
@ -26,6 +26,7 @@
|
||||
#include <ftw.h>
|
||||
#include <mntent.h>
|
||||
#include <linux/limits.h>
|
||||
#include <linux/version.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#include <btrfsutil.h>
|
||||
@ -39,12 +40,14 @@
|
||||
#include "list_sort.h"
|
||||
#include "disk-io.h"
|
||||
#include "help.h"
|
||||
#include "fsfeatures.h"
|
||||
|
||||
/*
|
||||
* for btrfs fi show, we maintain a hash of fsids we've already printed.
|
||||
* This way we don't print dups if a given FS is mounted more than once.
|
||||
*/
|
||||
static struct seen_fsid *seen_fsid_hash[SEEN_FSID_HASH_SIZE] = {NULL,};
|
||||
static mode_t defrag_open_mode = O_RDONLY;
|
||||
|
||||
static const char * const filesystem_cmd_group_usage[] = {
|
||||
"btrfs filesystem [<group>] <command> [<args>]",
|
||||
@ -880,7 +883,7 @@ static int defrag_callback(const char *fpath, const struct stat *sb,
|
||||
if ((typeflag == FTW_F) && S_ISREG(sb->st_mode)) {
|
||||
if (defrag_global_verbose)
|
||||
printf("%s\n", fpath);
|
||||
fd = open(fpath, O_RDWR);
|
||||
fd = open(fpath, defrag_open_mode);
|
||||
if (fd < 0) {
|
||||
goto error;
|
||||
}
|
||||
@ -917,6 +920,13 @@ static int cmd_filesystem_defrag(int argc, char **argv)
|
||||
int compress_type = BTRFS_COMPRESS_NONE;
|
||||
DIR *dirstream;
|
||||
|
||||
/*
|
||||
* Kernel 4.19+ supports defragmention of files open read-only,
|
||||
* otherwise it's an ETXTBSY error
|
||||
*/
|
||||
if (get_running_kernel_version() < KERNEL_VERSION(4,19,0))
|
||||
defrag_open_mode = O_RDWR;
|
||||
|
||||
/*
|
||||
* 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
|
||||
@ -1017,7 +1027,7 @@ static int cmd_filesystem_defrag(int argc, char **argv)
|
||||
int defrag_err = 0;
|
||||
|
||||
dirstream = NULL;
|
||||
fd = open_file_or_dir(argv[i], &dirstream);
|
||||
fd = open_file_or_dir3(argv[i], &dirstream, defrag_open_mode);
|
||||
if (fd < 0) {
|
||||
error("cannot open %s: %m", argv[i]);
|
||||
ret = -errno;
|
||||
|
Loading…
Reference in New Issue
Block a user