/* * Copyright (C) 2013 FUJITSU LIMITED. All rights reserved. * Written by Miao Xie <miaox@cn.fujitsu.com> * * 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. */#ifndef __BTRFS_CHECK_H__#define __BTRFS_CHECK_H__#if BTRFS_FLAT_INCLUDES#include"kerncompat.h"#include"ctree.h"#include"extent-cache.h"#include"list.h"#else#include<btrfs/kerncompat.h>#include<btrfs/ctree.h>#include<btrfs/extent-cache.h>#include<btrfs/list.h>#endif /* BTRFS_FLAT_INCLUDES */structblock_group_record{structcache_extentcache;/* Used to identify the orphan block groups */structlist_headlist;u64generation;u64objectid;u8type;u64offset;u64flags;};structblock_group_tree{structcache_treetree;structlist_headblock_groups;};structdevice_record{structrb_nodenode;u64devid;u64generation;u64objectid;u8type;u64offset;u64total_byte;u64byte_used;u64real_used;};structstripe{u64devid;u64offset;u8dev_uuid[BTRFS_UUID_SIZE];};structchunk_record{structcache_extentcache;structlist_headlist;structlist_headdextents;structblock_group_record*bg_rec;u64generation;u64objectid;u8type;u64offset;u64owner;u64length;u64type_flags;u64stripe_len;u16num_stripes;u16sub_stripes;u32io_align;u32io_width;u32sector_size;structstripestripes[0];};structdevice_extent_record{structcache_extentcache;/* * Used to identify the orphan device extents (the device extents * don't belong to a chunk or a device) */structlist_headchunk_list;structlist_headdevice_list;u64generation;u64objectid;u8type;u64offset;u64chunk_objecteid;u64chunk_offset;u64length;};structdevice_extent_tree{structcache_treetree;/* * The idea is: * When checking the chunk information, we move the device extents * that has its chunk to the chunk's device extents list. After the * check, if there are still some device extents in no_chunk_orphans, * it means there are some device extents which don't belong to any * chunk. * * The usage of no_device_orphans is the same as the first one, but it * is for the device information check. */structlist_headno_chunk_orphans;structlist_headno_device_orphans;};staticinlineunsignedlongbtrfs_chunk_record_size(intnum_stripes){returnsizeof(structchunk_record)+sizeof(structstripe)*num_stripes;}voidfree_chunk_cache_tree(structcache_tree*chunk_cache);/* * Function to check validation for num_stripes, or it can call * float point error for 0 division * return < 0 for invalid combination * return 0 for valid combination */staticinlineintcheck_num_stripes(u64type,intnum_stripes){if(num_stripes==0)return-1;if(type&BTRFS_BLOCK_GROUP_RAID5&&num_stripes<=1)return-1;if(type&BTRFS_BLOCK_GROUP_RAID6&&num_stripes<=2)return-1;return0;}u64calc_stripe_length(u64type,u64length,intnum_stripes);/* For block group tree */staticinlinevoidblock_group_tree_init(structblock_group_tree*tree){cache_tree_init(&tree->tree);INIT_LIST_HEAD(&tree->block_groups);}intinsert_block_group_record(structblock_group_tree*tree,structblock_group_record*bg_rec);voidfree_block_group_tree(structblock_group_tree*tree);/* For device extent tree */staticinlinevoiddevice_extent_tree_init(structdevice_extent_tree*tree){cache_tree_init(&tree->tree);INIT_LIST_HEAD(&tree->no_chunk_orphans);INIT_LIST_HEAD(&tree->no_device_orphans);}intinsert_device_extent_record(structdevice_extent_tree*tree,structdevice_extent_record*de_rec);voidfree_device_extent_tree(structdevice_extent_tree*tree);/* Create various in-memory record by on-disk data */structchunk_record*btrfs_new_chunk_record(structextent_buffer*leaf,structbtrfs_key*key,intslot);structblock_group_record*btrfs_new_block_group_record(structextent_buffer*leaf,structbtrfs_key*key,intslot);structdevice_extent_record*btrfs_new_device_extent_record(structextent_buffer*leaf,structbtrfs_key*key,intslot);intcheck_chunks(structcache_tree*chunk_cache,structblock_group_tree*block_group_cache,structdevice_extent_tree*dev_extent_cache,structlist_head*good,structlist_head*bad,structlist_head*rebuild,intsilent);#endif