mirror of
https://github.com/koverstreet/bcachefs-tools.git
synced 2025-12-08 00:00:12 +03:00
cmd_attr: Add --options=- and --remove-all to unset options
Signed-off-by: Jérôme Poulin <jeromepoulin@gmail.com>
This commit is contained in:
parent
3321afc8b6
commit
5dd10a17e9
14
bcachefs.8
14
bcachefs.8
@ -576,7 +576,10 @@ Offset of existing superblock
|
|||||||
.El
|
.El
|
||||||
.Sh Commands for operating on files in a bcachefs filesystem
|
.Sh Commands for operating on files in a bcachefs filesystem
|
||||||
.Bl -tag -width Ds
|
.Bl -tag -width Ds
|
||||||
.It Nm Ic set-file-option Oo Ar options Oc Ar devices\ ...
|
.It Nm Ic set-file-option Oo Ar options Oc Ar [files|folders]\ ...
|
||||||
|
Set various per-file attributes on files and directories in a bcachefs filesystem.
|
||||||
|
When applied to directories, attributes are propagated recursively to all files
|
||||||
|
and subdirectories within.
|
||||||
.Bl -tag -width Ds
|
.Bl -tag -width Ds
|
||||||
.It Fl -data_replicas Ns = Ns Ar number
|
.It Fl -data_replicas Ns = Ns Ar number
|
||||||
Number of data replicas
|
Number of data replicas
|
||||||
@ -602,7 +605,16 @@ Enable erasure coding (DO NOT USE YET)
|
|||||||
|
|
||||||
.It Fl -nocow
|
.It Fl -nocow
|
||||||
Nocow mode: Writes will be done in place when possible.
|
Nocow mode: Writes will be done in place when possible.
|
||||||
|
.It Fl -remove-all
|
||||||
|
Remove all file options from the specified files/directories
|
||||||
.El
|
.El
|
||||||
|
.Pp
|
||||||
|
To remove specific options, use
|
||||||
|
.Ar --option=-
|
||||||
|
.Pp
|
||||||
|
Options can be chained together to perform multiple operations in a single command, for example:
|
||||||
|
.Dl bcachefs set-file-option --remove-all --compression=lz4 .
|
||||||
|
.Dl bcachefs set-file-option --compression=- --background_compression=zstd:10 --data_replicas=- file.txt
|
||||||
.El
|
.El
|
||||||
.Sh Commands for debugging
|
.Sh Commands for debugging
|
||||||
These commands work on offline, unmounted filesystems.
|
These commands work on offline, unmounted filesystems.
|
||||||
|
|||||||
@ -55,18 +55,54 @@ static void propagate_recurse(int dirfd)
|
|||||||
closedir(dir);
|
closedir(dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_setattr(char *path, struct bch_opt_strs opts)
|
static void remove_bcachefs_attr(const char *path, const char *full_attr_name)
|
||||||
|
{
|
||||||
|
if (removexattr(path, full_attr_name) != 0) {
|
||||||
|
// EINVAL in case bcachefs-tools is newer than kernel
|
||||||
|
if (errno != ENODATA && errno != EINVAL) {
|
||||||
|
fprintf(stderr, "error removing attribute %s from %s: %m\n",
|
||||||
|
full_attr_name, path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void remove_all_bcachefs_attrs(const char *path)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
|
for (i = 0; i < bch2_opts_nr; i++) {
|
||||||
|
if (bch2_opt_table[i].flags & OPT_INODE) {
|
||||||
|
// Only works on empty directory.
|
||||||
|
if (strcmp(bch2_opt_table[i].attr.name, "casefold") == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
char *full_name = mprintf("bcachefs.%s", bch2_opt_table[i].attr.name);
|
||||||
|
remove_bcachefs_attr(path, full_name);
|
||||||
|
free(full_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void do_setattr(char *path, struct bch_opt_strs opts, bool remove_all)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
if (remove_all) {
|
||||||
|
remove_all_bcachefs_attrs(path);
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < bch2_opts_nr; i++) {
|
for (i = 0; i < bch2_opts_nr; i++) {
|
||||||
if (!opts.by_id[i])
|
if (!opts.by_id[i])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
char *n = mprintf("bcachefs.%s", bch2_opt_table[i].attr.name);
|
char *n = mprintf("bcachefs.%s", bch2_opt_table[i].attr.name);
|
||||||
|
|
||||||
if (setxattr(path, n, opts.by_id[i], strlen(opts.by_id[i]), 0))
|
if (strcmp(opts.by_id[i], "-") == 0) {
|
||||||
die("setxattr error: %m");
|
remove_bcachefs_attr(path, n);
|
||||||
|
} else {
|
||||||
|
if (setxattr(path, n, opts.by_id[i], strlen(opts.by_id[i]), 0))
|
||||||
|
die("setxattr error: %m");
|
||||||
|
}
|
||||||
|
|
||||||
free(n);
|
free(n);
|
||||||
}
|
}
|
||||||
@ -90,15 +126,27 @@ static void setattr_usage(void)
|
|||||||
"Options:");
|
"Options:");
|
||||||
|
|
||||||
bch2_opts_usage(OPT_INODE);
|
bch2_opts_usage(OPT_INODE);
|
||||||
puts(" -h Display this help and exit\n"
|
puts(" --remove-all Remove all file options\n"
|
||||||
|
" To remove specific options, use: --option=-\n"
|
||||||
|
" -h Display this help and exit\n"
|
||||||
"Report bugs to <linux-bcachefs@vger.kernel.org>");
|
"Report bugs to <linux-bcachefs@vger.kernel.org>");
|
||||||
}
|
}
|
||||||
|
|
||||||
int cmd_setattr(int argc, char *argv[])
|
int cmd_setattr(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
unsigned i;
|
||||||
|
bool remove_all = false;
|
||||||
|
|
||||||
|
for (i = 1; i < argc; i++) {
|
||||||
|
if (strcmp(argv[i], "--remove-all") == 0) {
|
||||||
|
remove_all = true;
|
||||||
|
bch_remove_arg_from_argv(&argc, argv, i);
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct bch_opt_strs opts =
|
struct bch_opt_strs opts =
|
||||||
bch2_cmdline_opts_get(&argc, argv, OPT_INODE);
|
bch2_cmdline_opts_get(&argc, argv, OPT_INODE);
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
for (i = 1; i < argc; i++)
|
for (i = 1; i < argc; i++)
|
||||||
if (argv[i][0] == '-') {
|
if (argv[i][0] == '-') {
|
||||||
@ -111,7 +159,7 @@ int cmd_setattr(int argc, char *argv[])
|
|||||||
die("Please supply one or more files");
|
die("Please supply one or more files");
|
||||||
|
|
||||||
for (i = 1; i < argc; i++)
|
for (i = 1; i < argc; i++)
|
||||||
do_setattr(argv[i], opts);
|
do_setattr(argv[i], opts, remove_all);
|
||||||
bch2_opt_strs_free(&opts);
|
bch2_opt_strs_free(&opts);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@ -737,6 +737,12 @@ noopt:
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void bch_remove_arg_from_argv(int *argc, char *argv[], int index)
|
||||||
|
{
|
||||||
|
memmove(&argv[index], &argv[index + 1], (*argc - index) * sizeof(char*));
|
||||||
|
(*argc)--;
|
||||||
|
}
|
||||||
|
|
||||||
struct bch_opt_strs bch2_cmdline_opts_get(int *argc, char *argv[],
|
struct bch_opt_strs bch2_cmdline_opts_get(int *argc, char *argv[],
|
||||||
unsigned opt_types)
|
unsigned opt_types)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -31,6 +31,7 @@ void bch2_opt_strs_free(struct bch_opt_strs *);
|
|||||||
|
|
||||||
const struct bch_option *bch2_cmdline_opt_parse(int argc, char *argv[],
|
const struct bch_option *bch2_cmdline_opt_parse(int argc, char *argv[],
|
||||||
unsigned opt_types);
|
unsigned opt_types);
|
||||||
|
void bch_remove_arg_from_argv(int *argc, char *argv[], int index);
|
||||||
struct bch_opt_strs bch2_cmdline_opts_get(int *, char *[], unsigned);
|
struct bch_opt_strs bch2_cmdline_opts_get(int *, char *[], unsigned);
|
||||||
struct bch_opts bch2_parse_opts(struct bch_opt_strs);
|
struct bch_opts bch2_parse_opts(struct bch_opt_strs);
|
||||||
void bch2_opts_usage(unsigned);
|
void bch2_opts_usage(unsigned);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user