Here is everything for the btrfslabel patches together.  Let me know if 
anything needs to be changed to get it merged.

Thanks,

Morey

This part is for the progs-unstable tree:
---------------------------------------------------

diff -r da35ab2b0b54 Makefile
--- a/Makefile  Wed Aug 06 12:17:01 2008 -0400
+++ b/Makefile  Thu Aug 07 17:11:44 2008 -0600
@@ -15,7 +15,7 @@
bindir = $(prefix)/bin
LIBS=-luuid

-progs = btrfsctl btrfsck mkfs.btrfs debug-tree btrfs-show btrfs-vol
+progs = btrfsctl btrfsck mkfs.btrfs debug-tree btrfs-show btrfs-vol btrfslabel

# make C=1 to enable sparse
ifdef C
@@ -45,6 +45,9 @@

btrfsck: $(objects) btrfsck.o bit-radix.o
        gcc $(CFLAGS) -o btrfsck btrfsck.o $(objects) bit-radix.o $(LDFLAGS) 
$(LIBS)
+
+btrfslabel: $(objects) btrfslabel.o
+       gcc $(CFLAGS) -o btrfslabel btrfslabel.o $(objects) $(LDFLAGS) $(LIBS)

mkfs.btrfs: $(objects) mkfs.o
        gcc $(CFLAGS) -o mkfs.btrfs $(objects) mkfs.o $(LDFLAGS) $(LIBS)
