@@ -108,11 +108,10 @@ static struct Command commands[] = {
"device delete", "<dev> [<dev>..] <path>\n"
"Remove a device from a filesystem."
},
- /* coming soon
- { 2, "filesystem label", "<label> <path>\n"
+ { do_set_label, 2,
+ "filesystem label", "<label> <path>\n"
"Set the label of a filesystem"
- }
- */
+ },
{ 0, 0 , 0 }
};
@@ -834,6 +834,40 @@ int do_set_default_subvol(int nargs, char **argv)
return 0;
}
+int do_set_label(int nargs, char **argv)
+{
+ int fd, ret;
+ char *path = argv[2];
+ char *label = parse_label(argv[1]);
+ size_t len = strlen(label);
+ struct btrfs_ioctl_fs_label_args label_args;
+
+ if (len == 0 || len >= BTRFS_LABEL_SIZE) {
+ fprintf(stderr, "ERROR: label length too long ('%s')\n",
+ label);
+ free(label);
+ return 14;
+ }
+
+ fd = open_file_or_dir(path);
+ if (fd < 0) {
+ free(label);
+ fprintf(stderr, "ERROR: can't access to '%s'\n", path);
+ return 12;
+ }
+
+ strcpy(label_args.label, label);
+ ret = ioctl(fd, BTRFS_IOC_FS_SETLABEL, &label_args);
+ close(fd);
+ free(label);
+ if(ret < 0) {
+ fprintf(stderr, "ERROR: unable to set a new label\n");
+ return 30;
+ }
+
+ return 0;
+}
+
int do_df_filesystem(int nargs, char **argv)
{
struct btrfs_ioctl_space_args *sargs;
@@ -32,3 +32,4 @@ int list_subvols(int fd);
int do_df_filesystem(int nargs, char **argv);
int find_updated_files(int fd, u64 root_id, u64 oldest_gen);
int do_find_newer(int argc, char **argv);
+int do_set_label(int argc, char **argv);
@@ -345,6 +345,10 @@ struct btrfs_super_block {
u8 sys_chunk_array[BTRFS_SYSTEM_CHUNK_ARRAY_SIZE];
} __attribute__ ((__packed__));
+struct btrfs_ioctl_fs_label_args {
+ char label[BTRFS_LABEL_SIZE];
+};
+
/*
* Compat flags that we support. If any incompat flags are set other
than the
* ones specified below then we will fail to mount
@@ -169,4 +169,6 @@ struct btrfs_ioctl_space_args {
#define BTRFS_IOC_DEFAULT_SUBVOL _IOW(BTRFS_IOCTL_MAGIC, 19, u64)
#define BTRFS_IOC_SPACE_INFO _IOWR(BTRFS_IOCTL_MAGIC, 20, \
struct btrfs_ioctl_space_args)
+#define BTRFS_IOC_FS_SETLABEL _IOW(BTRFS_IOCTL_MAGIC, 50, \
+ struct btrfs_ioctl_fs_label_args)
#endif
@@ -303,25 +303,6 @@ static u64 parse_profile(char *s)
return 0;
}
-static char *parse_label(char *input)
-{
- int i;
- int len = strlen(input);
-
- if (len >= BTRFS_LABEL_SIZE) {
- fprintf(stderr, "Label %s is too long (max %d)\n", input,
- BTRFS_LABEL_SIZE - 1);
- exit(1);
- }
- for (i = 0; i < len; i++) {
- if (input[i] == '/' || input[i] == '\\') {
- fprintf(stderr, "invalid label %s\n", input);
- exit(1);
- }
- }
- return strdup(input);
-}
-
static struct option long_options[] = {
{ "alloc-start", 1, NULL, 'A'},
{ "byte-count", 1, NULL, 'b' },
@@ -993,3 +993,21 @@ char *pretty_sizes(u64 size)
return pretty;
}
+char *parse_label(const char *input)
+{
+ int i;
+ int len = strlen(input);
+
+ if (len >= BTRFS_LABEL_SIZE) {
+ fprintf(stderr, "Label %s is too long (max %d)\n", input,
+ BTRFS_LABEL_SIZE - 1);
+ exit(1);
+ }
+ for (i = 0; i < len; i++) {
+ if (input[i] == '/' || input[i] == '\\') {
+ fprintf(stderr, "invalid label %s\n", input);
+ exit(1);
+ }
+ }
+ return strdup(input);
+}
@@ -40,4 +40,5 @@ int check_mounted(const char *devicename);
int btrfs_device_already_in_root(struct btrfs_root *root, int fd,
int super_offset);
char *pretty_sizes(u64 size);
+char *parse_label(const char *);
#endif
Fix the ioctl number of BTRFS_IOC_FS_SETLABEL to 50. Signed-off-by: Jie Liu <jeff.liu@oracle.com> --- btrfs.c | 7 +++---- btrfs_cmds.c | 34 ++++++++++++++++++++++++++++++++++ btrfs_cmds.h | 1 + ctree.h | 4 ++++ ioctl.h | 2 ++ mkfs.c | 19 ------------------- utils.c | 18 ++++++++++++++++++ utils.h | 1 + 8 files changed, 63 insertions(+), 23 deletions(-)