/* drop the root item for 'key' from 'root' */
int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root,
		   struct btrfs_key *key)
{
	struct btrfs_path *path;
	int ret;
	u32 refs;
	struct btrfs_root_item *ri;
	struct extent_buffer *leaf;

	path = btrfs_alloc_path();
	BUG_ON(!path);
	ret = btrfs_search_slot(trans, root, key, path, -1, 1);
	if (ret < 0)
		goto out;

	BUG_ON(ret != 0);
	leaf = path->nodes[0];
	ri = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_root_item);

	refs = btrfs_disk_root_refs(leaf, ri);
	BUG_ON(refs != 0);
	ret = btrfs_del_item(trans, root, path);
out:
	btrfs_free_path(path);
	return ret;
}
示例#2
0
int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root,
		   struct btrfs_key *key)
{
	struct btrfs_path *path;
	int ret;
	u32 refs;
	struct btrfs_root_item *ri;
	struct extent_buffer *leaf;

	path = btrfs_alloc_path();
	BUG_ON(!path);
	ret = btrfs_search_slot(trans, root, key, path, -1, 1);
	if (ret < 0)
		goto out;
	if (ret) {
btrfs_print_leaf(root, path->nodes[0]);
printk("failed to del %llu %u %llu\n",
	(unsigned long long)key->objectid,
	key->type,
	(unsigned long long)key->offset);

	}
	BUG_ON(ret != 0);
	leaf = path->nodes[0];
	ri = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_root_item);

	refs = btrfs_disk_root_refs(leaf, ri);
	BUG_ON(refs != 0);
	ret = btrfs_del_item(trans, root, path);