diff -r da35ab2b0b54 btrfslabel.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/btrfslabel.c      Thu Aug 07 17:11:44 2008 -0600
@@ -0,0 +1,244 @@
+/*
+ * 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
+ * License v2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ */
+
+#define _GNU_SOURCE
+
+#ifndef __CHECKER__
+#include <sys/ioctl.h>
+#include <sys/mount.h>
+#include "ioctl.h"
+#endif /* __CHECKER__ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <linux/fs.h>
+#include <linux/limits.h>
+#include <ctype.h>
+#include "kerncompat.h"
+#include "ctree.h"
+#include "utils.h"
+#include "version.h"
+#include "disk-io.h"
+#include "transaction.h"
+
+#define MOUNTED                        1
+#define UNMOUNTED                      2
+#define GET_LABEL                      3
+#define SET_LABEL                      4
+
+#ifdef __CHECKER__
+#define BTRFS_IOC_SET_LABEL            0
+#define BTRFS_IOC_GET_LABEL            0
+struct btrfs_ioctl_label_args { char name[BTRFS_LABEL_SIZE]; };
+static inline int ioctl(int fd, int define, void *arg) { return 0; }
+#endif /*__CHECKER__*/
+
+static void print_usage(void)
+{
+       fprintf(stderr, "usage: btrfslabel dev [newlabel]\n");
+       fprintf(stderr, "%s\n", BTRFS_BUILD_VERSION);
+       exit(1);
+}
+
+static void change_label_unmounted(char *dev, char *nLabel)
+{
+       struct btrfs_root *root;
+       struct btrfs_trans_handle *trans;
+
+       /* Open the super_block at the default location
+        * and as read-write.
+        */
+       root = open_ctree(dev, 0, 1);
+
+       trans = btrfs_start_transaction(root, 1);
+       strncpy(root->fs_info->super_copy.label, nLabel, BTRFS_LABEL_SIZE);
+       btrfs_commit_transaction(trans, root);
+
+       /* Now we close it since we are done. */
+       close_ctree(root);
+}
+
+static void get_label_unmounted(char *dev)
+{
+       struct btrfs_root *root;
+
+       /* Open the super_block at the default location
+        * and as read-only.
+        */
+       root = open_ctree(dev, 0, 0);
+
+       fprintf(stdout, "%s\n", root->fs_info->super_copy.label);
+
+       /* Now we close it since we are done. */
+       close_ctree(root);
+}
+
+static void mount_label_op(char *dev, char *nLabel, int cmd)
+{
+       struct btrfs_ioctl_label_args label_args;       
+       int ret = 0;
+       DIR *dirstream;
+       int fd;
+       char *mount_point;
+
+       mount_point = malloc(PATH_MAX);
+       if (mount_point == NULL)
+       {
+               fprintf(stderr, "FATAL: Unable to allocate memory\n");
+               exit(1);
+       }
+
+       if (get_mountpt(dev, mount_point, PATH_MAX) != 0)
+       {
+               fprintf(stderr, "FATAL: Unable to determine mount point\n");
+               exit(1);
+       }
+
+       dirstream = opendir(mount_point);
+       if (!dirstream)
+       {
+               fprintf(stderr, "FATAL: Unable to access mount point %s\n", 
mount_point);
+               exit(1);
+       }
+
+       fd = dirfd(dirstream);
+       if (!fd)
+       {
+               fprintf(stderr, "FATAL: Unable to access btrfs on %s\n", dev);
+               exit(1);
+       }
+       
+       switch(cmd)
+       {
+               case GET_LABEL:
+                       ret = ioctl(fd, BTRFS_IOC_GET_LABEL, &label_args);
+                       if (ret == 0)
+                       {
+                               fprintf(stdout, "%s\n", label_args.name);
+                       } else
+                       {
+                               fprintf(stderr, "FATAL: Unable to get label for 
%s\n", dev);
+                               exit(1);
+                       }
+                       break;
+               case SET_LABEL:
+                       strncpy(label_args.name, nLabel, BTRFS_LABEL_SIZE);
+
+                       ret = ioctl(fd, BTRFS_IOC_SET_LABEL, &label_args);
+                       if (ret != 0)
+                       {
+                               fprintf(stderr, "FATAL: Unable to set label for 
%s\n", dev);
+                               exit(1);
+                       }
+                       break;
+               default:
+                       fprintf(stderr, "FATAL: Unknown mounted label 
operation\n");
+                       exit(1);
+                       break;
+       }
+
+       /* Release the memory we used */
+       free(mount_point);
+}
+
+int main(int argc, char **argv)
+{
+       char *btrfs_dev;
+       char *nLabel;
+       int ret = 0;
+       int workas = 0;
+       int check_val = 0;
+
+       if (argc <= 1)
+       {
+               print_usage();
+       }
+
+       btrfs_dev = argv[1];
+       ret = check_mounted(btrfs_dev);
+       if (ret < 0)
+       {
+               fprintf(stderr, "FATAL: error checking %s mount status\n", 
btrfs_dev);
+               exit(1);
+       }
+
+       switch(ret)
+       {
+               case 0:
+                       workas = UNMOUNTED;
+                       break;
+               case 1:
+                       workas = MOUNTED;
+                       break;
+               default:
+                       fprintf(stderr, "BUG: unknown return code from 
check_mounted()\n");
+                       exit(1);
+                       break;
+       }
+
+       if (argc == 2)
+       {
+               /* They just want to know what the current label is */
+               if (workas == MOUNTED)
+               {
+                       mount_label_op(btrfs_dev, NULL, GET_LABEL);
+               } else
+               {
+                       /* Get the label from an unmouted filesystem */
+                       get_label_unmounted(btrfs_dev);
+               }
+       } else if (argc == 3)
+       {
+               /* They have requested we change the label */
+               nLabel = argv[2];
+               check_val = check_label(nLabel);
+
+               if (check_val == -1)
+               {
+                       fprintf(stderr, "Label %s is too long (max %d)\n", 
nLabel,
+                               BTRFS_LABEL_SIZE);
+                       exit(1);
+               }
+
+               if (check_val == -2)
+               {
+                       fprintf(stderr, "invalid label %s\n", nLabel);
+                       exit(1);
+               }
+
+               if (workas == MOUNTED)
+               {
+                       mount_label_op(btrfs_dev, nLabel, SET_LABEL);
+               } else
+               {
+                       /* We are going to change the label on an unmounted 
filesystem */
+                       change_label_unmounted(btrfs_dev, nLabel);
+               }
+       } else
+       {
+               fprintf(stderr, "FATAL: too many arguements\n\n");
+               print_usage();
+       }
+
+       return ret;
+}
diff -r da35ab2b0b54 ioctl.h
--- a/ioctl.h   Wed Aug 06 12:17:01 2008 -0400
+++ b/ioctl.h   Thu Aug 07 17:11:44 2008 -0600
@@ -19,6 +19,7 @@
#ifndef __IOCTL_
#define __IOCTL_
#include <linux/ioctl.h>
+#include "ctree.h"

#define BTRFS_IOCTL_MAGIC 0x94
#define BTRFS_VOL_NAME_MAX 255
@@ -26,6 +27,10 @@

struct btrfs_ioctl_vol_args {
        char name[BTRFS_PATH_NAME_MAX + 1];
+};
+
+struct btrfs_ioctl_label_args {
+       char name[BTRFS_LABEL_SIZE + 1];
};

#define BTRFS_IOC_SNAP_CREATE _IOW(BTRFS_IOCTL_MAGIC, 1, \
@@ -52,4 +57,10 @@
#define BTRFS_IOC_BALANCE _IOW(BTRFS_IOCTL_MAGIC, 12, \
                                   struct btrfs_ioctl_vol_args)

+/* Used to set and get the current volume label */
+#define BTRFS_IOC_SET_LABEL    _IOW(BTRFS_IOCTL_MAGIC, 13, \
+                                       struct btrfs_ioctl_label_args)
+#define BTRFS_IOC_GET_LABEL    _IOW(BTRFS_IOCTL_MAGIC, 14, \
+                                       struct btrfs_ioctl_label_args)
+
#endif
diff -r da35ab2b0b54 mkfs.c
--- a/mkfs.c    Wed Aug 06 12:17:01 2008 -0400
+++ b/mkfs.c    Thu Aug 07 17:11:44 2008 -0600
@@ -246,6 +246,7 @@
        fprintf(stderr, "options:\n");
        fprintf(stderr, "\t -b --byte-count total number of bytes in the FS\n");
        fprintf(stderr, "\t -l --leafsize size of btree leaves\n");
+       fprintf(stderr, "\t -L --label of the filesystem\n");
        fprintf(stderr, "\t -n --nodesize size of btree leaves\n");
        fprintf(stderr, "\t -s --sectorsize min block allocation\n");
        fprintf(stderr, "%s\n", BTRFS_BUILD_VERSION);
@@ -271,20 +272,19 @@

static char *parse_label(char *input)
{
-       int i;
-       int len = strlen(input);
+       int check_val = check_label(input);

-       if (len > BTRFS_LABEL_SIZE) {
+       if (check_val == -1) {
                fprintf(stderr, "Label %s is too long (max %d)\n", input,
                        BTRFS_LABEL_SIZE);
                exit(1);
        }
-       for (i = 0; i < len; i++) {
-               if (input[i] == '/' || input[i] == '\\') {
-                       fprintf(stderr, "invalid label %s\n", input);
-                       exit(1);
-               }
+
+       if (check_val == -2) {
+               fprintf(stderr, "invalid label %s\n", input);
+               exit(1);
        }
+
        return strdup(input);
}

diff -r da35ab2b0b54 utils.c
--- a/utils.c   Wed Aug 06 12:17:01 2008 -0400
+++ b/utils.c   Thu Aug 07 17:11:44 2008 -0600
@@ -572,7 +572,7 @@
}

/*
- * returns 1 if the device was mounted, < 0 on error or 0 if everything
+ * returns 1 if the device is mounted, < 0 on error or 0 if everything
 * is safe to continue.  TODO, this should also scan multi-device filesystems
 */
int check_mounted(char *file)
@@ -620,6 +620,39 @@
        }

        endmntent (f);
+       return ret;
+}
+
+/* Gets the mount point of btrfs filesystem that is using the specified device.
+ * Returns 0 is everything is good, <0 if we have an error.
+ * TODO: Fix this fucntion and check_mounted to work with multiple drive BTRFS
+ * setups.
+ */
+int get_mountpt(char *dev, char *mntpt, size_t size)
+{
+       struct mntent *mnt;
+       FILE *f;
+       int ret = 0;
+
+       f = setmntent("/proc/mounts", "r");
+       if (f == NULL)
+               return -errno;
+
+       while ((mnt = getmntent(f)) != NULL )
+       {
+               if (strcmp(dev, mnt->mnt_fsname) == 0)
+               {
+                       strncpy(mntpt, mnt->mnt_dir, size);
+                       break;
+               }
+       }
+
+       if (mnt == NULL)
+       {
+               /* We didn't find an entry so lets report an error */
+               ret = -1;
+       }
+
        return ret;
}

