* btrfsLabel Patches
@ 2008-08-12 14:33 Morey Roof
0 siblings, 0 replies; only message in thread
From: Morey Roof @ 2008-08-12 14:33 UTC (permalink / raw)
To: linux-btrfs
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
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2008-08-12 14:33 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-08-12 14:33 btrfsLabel Patches Morey Roof
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.