out:
	btrfs_release_path(root, path);
	btrfs_free_path(path);
	return ret;
}
示例#3
0
void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l)
{
	int i;
	u32 type;
	u32 nr = btrfs_header_nritems(l);
	struct btrfs_item *item;
	struct btrfs_root_item *ri;
	struct btrfs_dir_item *di;
	struct btrfs_inode_item *ii;
	struct btrfs_block_group_item *bi;
	struct btrfs_file_extent_item *fi;
	struct btrfs_extent_data_ref *dref;
	struct btrfs_shared_data_ref *sref;
	struct btrfs_dev_extent *dev_extent;
	struct btrfs_key key;
	struct btrfs_key found_key;

	printk(KERN_INFO "leaf %llu total ptrs %d free space %d\n",
		(unsigned long long)btrfs_header_bytenr(l), nr,
		btrfs_leaf_free_space(root, l));
	for (i = 0 ; i < nr ; i++) {
		item = btrfs_item_nr(l, i);
		btrfs_item_key_to_cpu(l, &key, i);
		type = btrfs_key_type(&key);
		printk(KERN_INFO "\titem %d key (%llu %x %llu) itemoff %d "
		       "itemsize %d\n",
			i,
			(unsigned long long)key.objectid, type,
			(unsigned long long)key.offset,
			btrfs_item_offset(l, item), btrfs_item_size(l, item));
		switch (type) {
		case BTRFS_INODE_ITEM_KEY:
			ii = btrfs_item_ptr(l, i, struct btrfs_inode_item);
			printk(KERN_INFO "\t\tinode generation %llu size %llu "
			       "mode %o\n",
			       (unsigned long long)
			       btrfs_inode_generation(l, ii),
			      (unsigned long long)btrfs_inode_size(l, ii),
			       btrfs_inode_mode(l, ii));
			break;
		case BTRFS_DIR_ITEM_KEY:
			di = btrfs_item_ptr(l, i, struct btrfs_dir_item);
			btrfs_dir_item_key_to_cpu(l, di, &found_key);
			printk(KERN_INFO "\t\tdir oid %llu type %u\n",
				(unsigned long long)found_key.objectid,
				btrfs_dir_type(l, di));
			break;
		case BTRFS_ROOT_ITEM_KEY:
			ri = btrfs_item_ptr(l, i, struct btrfs_root_item);
			printk(KERN_INFO "\t\troot data bytenr %llu refs %u\n",
				(unsigned long long)
				btrfs_disk_root_bytenr(l, ri),
				btrfs_disk_root_refs(l, ri));
			break;
		case BTRFS_EXTENT_ITEM_KEY:
			print_extent_item(l, i);
			break;
		case BTRFS_TREE_BLOCK_REF_KEY:
			printk(KERN_INFO "\t\ttree block backref\n");
			break;
		case BTRFS_SHARED_BLOCK_REF_KEY:
			printk(KERN_INFO "\t\tshared block backref\n");
			break;
		case BTRFS_EXTENT_DATA_REF_KEY:
			dref = btrfs_item_ptr(l, i,
					      struct btrfs_extent_data_ref);
			print_extent_data_ref(l, dref);
			break;
		case BTRFS_SHARED_DATA_REF_KEY:
			sref = btrfs_item_ptr(l, i,
					      struct btrfs_shared_data_ref);
			printk(KERN_INFO "\t\tshared data backref count %u\n",
			       btrfs_shared_data_ref_count(l, sref));
			break;
		case BTRFS_EXTENT_DATA_KEY:
			fi = btrfs_item_ptr(l, i,
					    struct btrfs_file_extent_item);
			if (btrfs_file_extent_type(l, fi) ==
			    BTRFS_FILE_EXTENT_INLINE) {
				printk(KERN_INFO "\t\tinline extent data "
				       "size %u\n",
				       btrfs_file_extent_inline_len(l, fi));
				break;
			}
			printk(KERN_INFO "\t\textent data disk bytenr %llu "
			       "nr %llu\n",
			       (unsigned long long)
			       btrfs_file_extent_disk_bytenr(l, fi),
			       (unsigned long long)
			       btrfs_file_extent_disk_num_bytes(l, fi));
			printk(KERN_INFO "\t\textent data offset %llu "
			       "nr %llu ram %llu\n",
			       (unsigned long long)
			       btrfs_file_extent_offset(l, fi),
			       (unsigned long long)
			       btrfs_file_extent_num_bytes(l, fi),
			       (unsigned long long)
			       btrfs_file_extent_ram_bytes(l, fi));
			break;
		case BTRFS_EXTENT_REF_V0_KEY:
#ifdef BTRFS_COMPAT_EXTENT_TREE_V0
			print_extent_ref_v0(l, i);
#else
			BUG();
#endif
			break;
		case BTRFS_BLOCK_GROUP_ITEM_KEY:
			bi = btrfs_item_ptr(l, i,
					    struct btrfs_block_group_item);
			printk(KERN_INFO "\t\tblock group used %llu\n",
			       (unsigned long long)
			       btrfs_disk_block_group_used(l, bi));
			break;
		case BTRFS_CHUNK_ITEM_KEY:
			print_chunk(l, btrfs_item_ptr(l, i,
						      struct btrfs_chunk));
			break;
		case BTRFS_DEV_ITEM_KEY:
			print_dev_item(l, btrfs_item_ptr(l, i,
					struct btrfs_dev_item));
			break;
		case BTRFS_DEV_EXTENT_KEY:
			dev_extent = btrfs_item_ptr(l, i,
						    struct btrfs_dev_extent);
			printk(KERN_INFO "\t\tdev extent chunk_tree %llu\n"
			       "\t\tchunk objectid %llu chunk offset %llu "
			       "length %llu\n",
			       (unsigned long long)
			       btrfs_dev_extent_chunk_tree(l, dev_extent),
			       (unsigned long long)
			       btrfs_dev_extent_chunk_objectid(l, dev_extent),
			       (unsigned long long)
			       btrfs_dev_extent_chunk_offset(l, dev_extent),
			       (unsigned long long)
			       btrfs_dev_extent_length(l, dev_extent));
		};
	}
}
示例#4
0
/*
 * at mount time we want to find all the old transaction snapshots that were in
 * the process of being deleted if we crashed.  This is any root item with an
 * offset lower than the latest root.  They need to be queued for deletion to
 * finish what was happening when we crashed.
 */
int btrfs_find_dead_roots(struct btrfs_root *root, u64 objectid)
{
	struct btrfs_root *dead_root;
	struct btrfs_item *item;
	struct btrfs_root_item *ri;
	struct btrfs_key key;
	struct btrfs_key found_key;
	struct btrfs_path *path;
	int ret;
	u32 nritems;
	struct extent_buffer *leaf;
	int slot;

	key.objectid = objectid;
	btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY);
	key.offset = 0;
	path = btrfs_alloc_path();
	if (!path)
		return -ENOMEM;

