With this new ioctl(2), we can get the label for a mounted file system.
It still does normal process to fetch label if the specified file system is 
unmounted.

Signed-off-by: Jie Liu <jeff....@oracle.com>
Signed-off-by: Anand Jain <anand.j...@oracle.com>

---
 btrfslabel.c |   74 ++++++++++++++++++++++++++++++++++++++--------------------
 ioctl.h      |    2 ++
 utils.c      |    2 +-
 utils.h      |    1 +
 4 files changed, 53 insertions(+), 26 deletions(-)

diff --git a/btrfslabel.c b/btrfslabel.c
index cb142b0..443eff6 100644
--- a/btrfslabel.c
+++ b/btrfslabel.c
@@ -67,45 +67,69 @@ static void change_label_unmounted(char *dev, char *nLabel)
        close_ctree(root);
 }
 
-int get_label_unmounted(char *dev)
+static int get_label_unmounted(const char *dev)
 {
-       struct btrfs_root *root;
+       struct btrfs_root *root;
+       int ret;
 
-       /* Open the super_block at the default location
-        * and as read-only.
-        */
-       root = open_ctree(dev, 0, 0);
+       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;
+       }
 
-       if(!root)
-         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);
+       fprintf(stdout, "%s\n", root->fs_info->super_copy.label);
 
-       /* Now we close it since we are done. */
-       close_ctree(root);
-       return 0;
+       /* Now we close it since we are done. */
+       close_ctree(root);
+       return 0;
 }
 
-int get_label(char *btrfs_dev)
+/*
+ * 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;
 
-       int ret;
-       ret = check_mounted(btrfs_dev);
-       if (ret < 0)
-       {
-              fprintf(stderr, "FATAL: error checking %s mount status\n", 
btrfs_dev);
-              return -1;
+       fd = open(mount_path, O_RDONLY | O_NOATIME);
+       if (fd < 0) {
+               fprintf(stderr, "ERROR: unable access to '%s'\n", mount_path);
+               return -1;
        }
 
-       if(ret != 0)
-       {
-              fprintf(stderr, "FATAL: the filesystem has to be unmounted\n");
-              return -2;
+       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;
        }
-       ret = get_label_unmounted(btrfs_dev);
-       return ret;
+
+       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(char *btrfs_dev, char *nLabel)
 {
diff --git a/ioctl.h b/ioctl.h
index 6fda3a1..0807b05 100644
--- a/ioctl.h
+++ b/ioctl.h
@@ -432,4 +432,6 @@ struct btrfs_ioctl_clone_range_args {
                                        struct btrfs_ioctl_qgroup_create_args)
 #define BTRFS_IOC_QGROUP_LIMIT _IOR(BTRFS_IOCTL_MAGIC, 43, \
                                        struct btrfs_ioctl_qgroup_limit_args)
+#define BTRFS_IOC_GET_FSLABEL _IOR(BTRFS_IOCTL_MAGIC, 49, \
+                                  char[BTRFS_LABEL_SIZE])
 #endif
diff --git a/utils.c b/utils.c
index 205e667..d59bca3 100644
--- a/utils.c
+++ b/utils.c
@@ -811,7 +811,7 @@ int check_mounted(const char* file)
                return -errno;
        }
 
-       ret =  check_mounted_where(fd, file, NULL, 0, NULL);
+       ret = check_mounted_where(fd, file, NULL, 0, NULL);
        close(fd);
 
        return ret;
diff --git a/utils.h b/utils.h
index 3a0368b..8750f28 100644
--- a/utils.h
+++ b/utils.h
@@ -46,4 +46,5 @@ int check_label(char *input);
 int get_mountpt(char *dev, char *mntpt, size_t size);
 
 int btrfs_scan_block_devices(int run_ioctl);
+int is_existing_blk_or_reg_file(const char* filename);
 #endif
-- 
1.7.9.5
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to