From a62332eeb2235ef1cbdd270323bc68e106c632ac Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Mon, 5 May 2008 09:45:26 -0400 Subject: [PATCH] Add a readonly flag open_ctree to force RO opens --- btrfsck.c | 2 +- convert.c | 6 +++--- ctree.h | 1 + debug-tree.c | 2 +- dir-test.c | 4 ++-- disk-io.c | 25 ++++++++++++++++++++----- disk-io.h | 5 +++-- mkfs.c | 4 ++-- quick-test.c | 10 +++++----- 9 files changed, 38 insertions(+), 21 deletions(-) diff --git a/btrfsck.c b/btrfsck.c index 174c7f90..b4472251 100644 --- a/btrfsck.c +++ b/btrfsck.c @@ -746,7 +746,7 @@ int main(int ac, char **av) { cache_tree_init(&nodes); cache_tree_init(&reada); - root = open_ctree(av[1], 0); + root = open_ctree(av[1], 0, 0); bits_nr = 1024; bits = malloc(bits_nr * sizeof(struct block_info)); diff --git a/convert.c b/convert.c index 80dc3f59..219f849b 100644 --- a/convert.c +++ b/convert.c @@ -2189,7 +2189,7 @@ int do_convert(const char *devname, int datacsum, int packing, int noxattr) fprintf(stderr, "unable to update system chunk\n"); goto fail; } - root = open_ctree_fd(fd, devname, super_bytenr); + root = open_ctree_fd(fd, devname, super_bytenr, O_RDWR); if (!root) { fprintf(stderr, "unable to open ctree\n"); goto fail; @@ -2251,7 +2251,7 @@ int do_convert(const char *devname, int datacsum, int packing, int noxattr) goto fail; } - root = open_ctree_fd(fd, devname, 0); + root = open_ctree_fd(fd, devname, 0, O_RDWR); if (!root) { fprintf(stderr, "unable to open ctree\n"); goto fail; @@ -2349,7 +2349,7 @@ int do_rollback(const char *devname, int force) fprintf(stderr, "unable to open %s\n", devname); goto fail; } - root = open_ctree_fd(fd, devname, 0); + root = open_ctree_fd(fd, devname, 0, O_RDWR); if (!root) { fprintf(stderr, "unable to open ctree\n"); goto fail; diff --git a/ctree.h b/ctree.h index d2853448..a5a284c6 100644 --- a/ctree.h +++ b/ctree.h @@ -515,6 +515,7 @@ struct btrfs_fs_info { struct btrfs_fs_devices *fs_devices; struct list_head space_info; int system_allocs; + int readonly; }; /* diff --git a/debug-tree.c b/debug-tree.c index acfa442d..21162ecf 100644 --- a/debug-tree.c +++ b/debug-tree.c @@ -130,7 +130,7 @@ int main(int ac, char **av) if (ac != 1) print_usage(); - root = open_ctree(av[optind], 0); + root = open_ctree(av[optind], 0, 0); if (!root) { fprintf(stderr, "unable to open %s\n", av[optind]); exit(1); diff --git a/dir-test.c b/dir-test.c index 54ddee2d..44f27587 100644 --- a/dir-test.c +++ b/dir-test.c @@ -435,7 +435,7 @@ int main(int ac, char **av) struct btrfs_trans_handle *trans; radix_tree_init(); - root = open_ctree(av[ac-1], &super); + root = open_ctree(av[ac-1], &super, 0); trans = btrfs_start_transaction(root, 1); dir_oid = btrfs_super_root_dir(&super); @@ -478,7 +478,7 @@ int main(int ac, char **av) btrfs_header_level(&root->node->node.header), btrfs_header_nritems(&root->node->node.header)); close_ctree(root, &super); - root = open_ctree("dbfile", &super); + root = open_ctree("dbfile", &super, 0); } while(count--) { ret = ops[op](trans, root, &radix); diff --git a/disk-io.c b/disk-io.c index 23c9aa89..939f7727 100644 --- a/disk-io.c +++ b/disk-io.c @@ -454,22 +454,27 @@ insert: return root; } -struct btrfs_root *open_ctree(const char *filename, u64 sb_bytenr) +struct btrfs_root *open_ctree(const char *filename, u64 sb_bytenr, int writes) { int fp; struct btrfs_root *root; + int flags = O_CREAT | O_RDWR; - fp = open(filename, O_CREAT | O_RDWR, 0600); + if (!writes) + flags = O_RDONLY; + + fp = open(filename, flags, 0600); if (fp < 0) { return NULL; } - root = open_ctree_fd(fp, filename, sb_bytenr); + root = open_ctree_fd(fp, filename, sb_bytenr, writes); close(fp); return root; } -struct btrfs_root *open_ctree_fd(int fp, const char *path, u64 sb_bytenr) +struct btrfs_root *open_ctree_fd(int fp, const char *path, u64 sb_bytenr, + int writes) { u32 sectorsize; u32 nodesize; @@ -510,6 +515,9 @@ struct btrfs_root *open_ctree_fd(int fp, const char *path, u64 sb_bytenr) fs_info->chunk_root = chunk_root; fs_info->dev_root = dev_root; + if (!writes) + fs_info->readonly = 1; + extent_io_tree_init(&fs_info->extent_cache); extent_io_tree_init(&fs_info->free_space_cache); extent_io_tree_init(&fs_info->block_group_cache); @@ -527,7 +535,10 @@ struct btrfs_root *open_ctree_fd(int fp, const char *path, u64 sb_bytenr) __setup_root(4096, 4096, 4096, 4096, tree_root, fs_info, BTRFS_ROOT_TREE_OBJECTID); - ret = btrfs_open_devices(fs_devices, O_RDWR); + if (writes) + ret = btrfs_open_devices(fs_devices, O_RDWR); + else + ret = btrfs_open_devices(fs_devices, O_RDONLY); BUG_ON(ret); ret = btrfs_bootstrap_super_map(&fs_info->mapping_tree, fs_devices); @@ -656,6 +667,10 @@ int write_ctree_super(struct btrfs_trans_handle *trans, int ret; struct btrfs_root *tree_root = root->fs_info->tree_root; struct btrfs_root *chunk_root = root->fs_info->chunk_root; + + if (root->fs_info->readonly) + return 0; + btrfs_set_super_generation(&root->fs_info->super_copy, trans->transid); btrfs_set_super_root(&root->fs_info->super_copy, diff --git a/disk-io.h b/disk-io.h index bd8ca63c..b0328445 100644 --- a/disk-io.h +++ b/disk-io.h @@ -31,8 +31,9 @@ struct extent_buffer *btrfs_find_create_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize); int clean_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct extent_buffer *buf); -struct btrfs_root *open_ctree(const char *filename, u64 sb_bytenr); -struct btrfs_root *open_ctree_fd(int fp, const char *path, u64 sb_bytenr); +struct btrfs_root *open_ctree(const char *filename, u64 sb_bytenr, int writes); +struct btrfs_root *open_ctree_fd(int fp, const char *path, u64 sb_bytenr, + int writes); int close_ctree(struct btrfs_root *root); int write_ctree_super(struct btrfs_trans_handle *trans, struct btrfs_root *root); diff --git a/mkfs.c b/mkfs.c index 740cc81d..e1b42971 100644 --- a/mkfs.c +++ b/mkfs.c @@ -77,7 +77,7 @@ static int make_root_dir(int fd, const char *device_name) { u64 chunk_size = 0; int ret; - root = open_ctree_fd(fd, device_name, 0); + root = open_ctree_fd(fd, device_name, 0, O_RDWR); if (!root) { fprintf(stderr, "ctree init failed\n"); @@ -408,7 +408,7 @@ int main(int ac, char **av) fprintf(stderr, "failed to setup the root directory\n"); exit(1); } - root = open_ctree(file, 0); + root = open_ctree(file, 0, O_RDWR); root->fs_info->alloc_start = alloc_start; trans = btrfs_start_transaction(root, 1); diff --git a/quick-test.c b/quick-test.c index 16a3bf47..44c23185 100644 --- a/quick-test.c +++ b/quick-test.c @@ -50,7 +50,7 @@ int main(int ac, char **av) { radix_tree_init(); - root = open_ctree(av[1], BTRFS_SUPER_INFO_OFFSET); + root = open_ctree(av[1], BTRFS_SUPER_INFO_OFFSET, O_RDWR); trans = btrfs_start_transaction(root, 1); srand(55); btrfs_set_key_type(&ins, BTRFS_STRING_ITEM_KEY); @@ -73,7 +73,7 @@ int main(int ac, char **av) { btrfs_commit_transaction(trans, root); close_ctree(root); exit(1); - root = open_ctree(av[1], BTRFS_SUPER_INFO_OFFSET); + root = open_ctree(av[1], BTRFS_SUPER_INFO_OFFSET, O_RDWR); printf("starting search\n"); srand(55); for (i = 0; i < run_size; i++) { @@ -92,7 +92,7 @@ int main(int ac, char **av) { } close_ctree(root); - root = open_ctree(av[1], BTRFS_SUPER_INFO_OFFSET); + root = open_ctree(av[1], BTRFS_SUPER_INFO_OFFSET, O_RDWR); printf("node %p level %d total ptrs %d free spc %lu\n", root->node, btrfs_header_level(root->node), btrfs_header_nritems(root->node), @@ -120,7 +120,7 @@ int main(int ac, char **av) { btrfs_commit_transaction(trans, root); close_ctree(root); - root = open_ctree(av[1], BTRFS_SUPER_INFO_OFFSET); + root = open_ctree(av[1], BTRFS_SUPER_INFO_OFFSET, O_RDWR); trans = btrfs_start_transaction(root, 1); srand(128); for (i = 0; i < run_size; i++) { @@ -136,7 +136,7 @@ int main(int ac, char **av) { btrfs_commit_transaction(trans, root); close_ctree(root); - root = open_ctree(av[1], BTRFS_SUPER_INFO_OFFSET); + root = open_ctree(av[1], BTRFS_SUPER_INFO_OFFSET, O_RDWR); srand(128); printf("starting search2\n"); for (i = 0; i < run_size; i++) {