From efbbbc88cbee3f28c6b4a4c34623e13dc1e2e700 Mon Sep 17 00:00:00 2001 From: Jeff Liu Date: Wed, 30 Jan 2013 16:32:47 +0800 Subject: btrfs-progs: move btrfslabel.[c|h] stuff to utils.[c|h] Clean btrfslabel.[c|h] out of the source tree and move those related functions to utils.[c|h]. CC: Gene Czarcinski Signed-off-by: Jie Liu Signed-off-by: David Sterba --- utils.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) (limited to 'utils.c') diff --git a/utils.c b/utils.c index 50e54532..ac3c053e 100644 --- a/utils.c +++ b/utils.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2007 Oracle. All rights reserved. + * Copyright (C) 2008 Morey Roof. All rights reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public @@ -19,6 +20,7 @@ #define _XOPEN_SOURCE 700 #define __USE_XOPEN2K8 #define __XOPEN2K8 /* due to an error in dirent.h, to get dirfd() */ +#define _GNU_SOURCE /* O_NOATIME */ #include #include #include @@ -1164,6 +1166,134 @@ static int check_label(const char *input) return 0; } +static int set_label_unmounted(const char *dev, const char *label) +{ + struct btrfs_trans_handle *trans; + struct btrfs_root *root; + int ret; + + ret = check_mounted(dev); + if (ret < 0) { + fprintf(stderr, "FATAL: error checking %s mount status\n", dev); + return -1; + } + if (ret > 0) { + fprintf(stderr, "ERROR: dev %s is mounted, use mount point\n", + dev); + return -1; + } + + /* Open the super_block at the default location + * and as read-write. + */ + root = open_ctree(dev, 0, 1); + if (!root) /* errors are printed by open_ctree() */ + return -1; + + trans = btrfs_start_transaction(root, 1); + snprintf(root->fs_info->super_copy.label, BTRFS_LABEL_SIZE, "%s", + label); + btrfs_commit_transaction(trans, root); + + /* Now we close it since we are done. */ + close_ctree(root); + return 0; +} + +static int set_label_mounted(const char *mount_path, const char *label) +{ + int fd; + + fd = open(mount_path, O_RDONLY | O_NOATIME); + if (fd < 0) { + fprintf(stderr, "ERROR: unable access to '%s'\n", mount_path); + return -1; + } + + if (ioctl(fd, BTRFS_IOC_SET_FSLABEL, label) < 0) { + fprintf(stderr, "ERROR: unable to set label %s\n", + strerror(errno)); + close(fd); + return -1; + } + + return 0; +} + +static int get_label_unmounted(const char *dev) +{ + struct btrfs_root *root; + int ret; + + ret = check_mounted(dev); + if (ret < 0) { + fprintf(stderr, "FATAL: error checking %s mount status\n", dev); + return -1; + } + if (ret > 0) { + fprintf(stderr, "ERROR: dev %s is mounted, use mount point\n", + dev); + return -1; + } + + /* Open the super_block at the default location + * and as read-only. + */ + root = open_ctree(dev, 0, 0); + if(!root) + return -1; + + fprintf(stdout, "%s\n", root->fs_info->super_copy.label); + + /* Now we close it since we are done. */ + close_ctree(root); + return 0; +} + +/* + * If a partition is mounted, try to get the filesystem label via its + * mounted path rather than device. Return the corresponding error + * the user specified the device path. + */ +static int get_label_mounted(const char *mount_path) +{ + char label[BTRFS_LABEL_SIZE]; + int fd; + + fd = open(mount_path, O_RDONLY | O_NOATIME); + if (fd < 0) { + fprintf(stderr, "ERROR: unable access to '%s'\n", mount_path); + return -1; + } + + memset(label, '\0', sizeof(label)); + if (ioctl(fd, BTRFS_IOC_GET_FSLABEL, label) < 0) { + fprintf(stderr, "ERROR: unable get label %s\n", strerror(errno)); + close(fd); + return -1; + } + + fprintf(stdout, "%s\n", label); + return 0; +} + +int get_label(const char *btrfs_dev) +{ + return is_existing_blk_or_reg_file(btrfs_dev) ? + get_label_unmounted(btrfs_dev) : + get_label_mounted(btrfs_dev); +} + +int set_label(const char *btrfs_dev, const char *label) +{ + if (check_label(label)) + return -1; + + return is_existing_blk_or_reg_file(btrfs_dev) ? + set_label_unmounted(btrfs_dev, label) : + set_label_mounted(btrfs_dev, label); +} + int btrfs_scan_block_devices(int run_ioctl) { -- cgit v1.2.3