From 43f6ab83bf23a9833355b9970ddc600e445f2805 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Tue, 10 Apr 2007 09:27:30 -0400 Subject: [PATCH] btrfsctl --- Makefile | 8 +++++-- btrfsctl.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++ debug-tree.c | 59 ++++++++++++++++++++++++++++++++++++++++++------- disk-io.c | 3 --- ioctl.h | 13 +++++++++++ 5 files changed, 132 insertions(+), 13 deletions(-) create mode 100644 btrfsctl.c create mode 100644 ioctl.h diff --git a/Makefile b/Makefile index 50d980a3..219ce80b 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ CC=gcc CFLAGS = -g -Wall -Werror headers = radix-tree.h ctree.h disk-io.h kerncompat.h print-tree.h list.h \ - transaction.h + transaction.h ioctl.h objects = ctree.o disk-io.o radix-tree.o extent-tree.o print-tree.o \ root-tree.o dir-item.o hash.o file-item.o inode-item.o \ inode-map.o \ @@ -16,7 +16,11 @@ check=sparse $(CHECKFLAGS) $(check) $< $(CC) $(CFLAGS) -c $< -all: bit-radix-test tester debug-tree quick-test dir-test tags mkfs.btrfs +all: bit-radix-test tester debug-tree quick-test dir-test tags mkfs.btrfs \ + btrfsctl + +btrfsctl: ioctl.h btrfsctl.o + gcc $(CFLAGS) -o btrfsctl btrfsctl.o mkfs.btrfs: $(objects) mkfs.o gcc $(CFLAGS) -o mkfs.btrfs $(objects) mkfs.o -luuid diff --git a/btrfsctl.c b/btrfsctl.c new file mode 100644 index 00000000..cab846b0 --- /dev/null +++ b/btrfsctl.c @@ -0,0 +1,62 @@ +#ifndef __CHECKER__ +#include +#include +#include "ioctl.h" +#endif +#include +#include +#include +#include +#include +#include +#include "kerncompat.h" + +#ifdef __CHECKER__ +#define BLKGETSIZE64 0 +#define BTRFS_IOC_SNAP_CREATE 0 +#define BTRFS_VOL_NAME_MAX 255 +struct btrfs_ioctl_vol_args { char name[BTRFS_VOL_NAME_MAX]; }; +static inline int ioctl(int fd, int define, void *arg) { return 0; } +#endif + +void print_usage(void) +{ + printf("usage: btrfsctl [ -s snapshot_name ] dir\n"); + exit(1); +} + +int main(int ac, char **av) +{ + char *fname; + int fd; + int ret; + struct btrfs_ioctl_vol_args args; + char *name; + int i; + + for (i = 1; i < ac - 1; i++) { + if (strcmp(av[i], "-s") == 0) { + if (i + 1 >= ac - 1) { + fprintf(stderr, "-s requires an arg"); + print_usage(); + } + name = av[i + 1]; + if (strlen(name) >= BTRFS_VOL_NAME_MAX) { + fprintf(stderr, "snapshot name is too long\n"); + exit(1); + } + } + } + fname = av[ac - 1]; +printf("fname is %s\n", fname); + fd = open(fname, O_RDWR); + if (fd < 0) { + perror("open"); + exit(1); + } + strcpy(args.name, name); + ret = ioctl(fd, BTRFS_IOC_SNAP_CREATE, &args); + printf("ioctl returns %d\n", ret); + return 0; +} + diff --git a/debug-tree.c b/debug-tree.c index 5de69f2f..5e7165cc 100644 --- a/debug-tree.c +++ b/debug-tree.c @@ -11,7 +11,14 @@ int main(int ac, char **av) { struct btrfs_super_block super; struct btrfs_root *root; + struct btrfs_path path; + struct btrfs_key key; + struct btrfs_root_item *ri; + struct btrfs_leaf *leaf; + struct btrfs_key found_key; char uuidbuf[37]; + int ret; + int slot; if (ac != 2) { fprintf(stderr, "usage: %s device\n", av[0]); @@ -23,17 +30,53 @@ int main(int ac, char **av) { fprintf(stderr, "unable to open %s\n", av[1]); exit(1); } - printf("fs tree\n"); - btrfs_print_tree(root, root->node); - printf("map tree\n"); - btrfs_print_tree(root->fs_info->extent_root, - root->fs_info->extent_root->node); - printf("inode tree\n"); - btrfs_print_tree(root->fs_info->inode_root, - root->fs_info->inode_root->node); printf("root tree\n"); btrfs_print_tree(root->fs_info->tree_root, root->fs_info->tree_root->node); + btrfs_init_path(&path); + key.offset = 0; + key.objectid = 0; + key.flags = 0; + btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY); + ret = btrfs_search_slot(NULL, root->fs_info->tree_root, + &key, &path, 0, 0); + BUG_ON(ret < 0); + while(1) { + leaf = &path.nodes[0]->leaf; + slot = path.slots[0]; + if (slot >= btrfs_header_nritems(&leaf->header)) { + ret = btrfs_next_leaf(root, &path); + if (ret != 0) + break; + leaf = &path.nodes[0]->leaf; + slot = path.slots[0]; + } + btrfs_disk_key_to_cpu(&found_key, + &leaf->items[path.slots[0]].key); + if (btrfs_key_type(&found_key) == BTRFS_ROOT_ITEM_KEY) { + struct btrfs_buffer *buf; + ri = btrfs_item_ptr(leaf, path.slots[0], + struct btrfs_root_item); + buf = read_tree_block(root->fs_info->tree_root, + btrfs_root_blocknr(ri)); + switch(found_key.objectid) { + case BTRFS_ROOT_TREE_OBJECTID: + printf("root "); + break; + case BTRFS_EXTENT_TREE_OBJECTID: + printf("extent tree "); + break; + case BTRFS_INODE_MAP_OBJECTID: + printf("inode map"); + break; + } + printf("tree %Lu %Lu %u\n", found_key.objectid, + found_key.offset, found_key.flags); + btrfs_print_tree(root, buf); + } + path.slots[0]++; + } + btrfs_release_path(root, &path); printf("total blocks %Lu\n", btrfs_super_total_blocks(&super)); printf("blocks used %Lu\n", btrfs_super_blocks_used(&super)); uuidbuf[36] = '\0'; diff --git a/disk-io.c b/disk-io.c index 0911d4ee..d30f63ac 100644 --- a/disk-io.c +++ b/disk-io.c @@ -18,9 +18,6 @@ static int check_tree_block(struct btrfs_root *root, struct btrfs_buffer *buf) { if (buf->blocknr != btrfs_header_blocknr(&buf->node.header)) BUG(); - if (root->node && btrfs_header_parentid(&buf->node.header) != - btrfs_header_parentid(&root->node->node.header)) - BUG(); if (memcmp(root->fs_info->disk_super->fsid, buf->node.header.fsid, sizeof(buf->node.header.fsid))) BUG(); diff --git a/ioctl.h b/ioctl.h new file mode 100644 index 00000000..201fb327 --- /dev/null +++ b/ioctl.h @@ -0,0 +1,13 @@ +#ifndef __IOCTL_ +#define __IOCTL_ +#include + +#define BTRFS_IOCTL_MAGIC 0x94 +#define BTRFS_VOL_NAME_MAX 255 +struct btrfs_ioctl_vol_args { + char name[BTRFS_VOL_NAME_MAX + 1]; +}; + +#define BTRFS_IOC_SNAP_CREATE _IOW(BTRFS_IOCTL_MAGIC, 1, \ + struct btrfs_ioctl_vol_args) +#endif