again:
	ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
	if (ret < 0)
		goto err;
	while (1) {
		leaf = path->nodes[0];
		nritems = btrfs_header_nritems(leaf);
		slot = path->slots[0];
		if (slot >= nritems) {
			ret = btrfs_next_leaf(root, path);
			if (ret)
				break;
			leaf = path->nodes[0];
			nritems = btrfs_header_nritems(leaf);
			slot = path->slots[0];
		}
		item = btrfs_item_nr(leaf, slot);
		btrfs_item_key_to_cpu(leaf, &key, slot);
		if (btrfs_key_type(&key) != BTRFS_ROOT_ITEM_KEY)
			goto next;

		if (key.objectid < objectid)
			goto next;

		if (key.objectid > objectid)
			break;

		ri = btrfs_item_ptr(leaf, slot, struct btrfs_root_item);
		if (btrfs_disk_root_refs(leaf, ri) != 0)
			goto next;

		memcpy(&found_key, &key, sizeof(key));
		key.offset++;
		btrfs_release_path(root, path);
		dead_root =
			btrfs_read_fs_root_no_radix(root->fs_info->tree_root,
						    &found_key);
		if (IS_ERR(dead_root)) {
			ret = PTR_ERR(dead_root);
			goto err;
		}

		ret = btrfs_add_dead_root(dead_root);
		if (ret)
			goto err;
		goto again;
next:
		slot++;
		path->slots[0]++;
	}
	ret = 0;