@@ -803,3 +836,27 @@
        return pretty;
}

+/*
+ * Checks to make sure that the label matches our requirements.
+ * Returns:
+       0    if everything is safe and usable
+      -1    if the label is too long
+      -2    if the label contains an invalid character
+ */
+int check_label(char *input)
+{
+       int i;
+       int len = strlen(input);
+
+       if (len > BTRFS_LABEL_SIZE) {
+               return -1;
+       }
+
+       for (i = 0; i < len; i++) {
+               if (input[i] == '/' || input[i] == '\\') {
+                       return -2;
+               }
+       }
+
+       return 0;
+}
diff -r da35ab2b0b54 utils.h
--- a/utils.h   Wed Aug 06 12:17:01 2008 -0400
+++ b/utils.h   Thu Aug 07 17:11:45 2008 -0600
@@ -40,4 +40,6 @@
int btrfs_device_already_in_root(struct btrfs_root *root, int fd,
                                 int super_offset);
char *pretty_sizes(u64 size);
+int check_label(char *input);
+int get_mountpt(char *dev, char *mntpt, size_t size);
#endif


------------------------------------------------------------------------

This part is for the kernel-unstable tree


------------------------------------------------------------------------
diff -r b68faa369602 ioctl.c
--- a/ioctl.c   Wed Aug 06 14:41:23 2008 -0600
+++ b/ioctl.c   Thu Aug 07 09:57:27 2008 -0600
@@ -749,6 +749,53 @@
        return ret;
}

