diff options
Diffstat (limited to 'check/mode-original.h')
-rw-r--r-- | check/mode-original.h | 294 |
1 files changed, 294 insertions, 0 deletions
diff --git a/check/mode-original.h b/check/mode-original.h new file mode 100644 index 00000000..f859af47 --- /dev/null +++ b/check/mode-original.h @@ -0,0 +1,294 @@ +/* + * 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. + */ + +/* + * Defines and function declarations for original mode check. + */ + +#ifndef __BTRFS_CHECK_MODE_ORIGINAL_H__ +#define __BTRFS_CHECK_MODE_ORIGINAL_H__ + +#include "rbtree-utils.h" + +struct extent_backref { + struct rb_node node; + unsigned int is_data:1; + unsigned int found_extent_tree:1; + unsigned int full_backref:1; + unsigned int found_ref:1; + unsigned int broken:1; +}; + +static inline struct extent_backref* rb_node_to_extent_backref(struct rb_node *node) +{ + return rb_entry(node, struct extent_backref, node); +} + +struct data_backref { + struct extent_backref node; + union { + u64 parent; + u64 root; + }; + u64 owner; + u64 offset; + u64 disk_bytenr; + u64 bytes; + u64 ram_bytes; + u32 num_refs; + u32 found_ref; +}; + +static inline struct data_backref* to_data_backref(struct extent_backref *back) +{ + return container_of(back, struct data_backref, node); +} + +/* + * Much like data_backref, just removed the undetermined members + * and change it to use list_head. + * During extent scan, it is stored in root->orphan_data_extent. + * During fs tree scan, it is then moved to inode_rec->orphan_data_extents. + */ +struct orphan_data_extent { + struct list_head list; + u64 root; + u64 objectid; + u64 offset; + u64 disk_bytenr; + u64 disk_len; +}; + +struct tree_backref { + struct extent_backref node; + union { + u64 parent; + u64 root; + }; +}; + +static inline struct tree_backref* to_tree_backref(struct extent_backref *back) +{ + return container_of(back, struct tree_backref, node); +} + +/* Explicit initialization for extent_record::flag_block_full_backref */ +enum { FLAG_UNSET = 2 }; + +struct extent_record { + struct list_head backrefs; + struct list_head dups; + struct rb_root backref_tree; + struct list_head list; + struct cache_extent cache; + struct btrfs_disk_key parent_key; + u64 start; + u64 max_size; + u64 nr; + u64 refs; + u64 extent_item_refs; + u64 generation; + u64 parent_generation; + u64 info_objectid; + u32 num_duplicates; + u8 info_level; + unsigned int flag_block_full_backref:2; + unsigned int found_rec:1; + unsigned int content_checked:1; + unsigned int owner_ref_checked:1; + unsigned int is_root:1; + unsigned int metadata:1; + unsigned int bad_full_backref:1; + unsigned int crossing_stripes:1; + unsigned int wrong_chunk_type:1; +}; + +static inline struct extent_record* to_extent_record(struct list_head *entry) +{ + return container_of(entry, struct extent_record, list); +} + +struct inode_backref { + struct list_head list; + unsigned int found_dir_item:1; + unsigned int found_dir_index:1; + unsigned int found_inode_ref:1; + u8 filetype; + u8 ref_type; + int errors; + u64 dir; + u64 index; + u16 namelen; + char name[0]; +}; + +static inline struct inode_backref* to_inode_backref(struct list_head *entry) +{ + return list_entry(entry, struct inode_backref, list); +} + +struct root_item_record { + struct list_head list; + u64 objectid; + u64 bytenr; + u64 last_snapshot; + u8 level; + u8 drop_level; + struct btrfs_key drop_key; +}; + +#define REF_ERR_NO_DIR_ITEM (1 << 0) +#define REF_ERR_NO_DIR_INDEX (1 << 1) +#define REF_ERR_NO_INODE_REF (1 << 2) +#define REF_ERR_DUP_DIR_ITEM (1 << 3) +#define REF_ERR_DUP_DIR_INDEX (1 << 4) +#define REF_ERR_DUP_INODE_REF (1 << 5) +#define REF_ERR_INDEX_UNMATCH (1 << 6) +#define REF_ERR_FILETYPE_UNMATCH (1 << 7) +#define REF_ERR_NAME_TOO_LONG (1 << 8) // 100 +#define REF_ERR_NO_ROOT_REF (1 << 9) +#define REF_ERR_NO_ROOT_BACKREF (1 << 10) +#define REF_ERR_DUP_ROOT_REF (1 << 11) +#define REF_ERR_DUP_ROOT_BACKREF (1 << 12) + +struct file_extent_hole { + struct rb_node node; + u64 start; + u64 len; +}; + +#define I_ERR_NO_INODE_ITEM (1 << 0) +#define I_ERR_NO_ORPHAN_ITEM (1 << 1) +#define I_ERR_DUP_INODE_ITEM (1 << 2) +#define I_ERR_DUP_DIR_INDEX (1 << 3) +#define I_ERR_ODD_DIR_ITEM (1 << 4) +#define I_ERR_ODD_FILE_EXTENT (1 << 5) +#define I_ERR_BAD_FILE_EXTENT (1 << 6) +#define I_ERR_FILE_EXTENT_OVERLAP (1 << 7) +#define I_ERR_FILE_EXTENT_DISCOUNT (1 << 8) // 100 +#define I_ERR_DIR_ISIZE_WRONG (1 << 9) +#define I_ERR_FILE_NBYTES_WRONG (1 << 10) // 400 +#define I_ERR_ODD_CSUM_ITEM (1 << 11) +#define I_ERR_SOME_CSUM_MISSING (1 << 12) +#define I_ERR_LINK_COUNT_WRONG (1 << 13) +#define I_ERR_FILE_EXTENT_ORPHAN (1 << 14) + +struct inode_record { + struct list_head backrefs; + unsigned int checked:1; + unsigned int merging:1; + unsigned int found_inode_item:1; + unsigned int found_dir_item:1; + unsigned int found_file_extent:1; + unsigned int found_csum_item:1; + unsigned int some_csum_missing:1; + unsigned int nodatasum:1; + int errors; + + u64 ino; + u32 nlink; + u32 imode; + u64 isize; + u64 nbytes; + + u32 found_link; + u64 found_size; + u64 extent_start; + u64 extent_end; + struct rb_root holes; + struct list_head orphan_extents; + + u32 refs; +}; + +struct root_backref { + struct list_head list; + unsigned int found_dir_item:1; + unsigned int found_dir_index:1; + unsigned int found_back_ref:1; + unsigned int found_forward_ref:1; + unsigned int reachable:1; + int errors; + u64 ref_root; + u64 dir; + u64 index; + u16 namelen; + char name[0]; +}; + +static inline struct root_backref* to_root_backref(struct list_head *entry) +{ + return list_entry(entry, struct root_backref, list); +} + +struct root_record { + struct list_head backrefs; + struct cache_extent cache; + unsigned int found_root_item:1; + u64 objectid; + u32 found_ref; +}; + +struct ptr_node { + struct cache_extent cache; + void *data; +}; + +struct shared_node { + struct cache_extent cache; + struct cache_tree root_cache; + struct cache_tree inode_cache; + struct inode_record *current; + u32 refs; +}; + +struct block_info { + u64 start; + u32 size; +}; + +struct walk_control { + struct cache_tree shared; + struct shared_node *nodes[BTRFS_MAX_LEVEL]; + int active_node; + int root_level; +}; + +struct bad_item { + struct btrfs_key key; + u64 root_id; + struct list_head list; +}; + +struct extent_entry { + u64 bytenr; + u64 bytes; + int count; + int broken; + struct list_head list; +}; + +struct root_item_info { + /* level of the root */ + u8 level; + /* number of nodes at this level, must be 1 for a root */ + int node_count; + u64 bytenr; + u64 gen; + struct cache_extent cache_extent; +}; + +#endif |