update btrfs-progs for seed device support
Subsystems (2)
PATCH 1/1 update btrfs-progs for seed device support
hello,
This patch has following 3 things.
1) Update device management code to match the kernel code.
2) Allocator fixes.
3) Add a program called btrfstune to set/clear the SEEDING super block flags.
Regards
Yan Zheng <[email protected]>
---
btrfstune.c +126 -0
@@ -0,0 +1,126 @@ +/* +* Copyright (C) 2008 Oracle. 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 _XOPEN_SOURCE 500 +#define _GNU_SOURCE 1 +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <dirent.h> +#include "kerncompat.h" +#include "ctree.h" +#include "disk-io.h" +#include "transaction.h" +#include "utils.h" +#include "version.h" + +static char *device; + +int update_seeding_flag (struct btrfs_root *root,int set_flag) +{ +struct btrfs_trans_handle *trans; +struct btrfs_super_block *disk_super; +u64 super_flags; + + disk_super = &root->fs_info->super_copy; + super_flags =btrfs_super_flags (disk_super); +if (set_flag) { +if (super_flags &BTRFS_SUPER_FLAG_SEEDING ) { +fprintf (stderr,"seeding flag is already set on %s\n" , + device); +return 1 ; + } + super_flags |=BTRFS_SUPER_FLAG_SEEDING ; + }else { +if (!(super_flags &BTRFS_SUPER_FLAG_SEEDING )) { +fprintf (stderr,"seeding flag is not set on %s\n" , + device); +return 1 ; + } + super_flags &= ~BTRFS_SUPER_FLAG_SEEDING ; + } + + trans =btrfs_start_transaction (root,1 ); +btrfs_set_super_flags (disk_super, super_flags); +btrfs_commit_transaction (trans, root); + +return 0 ; +} + +static void print_usage (void ) +{ +fprintf (stderr,"usage: btrfstune [options] device\n" ); +fprintf (stderr,"\t-S value\tenable/disable seeding\n" ); +} + +int main (int argc,char *argv[]) +{ +struct btrfs_root *root; +int success =0 ; +int seeding_flag =0 ; +int seeding_value =0 ; +int ret; + +while (1 ) { +int c =getopt (argc, argv,"S:" ); +if (c <0 ) +break ; +switch (c) { +case 'S' : + seeding_flag =1 ; + seeding_value =atoi (optarg); +break ; +default : +print_usage (); +return 1 ; + } + } + + argc = argc - optind; + device = argv[optind]; +if (argc !=1 ) { +print_usage (); +return 1 ; + } + +if (check_mounted (device)) { +fprintf (stderr,"%s is mounted\n" , device); +return 1 ; + } + + root =open_ctree (device,0 ,1 ); + +if (seeding_flag) { + ret =update_seeding_flag (root, seeding_value); +if (!ret) + success++; + } + +if (success >0 ) { + ret =0 ; + }else { + root->fs_info->readonly =1 ; + ret =1 ; + } +close_ctree (root); + +return ret; +}
ctree.c +8 -0
@@ -111,6 +111,10 @@ int btrfs_copy_root(struct btrfs_trans_hbtrfs_set_header_generation (cow, trans->transid);btrfs_set_header_owner (cow, new_root_objectid);btrfs_clear_header_flag (cow,BTRFS_HEADER_FLAG_WRITTEN ); + +write_extent_buffer (cow, root->fs_info->fsid, + (unsigned long )btrfs_header_fsid (cow), +BTRFS_FSID_SIZE );WARN_ON (btrfs_header_generation (buf) > trans->transid); ret =btrfs_inc_ref (trans, new_root, buf, cow,NULL );
@@ -161,6 +165,10 @@ int __btrfs_cow_block(struct btrfs_transbtrfs_set_header_owner (cow, root->root_key.objectid);btrfs_clear_header_flag (cow,BTRFS_HEADER_FLAG_WRITTEN ); +write_extent_buffer (cow, root->fs_info->fsid, + (unsigned long )btrfs_header_fsid (cow), +BTRFS_FSID_SIZE ); +WARN_ON (btrfs_header_generation (buf) > trans->transid);if (btrfs_header_generation (buf) != trans->transid) { different_trans =1 ;
ctree.h +18 -0
@@ -160,6 +160,9 @@ struct btrfs_dev_item {/* type and info about this device */ __le64 type; +/* expected generation for this device */ +__le64 generation; +/* grouping information for allocation decisions */ __le32 dev_group;
@@ -171,6 +174,9 @@ struct btrfs_dev_item {/* btrfs generated uuid for this device */ u8 uuid[BTRFS_UUID_SIZE ]; + +/* uuid of FS who owns this device */ +u8 fsid[BTRFS_UUID_SIZE ]; } __attribute__ ((__packed__));struct btrfs_stripe {
@@ -246,6 +252,8 @@ struct btrfs_header { sizeof(struct btrfs_item) - \ sizeof(struct btrfs_file_extent_item)) +#define BTRFS_SUPER_FLAG_SEEDING (1ULL << 32) +/* * this is a very generous portion of the super block, giving us * room to translate 14 chunks with 3 stripes each.
@@ -524,6 +532,7 @@ struct btrfs_block_group_cache {u64 pinned;u64 flags;int cached; +int ro; };struct btrfs_extent_ops {
@@ -744,6 +753,7 @@ BTRFS_SETGET_FUNCS(device_id, struct btr BTRFS_SETGET_FUNCS(device_group, struct btrfs_dev_item, dev_group, 32); BTRFS_SETGET_FUNCS(device_seek_speed, struct btrfs_dev_item, seek_speed, 8); BTRFS_SETGET_FUNCS(device_bandwidth, struct btrfs_dev_item, bandwidth, 8); +BTRFS_SETGET_FUNCS(device_generation, struct btrfs_dev_item, generation, 64); BTRFS_SETGET_STACK_FUNCS(stack_device_type, struct btrfs_dev_item, type, 64); BTRFS_SETGET_STACK_FUNCS(stack_device_total_bytes, struct btrfs_dev_item,
@@ -763,12 +773,19 @@ BTRFS_SETGET_STACK_FUNCS(stack_device_se seek_speed, 8); BTRFS_SETGET_STACK_FUNCS(stack_device_bandwidth, struct btrfs_dev_item, bandwidth,8 ); +BTRFS_SETGET_STACK_FUNCS(stack_device_generation, struct btrfs_dev_item, + generation,64 );static inline char *btrfs_device_uuid (struct btrfs_dev_item *d) {return (char *)d + offsetof(struct btrfs_dev_item , uuid); } +static inline char *btrfs_device_fsid (struct btrfs_dev_item *d) +{ +return (char *)d + offsetof(struct btrfs_dev_item , fsid); +} + BTRFS_SETGET_FUNCS(chunk_length, struct btrfs_chunk, length, 64); BTRFS_SETGET_FUNCS(chunk_owner, struct btrfs_chunk, owner, 64); BTRFS_SETGET_FUNCS(chunk_stripe_len, struct btrfs_chunk, stripe_len, 64);
@@ -1259,6 +1276,7 @@ BTRFS_SETGET_STACK_FUNCS(root_last_snaps/* struct btrfs_super_block */ BTRFS_SETGET_STACK_FUNCS(super_bytenr, struct btrfs_super_block, bytenr, 64); +BTRFS_SETGET_STACK_FUNCS(super_flags, struct btrfs_super_block, flags, 64); BTRFS_SETGET_STACK_FUNCS(super_generation, struct btrfs_super_block, generation,64 ); BTRFS_SETGET_STACK_FUNCS(super_root, struct btrfs_super_block, root, 64);
disk-io.c +23 -6
@@ -37,14 +37,24 @@static int check_tree_block (struct btrfs_root *root,struct extent_buffer *buf) { + +struct btrfs_fs_devices *fs_devices; +int ret =1 ; +if (buf->start !=btrfs_header_bytenr (buf)) -return 1 ; +return ret; -if (memcmp_extent_buffer (buf, root->fs_info->fsid, - (unsigned long )btrfs_header_fsid (buf), -BTRFS_FSID_SIZE )) -return 1 ; -return 0 ; + fs_devices = root->fs_info->fs_devices; +while (fs_devices) { +if (!memcmp_extent_buffer (buf, fs_devices->fsid, + (unsigned long )btrfs_header_fsid (buf), +BTRFS_FSID_SIZE )) { + ret =0 ; +break ; + } + fs_devices = fs_devices->seed; + } +return ret; }u32 btrfs_csum_data (struct btrfs_root *root,char *data,u32 seed,size_t len)
@@ -685,6 +695,10 @@ int write_all_supers(struct btrfs_root * dev_item);list_for_each (cur, head) { dev = list_entry(cur, struct btrfs_device, dev_list); +if (!dev->writeable) +continue ; + +btrfs_set_device_generation (sb, dev_item,0 );btrfs_set_device_type (sb, dev_item, dev->type);btrfs_set_device_id (sb, dev_item, dev->devid);btrfs_set_device_total_bytes (sb, dev_item, dev->total_bytes);
@@ -695,6 +709,9 @@ int write_all_supers(struct btrfs_root *write_extent_buffer (sb, dev->uuid, (unsigned long )btrfs_device_uuid (dev_item),BTRFS_UUID_SIZE ); +write_extent_buffer (sb, dev->fs_devices->fsid, + (unsigned long )btrfs_device_fsid (dev_item), +BTRFS_UUID_SIZE ); sb->fd = dev->fd; sb->dev_bytenr = sb->start;btrfs_set_header_flag (sb,BTRFS_HEADER_FLAG_WRITTEN );
extent-tree.c +47 -34
198 lines not on this page · raw message
Makefile +4 -1
@@ -15,7 +15,7 @@ prefix ?= /usr/local 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 btrfstune # make C=1 to enable sparse ifdef C
@@ -52,6 +52,9 @@ mkfs.btrfs: $(objects) mkfs.o debug-tree: $(objects) debug-tree.o gcc $(CFLAGS) -o debug-tree $(objects) debug-tree.o $(LDFLAGS) $(LIBS) +btrfstune: $(objects) btrfstune.o + gcc $(CFLAGS) -o btrfstune $(objects) btrfstune.o $(LDFLAGS) $(LIBS) + dir-test: $(objects) dir-test.o gcc $(CFLAGS) -o dir-test $(objects) dir-test.o $(LDFLAGS) $(LIBS)
utils.c +7 -1
@@ -96,7 +96,7 @@ int make_btrfs(int fd, const char *devicbtrfs_set_super_root (&super, blocks[1 ]);btrfs_set_super_chunk_root (&super, blocks[3 ]);btrfs_set_super_total_bytes (&super, num_bytes); -btrfs_set_super_bytes_used (&super, first_free +5 * leafsize); +btrfs_set_super_bytes_used (&super,5 * leafsize);btrfs_set_super_sectorsize (&super, sectorsize);btrfs_set_super_leafsize (&super, leafsize);btrfs_set_super_nodesize (&super, nodesize);
@@ -252,6 +252,7 @@ int make_btrfs(int fd, const char *devic dev_item = btrfs_item_ptr(buf, nritems, struct btrfs_dev_item);btrfs_set_device_id (buf, dev_item,1 ); +btrfs_set_device_generation (buf, dev_item,0 );btrfs_set_device_total_bytes (buf, dev_item, num_bytes);btrfs_set_device_bytes_used (buf, dev_item,BTRFS_MKFS_SYSTEM_GROUP_SIZE );
@@ -263,6 +264,9 @@ int make_btrfs(int fd, const char *devicwrite_extent_buffer (buf, super.dev_item.uuid, (unsigned long )btrfs_device_uuid (dev_item),BTRFS_UUID_SIZE ); +write_extent_buffer (buf, super.fsid, + (unsigned long )btrfs_device_fsid (dev_item), +BTRFS_UUID_SIZE );read_extent_buffer (buf, &super.dev_item, (unsigned long )dev_item,sizeof (*dev_item));
@@ -456,6 +460,7 @@ int btrfs_add_to_fsid(struct btrfs_trans device->io_align = io_align; device->sector_size = sectorsize; device->fd = fd; + device->writeable =1 ; device->total_bytes = block_count; device->bytes_used =0 ; device->total_ios =0 ;
@@ -489,6 +494,7 @@ int btrfs_add_to_fsid(struct btrfs_transkfree (buf);list_add (&device->dev_list, &root->fs_info->fs_devices->devices); + device->fs_devices = root->fs_info->fs_devices; ret =btrfs_bootstrap_super_map (&root->fs_info->mapping_tree, root->fs_info->fs_devices);BUG_ON (ret);
volumes.c +102 -10
197 lines not on this page · raw message
volumes.h +7 -0
@@ -21,11 +21,14 @@struct btrfs_device {struct list_head dev_list;struct btrfs_root *dev_root; +struct btrfs_fs_devices *fs_devices;u64 total_ios;int fd; +int writeable; +char *name;/* these are read off the super block, only in the progs */
@@ -69,6 +72,9 @@ struct btrfs_fs_devices {int lowest_bdev;struct list_head devices;struct list_head list; + +int seeding; +struct btrfs_fs_devices *seed; };struct btrfs_bio_stripe {
@@ -120,4 +126,5 @@ struct list_head *btrfs_scanned_uuids(voint btrfs_add_system_chunk (struct btrfs_trans_handle *trans,struct btrfs_root *root,struct btrfs_key *key,struct btrfs_chunk *chunk,int item_size); +int btrfs_chunk_readonly (struct btrfs_root *root,u64 chunk_offset);#endif