if (extent_type == BTRFS_FILE_EXTENT_REG ||
extent_type == BTRFS_FILE_EXTENT_PREALLOC) {
- struct btrfs_block_group_cache *block_group;
disk_bytenr = btrfs_file_extent_disk_bytenr(leaf, fi);
extent_end = found_key.offset +
btrfs_file_extent_num_bytes(leaf, fi);
goto out_check;
if (btrfs_cross_ref_exist(trans, root, disk_bytenr))
goto out_check;
- block_group = btrfs_lookup_block_group(root->fs_info,
- disk_bytenr);
- if (!block_group || block_group->ro)
+ if (btrfs_extent_readonly(root, disk_bytenr))
goto out_check;
disk_bytenr += btrfs_file_extent_offset(leaf, fi);
nocow = 1;
struct btrfs_root *root = BTRFS_I(inode)->root;
int ret = 0;
- ret = btrfs_csum_one_bio(root, inode, bio);
+ ret = btrfs_csum_one_bio(root, inode, bio, 0, 0);
BUG_ON(ret);
return 0;
}
btrfs_test_flag(inode, NODATASUM);
if (!(rw & (1 << BIO_RW))) {
-
- if (bio_flags & EXTENT_BIO_COMPRESSED)
+ if (bio_flags & EXTENT_BIO_COMPRESSED) {
return btrfs_submit_compressed_read(inode, bio,
mirror_num, bio_flags);
- else if (!skip_sum)
- btrfs_lookup_bio_sums(root, inode, bio);
+ } else if (!skip_sum)
+ btrfs_lookup_bio_sums(root, inode, bio, NULL);
goto mapit;
} else if (!skip_sum) {
/* we're doing a write, do the async checksumming */
btrfs_set_trans_block_group(trans, inode);
list_for_each(cur, list) {
sum = list_entry(cur, struct btrfs_ordered_sum, list);
- btrfs_csum_file_blocks(trans, BTRFS_I(inode)->root,
- inode, sum);
+ btrfs_csum_file_blocks(trans,
+ BTRFS_I(inode)->root->fs_info->csum_root, sum);
}
return 0;
}
u64 start;
u64 len;
u64 logical;
+ unsigned long bio_flags;
int last_mirror;
};
int ret;
int rw;
u64 logical;
- unsigned long bio_flags = 0;
ret = get_state_private(failure_tree, start, &private);
if (ret) {
failrec->start = start;
failrec->len = end - start + 1;
failrec->last_mirror = 0;
+ failrec->bio_flags = 0;
spin_lock(&em_tree->lock);
em = lookup_extent_mapping(em_tree, start, failrec->len);
}
logical = start - em->start;
logical = em->block_start + logical;
- if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags))
- bio_flags = EXTENT_BIO_COMPRESSED;
+ if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags)) {
+ logical = em->block_start;
+ failrec->bio_flags = EXTENT_BIO_COMPRESSED;
+ }
failrec->logical = logical;
free_extent_map(em);
set_extent_bits(failure_tree, start, end, EXTENT_LOCKED |
bio->bi_sector = failrec->logical >> 9;
bio->bi_bdev = failed_bio->bi_bdev;
bio->bi_size = 0;
+
bio_add_page(bio, page, failrec->len, start - page_offset(page));
if (failed_bio->bi_rw & (1 << BIO_RW))
rw = WRITE;
BTRFS_I(inode)->io_tree.ops->submit_bio_hook(inode, rw, bio,
failrec->last_mirror,
- bio_flags);
+ failrec->bio_flags);
return 0;
}
u32 csum = ~(u32)0;
unsigned long flags;
+ if (PageChecked(page)) {
+ ClearPageChecked(page);
+ goto good;
+ }
if (btrfs_test_opt(root, NODATASUM) ||
btrfs_test_flag(inode, NODATASUM))
return 0;
+
if (state && state->start == start) {
private = state->private;
ret = 0;
}
kunmap_atomic(kaddr, KM_IRQ0);
local_irq_restore(flags);
-
+good:
/* if the io failure tree for this inode is non-empty,
* check to see if we've recovered from a failed IO
*/
inode_set_bytes(inode, btrfs_inode_nbytes(leaf, inode_item));
BTRFS_I(inode)->generation = btrfs_inode_generation(leaf, inode_item);
+ BTRFS_I(inode)->sequence = btrfs_inode_sequence(leaf, inode_item);
inode->i_generation = BTRFS_I(inode)->generation;
inode->i_rdev = 0;
rdev = btrfs_inode_rdev(leaf, inode_item);
BTRFS_I(inode)->index_cnt = (u64)-1;
+ BTRFS_I(inode)->flags = btrfs_inode_flags(leaf, inode_item);
alloc_group_block = btrfs_inode_block_group(leaf, inode_item);
- BTRFS_I(inode)->block_group = btrfs_lookup_block_group(root->fs_info,
- alloc_group_block);
- BTRFS_I(inode)->flags = btrfs_inode_flags(leaf, inode_item);
- if (!BTRFS_I(inode)->block_group) {
- BTRFS_I(inode)->block_group = btrfs_find_block_group(root,
- NULL, 0,
- BTRFS_BLOCK_GROUP_METADATA, 0);
- }
+ BTRFS_I(inode)->block_group = btrfs_find_block_group(root, 0,
+ alloc_group_block, 0);
btrfs_free_path(path);
inode_item = NULL;
btrfs_set_inode_nbytes(leaf, item, inode_get_bytes(inode));
btrfs_set_inode_generation(leaf, item, BTRFS_I(inode)->generation);
+ btrfs_set_inode_sequence(leaf, item, BTRFS_I(inode)->sequence);
btrfs_set_inode_transid(leaf, item, trans->transid);
btrfs_set_inode_rdev(leaf, item, inode->i_rdev);
btrfs_set_inode_flags(leaf, item, BTRFS_I(inode)->flags);
- btrfs_set_inode_block_group(leaf, item,
- BTRFS_I(inode)->block_group->key.objectid);
+ btrfs_set_inode_block_group(leaf, item, BTRFS_I(inode)->block_group);
}
/*
return err;
}
+#if 0
/*
* when truncating bytes in a file, it is possible to avoid reading
* the leaves that contain only checksum items. This can be the
return ret;
}
+#endif
+
/*
* this can truncate away extent items, csum items and directory items.
* It starts at a high offset and removes keys until it can't find
btrfs_init_path(path);
- ret = drop_csum_leaves(trans, root, path, inode, new_size);
- BUG_ON(ret);
-
search_again:
ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
if (ret < 0) {
}
item_end--;
}
- if (found_type == BTRFS_CSUM_ITEM_KEY) {
- ret = btrfs_csum_truncate(trans, root, path,
- new_size);
- BUG_ON(ret);
- }
if (item_end < new_size) {
if (found_type == BTRFS_DIR_ITEM_KEY) {
found_type = BTRFS_INODE_ITEM_KEY;
} else if (found_type == BTRFS_EXTENT_ITEM_KEY) {
- found_type = BTRFS_CSUM_ITEM_KEY;
+ found_type = BTRFS_EXTENT_DATA_KEY;
} else if (found_type == BTRFS_EXTENT_DATA_KEY) {
found_type = BTRFS_XATTR_ITEM_KEY;
} else if (found_type == BTRFS_XATTR_ITEM_KEY) {
bi->i_default_acl = NULL;
bi->generation = 0;
+ bi->sequence = 0;
bi->last_trans = 0;
bi->logged_trans = 0;
bi->delalloc_bytes = 0;
inode->i_mapping, GFP_NOFS);
INIT_LIST_HEAD(&BTRFS_I(inode)->delalloc_inodes);
btrfs_ordered_inode_tree_init(&BTRFS_I(inode)->ordered_tree);
- mutex_init(&BTRFS_I(inode)->csum_mutex);
mutex_init(&BTRFS_I(inode)->extent_mutex);
mutex_init(&BTRFS_I(inode)->log_mutex);
}
struct btrfs_root *root,
struct inode *dir,
const char *name, int name_len,
- u64 ref_objectid,
- u64 objectid,
- struct btrfs_block_group_cache *group,
- int mode, u64 *index)
+ u64 ref_objectid, u64 objectid,
+ u64 alloc_hint, int mode, u64 *index)
{
struct inode *inode;
struct btrfs_inode_item *inode_item;
- struct btrfs_block_group_cache *new_inode_group;
struct btrfs_key *location;
struct btrfs_path *path;
struct btrfs_inode_ref *ref;
owner = 0;
else
owner = 1;
- new_inode_group = btrfs_find_block_group(root, group, 0,
- BTRFS_BLOCK_GROUP_METADATA, owner);
- if (!new_inode_group) {
- printk("find_block group failed\n");
- new_inode_group = group;
- }
- BTRFS_I(inode)->block_group = new_inode_group;
+ BTRFS_I(inode)->block_group =
+ btrfs_find_block_group(root, 0, alloc_hint, owner);
key[0].objectid = objectid;
btrfs_set_key_type(&key[0], BTRFS_INODE_ITEM_KEY);
/*
* create a new subvolume directory/inode (helper for the ioctl).
*/
-int btrfs_create_subvol_root(struct btrfs_root *new_root, struct dentry *dentry,
- struct btrfs_trans_handle *trans, u64 new_dirid,
- struct btrfs_block_group_cache *block_group)
+int btrfs_create_subvol_root(struct btrfs_trans_handle *trans,
+ struct btrfs_root *new_root, struct dentry *dentry,
+ u64 new_dirid, u64 alloc_hint)
{
struct inode *inode;
int error;
u64 index = 0;
inode = btrfs_new_inode(trans, new_root, NULL, "..", 2, new_dirid,
- new_dirid, block_group, S_IFDIR | 0700, &index);
+ new_dirid, alloc_hint, S_IFDIR | 0700, &index);
if (IS_ERR(inode))
return PTR_ERR(inode);
inode->i_op = &btrfs_dir_inode_operations;