+long btrfs_ioctl_set_label(struct btrfs_root *root, void __user *arg)
+{
+       struct btrfs_trans_handle *trans;
+       struct btrfs_ioctl_label_args *label_args;
+       int ret = 0;
+
+       label_args = kmalloc(sizeof(*label_args), GFP_NOFS);
+
+       if (!label_args)
+               return -ENOMEM;
+
+       if (copy_from_user(label_args, arg, sizeof(*label_args)))
+       {
+               ret = -EFAULT;
+       } else
+       {
+               /* Everything looks good, so lets do a label change */
+               label_args->name[BTRFS_LABEL_SIZE] = 0x00;
+               trans = btrfs_start_transaction(root, 1);
+               strncpy(root->fs_info->super_copy.label, label_args->name, 
BTRFS_LABEL_SIZE);
+               btrfs_commit_transaction(trans, root);
+       }
+
+       kfree(label_args);
+       return ret;
+}
+
+long btrfs_ioctl_get_label(struct btrfs_root *root, void __user *arg)
+{
+       struct btrfs_ioctl_label_args *label_args;
+       int ret = 0;
+
+       label_args = kmalloc(sizeof(*label_args), GFP_NOFS);
+
+       if (!label_args)
+               return -ENOMEM;
+
+       strncpy(label_args->name, root->fs_info->super_copy.label, 
BTRFS_LABEL_SIZE);
+       if (copy_to_user(arg, label_args, sizeof(*label_args)))
+       {
+               ret = -EFAULT;
+       }
+
+       kfree(label_args);
+       return ret;
+}
+
long btrfs_ioctl(struct file *file, unsigned int
                cmd, unsigned long arg)
{
@@ -773,6 +820,10 @@
                return btrfs_ioctl_trans_start(file);
        case BTRFS_IOC_TRANS_END:
                return btrfs_ioctl_trans_end(file);
+       case BTRFS_IOC_SET_LABEL:
+               return btrfs_ioctl_set_label(root, (void __user *)arg);
+       case BTRFS_IOC_GET_LABEL:
+               return btrfs_ioctl_get_label(root, (void __user *)arg);
        case BTRFS_IOC_SYNC:
                btrfs_start_delalloc_inodes(root);
                btrfs_sync_fs(file->f_dentry->d_sb, 1);
diff -r b68faa369602 ioctl.h
--- a/ioctl.h   Wed Aug 06 14:41:23 2008 -0600
+++ b/ioctl.h   Thu Aug 07 09:57:27 2008 -0600
@@ -19,6 +19,7 @@
#ifndef __IOCTL__
#define __IOCTL__
#include <linux/ioctl.h>
+#include "ctree.h"

#define BTRFS_IOCTL_MAGIC 0x94
#define BTRFS_VOL_NAME_MAX 255
@@ -26,6 +27,10 @@

struct btrfs_ioctl_vol_args {
        char name[BTRFS_PATH_NAME_MAX + 1];
+};
+
+struct btrfs_ioctl_label_args {
+       char name[BTRFS_LABEL_SIZE + 1];
};

#define BTRFS_IOC_SNAP_CREATE _IOW(BTRFS_IOCTL_MAGIC, 1, \
@@ -52,4 +57,10 @@
#define BTRFS_IOC_BALANCE _IOW(BTRFS_IOCTL_MAGIC, 12, \
                                   struct btrfs_ioctl_vol_args)

+/* Used to set and get the current volume label */
+#define BTRFS_IOC_SET_LABEL    _IOW(BTRFS_IOCTL_MAGIC, 13, \
+                                       struct btrfs_ioctl_label_args)
+#define BTRFS_IOC_GET_LABEL    _IOW(BTRFS_IOCTL_MAGIC, 14, \
+                                       struct btrfs_ioctl_label_args)
+
#endif

--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to