err:
	btrfs_free_path(path);
	return ret;
}
示例#5
0
文件: print-tree.c 项目: 020gzh/linux
void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l)
{
	int i;
	u32 type, nr;
	struct btrfs_item *item;
	struct btrfs_root_item *ri;
	struct btrfs_dir_item *di;
	struct btrfs_inode_item *ii;
	struct btrfs_block_group_item *bi;
	struct btrfs_file_extent_item *fi;
	struct btrfs_extent_data_ref *dref;
	struct btrfs_shared_data_ref *sref;
	struct btrfs_dev_extent *dev_extent;
	struct btrfs_key key;
	struct btrfs_key found_key;

	if (!l)
		return;

	nr = btrfs_header_nritems(l);

	btrfs_info(root->fs_info, "leaf %llu total ptrs %d free space %d",
		   btrfs_header_bytenr(l), nr, btrfs_leaf_free_space(root, l));
	for (i = 0 ; i < nr ; i++) {
		item = btrfs_item_nr(i);
		btrfs_item_key_to_cpu(l, &key, i);
		type = key.type;
		printk(KERN_INFO "\titem %d key (%llu %u %llu) itemoff %d "
		       "itemsize %d\n",
			i, key.objectid, type, key.offset,
			btrfs_item_offset(l, item), btrfs_item_size(l, item));
		switch (type) {
		case BTRFS_INODE_ITEM_KEY:
			ii = btrfs_item_ptr(l, i, struct btrfs_inode_item);
			printk(KERN_INFO "\t\tinode generation %llu size %llu "
			       "mode %o\n",
			       btrfs_inode_generation(l, ii),
			       btrfs_inode_size(l, ii),
			       btrfs_inode_mode(l, ii));
			break;
		case BTRFS_DIR_ITEM_KEY:
			di = btrfs_item_ptr(l, i, struct btrfs_dir_item);
			btrfs_dir_item_key_to_cpu(l, di, &found_key);
			printk(KERN_INFO "\t\tdir oid %llu type %u\n",
				found_key.objectid,
				btrfs_dir_type(l, di));
			break;
		case BTRFS_ROOT_ITEM_KEY:
			ri = btrfs_item_ptr(l, i, struct btrfs_root_item);
			printk(KERN_INFO "\t\troot data bytenr %llu refs %u\n",
				btrfs_disk_root_bytenr(l, ri),
				btrfs_disk_root_refs(l, ri));
			break;
		case BTRFS_EXTENT_ITEM_KEY:
		case BTRFS_METADATA_ITEM_KEY:
			print_extent_item(l, i, type);
			break;
		case BTRFS_TREE_BLOCK_REF_KEY:
			printk(KERN_INFO "\t\ttree block backref\n");
			break;
		case BTRFS_SHARED_BLOCK_REF_KEY:
			printk(KERN_INFO "\t\tshared block backref\n");
			break;
		case BTRFS_EXTENT_DATA_REF_KEY:
			dref = btrfs_item_ptr(l, i,
					      struct btrfs_extent_data_ref);
			print_extent_data_ref(l, dref);
			break;
		case BTRFS_SHARED_DATA_REF_KEY:
			sref = btrfs_item_ptr(l, i,
					      struct btrfs_shared_data_ref);
			printk(KERN_INFO "\t\tshared data backref count %u\n",
			       btrfs_shared_data_ref_count(l, sref));
			break;
		case BTRFS_EXTENT_DATA_KEY:
			fi = btrfs_item_ptr(l, i,
					    struct btrfs_file_extent_item);
			if (btrfs_file_extent_type(l, fi) ==
			    BTRFS_FILE_EXTENT_INLINE) {
				printk(KERN_INFO "\t\tinline extent data "
				       "size %u\n",
				       btrfs_file_extent_inline_len(l, i, fi));
				break;
			}
			printk(KERN_INFO "\t\textent data disk bytenr %llu "
			       "nr %llu\n",
			       btrfs_file_extent_disk_bytenr(l, fi),
			       btrfs_file_extent_disk_num_bytes(l, fi));
			printk(KERN_INFO "\t\textent data offset %llu "
			       "nr %llu ram %llu\n",
			       btrfs_file_extent_offset(l, fi),
			       btrfs_file_extent_num_bytes(l, fi),
			       btrfs_file_extent_ram_bytes(l, fi));
			break;
		case BTRFS_EXTENT_REF_V0_KEY:
#ifdef BTRFS_COMPAT_EXTENT_TREE_V0
			print_extent_ref_v0(l, i);
#else
			BUG();
#endif
			break;
		case BTRFS_BLOCK_GROUP_ITEM_KEY:
			bi = btrfs_item_ptr(l, i,
					    struct btrfs_block_group_item);
			printk(KERN_INFO "\t\tblock group used %llu\n",
			       btrfs_disk_block_group_used(l, bi));
			break;
		case BTRFS_CHUNK_ITEM_KEY:
			print_chunk(l, btrfs_item_ptr(l, i,
						      struct btrfs_chunk));
			break;
		case BTRFS_DEV_ITEM_KEY:
			print_dev_item(l, btrfs_item_ptr(l, i,
					struct btrfs_dev_item));
			break;
		case BTRFS_DEV_EXTENT_KEY:
			dev_extent = btrfs_item_ptr(l, i,
						    struct btrfs_dev_extent);
			printk(KERN_INFO "\t\tdev extent chunk_tree %llu\n"
			       "\t\tchunk objectid %llu chunk offset %llu "
			       "length %llu\n",
			       btrfs_dev_extent_chunk_tree(l, dev_extent),
			       btrfs_dev_extent_chunk_objectid(l, dev_extent),
			       btrfs_dev_extent_chunk_offset(l, dev_extent),
			       btrfs_dev_extent_length(l, dev_extent));
			break;
		case BTRFS_PERSISTENT_ITEM_KEY:
			printk(KERN_INFO "\t\tpersistent item objectid %llu offset %llu\n",
					key.objectid, key.offset);
			switch (key.objectid) {
			case BTRFS_DEV_STATS_OBJECTID:
				printk(KERN_INFO "\t\tdevice stats\n");
				break;
			default:
				printk(KERN_INFO "\t\tunknown persistent item\n");
			}
			break;
		case BTRFS_TEMPORARY_ITEM_KEY:
			printk(KERN_INFO "\t\ttemporary item objectid %llu offset %llu\n",
					key.objectid, key.offset);
			switch (key.objectid) {
			case BTRFS_BALANCE_OBJECTID:
				printk(KERN_INFO "\t\tbalance status\n");
				break;
			default:
				printk(KERN_INFO "\t\tunknown temporary item\n");
			}
			break;
		case BTRFS_DEV_REPLACE_KEY:
			printk(KERN_INFO "\t\tdev replace\n");
			break;
		case BTRFS_UUID_KEY_SUBVOL:
		case BTRFS_UUID_KEY_RECEIVED_SUBVOL:
			print_uuid_item(l, btrfs_item_ptr_offset(l, i),
					btrfs_item_size_nr(l, i));
			break;
		};
	}
}