提交 9003ed1f 编写于 作者: L Linus Torvalds

Merge branch 'for-linus-4.11' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs

Pull btrfs updates from Chris Mason:
 "This has a series of fixes and cleanups that Dave Sterba has been
  collecting.

  There is a pretty big variety here, cleaning up internal APIs and
  fixing corner cases"

* 'for-linus-4.11' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs: (124 commits)
  Btrfs: use the correct type when creating cow dio extent
  Btrfs: fix deadlock between dedup on same file and starting writeback
  btrfs: use btrfs_debug instead of pr_debug in transaction abort
  btrfs: btrfs_truncate_free_space_cache always allocates path
  btrfs: free-space-cache, clean up unnecessary root arguments
  btrfs: convert btrfs_inc_block_group_ro to accept fs_info
  btrfs: flush_space always takes fs_info->fs_root
  btrfs: pass fs_info to (more) routines that are only called with extent_root
  btrfs: qgroup: Move half of the qgroup accounting time out of commit trans
  btrfs: remove unused parameter from adjust_slots_upwards
  btrfs: remove unused parameters from __btrfs_write_out_cache
  btrfs: remove unused parameter from cleanup_write_cache_enospc
  btrfs: remove unused parameter from __add_inode_ref
  btrfs: remove unused parameter from clone_copy_inline_extent
  btrfs: remove unused parameters from btrfs_cmp_data
  btrfs: remove unused parameter from __add_inline_refs
  btrfs: remove unused parameters from scrub_setup_wr_ctx
  btrfs: remove unused parameter from create_snapshot
  btrfs: remove unused parameter from init_first_rw_device
  btrfs: remove unused parameter from __btrfs_alloc_chunk
  ...
...@@ -956,8 +956,7 @@ static int __add_delayed_refs(struct btrfs_delayed_ref_head *head, u64 seq, ...@@ -956,8 +956,7 @@ static int __add_delayed_refs(struct btrfs_delayed_ref_head *head, u64 seq,
/* /*
* add all inline backrefs for bytenr to the list * add all inline backrefs for bytenr to the list
*/ */
static int __add_inline_refs(struct btrfs_fs_info *fs_info, static int __add_inline_refs(struct btrfs_path *path, u64 bytenr,
struct btrfs_path *path, u64 bytenr,
int *info_level, struct list_head *prefs, int *info_level, struct list_head *prefs,
struct ref_root *ref_tree, struct ref_root *ref_tree,
u64 *total_refs, u64 inum) u64 *total_refs, u64 inum)
...@@ -1284,7 +1283,7 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans, ...@@ -1284,7 +1283,7 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans,
*/ */
delayed_refs = &trans->transaction->delayed_refs; delayed_refs = &trans->transaction->delayed_refs;
spin_lock(&delayed_refs->lock); spin_lock(&delayed_refs->lock);
head = btrfs_find_delayed_ref_head(trans, bytenr); head = btrfs_find_delayed_ref_head(delayed_refs, bytenr);
if (head) { if (head) {
if (!mutex_trylock(&head->mutex)) { if (!mutex_trylock(&head->mutex)) {
atomic_inc(&head->node.refs); atomic_inc(&head->node.refs);
...@@ -1354,7 +1353,7 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans, ...@@ -1354,7 +1353,7 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans,
if (key.objectid == bytenr && if (key.objectid == bytenr &&
(key.type == BTRFS_EXTENT_ITEM_KEY || (key.type == BTRFS_EXTENT_ITEM_KEY ||
key.type == BTRFS_METADATA_ITEM_KEY)) { key.type == BTRFS_METADATA_ITEM_KEY)) {
ret = __add_inline_refs(fs_info, path, bytenr, ret = __add_inline_refs(path, bytenr,
&info_level, &prefs, &info_level, &prefs,
ref_tree, &total_refs, ref_tree, &total_refs,
inum); inum);
......
...@@ -224,16 +224,16 @@ static inline void btrfs_insert_inode_hash(struct inode *inode) ...@@ -224,16 +224,16 @@ static inline void btrfs_insert_inode_hash(struct inode *inode)
__insert_inode_hash(inode, h); __insert_inode_hash(inode, h);
} }
static inline u64 btrfs_ino(struct inode *inode) static inline u64 btrfs_ino(struct btrfs_inode *inode)
{ {
u64 ino = BTRFS_I(inode)->location.objectid; u64 ino = inode->location.objectid;
/* /*
* !ino: btree_inode * !ino: btree_inode
* type == BTRFS_ROOT_ITEM_KEY: subvol dir * type == BTRFS_ROOT_ITEM_KEY: subvol dir
*/ */
if (!ino || BTRFS_I(inode)->location.type == BTRFS_ROOT_ITEM_KEY) if (!ino || inode->location.type == BTRFS_ROOT_ITEM_KEY)
ino = inode->i_ino; ino = inode->vfs_inode.i_ino;
return ino; return ino;
} }
...@@ -248,23 +248,21 @@ static inline bool btrfs_is_free_space_inode(struct inode *inode) ...@@ -248,23 +248,21 @@ static inline bool btrfs_is_free_space_inode(struct inode *inode)
struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_root *root = BTRFS_I(inode)->root;
if (root == root->fs_info->tree_root && if (root == root->fs_info->tree_root &&
btrfs_ino(inode) != BTRFS_BTREE_INODE_OBJECTID) btrfs_ino(BTRFS_I(inode)) != BTRFS_BTREE_INODE_OBJECTID)
return true; return true;
if (BTRFS_I(inode)->location.objectid == BTRFS_FREE_INO_OBJECTID) if (BTRFS_I(inode)->location.objectid == BTRFS_FREE_INO_OBJECTID)
return true; return true;
return false; return false;
} }
static inline int btrfs_inode_in_log(struct inode *inode, u64 generation) static inline int btrfs_inode_in_log(struct btrfs_inode *inode, u64 generation)
{ {
int ret = 0; int ret = 0;
spin_lock(&BTRFS_I(inode)->lock); spin_lock(&inode->lock);
if (BTRFS_I(inode)->logged_trans == generation && if (inode->logged_trans == generation &&
BTRFS_I(inode)->last_sub_trans <= inode->last_sub_trans <= inode->last_log_commit &&
BTRFS_I(inode)->last_log_commit && inode->last_sub_trans <= inode->root->last_log_commit) {
BTRFS_I(inode)->last_sub_trans <=
BTRFS_I(inode)->root->last_log_commit) {
/* /*
* After a ranged fsync we might have left some extent maps * After a ranged fsync we might have left some extent maps
* (that fall outside the fsync's range). So return false * (that fall outside the fsync's range). So return false
...@@ -272,10 +270,10 @@ static inline int btrfs_inode_in_log(struct inode *inode, u64 generation) ...@@ -272,10 +270,10 @@ static inline int btrfs_inode_in_log(struct inode *inode, u64 generation)
* will be called and process those extent maps. * will be called and process those extent maps.
*/ */
smp_mb(); smp_mb();
if (list_empty(&BTRFS_I(inode)->extent_tree.modified_extents)) if (list_empty(&inode->extent_tree.modified_extents))
ret = 1; ret = 1;
} }
spin_unlock(&BTRFS_I(inode)->lock); spin_unlock(&inode->lock);
return ret; return ret;
} }
...@@ -326,6 +324,24 @@ static inline void btrfs_inode_resume_unlocked_dio(struct inode *inode) ...@@ -326,6 +324,24 @@ static inline void btrfs_inode_resume_unlocked_dio(struct inode *inode)
&BTRFS_I(inode)->runtime_flags); &BTRFS_I(inode)->runtime_flags);
} }
static inline void btrfs_print_data_csum_error(struct inode *inode,
u64 logical_start, u32 csum, u32 csum_expected, int mirror_num)
{
struct btrfs_root *root = BTRFS_I(inode)->root;
/* Output minus objectid, which is more meaningful */
if (root->objectid >= BTRFS_LAST_FREE_OBJECTID)
btrfs_warn_rl(root->fs_info,
"csum failed root %lld ino %lld off %llu csum 0x%08x expected csum 0x%08x mirror %d",
root->objectid, btrfs_ino(BTRFS_I(inode)),
logical_start, csum, csum_expected, mirror_num);
else
btrfs_warn_rl(root->fs_info,
"csum failed root %llu ino %llu off %llu csum 0x%08x expected csum 0x%08x mirror %d",
root->objectid, btrfs_ino(BTRFS_I(inode)),
logical_start, csum, csum_expected, mirror_num);
}
bool btrfs_page_exists_in_range(struct inode *inode, loff_t start, loff_t end); bool btrfs_page_exists_in_range(struct inode *inode, loff_t start, loff_t end);
#endif #endif
...@@ -124,10 +124,8 @@ static int check_compressed_csum(struct inode *inode, ...@@ -124,10 +124,8 @@ static int check_compressed_csum(struct inode *inode,
kunmap_atomic(kaddr); kunmap_atomic(kaddr);
if (csum != *cb_sum) { if (csum != *cb_sum) {
btrfs_info(BTRFS_I(inode)->root->fs_info, btrfs_print_data_csum_error(inode, disk_start, csum,
"csum failed ino %llu extent %llu csum %u wanted %u mirror %d", *cb_sum, cb->mirror_num);
btrfs_ino(inode), disk_start, csum, *cb_sum,
cb->mirror_num);
ret = -EIO; ret = -EIO;
goto fail; goto fail;
} }
......
...@@ -28,9 +28,9 @@ ...@@ -28,9 +28,9 @@
static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root
*root, struct btrfs_path *path, int level); *root, struct btrfs_path *path, int level);
static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root *root,
*root, struct btrfs_key *ins_key, const struct btrfs_key *ins_key, struct btrfs_path *path,
struct btrfs_path *path, int data_size, int extend); int data_size, int extend);
static int push_node_left(struct btrfs_trans_handle *trans, static int push_node_left(struct btrfs_trans_handle *trans,
struct btrfs_fs_info *fs_info, struct btrfs_fs_info *fs_info,
struct extent_buffer *dst, struct extent_buffer *dst,
...@@ -426,7 +426,7 @@ void btrfs_put_tree_mod_seq(struct btrfs_fs_info *fs_info, ...@@ -426,7 +426,7 @@ void btrfs_put_tree_mod_seq(struct btrfs_fs_info *fs_info,
tm_root = &fs_info->tree_mod_log; tm_root = &fs_info->tree_mod_log;
for (node = rb_first(tm_root); node; node = next) { for (node = rb_first(tm_root); node; node = next) {
next = rb_next(node); next = rb_next(node);
tm = container_of(node, struct tree_mod_elem, node); tm = rb_entry(node, struct tree_mod_elem, node);
if (tm->seq > min_seq) if (tm->seq > min_seq)
continue; continue;
rb_erase(node, tm_root); rb_erase(node, tm_root);
...@@ -460,7 +460,7 @@ __tree_mod_log_insert(struct btrfs_fs_info *fs_info, struct tree_mod_elem *tm) ...@@ -460,7 +460,7 @@ __tree_mod_log_insert(struct btrfs_fs_info *fs_info, struct tree_mod_elem *tm)
tm_root = &fs_info->tree_mod_log; tm_root = &fs_info->tree_mod_log;
new = &tm_root->rb_node; new = &tm_root->rb_node;
while (*new) { while (*new) {
cur = container_of(*new, struct tree_mod_elem, node); cur = rb_entry(*new, struct tree_mod_elem, node);
parent = *new; parent = *new;
if (cur->logical < tm->logical) if (cur->logical < tm->logical)
new = &((*new)->rb_left); new = &((*new)->rb_left);
...@@ -746,7 +746,7 @@ __tree_mod_log_search(struct btrfs_fs_info *fs_info, u64 start, u64 min_seq, ...@@ -746,7 +746,7 @@ __tree_mod_log_search(struct btrfs_fs_info *fs_info, u64 start, u64 min_seq,
tm_root = &fs_info->tree_mod_log; tm_root = &fs_info->tree_mod_log;
node = tm_root->rb_node; node = tm_root->rb_node;
while (node) { while (node) {
cur = container_of(node, struct tree_mod_elem, node); cur = rb_entry(node, struct tree_mod_elem, node);
if (cur->logical < start) { if (cur->logical < start) {
node = node->rb_left; node = node->rb_left;
} else if (cur->logical > start) { } else if (cur->logical > start) {
...@@ -1074,7 +1074,7 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans, ...@@ -1074,7 +1074,7 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans,
ret = btrfs_dec_ref(trans, root, buf, 1); ret = btrfs_dec_ref(trans, root, buf, 1);
BUG_ON(ret); /* -ENOMEM */ BUG_ON(ret); /* -ENOMEM */
} }
clean_tree_block(trans, fs_info, buf); clean_tree_block(fs_info, buf);
*last_ref = 1; *last_ref = 1;
} }
return 0; return 0;
...@@ -1326,7 +1326,7 @@ __tree_mod_log_rewind(struct btrfs_fs_info *fs_info, struct extent_buffer *eb, ...@@ -1326,7 +1326,7 @@ __tree_mod_log_rewind(struct btrfs_fs_info *fs_info, struct extent_buffer *eb,
next = rb_next(&tm->node); next = rb_next(&tm->node);
if (!next) if (!next)
break; break;
tm = container_of(next, struct tree_mod_elem, node); tm = rb_entry(next, struct tree_mod_elem, node);
if (tm->logical != first_tm->logical) if (tm->logical != first_tm->logical)
break; break;
} }
...@@ -1580,7 +1580,8 @@ static int close_blocks(u64 blocknr, u64 other, u32 blocksize) ...@@ -1580,7 +1580,8 @@ static int close_blocks(u64 blocknr, u64 other, u32 blocksize)
/* /*
* compare two keys in a memcmp fashion * compare two keys in a memcmp fashion
*/ */
static int comp_keys(struct btrfs_disk_key *disk, struct btrfs_key *k2) static int comp_keys(const struct btrfs_disk_key *disk,
const struct btrfs_key *k2)
{ {
struct btrfs_key k1; struct btrfs_key k1;
...@@ -1592,7 +1593,7 @@ static int comp_keys(struct btrfs_disk_key *disk, struct btrfs_key *k2) ...@@ -1592,7 +1593,7 @@ static int comp_keys(struct btrfs_disk_key *disk, struct btrfs_key *k2)
/* /*
* same as comp_keys only with two btrfs_key's * same as comp_keys only with two btrfs_key's
*/ */
int btrfs_comp_cpu_keys(struct btrfs_key *k1, struct btrfs_key *k2) int btrfs_comp_cpu_keys(const struct btrfs_key *k1, const struct btrfs_key *k2)
{ {
if (k1->objectid > k2->objectid) if (k1->objectid > k2->objectid)
return 1; return 1;
...@@ -1732,8 +1733,8 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans, ...@@ -1732,8 +1733,8 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,
* slot may point to max if the key is bigger than all of the keys * slot may point to max if the key is bigger than all of the keys
*/ */
static noinline int generic_bin_search(struct extent_buffer *eb, static noinline int generic_bin_search(struct extent_buffer *eb,
unsigned long p, unsigned long p, int item_size,
int item_size, struct btrfs_key *key, const struct btrfs_key *key,
int max, int *slot) int max, int *slot)
{ {
int low = 0; int low = 0;
...@@ -1802,7 +1803,7 @@ static noinline int generic_bin_search(struct extent_buffer *eb, ...@@ -1802,7 +1803,7 @@ static noinline int generic_bin_search(struct extent_buffer *eb,
* simple bin_search frontend that does the right thing for * simple bin_search frontend that does the right thing for
* leaves vs nodes * leaves vs nodes
*/ */
static int bin_search(struct extent_buffer *eb, struct btrfs_key *key, static int bin_search(struct extent_buffer *eb, const struct btrfs_key *key,
int level, int *slot) int level, int *slot)
{ {
if (level == 0) if (level == 0)
...@@ -1819,7 +1820,7 @@ static int bin_search(struct extent_buffer *eb, struct btrfs_key *key, ...@@ -1819,7 +1820,7 @@ static int bin_search(struct extent_buffer *eb, struct btrfs_key *key,
slot); slot);
} }
int btrfs_bin_search(struct extent_buffer *eb, struct btrfs_key *key, int btrfs_bin_search(struct extent_buffer *eb, const struct btrfs_key *key,
int level, int *slot) int level, int *slot)
{ {
return bin_search(eb, key, level, slot); return bin_search(eb, key, level, slot);
...@@ -1937,7 +1938,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, ...@@ -1937,7 +1938,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
path->locks[level] = 0; path->locks[level] = 0;
path->nodes[level] = NULL; path->nodes[level] = NULL;
clean_tree_block(trans, fs_info, mid); clean_tree_block(fs_info, mid);
btrfs_tree_unlock(mid); btrfs_tree_unlock(mid);
/* once for the path */ /* once for the path */
free_extent_buffer(mid); free_extent_buffer(mid);
...@@ -1998,7 +1999,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, ...@@ -1998,7 +1999,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
if (wret < 0 && wret != -ENOSPC) if (wret < 0 && wret != -ENOSPC)
ret = wret; ret = wret;
if (btrfs_header_nritems(right) == 0) { if (btrfs_header_nritems(right) == 0) {
clean_tree_block(trans, fs_info, right); clean_tree_block(fs_info, right);
btrfs_tree_unlock(right); btrfs_tree_unlock(right);
del_ptr(root, path, level + 1, pslot + 1); del_ptr(root, path, level + 1, pslot + 1);
root_sub_used(root, right->len); root_sub_used(root, right->len);
...@@ -2042,7 +2043,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, ...@@ -2042,7 +2043,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
BUG_ON(wret == 1); BUG_ON(wret == 1);
} }
if (btrfs_header_nritems(mid) == 0) { if (btrfs_header_nritems(mid) == 0) {
clean_tree_block(trans, fs_info, mid); clean_tree_block(fs_info, mid);
btrfs_tree_unlock(mid); btrfs_tree_unlock(mid);
del_ptr(root, path, level + 1, pslot); del_ptr(root, path, level + 1, pslot);
root_sub_used(root, mid->len); root_sub_used(root, mid->len);
...@@ -2437,10 +2438,9 @@ noinline void btrfs_unlock_up_safe(struct btrfs_path *path, int level) ...@@ -2437,10 +2438,9 @@ noinline void btrfs_unlock_up_safe(struct btrfs_path *path, int level)
* reada. -EAGAIN is returned and the search must be repeated. * reada. -EAGAIN is returned and the search must be repeated.
*/ */
static int static int
read_block_for_search(struct btrfs_trans_handle *trans, read_block_for_search(struct btrfs_root *root, struct btrfs_path *p,
struct btrfs_root *root, struct btrfs_path *p, struct extent_buffer **eb_ret, int level, int slot,
struct extent_buffer **eb_ret, int level, int slot, const struct btrfs_key *key)
struct btrfs_key *key, u64 time_seq)
{ {
struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_fs_info *fs_info = root->fs_info;
u64 blocknr; u64 blocknr;
...@@ -2587,7 +2587,7 @@ setup_nodes_for_search(struct btrfs_trans_handle *trans, ...@@ -2587,7 +2587,7 @@ setup_nodes_for_search(struct btrfs_trans_handle *trans,
} }
static void key_search_validate(struct extent_buffer *b, static void key_search_validate(struct extent_buffer *b,
struct btrfs_key *key, const struct btrfs_key *key,
int level) int level)
{ {
#ifdef CONFIG_BTRFS_ASSERT #ifdef CONFIG_BTRFS_ASSERT
...@@ -2606,7 +2606,7 @@ static void key_search_validate(struct extent_buffer *b, ...@@ -2606,7 +2606,7 @@ static void key_search_validate(struct extent_buffer *b,
#endif #endif
} }
static int key_search(struct extent_buffer *b, struct btrfs_key *key, static int key_search(struct extent_buffer *b, const struct btrfs_key *key,
int level, int *prev_cmp, int *slot) int level, int *prev_cmp, int *slot)
{ {
if (*prev_cmp != 0) { if (*prev_cmp != 0) {
...@@ -2668,9 +2668,9 @@ int btrfs_find_item(struct btrfs_root *fs_root, struct btrfs_path *path, ...@@ -2668,9 +2668,9 @@ int btrfs_find_item(struct btrfs_root *fs_root, struct btrfs_path *path,
* tree. if ins_len < 0, nodes will be merged as we walk down the tree (if * tree. if ins_len < 0, nodes will be merged as we walk down the tree (if
* possible) * possible)
*/ */
int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root *root,
*root, struct btrfs_key *key, struct btrfs_path *p, int const struct btrfs_key *key, struct btrfs_path *p,
ins_len, int cow) int ins_len, int cow)
{ {
struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_fs_info *fs_info = root->fs_info;
struct extent_buffer *b; struct extent_buffer *b;
...@@ -2870,8 +2870,8 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root ...@@ -2870,8 +2870,8 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root
goto done; goto done;
} }
err = read_block_for_search(trans, root, p, err = read_block_for_search(root, p, &b, level,
&b, level, slot, key, 0); slot, key);
if (err == -EAGAIN) if (err == -EAGAIN)
goto again; goto again;
if (err) { if (err) {
...@@ -2953,7 +2953,7 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root ...@@ -2953,7 +2953,7 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root
* The resulting path and return value will be set up as if we called * The resulting path and return value will be set up as if we called
* btrfs_search_slot at that point in time with ins_len and cow both set to 0. * btrfs_search_slot at that point in time with ins_len and cow both set to 0.
*/ */
int btrfs_search_old_slot(struct btrfs_root *root, struct btrfs_key *key, int btrfs_search_old_slot(struct btrfs_root *root, const struct btrfs_key *key,
struct btrfs_path *p, u64 time_seq) struct btrfs_path *p, u64 time_seq)
{ {
struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_fs_info *fs_info = root->fs_info;
...@@ -3014,8 +3014,8 @@ int btrfs_search_old_slot(struct btrfs_root *root, struct btrfs_key *key, ...@@ -3014,8 +3014,8 @@ int btrfs_search_old_slot(struct btrfs_root *root, struct btrfs_key *key,
goto done; goto done;
} }
err = read_block_for_search(NULL, root, p, &b, level, err = read_block_for_search(root, p, &b, level,
slot, key, time_seq); slot, key);
if (err == -EAGAIN) if (err == -EAGAIN)
goto again; goto again;
if (err) { if (err) {
...@@ -3067,8 +3067,9 @@ int btrfs_search_old_slot(struct btrfs_root *root, struct btrfs_key *key, ...@@ -3067,8 +3067,9 @@ int btrfs_search_old_slot(struct btrfs_root *root, struct btrfs_key *key,
* < 0 on error * < 0 on error
*/ */
int btrfs_search_slot_for_read(struct btrfs_root *root, int btrfs_search_slot_for_read(struct btrfs_root *root,
struct btrfs_key *key, struct btrfs_path *p, const struct btrfs_key *key,
int find_higher, int return_any) struct btrfs_path *p, int find_higher,
int return_any)
{ {
int ret; int ret;
struct extent_buffer *leaf; struct extent_buffer *leaf;
...@@ -3166,7 +3167,7 @@ static void fixup_low_keys(struct btrfs_fs_info *fs_info, ...@@ -3166,7 +3167,7 @@ static void fixup_low_keys(struct btrfs_fs_info *fs_info,
*/ */
void btrfs_set_item_key_safe(struct btrfs_fs_info *fs_info, void btrfs_set_item_key_safe(struct btrfs_fs_info *fs_info,
struct btrfs_path *path, struct btrfs_path *path,
struct btrfs_key *new_key) const struct btrfs_key *new_key)
{ {
struct btrfs_disk_key disk_key; struct btrfs_disk_key disk_key;
struct extent_buffer *eb; struct extent_buffer *eb;
...@@ -3594,8 +3595,7 @@ noinline int btrfs_leaf_free_space(struct btrfs_fs_info *fs_info, ...@@ -3594,8 +3595,7 @@ noinline int btrfs_leaf_free_space(struct btrfs_fs_info *fs_info,
* min slot controls the lowest index we're willing to push to the * min slot controls the lowest index we're willing to push to the
* right. We'll push up to and including min_slot, but no lower * right. We'll push up to and including min_slot, but no lower
*/ */
static noinline int __push_leaf_right(struct btrfs_trans_handle *trans, static noinline int __push_leaf_right(struct btrfs_fs_info *fs_info,
struct btrfs_fs_info *fs_info,
struct btrfs_path *path, struct btrfs_path *path,
int data_size, int empty, int data_size, int empty,
struct extent_buffer *right, struct extent_buffer *right,
...@@ -3704,7 +3704,7 @@ static noinline int __push_leaf_right(struct btrfs_trans_handle *trans, ...@@ -3704,7 +3704,7 @@ static noinline int __push_leaf_right(struct btrfs_trans_handle *trans,
if (left_nritems) if (left_nritems)
btrfs_mark_buffer_dirty(left); btrfs_mark_buffer_dirty(left);
else else
clean_tree_block(trans, fs_info, left); clean_tree_block(fs_info, left);
btrfs_mark_buffer_dirty(right); btrfs_mark_buffer_dirty(right);
...@@ -3716,7 +3716,7 @@ static noinline int __push_leaf_right(struct btrfs_trans_handle *trans, ...@@ -3716,7 +3716,7 @@ static noinline int __push_leaf_right(struct btrfs_trans_handle *trans,
if (path->slots[0] >= left_nritems) { if (path->slots[0] >= left_nritems) {
path->slots[0] -= left_nritems; path->slots[0] -= left_nritems;
if (btrfs_header_nritems(path->nodes[0]) == 0) if (btrfs_header_nritems(path->nodes[0]) == 0)
clean_tree_block(trans, fs_info, path->nodes[0]); clean_tree_block(fs_info, path->nodes[0]);
btrfs_tree_unlock(path->nodes[0]); btrfs_tree_unlock(path->nodes[0]);
free_extent_buffer(path->nodes[0]); free_extent_buffer(path->nodes[0]);
path->nodes[0] = right; path->nodes[0] = right;
...@@ -3809,7 +3809,7 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root ...@@ -3809,7 +3809,7 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
return 0; return 0;
} }
return __push_leaf_right(trans, fs_info, path, min_data_size, empty, return __push_leaf_right(fs_info, path, min_data_size, empty,
right, free_space, left_nritems, min_slot); right, free_space, left_nritems, min_slot);
out_unlock: out_unlock:
btrfs_tree_unlock(right); btrfs_tree_unlock(right);
...@@ -3825,8 +3825,7 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root ...@@ -3825,8 +3825,7 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
* item at 'max_slot' won't be touched. Use (u32)-1 to make us do all the * item at 'max_slot' won't be touched. Use (u32)-1 to make us do all the
* items * items
*/ */
static noinline int __push_leaf_left(struct btrfs_trans_handle *trans, static noinline int __push_leaf_left(struct btrfs_fs_info *fs_info,
struct btrfs_fs_info *fs_info,
struct btrfs_path *path, int data_size, struct btrfs_path *path, int data_size,
int empty, struct extent_buffer *left, int empty, struct extent_buffer *left,
int free_space, u32 right_nritems, int free_space, u32 right_nritems,
...@@ -3945,7 +3944,7 @@ static noinline int __push_leaf_left(struct btrfs_trans_handle *trans, ...@@ -3945,7 +3944,7 @@ static noinline int __push_leaf_left(struct btrfs_trans_handle *trans,
if (right_nritems) if (right_nritems)
btrfs_mark_buffer_dirty(right); btrfs_mark_buffer_dirty(right);
else else
clean_tree_block(trans, fs_info, right); clean_tree_block(fs_info, right);
btrfs_item_key(right, &disk_key, 0); btrfs_item_key(right, &disk_key, 0);
fixup_low_keys(fs_info, path, &disk_key, 1); fixup_low_keys(fs_info, path, &disk_key, 1);
...@@ -4035,7 +4034,7 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root ...@@ -4035,7 +4034,7 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
goto out; goto out;
} }
return __push_leaf_left(trans, fs_info, path, min_data_size, return __push_leaf_left(fs_info, path, min_data_size,
empty, left, free_space, right_nritems, empty, left, free_space, right_nritems,
max_slot); max_slot);
out: out:
...@@ -4180,7 +4179,7 @@ static noinline int push_for_double_split(struct btrfs_trans_handle *trans, ...@@ -4180,7 +4179,7 @@ static noinline int push_for_double_split(struct btrfs_trans_handle *trans,
*/ */
static noinline int split_leaf(struct btrfs_trans_handle *trans, static noinline int split_leaf(struct btrfs_trans_handle *trans,
struct btrfs_root *root, struct btrfs_root *root,
struct btrfs_key *ins_key, const struct btrfs_key *ins_key,
struct btrfs_path *path, int data_size, struct btrfs_path *path, int data_size,
int extend) int extend)
{ {
...@@ -4412,10 +4411,9 @@ static noinline int setup_leaf_for_split(struct btrfs_trans_handle *trans, ...@@ -4412,10 +4411,9 @@ static noinline int setup_leaf_for_split(struct btrfs_trans_handle *trans,
return ret; return ret;
} }
static noinline int split_item(struct btrfs_trans_handle *trans, static noinline int split_item(struct btrfs_fs_info *fs_info,
struct btrfs_fs_info *fs_info,
struct btrfs_path *path, struct btrfs_path *path,
struct btrfs_key *new_key, const struct btrfs_key *new_key,
unsigned long split_offset) unsigned long split_offset)
{ {
struct extent_buffer *leaf; struct extent_buffer *leaf;
...@@ -4501,7 +4499,7 @@ static noinline int split_item(struct btrfs_trans_handle *trans, ...@@ -4501,7 +4499,7 @@ static noinline int split_item(struct btrfs_trans_handle *trans,
int btrfs_split_item(struct btrfs_trans_handle *trans, int btrfs_split_item(struct btrfs_trans_handle *trans,
struct btrfs_root *root, struct btrfs_root *root,
struct btrfs_path *path, struct btrfs_path *path,
struct btrfs_key *new_key, const struct btrfs_key *new_key,
unsigned long split_offset) unsigned long split_offset)
{ {
int ret; int ret;
...@@ -4510,7 +4508,7 @@ int btrfs_split_item(struct btrfs_trans_handle *trans, ...@@ -4510,7 +4508,7 @@ int btrfs_split_item(struct btrfs_trans_handle *trans,
if (ret) if (ret)
return ret; return ret;
ret = split_item(trans, root->fs_info, path, new_key, split_offset); ret = split_item(root->fs_info, path, new_key, split_offset);
return ret; return ret;
} }
...@@ -4525,7 +4523,7 @@ int btrfs_split_item(struct btrfs_trans_handle *trans, ...@@ -4525,7 +4523,7 @@ int btrfs_split_item(struct btrfs_trans_handle *trans,
int btrfs_duplicate_item(struct btrfs_trans_handle *trans, int btrfs_duplicate_item(struct btrfs_trans_handle *trans,
struct btrfs_root *root, struct btrfs_root *root,
struct btrfs_path *path, struct btrfs_path *path,
struct btrfs_key *new_key) const struct btrfs_key *new_key)
{ {
struct extent_buffer *leaf; struct extent_buffer *leaf;
int ret; int ret;
...@@ -4726,7 +4724,7 @@ void btrfs_extend_item(struct btrfs_fs_info *fs_info, struct btrfs_path *path, ...@@ -4726,7 +4724,7 @@ void btrfs_extend_item(struct btrfs_fs_info *fs_info, struct btrfs_path *path,
* that doesn't call btrfs_search_slot * that doesn't call btrfs_search_slot
*/ */
void setup_items_for_insert(struct btrfs_root *root, struct btrfs_path *path, void setup_items_for_insert(struct btrfs_root *root, struct btrfs_path *path,
struct btrfs_key *cpu_key, u32 *data_size, const struct btrfs_key *cpu_key, u32 *data_size,
u32 total_data, u32 total_size, int nr) u32 total_data, u32 total_size, int nr)
{ {
struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_fs_info *fs_info = root->fs_info;
...@@ -4820,7 +4818,7 @@ void setup_items_for_insert(struct btrfs_root *root, struct btrfs_path *path, ...@@ -4820,7 +4818,7 @@ void setup_items_for_insert(struct btrfs_root *root, struct btrfs_path *path,
int btrfs_insert_empty_items(struct btrfs_trans_handle *trans, int btrfs_insert_empty_items(struct btrfs_trans_handle *trans,
struct btrfs_root *root, struct btrfs_root *root,
struct btrfs_path *path, struct btrfs_path *path,
struct btrfs_key *cpu_key, u32 *data_size, const struct btrfs_key *cpu_key, u32 *data_size,
int nr) int nr)
{ {
int ret = 0; int ret = 0;
...@@ -4851,9 +4849,9 @@ int btrfs_insert_empty_items(struct btrfs_trans_handle *trans, ...@@ -4851,9 +4849,9 @@ int btrfs_insert_empty_items(struct btrfs_trans_handle *trans,
* Given a key and some data, insert an item into the tree. * Given a key and some data, insert an item into the tree.
* This does all the path init required, making room in the tree if needed. * This does all the path init required, making room in the tree if needed.
*/ */
int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root *root,
*root, struct btrfs_key *cpu_key, void *data, u32 const struct btrfs_key *cpu_key, void *data,
data_size) u32 data_size)
{ {
int ret = 0; int ret = 0;
struct btrfs_path *path; struct btrfs_path *path;
...@@ -5008,7 +5006,7 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root, ...@@ -5008,7 +5006,7 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root,
btrfs_set_header_level(leaf, 0); btrfs_set_header_level(leaf, 0);
} else { } else {
btrfs_set_path_blocking(path); btrfs_set_path_blocking(path);
clean_tree_block(trans, fs_info, leaf); clean_tree_block(fs_info, leaf);
btrfs_del_leaf(trans, root, path, leaf); btrfs_del_leaf(trans, root, path, leaf);
} }
} else { } else {
...@@ -5243,7 +5241,7 @@ int btrfs_search_forward(struct btrfs_root *root, struct btrfs_key *min_key, ...@@ -5243,7 +5241,7 @@ int btrfs_search_forward(struct btrfs_root *root, struct btrfs_key *min_key,
static int tree_move_down(struct btrfs_fs_info *fs_info, static int tree_move_down(struct btrfs_fs_info *fs_info,
struct btrfs_path *path, struct btrfs_path *path,
int *level, int root_level) int *level)
{ {
struct extent_buffer *eb; struct extent_buffer *eb;
...@@ -5258,8 +5256,7 @@ static int tree_move_down(struct btrfs_fs_info *fs_info, ...@@ -5258,8 +5256,7 @@ static int tree_move_down(struct btrfs_fs_info *fs_info,
return 0; return 0;
} }
static int tree_move_next_or_upnext(struct btrfs_fs_info *fs_info, static int tree_move_next_or_upnext(struct btrfs_path *path,
struct btrfs_path *path,
int *level, int root_level) int *level, int root_level)
{ {
int ret = 0; int ret = 0;
...@@ -5298,10 +5295,9 @@ static int tree_advance(struct btrfs_fs_info *fs_info, ...@@ -5298,10 +5295,9 @@ static int tree_advance(struct btrfs_fs_info *fs_info,
int ret; int ret;
if (*level == 0 || !allow_down) { if (*level == 0 || !allow_down) {
ret = tree_move_next_or_upnext(fs_info, path, level, ret = tree_move_next_or_upnext(path, level, root_level);
root_level);
} else { } else {
ret = tree_move_down(fs_info, path, level, root_level); ret = tree_move_down(fs_info, path, level);
} }
if (ret >= 0) { if (ret >= 0) {
if (*level == 0) if (*level == 0)
...@@ -5784,8 +5780,8 @@ int btrfs_next_old_leaf(struct btrfs_root *root, struct btrfs_path *path, ...@@ -5784,8 +5780,8 @@ int btrfs_next_old_leaf(struct btrfs_root *root, struct btrfs_path *path,
next = c; next = c;
next_rw_lock = path->locks[level]; next_rw_lock = path->locks[level];
ret = read_block_for_search(NULL, root, path, &next, level, ret = read_block_for_search(root, path, &next, level,
slot, &key, 0); slot, &key);
if (ret == -EAGAIN) if (ret == -EAGAIN)
goto again; goto again;
...@@ -5834,8 +5830,8 @@ int btrfs_next_old_leaf(struct btrfs_root *root, struct btrfs_path *path, ...@@ -5834,8 +5830,8 @@ int btrfs_next_old_leaf(struct btrfs_root *root, struct btrfs_path *path,
if (!level) if (!level)
break; break;
ret = read_block_for_search(NULL, root, path, &next, level, ret = read_block_for_search(root, path, &next, level,
0, &key, 0); 0, &key);
if (ret == -EAGAIN) if (ret == -EAGAIN)
goto again; goto again;
......
...@@ -97,6 +97,14 @@ static const int btrfs_csum_sizes[] = { 4 }; ...@@ -97,6 +97,14 @@ static const int btrfs_csum_sizes[] = { 4 };
#define BTRFS_MAX_EXTENT_SIZE SZ_128M #define BTRFS_MAX_EXTENT_SIZE SZ_128M
/*
* Count how many BTRFS_MAX_EXTENT_SIZE cover the @size
*/
static inline u32 count_max_extents(u64 size)
{
return div_u64(size + BTRFS_MAX_EXTENT_SIZE - 1, BTRFS_MAX_EXTENT_SIZE);
}
struct btrfs_mapping_tree { struct btrfs_mapping_tree {
struct extent_map_tree map_tree; struct extent_map_tree map_tree;
}; };
...@@ -1953,7 +1961,7 @@ BTRFS_SETGET_STACK_FUNCS(disk_key_offset, struct btrfs_disk_key, offset, 64); ...@@ -1953,7 +1961,7 @@ BTRFS_SETGET_STACK_FUNCS(disk_key_offset, struct btrfs_disk_key, offset, 64);
BTRFS_SETGET_STACK_FUNCS(disk_key_type, struct btrfs_disk_key, type, 8); BTRFS_SETGET_STACK_FUNCS(disk_key_type, struct btrfs_disk_key, type, 8);
static inline void btrfs_disk_key_to_cpu(struct btrfs_key *cpu, static inline void btrfs_disk_key_to_cpu(struct btrfs_key *cpu,
struct btrfs_disk_key *disk) const struct btrfs_disk_key *disk)
{ {
cpu->offset = le64_to_cpu(disk->offset); cpu->offset = le64_to_cpu(disk->offset);
cpu->type = disk->type; cpu->type = disk->type;
...@@ -1961,7 +1969,7 @@ static inline void btrfs_disk_key_to_cpu(struct btrfs_key *cpu, ...@@ -1961,7 +1969,7 @@ static inline void btrfs_disk_key_to_cpu(struct btrfs_key *cpu,
} }
static inline void btrfs_cpu_key_to_disk(struct btrfs_disk_key *disk, static inline void btrfs_cpu_key_to_disk(struct btrfs_disk_key *disk,
struct btrfs_key *cpu) const struct btrfs_key *cpu)
{ {
disk->offset = cpu_to_le64(cpu->offset); disk->offset = cpu_to_le64(cpu->offset);
disk->type = cpu->type; disk->type = cpu->type;
...@@ -1993,8 +2001,7 @@ static inline void btrfs_dir_item_key_to_cpu(struct extent_buffer *eb, ...@@ -1993,8 +2001,7 @@ static inline void btrfs_dir_item_key_to_cpu(struct extent_buffer *eb,
btrfs_disk_key_to_cpu(key, &disk_key); btrfs_disk_key_to_cpu(key, &disk_key);
} }
static inline u8 btrfs_key_type(const struct btrfs_key *key)
static inline u8 btrfs_key_type(struct btrfs_key *key)
{ {
return key->type; return key->type;
} }
...@@ -2577,8 +2584,7 @@ int btrfs_pin_extent_for_log_replay(struct btrfs_fs_info *fs_info, ...@@ -2577,8 +2584,7 @@ int btrfs_pin_extent_for_log_replay(struct btrfs_fs_info *fs_info,
u64 bytenr, u64 num_bytes); u64 bytenr, u64 num_bytes);
int btrfs_exclude_logged_extents(struct btrfs_fs_info *fs_info, int btrfs_exclude_logged_extents(struct btrfs_fs_info *fs_info,
struct extent_buffer *eb); struct extent_buffer *eb);
int btrfs_cross_ref_exist(struct btrfs_trans_handle *trans, int btrfs_cross_ref_exist(struct btrfs_root *root,
struct btrfs_root *root,
u64 objectid, u64 offset, u64 bytenr); u64 objectid, u64 offset, u64 bytenr);
struct btrfs_block_group_cache *btrfs_lookup_block_group( struct btrfs_block_group_cache *btrfs_lookup_block_group(
struct btrfs_fs_info *info, struct btrfs_fs_info *info,
...@@ -2587,10 +2593,11 @@ void btrfs_get_block_group(struct btrfs_block_group_cache *cache); ...@@ -2587,10 +2593,11 @@ void btrfs_get_block_group(struct btrfs_block_group_cache *cache);
void btrfs_put_block_group(struct btrfs_block_group_cache *cache); void btrfs_put_block_group(struct btrfs_block_group_cache *cache);
int get_block_group_index(struct btrfs_block_group_cache *cache); int get_block_group_index(struct btrfs_block_group_cache *cache);
struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans, struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans,
struct btrfs_root *root, u64 parent, struct btrfs_root *root,
u64 root_objectid, u64 parent, u64 root_objectid,
struct btrfs_disk_key *key, int level, const struct btrfs_disk_key *key,
u64 hint, u64 empty_size); int level, u64 hint,
u64 empty_size);
void btrfs_free_tree_block(struct btrfs_trans_handle *trans, void btrfs_free_tree_block(struct btrfs_trans_handle *trans,
struct btrfs_root *root, struct btrfs_root *root,
struct extent_buffer *buf, struct extent_buffer *buf,
...@@ -2623,8 +2630,7 @@ int btrfs_free_reserved_extent(struct btrfs_fs_info *fs_info, ...@@ -2623,8 +2630,7 @@ int btrfs_free_reserved_extent(struct btrfs_fs_info *fs_info,
u64 start, u64 len, int delalloc); u64 start, u64 len, int delalloc);
int btrfs_free_and_pin_reserved_extent(struct btrfs_fs_info *fs_info, int btrfs_free_and_pin_reserved_extent(struct btrfs_fs_info *fs_info,
u64 start, u64 len); u64 start, u64 len);
void btrfs_prepare_extent_commit(struct btrfs_trans_handle *trans, void btrfs_prepare_extent_commit(struct btrfs_fs_info *fs_info);
struct btrfs_fs_info *fs_info);
int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans,
struct btrfs_fs_info *fs_info); struct btrfs_fs_info *fs_info);
int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
...@@ -2696,8 +2702,7 @@ int btrfs_subvolume_reserve_metadata(struct btrfs_root *root, ...@@ -2696,8 +2702,7 @@ int btrfs_subvolume_reserve_metadata(struct btrfs_root *root,
int nitems, int nitems,
u64 *qgroup_reserved, bool use_global_rsv); u64 *qgroup_reserved, bool use_global_rsv);
void btrfs_subvolume_release_metadata(struct btrfs_fs_info *fs_info, void btrfs_subvolume_release_metadata(struct btrfs_fs_info *fs_info,
struct btrfs_block_rsv *rsv, struct btrfs_block_rsv *rsv);
u64 qgroup_reserved);
int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes); int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes);
void btrfs_delalloc_release_metadata(struct inode *inode, u64 num_bytes); void btrfs_delalloc_release_metadata(struct inode *inode, u64 num_bytes);
int btrfs_delalloc_reserve_space(struct inode *inode, u64 start, u64 len); int btrfs_delalloc_reserve_space(struct inode *inode, u64 start, u64 len);
...@@ -2724,7 +2729,7 @@ int btrfs_cond_migrate_bytes(struct btrfs_fs_info *fs_info, ...@@ -2724,7 +2729,7 @@ int btrfs_cond_migrate_bytes(struct btrfs_fs_info *fs_info,
void btrfs_block_rsv_release(struct btrfs_fs_info *fs_info, void btrfs_block_rsv_release(struct btrfs_fs_info *fs_info,
struct btrfs_block_rsv *block_rsv, struct btrfs_block_rsv *block_rsv,
u64 num_bytes); u64 num_bytes);
int btrfs_inc_block_group_ro(struct btrfs_root *root, int btrfs_inc_block_group_ro(struct btrfs_fs_info *fs_info,
struct btrfs_block_group_cache *cache); struct btrfs_block_group_cache *cache);
void btrfs_dec_block_group_ro(struct btrfs_block_group_cache *cache); void btrfs_dec_block_group_ro(struct btrfs_block_group_cache *cache);
void btrfs_put_block_group_cache(struct btrfs_fs_info *info); void btrfs_put_block_group_cache(struct btrfs_fs_info *info);
...@@ -2750,9 +2755,9 @@ u64 add_new_free_space(struct btrfs_block_group_cache *block_group, ...@@ -2750,9 +2755,9 @@ u64 add_new_free_space(struct btrfs_block_group_cache *block_group,
struct btrfs_fs_info *info, u64 start, u64 end); struct btrfs_fs_info *info, u64 start, u64 end);
/* ctree.c */ /* ctree.c */
int btrfs_bin_search(struct extent_buffer *eb, struct btrfs_key *key, int btrfs_bin_search(struct extent_buffer *eb, const struct btrfs_key *key,
int level, int *slot); int level, int *slot);
int btrfs_comp_cpu_keys(struct btrfs_key *k1, struct btrfs_key *k2); int btrfs_comp_cpu_keys(const struct btrfs_key *k1, const struct btrfs_key *k2);
int btrfs_previous_item(struct btrfs_root *root, int btrfs_previous_item(struct btrfs_root *root,
struct btrfs_path *path, u64 min_objectid, struct btrfs_path *path, u64 min_objectid,
int type); int type);
...@@ -2760,7 +2765,7 @@ int btrfs_previous_extent_item(struct btrfs_root *root, ...@@ -2760,7 +2765,7 @@ int btrfs_previous_extent_item(struct btrfs_root *root,
struct btrfs_path *path, u64 min_objectid); struct btrfs_path *path, u64 min_objectid);
void btrfs_set_item_key_safe(struct btrfs_fs_info *fs_info, void btrfs_set_item_key_safe(struct btrfs_fs_info *fs_info,
struct btrfs_path *path, struct btrfs_path *path,
struct btrfs_key *new_key); const struct btrfs_key *new_key);
struct extent_buffer *btrfs_root_node(struct btrfs_root *root); struct extent_buffer *btrfs_root_node(struct btrfs_root *root);
struct extent_buffer *btrfs_lock_root_node(struct btrfs_root *root); struct extent_buffer *btrfs_lock_root_node(struct btrfs_root *root);
int btrfs_find_next_key(struct btrfs_root *root, struct btrfs_path *path, int btrfs_find_next_key(struct btrfs_root *root, struct btrfs_path *path,
...@@ -2802,22 +2807,23 @@ void btrfs_truncate_item(struct btrfs_fs_info *fs_info, ...@@ -2802,22 +2807,23 @@ void btrfs_truncate_item(struct btrfs_fs_info *fs_info,
int btrfs_split_item(struct btrfs_trans_handle *trans, int btrfs_split_item(struct btrfs_trans_handle *trans,
struct btrfs_root *root, struct btrfs_root *root,
struct btrfs_path *path, struct btrfs_path *path,
struct btrfs_key *new_key, const struct btrfs_key *new_key,
unsigned long split_offset); unsigned long split_offset);
int btrfs_duplicate_item(struct btrfs_trans_handle *trans, int btrfs_duplicate_item(struct btrfs_trans_handle *trans,
struct btrfs_root *root, struct btrfs_root *root,
struct btrfs_path *path, struct btrfs_path *path,
struct btrfs_key *new_key); const struct btrfs_key *new_key);
int btrfs_find_item(struct btrfs_root *fs_root, struct btrfs_path *path, int btrfs_find_item(struct btrfs_root *fs_root, struct btrfs_path *path,
u64 inum, u64 ioff, u8 key_type, struct btrfs_key *found_key); u64 inum, u64 ioff, u8 key_type, struct btrfs_key *found_key);
int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root *root,
*root, struct btrfs_key *key, struct btrfs_path *p, int const struct btrfs_key *key, struct btrfs_path *p,
ins_len, int cow); int ins_len, int cow);
int btrfs_search_old_slot(struct btrfs_root *root, struct btrfs_key *key, int btrfs_search_old_slot(struct btrfs_root *root, const struct btrfs_key *key,
struct btrfs_path *p, u64 time_seq); struct btrfs_path *p, u64 time_seq);
int btrfs_search_slot_for_read(struct btrfs_root *root, int btrfs_search_slot_for_read(struct btrfs_root *root,
struct btrfs_key *key, struct btrfs_path *p, const struct btrfs_key *key,
int find_higher, int return_any); struct btrfs_path *p, int find_higher,
int return_any);
int btrfs_realloc_node(struct btrfs_trans_handle *trans, int btrfs_realloc_node(struct btrfs_trans_handle *trans,
struct btrfs_root *root, struct extent_buffer *parent, struct btrfs_root *root, struct extent_buffer *parent,
int start_slot, u64 *last_ret, int start_slot, u64 *last_ret,
...@@ -2840,19 +2846,20 @@ static inline int btrfs_del_item(struct btrfs_trans_handle *trans, ...@@ -2840,19 +2846,20 @@ static inline int btrfs_del_item(struct btrfs_trans_handle *trans,
} }
void setup_items_for_insert(struct btrfs_root *root, struct btrfs_path *path, void setup_items_for_insert(struct btrfs_root *root, struct btrfs_path *path,
struct btrfs_key *cpu_key, u32 *data_size, const struct btrfs_key *cpu_key, u32 *data_size,
u32 total_data, u32 total_size, int nr); u32 total_data, u32 total_size, int nr);
int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root *root,
*root, struct btrfs_key *key, void *data, u32 data_size); const struct btrfs_key *key, void *data, u32 data_size);
int btrfs_insert_empty_items(struct btrfs_trans_handle *trans, int btrfs_insert_empty_items(struct btrfs_trans_handle *trans,
struct btrfs_root *root, struct btrfs_root *root,
struct btrfs_path *path, struct btrfs_path *path,
struct btrfs_key *cpu_key, u32 *data_size, int nr); const struct btrfs_key *cpu_key, u32 *data_size,
int nr);
static inline int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, static inline int btrfs_insert_empty_item(struct btrfs_trans_handle *trans,
struct btrfs_root *root, struct btrfs_root *root,
struct btrfs_path *path, struct btrfs_path *path,
struct btrfs_key *key, const struct btrfs_key *key,
u32 data_size) u32 data_size)
{ {
return btrfs_insert_empty_items(trans, root, path, key, &data_size, 1); return btrfs_insert_empty_items(trans, root, path, key, &data_size, 1);
...@@ -2941,15 +2948,15 @@ int btrfs_del_root_ref(struct btrfs_trans_handle *trans, ...@@ -2941,15 +2948,15 @@ int btrfs_del_root_ref(struct btrfs_trans_handle *trans,
u64 root_id, u64 ref_id, u64 dirid, u64 *sequence, u64 root_id, u64 ref_id, u64 dirid, u64 *sequence,
const char *name, int name_len); const char *name, int name_len);
int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root, int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root,
struct btrfs_key *key); const struct btrfs_key *key);
int btrfs_insert_root(struct btrfs_trans_handle *trans, struct btrfs_root int btrfs_insert_root(struct btrfs_trans_handle *trans, struct btrfs_root *root,
*root, struct btrfs_key *key, struct btrfs_root_item const struct btrfs_key *key,
*item); struct btrfs_root_item *item);
int __must_check btrfs_update_root(struct btrfs_trans_handle *trans, int __must_check btrfs_update_root(struct btrfs_trans_handle *trans,
struct btrfs_root *root, struct btrfs_root *root,
struct btrfs_key *key, struct btrfs_key *key,
struct btrfs_root_item *item); struct btrfs_root_item *item);
int btrfs_find_root(struct btrfs_root *root, struct btrfs_key *search_key, int btrfs_find_root(struct btrfs_root *root, const struct btrfs_key *search_key,
struct btrfs_path *path, struct btrfs_root_item *root_item, struct btrfs_path *path, struct btrfs_root_item *root_item,
struct btrfs_key *root_key); struct btrfs_key *root_key);
int btrfs_find_orphan_roots(struct btrfs_fs_info *fs_info); int btrfs_find_orphan_roots(struct btrfs_fs_info *fs_info);
...@@ -3119,7 +3126,7 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry); ...@@ -3119,7 +3126,7 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry);
int btrfs_set_inode_index(struct inode *dir, u64 *index); int btrfs_set_inode_index(struct inode *dir, u64 *index);
int btrfs_unlink_inode(struct btrfs_trans_handle *trans, int btrfs_unlink_inode(struct btrfs_trans_handle *trans,
struct btrfs_root *root, struct btrfs_root *root,
struct inode *dir, struct inode *inode, struct btrfs_inode *dir, struct btrfs_inode *inode,
const char *name, int name_len); const char *name, int name_len);
int btrfs_add_link(struct btrfs_trans_handle *trans, int btrfs_add_link(struct btrfs_trans_handle *trans,
struct inode *parent_inode, struct inode *inode, struct inode *parent_inode, struct inode *inode,
...@@ -3447,7 +3454,8 @@ do { \ ...@@ -3447,7 +3454,8 @@ do { \
"BTRFS: Transaction aborted (error %d)\n", \ "BTRFS: Transaction aborted (error %d)\n", \
(errno)); \ (errno)); \
} else { \ } else { \
pr_debug("BTRFS: Transaction aborted (error %d)\n", \ btrfs_debug((trans)->fs_info, \
"Transaction aborted (error %d)", \
(errno)); \ (errno)); \
} \ } \
} \ } \
......
...@@ -72,14 +72,14 @@ static inline int btrfs_is_continuous_delayed_item( ...@@ -72,14 +72,14 @@ static inline int btrfs_is_continuous_delayed_item(
return 0; return 0;
} }
static struct btrfs_delayed_node *btrfs_get_delayed_node(struct inode *inode) static struct btrfs_delayed_node *btrfs_get_delayed_node(
struct btrfs_inode *btrfs_inode)
{ {
struct btrfs_inode *btrfs_inode = BTRFS_I(inode);
struct btrfs_root *root = btrfs_inode->root; struct btrfs_root *root = btrfs_inode->root;
u64 ino = btrfs_ino(inode); u64 ino = btrfs_ino(btrfs_inode);
struct btrfs_delayed_node *node; struct btrfs_delayed_node *node;
node = ACCESS_ONCE(btrfs_inode->delayed_node); node = READ_ONCE(btrfs_inode->delayed_node);
if (node) { if (node) {
atomic_inc(&node->refs); atomic_inc(&node->refs);
return node; return node;
...@@ -107,16 +107,15 @@ static struct btrfs_delayed_node *btrfs_get_delayed_node(struct inode *inode) ...@@ -107,16 +107,15 @@ static struct btrfs_delayed_node *btrfs_get_delayed_node(struct inode *inode)
/* Will return either the node or PTR_ERR(-ENOMEM) */ /* Will return either the node or PTR_ERR(-ENOMEM) */
static struct btrfs_delayed_node *btrfs_get_or_create_delayed_node( static struct btrfs_delayed_node *btrfs_get_or_create_delayed_node(
struct inode *inode) struct btrfs_inode *btrfs_inode)
{ {
struct btrfs_delayed_node *node; struct btrfs_delayed_node *node;
struct btrfs_inode *btrfs_inode = BTRFS_I(inode);
struct btrfs_root *root = btrfs_inode->root; struct btrfs_root *root = btrfs_inode->root;
u64 ino = btrfs_ino(inode); u64 ino = btrfs_ino(btrfs_inode);
int ret; int ret;
again: again:
node = btrfs_get_delayed_node(inode); node = btrfs_get_delayed_node(btrfs_inode);
if (node) if (node)
return node; return node;
...@@ -574,7 +573,7 @@ static void btrfs_delayed_item_release_metadata(struct btrfs_fs_info *fs_info, ...@@ -574,7 +573,7 @@ static void btrfs_delayed_item_release_metadata(struct btrfs_fs_info *fs_info,
static int btrfs_delayed_inode_reserve_metadata( static int btrfs_delayed_inode_reserve_metadata(
struct btrfs_trans_handle *trans, struct btrfs_trans_handle *trans,
struct btrfs_root *root, struct btrfs_root *root,
struct inode *inode, struct btrfs_inode *inode,
struct btrfs_delayed_node *node) struct btrfs_delayed_node *node)
{ {
struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_fs_info *fs_info = root->fs_info;
...@@ -603,13 +602,13 @@ static int btrfs_delayed_inode_reserve_metadata( ...@@ -603,13 +602,13 @@ static int btrfs_delayed_inode_reserve_metadata(
* worth which is less likely to hurt us. * worth which is less likely to hurt us.
*/ */
if (src_rsv && src_rsv->type == BTRFS_BLOCK_RSV_DELALLOC) { if (src_rsv && src_rsv->type == BTRFS_BLOCK_RSV_DELALLOC) {
spin_lock(&BTRFS_I(inode)->lock); spin_lock(&inode->lock);
if (test_and_clear_bit(BTRFS_INODE_DELALLOC_META_RESERVED, if (test_and_clear_bit(BTRFS_INODE_DELALLOC_META_RESERVED,
&BTRFS_I(inode)->runtime_flags)) &inode->runtime_flags))
release = true; release = true;
else else
src_rsv = NULL; src_rsv = NULL;
spin_unlock(&BTRFS_I(inode)->lock); spin_unlock(&inode->lock);
} }
/* /*
...@@ -1196,7 +1195,7 @@ int btrfs_run_delayed_items_nr(struct btrfs_trans_handle *trans, ...@@ -1196,7 +1195,7 @@ int btrfs_run_delayed_items_nr(struct btrfs_trans_handle *trans,
} }
int btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans, int btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans,
struct inode *inode) struct btrfs_inode *inode)
{ {
struct btrfs_delayed_node *delayed_node = btrfs_get_delayed_node(inode); struct btrfs_delayed_node *delayed_node = btrfs_get_delayed_node(inode);
struct btrfs_path *path; struct btrfs_path *path;
...@@ -1233,9 +1232,9 @@ int btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans, ...@@ -1233,9 +1232,9 @@ int btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans,
return ret; return ret;
} }
int btrfs_commit_inode_delayed_inode(struct inode *inode) int btrfs_commit_inode_delayed_inode(struct btrfs_inode *inode)
{ {
struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); struct btrfs_fs_info *fs_info = btrfs_sb(inode->vfs_inode.i_sb);
struct btrfs_trans_handle *trans; struct btrfs_trans_handle *trans;
struct btrfs_delayed_node *delayed_node = btrfs_get_delayed_node(inode); struct btrfs_delayed_node *delayed_node = btrfs_get_delayed_node(inode);
struct btrfs_path *path; struct btrfs_path *path;
...@@ -1288,15 +1287,15 @@ int btrfs_commit_inode_delayed_inode(struct inode *inode) ...@@ -1288,15 +1287,15 @@ int btrfs_commit_inode_delayed_inode(struct inode *inode)
return ret; return ret;
} }
void btrfs_remove_delayed_node(struct inode *inode) void btrfs_remove_delayed_node(struct btrfs_inode *inode)
{ {
struct btrfs_delayed_node *delayed_node; struct btrfs_delayed_node *delayed_node;
delayed_node = ACCESS_ONCE(BTRFS_I(inode)->delayed_node); delayed_node = READ_ONCE(inode->delayed_node);
if (!delayed_node) if (!delayed_node)
return; return;
BTRFS_I(inode)->delayed_node = NULL; inode->delayed_node = NULL;
btrfs_release_delayed_node(delayed_node); btrfs_release_delayed_node(delayed_node);
} }
...@@ -1434,7 +1433,7 @@ void btrfs_balance_delayed_items(struct btrfs_fs_info *fs_info) ...@@ -1434,7 +1433,7 @@ void btrfs_balance_delayed_items(struct btrfs_fs_info *fs_info)
int btrfs_insert_delayed_dir_index(struct btrfs_trans_handle *trans, int btrfs_insert_delayed_dir_index(struct btrfs_trans_handle *trans,
struct btrfs_fs_info *fs_info, struct btrfs_fs_info *fs_info,
const char *name, int name_len, const char *name, int name_len,
struct inode *dir, struct btrfs_inode *dir,
struct btrfs_disk_key *disk_key, u8 type, struct btrfs_disk_key *disk_key, u8 type,
u64 index) u64 index)
{ {
...@@ -1510,7 +1509,7 @@ static int btrfs_delete_delayed_insertion_item(struct btrfs_fs_info *fs_info, ...@@ -1510,7 +1509,7 @@ static int btrfs_delete_delayed_insertion_item(struct btrfs_fs_info *fs_info,
int btrfs_delete_delayed_dir_index(struct btrfs_trans_handle *trans, int btrfs_delete_delayed_dir_index(struct btrfs_trans_handle *trans,
struct btrfs_fs_info *fs_info, struct btrfs_fs_info *fs_info,
struct inode *dir, u64 index) struct btrfs_inode *dir, u64 index)
{ {
struct btrfs_delayed_node *node; struct btrfs_delayed_node *node;
struct btrfs_delayed_item *item; struct btrfs_delayed_item *item;
...@@ -1558,7 +1557,7 @@ int btrfs_delete_delayed_dir_index(struct btrfs_trans_handle *trans, ...@@ -1558,7 +1557,7 @@ int btrfs_delete_delayed_dir_index(struct btrfs_trans_handle *trans,
return ret; return ret;
} }
int btrfs_inode_delayed_dir_index_count(struct inode *inode) int btrfs_inode_delayed_dir_index_count(struct btrfs_inode *inode)
{ {
struct btrfs_delayed_node *delayed_node = btrfs_get_delayed_node(inode); struct btrfs_delayed_node *delayed_node = btrfs_get_delayed_node(inode);
...@@ -1575,7 +1574,7 @@ int btrfs_inode_delayed_dir_index_count(struct inode *inode) ...@@ -1575,7 +1574,7 @@ int btrfs_inode_delayed_dir_index_count(struct inode *inode)
return -EINVAL; return -EINVAL;
} }
BTRFS_I(inode)->index_cnt = delayed_node->index_cnt; inode->index_cnt = delayed_node->index_cnt;
btrfs_release_delayed_node(delayed_node); btrfs_release_delayed_node(delayed_node);
return 0; return 0;
} }
...@@ -1587,7 +1586,7 @@ bool btrfs_readdir_get_delayed_items(struct inode *inode, ...@@ -1587,7 +1586,7 @@ bool btrfs_readdir_get_delayed_items(struct inode *inode,
struct btrfs_delayed_node *delayed_node; struct btrfs_delayed_node *delayed_node;
struct btrfs_delayed_item *item; struct btrfs_delayed_item *item;
delayed_node = btrfs_get_delayed_node(inode); delayed_node = btrfs_get_delayed_node(BTRFS_I(inode));
if (!delayed_node) if (!delayed_node)
return false; return false;
...@@ -1776,7 +1775,7 @@ int btrfs_fill_inode(struct inode *inode, u32 *rdev) ...@@ -1776,7 +1775,7 @@ int btrfs_fill_inode(struct inode *inode, u32 *rdev)
struct btrfs_delayed_node *delayed_node; struct btrfs_delayed_node *delayed_node;
struct btrfs_inode_item *inode_item; struct btrfs_inode_item *inode_item;
delayed_node = btrfs_get_delayed_node(inode); delayed_node = btrfs_get_delayed_node(BTRFS_I(inode));
if (!delayed_node) if (!delayed_node)
return -ENOENT; return -ENOENT;
...@@ -1831,7 +1830,7 @@ int btrfs_delayed_update_inode(struct btrfs_trans_handle *trans, ...@@ -1831,7 +1830,7 @@ int btrfs_delayed_update_inode(struct btrfs_trans_handle *trans,
struct btrfs_delayed_node *delayed_node; struct btrfs_delayed_node *delayed_node;
int ret = 0; int ret = 0;
delayed_node = btrfs_get_or_create_delayed_node(inode); delayed_node = btrfs_get_or_create_delayed_node(BTRFS_I(inode));
if (IS_ERR(delayed_node)) if (IS_ERR(delayed_node))
return PTR_ERR(delayed_node); return PTR_ERR(delayed_node);
...@@ -1841,7 +1840,7 @@ int btrfs_delayed_update_inode(struct btrfs_trans_handle *trans, ...@@ -1841,7 +1840,7 @@ int btrfs_delayed_update_inode(struct btrfs_trans_handle *trans,
goto release_node; goto release_node;
} }
ret = btrfs_delayed_inode_reserve_metadata(trans, root, inode, ret = btrfs_delayed_inode_reserve_metadata(trans, root, BTRFS_I(inode),
delayed_node); delayed_node);
if (ret) if (ret)
goto release_node; goto release_node;
...@@ -1856,9 +1855,9 @@ int btrfs_delayed_update_inode(struct btrfs_trans_handle *trans, ...@@ -1856,9 +1855,9 @@ int btrfs_delayed_update_inode(struct btrfs_trans_handle *trans,
return ret; return ret;
} }
int btrfs_delayed_delete_inode_ref(struct inode *inode) int btrfs_delayed_delete_inode_ref(struct btrfs_inode *inode)
{ {
struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); struct btrfs_fs_info *fs_info = btrfs_sb(inode->vfs_inode.i_sb);
struct btrfs_delayed_node *delayed_node; struct btrfs_delayed_node *delayed_node;
/* /*
...@@ -1933,7 +1932,7 @@ static void __btrfs_kill_delayed_node(struct btrfs_delayed_node *delayed_node) ...@@ -1933,7 +1932,7 @@ static void __btrfs_kill_delayed_node(struct btrfs_delayed_node *delayed_node)
mutex_unlock(&delayed_node->mutex); mutex_unlock(&delayed_node->mutex);
} }
void btrfs_kill_delayed_inode_items(struct inode *inode) void btrfs_kill_delayed_inode_items(struct btrfs_inode *inode)
{ {
struct btrfs_delayed_node *delayed_node; struct btrfs_delayed_node *delayed_node;
......
...@@ -101,15 +101,15 @@ static inline void btrfs_init_delayed_root( ...@@ -101,15 +101,15 @@ static inline void btrfs_init_delayed_root(
int btrfs_insert_delayed_dir_index(struct btrfs_trans_handle *trans, int btrfs_insert_delayed_dir_index(struct btrfs_trans_handle *trans,
struct btrfs_fs_info *fs_info, struct btrfs_fs_info *fs_info,
const char *name, int name_len, const char *name, int name_len,
struct inode *dir, struct btrfs_inode *dir,
struct btrfs_disk_key *disk_key, u8 type, struct btrfs_disk_key *disk_key, u8 type,
u64 index); u64 index);
int btrfs_delete_delayed_dir_index(struct btrfs_trans_handle *trans, int btrfs_delete_delayed_dir_index(struct btrfs_trans_handle *trans,
struct btrfs_fs_info *fs_info, struct btrfs_fs_info *fs_info,
struct inode *dir, u64 index); struct btrfs_inode *dir, u64 index);
int btrfs_inode_delayed_dir_index_count(struct inode *inode); int btrfs_inode_delayed_dir_index_count(struct btrfs_inode *inode);
int btrfs_run_delayed_items(struct btrfs_trans_handle *trans, int btrfs_run_delayed_items(struct btrfs_trans_handle *trans,
struct btrfs_fs_info *fs_info); struct btrfs_fs_info *fs_info);
...@@ -119,17 +119,17 @@ int btrfs_run_delayed_items_nr(struct btrfs_trans_handle *trans, ...@@ -119,17 +119,17 @@ int btrfs_run_delayed_items_nr(struct btrfs_trans_handle *trans,
void btrfs_balance_delayed_items(struct btrfs_fs_info *fs_info); void btrfs_balance_delayed_items(struct btrfs_fs_info *fs_info);
int btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans, int btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans,
struct inode *inode); struct btrfs_inode *inode);
/* Used for evicting the inode. */ /* Used for evicting the inode. */
void btrfs_remove_delayed_node(struct inode *inode); void btrfs_remove_delayed_node(struct btrfs_inode *inode);
void btrfs_kill_delayed_inode_items(struct inode *inode); void btrfs_kill_delayed_inode_items(struct btrfs_inode *inode);
int btrfs_commit_inode_delayed_inode(struct inode *inode); int btrfs_commit_inode_delayed_inode(struct btrfs_inode *inode);
int btrfs_delayed_update_inode(struct btrfs_trans_handle *trans, int btrfs_delayed_update_inode(struct btrfs_trans_handle *trans,
struct btrfs_root *root, struct inode *inode); struct btrfs_root *root, struct inode *inode);
int btrfs_fill_inode(struct inode *inode, u32 *rdev); int btrfs_fill_inode(struct inode *inode, u32 *rdev);
int btrfs_delayed_delete_inode_ref(struct inode *inode); int btrfs_delayed_delete_inode_ref(struct btrfs_inode *inode);
/* Used for drop dead root */ /* Used for drop dead root */
void btrfs_kill_all_delayed_nodes(struct btrfs_root *root); void btrfs_kill_all_delayed_nodes(struct btrfs_root *root);
......
...@@ -550,13 +550,14 @@ add_delayed_ref_head(struct btrfs_fs_info *fs_info, ...@@ -550,13 +550,14 @@ add_delayed_ref_head(struct btrfs_fs_info *fs_info,
struct btrfs_delayed_ref_node *ref, struct btrfs_delayed_ref_node *ref,
struct btrfs_qgroup_extent_record *qrecord, struct btrfs_qgroup_extent_record *qrecord,
u64 bytenr, u64 num_bytes, u64 ref_root, u64 reserved, u64 bytenr, u64 num_bytes, u64 ref_root, u64 reserved,
int action, int is_data) int action, int is_data, int *qrecord_inserted_ret)
{ {
struct btrfs_delayed_ref_head *existing; struct btrfs_delayed_ref_head *existing;
struct btrfs_delayed_ref_head *head_ref = NULL; struct btrfs_delayed_ref_head *head_ref = NULL;
struct btrfs_delayed_ref_root *delayed_refs; struct btrfs_delayed_ref_root *delayed_refs;
int count_mod = 1; int count_mod = 1;
int must_insert_reserved = 0; int must_insert_reserved = 0;
int qrecord_inserted = 0;
/* If reserved is provided, it must be a data extent. */ /* If reserved is provided, it must be a data extent. */
BUG_ON(!is_data && reserved); BUG_ON(!is_data && reserved);
...@@ -623,6 +624,8 @@ add_delayed_ref_head(struct btrfs_fs_info *fs_info, ...@@ -623,6 +624,8 @@ add_delayed_ref_head(struct btrfs_fs_info *fs_info,
if(btrfs_qgroup_trace_extent_nolock(fs_info, if(btrfs_qgroup_trace_extent_nolock(fs_info,
delayed_refs, qrecord)) delayed_refs, qrecord))
kfree(qrecord); kfree(qrecord);
else
qrecord_inserted = 1;
} }
spin_lock_init(&head_ref->lock); spin_lock_init(&head_ref->lock);
...@@ -650,6 +653,8 @@ add_delayed_ref_head(struct btrfs_fs_info *fs_info, ...@@ -650,6 +653,8 @@ add_delayed_ref_head(struct btrfs_fs_info *fs_info,
atomic_inc(&delayed_refs->num_entries); atomic_inc(&delayed_refs->num_entries);
trans->delayed_ref_updates++; trans->delayed_ref_updates++;
} }
if (qrecord_inserted_ret)
*qrecord_inserted_ret = qrecord_inserted;
return head_ref; return head_ref;
} }
...@@ -779,6 +784,7 @@ int btrfs_add_delayed_tree_ref(struct btrfs_fs_info *fs_info, ...@@ -779,6 +784,7 @@ int btrfs_add_delayed_tree_ref(struct btrfs_fs_info *fs_info,
struct btrfs_delayed_ref_head *head_ref; struct btrfs_delayed_ref_head *head_ref;
struct btrfs_delayed_ref_root *delayed_refs; struct btrfs_delayed_ref_root *delayed_refs;
struct btrfs_qgroup_extent_record *record = NULL; struct btrfs_qgroup_extent_record *record = NULL;
int qrecord_inserted;
BUG_ON(extent_op && extent_op->is_data); BUG_ON(extent_op && extent_op->is_data);
ref = kmem_cache_alloc(btrfs_delayed_tree_ref_cachep, GFP_NOFS); ref = kmem_cache_alloc(btrfs_delayed_tree_ref_cachep, GFP_NOFS);
...@@ -806,12 +812,15 @@ int btrfs_add_delayed_tree_ref(struct btrfs_fs_info *fs_info, ...@@ -806,12 +812,15 @@ int btrfs_add_delayed_tree_ref(struct btrfs_fs_info *fs_info,
* the spin lock * the spin lock
*/ */
head_ref = add_delayed_ref_head(fs_info, trans, &head_ref->node, record, head_ref = add_delayed_ref_head(fs_info, trans, &head_ref->node, record,
bytenr, num_bytes, 0, 0, action, 0); bytenr, num_bytes, 0, 0, action, 0,
&qrecord_inserted);
add_delayed_tree_ref(fs_info, trans, head_ref, &ref->node, bytenr, add_delayed_tree_ref(fs_info, trans, head_ref, &ref->node, bytenr,
num_bytes, parent, ref_root, level, action); num_bytes, parent, ref_root, level, action);
spin_unlock(&delayed_refs->lock); spin_unlock(&delayed_refs->lock);
if (qrecord_inserted)
return btrfs_qgroup_trace_extent_post(fs_info, record);
return 0; return 0;
free_head_ref: free_head_ref:
...@@ -829,15 +838,14 @@ int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info, ...@@ -829,15 +838,14 @@ int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info,
struct btrfs_trans_handle *trans, struct btrfs_trans_handle *trans,
u64 bytenr, u64 num_bytes, u64 bytenr, u64 num_bytes,
u64 parent, u64 ref_root, u64 parent, u64 ref_root,
u64 owner, u64 offset, u64 reserved, int action, u64 owner, u64 offset, u64 reserved, int action)
struct btrfs_delayed_extent_op *extent_op)
{ {
struct btrfs_delayed_data_ref *ref; struct btrfs_delayed_data_ref *ref;
struct btrfs_delayed_ref_head *head_ref; struct btrfs_delayed_ref_head *head_ref;
struct btrfs_delayed_ref_root *delayed_refs; struct btrfs_delayed_ref_root *delayed_refs;
struct btrfs_qgroup_extent_record *record = NULL; struct btrfs_qgroup_extent_record *record = NULL;
int qrecord_inserted;
BUG_ON(extent_op && !extent_op->is_data);
ref = kmem_cache_alloc(btrfs_delayed_data_ref_cachep, GFP_NOFS); ref = kmem_cache_alloc(btrfs_delayed_data_ref_cachep, GFP_NOFS);
if (!ref) if (!ref)
return -ENOMEM; return -ENOMEM;
...@@ -859,7 +867,7 @@ int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info, ...@@ -859,7 +867,7 @@ int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info,
} }
} }
head_ref->extent_op = extent_op; head_ref->extent_op = NULL;
delayed_refs = &trans->transaction->delayed_refs; delayed_refs = &trans->transaction->delayed_refs;
spin_lock(&delayed_refs->lock); spin_lock(&delayed_refs->lock);
...@@ -870,13 +878,15 @@ int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info, ...@@ -870,13 +878,15 @@ int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info,
*/ */
head_ref = add_delayed_ref_head(fs_info, trans, &head_ref->node, record, head_ref = add_delayed_ref_head(fs_info, trans, &head_ref->node, record,
bytenr, num_bytes, ref_root, reserved, bytenr, num_bytes, ref_root, reserved,
action, 1); action, 1, &qrecord_inserted);
add_delayed_data_ref(fs_info, trans, head_ref, &ref->node, bytenr, add_delayed_data_ref(fs_info, trans, head_ref, &ref->node, bytenr,
num_bytes, parent, ref_root, owner, offset, num_bytes, parent, ref_root, owner, offset,
action); action);
spin_unlock(&delayed_refs->lock); spin_unlock(&delayed_refs->lock);
if (qrecord_inserted)
return btrfs_qgroup_trace_extent_post(fs_info, record);
return 0; return 0;
} }
...@@ -899,7 +909,7 @@ int btrfs_add_delayed_extent_op(struct btrfs_fs_info *fs_info, ...@@ -899,7 +909,7 @@ int btrfs_add_delayed_extent_op(struct btrfs_fs_info *fs_info,
add_delayed_ref_head(fs_info, trans, &head_ref->node, NULL, bytenr, add_delayed_ref_head(fs_info, trans, &head_ref->node, NULL, bytenr,
num_bytes, 0, 0, BTRFS_UPDATE_DELAYED_HEAD, num_bytes, 0, 0, BTRFS_UPDATE_DELAYED_HEAD,
extent_op->is_data); extent_op->is_data, NULL);
spin_unlock(&delayed_refs->lock); spin_unlock(&delayed_refs->lock);
return 0; return 0;
...@@ -911,11 +921,8 @@ int btrfs_add_delayed_extent_op(struct btrfs_fs_info *fs_info, ...@@ -911,11 +921,8 @@ int btrfs_add_delayed_extent_op(struct btrfs_fs_info *fs_info,
* the head node if any where found, or NULL if not. * the head node if any where found, or NULL if not.
*/ */
struct btrfs_delayed_ref_head * struct btrfs_delayed_ref_head *
btrfs_find_delayed_ref_head(struct btrfs_trans_handle *trans, u64 bytenr) btrfs_find_delayed_ref_head(struct btrfs_delayed_ref_root *delayed_refs, u64 bytenr)
{ {
struct btrfs_delayed_ref_root *delayed_refs;
delayed_refs = &trans->transaction->delayed_refs;
return find_ref_head(&delayed_refs->href_root, bytenr, 0); return find_ref_head(&delayed_refs->href_root, bytenr, 0);
} }
......
...@@ -250,8 +250,7 @@ int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info, ...@@ -250,8 +250,7 @@ int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info,
struct btrfs_trans_handle *trans, struct btrfs_trans_handle *trans,
u64 bytenr, u64 num_bytes, u64 bytenr, u64 num_bytes,
u64 parent, u64 ref_root, u64 parent, u64 ref_root,
u64 owner, u64 offset, u64 reserved, int action, u64 owner, u64 offset, u64 reserved, int action);
struct btrfs_delayed_extent_op *extent_op);
int btrfs_add_delayed_extent_op(struct btrfs_fs_info *fs_info, int btrfs_add_delayed_extent_op(struct btrfs_fs_info *fs_info,
struct btrfs_trans_handle *trans, struct btrfs_trans_handle *trans,
u64 bytenr, u64 num_bytes, u64 bytenr, u64 num_bytes,
...@@ -262,7 +261,8 @@ void btrfs_merge_delayed_refs(struct btrfs_trans_handle *trans, ...@@ -262,7 +261,8 @@ void btrfs_merge_delayed_refs(struct btrfs_trans_handle *trans,
struct btrfs_delayed_ref_head *head); struct btrfs_delayed_ref_head *head);
struct btrfs_delayed_ref_head * struct btrfs_delayed_ref_head *
btrfs_find_delayed_ref_head(struct btrfs_trans_handle *trans, u64 bytenr); btrfs_find_delayed_ref_head(struct btrfs_delayed_ref_root *delayed_refs,
u64 bytenr);
int btrfs_delayed_ref_lock(struct btrfs_trans_handle *trans, int btrfs_delayed_ref_lock(struct btrfs_trans_handle *trans,
struct btrfs_delayed_ref_head *head); struct btrfs_delayed_ref_head *head);
static inline void btrfs_delayed_ref_unlock(struct btrfs_delayed_ref_head *head) static inline void btrfs_delayed_ref_unlock(struct btrfs_delayed_ref_head *head)
......
...@@ -133,7 +133,7 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root ...@@ -133,7 +133,7 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
struct btrfs_disk_key disk_key; struct btrfs_disk_key disk_key;
u32 data_size; u32 data_size;
key.objectid = btrfs_ino(dir); key.objectid = btrfs_ino(BTRFS_I(dir));
key.type = BTRFS_DIR_ITEM_KEY; key.type = BTRFS_DIR_ITEM_KEY;
key.offset = btrfs_name_hash(name, name_len); key.offset = btrfs_name_hash(name, name_len);
...@@ -174,8 +174,7 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root ...@@ -174,8 +174,7 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
btrfs_release_path(path); btrfs_release_path(path);
ret2 = btrfs_insert_delayed_dir_index(trans, root->fs_info, name, ret2 = btrfs_insert_delayed_dir_index(trans, root->fs_info, name,
name_len, dir, &disk_key, type, name_len, BTRFS_I(dir), &disk_key, type, index);
index);
out_free: out_free:
btrfs_free_path(path); btrfs_free_path(path);
if (ret) if (ret)
......
...@@ -64,8 +64,7 @@ ...@@ -64,8 +64,7 @@
static const struct extent_io_ops btree_extent_io_ops; static const struct extent_io_ops btree_extent_io_ops;
static void end_workqueue_fn(struct btrfs_work *work); static void end_workqueue_fn(struct btrfs_work *work);
static void free_fs_root(struct btrfs_root *root); static void free_fs_root(struct btrfs_root *root);
static int btrfs_check_super_valid(struct btrfs_fs_info *fs_info, static int btrfs_check_super_valid(struct btrfs_fs_info *fs_info);
int read_only);
static void btrfs_destroy_ordered_extents(struct btrfs_root *root); static void btrfs_destroy_ordered_extents(struct btrfs_root *root);
static int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans, static int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans,
struct btrfs_fs_info *fs_info); struct btrfs_fs_info *fs_info);
...@@ -1005,7 +1004,7 @@ static int __btree_submit_bio_done(struct inode *inode, struct bio *bio, ...@@ -1005,7 +1004,7 @@ static int __btree_submit_bio_done(struct inode *inode, struct bio *bio,
return ret; return ret;
} }
static int check_async_write(struct inode *inode, unsigned long bio_flags) static int check_async_write(unsigned long bio_flags)
{ {
if (bio_flags & EXTENT_BIO_TREE_LOG) if (bio_flags & EXTENT_BIO_TREE_LOG)
return 0; return 0;
...@@ -1021,7 +1020,7 @@ static int btree_submit_bio_hook(struct inode *inode, struct bio *bio, ...@@ -1021,7 +1020,7 @@ static int btree_submit_bio_hook(struct inode *inode, struct bio *bio,
u64 bio_offset) u64 bio_offset)
{ {
struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
int async = check_async_write(inode, bio_flags); int async = check_async_write(bio_flags);
int ret; int ret;
if (bio_op(bio) != REQ_OP_WRITE) { if (bio_op(bio) != REQ_OP_WRITE) {
...@@ -1248,8 +1247,7 @@ struct extent_buffer *read_tree_block(struct btrfs_fs_info *fs_info, u64 bytenr, ...@@ -1248,8 +1247,7 @@ struct extent_buffer *read_tree_block(struct btrfs_fs_info *fs_info, u64 bytenr,
} }
void clean_tree_block(struct btrfs_trans_handle *trans, void clean_tree_block(struct btrfs_fs_info *fs_info,
struct btrfs_fs_info *fs_info,
struct extent_buffer *buf) struct extent_buffer *buf)
{ {
if (btrfs_header_generation(buf) == if (btrfs_header_generation(buf) ==
...@@ -2802,7 +2800,7 @@ int open_ctree(struct super_block *sb, ...@@ -2802,7 +2800,7 @@ int open_ctree(struct super_block *sb,
memcpy(fs_info->fsid, fs_info->super_copy->fsid, BTRFS_FSID_SIZE); memcpy(fs_info->fsid, fs_info->super_copy->fsid, BTRFS_FSID_SIZE);
ret = btrfs_check_super_valid(fs_info, sb->s_flags & MS_RDONLY); ret = btrfs_check_super_valid(fs_info);
if (ret) { if (ret) {
btrfs_err(fs_info, "superblock contains fatal errors"); btrfs_err(fs_info, "superblock contains fatal errors");
err = -EINVAL; err = -EINVAL;
...@@ -3411,7 +3409,7 @@ struct buffer_head *btrfs_read_dev_super(struct block_device *bdev) ...@@ -3411,7 +3409,7 @@ struct buffer_head *btrfs_read_dev_super(struct block_device *bdev)
*/ */
static int write_dev_supers(struct btrfs_device *device, static int write_dev_supers(struct btrfs_device *device,
struct btrfs_super_block *sb, struct btrfs_super_block *sb,
int do_barriers, int wait, int max_mirrors) int wait, int max_mirrors)
{ {
struct buffer_head *bh; struct buffer_head *bh;
int i; int i;
...@@ -3696,7 +3694,7 @@ int btrfs_calc_num_tolerated_disk_barrier_failures( ...@@ -3696,7 +3694,7 @@ int btrfs_calc_num_tolerated_disk_barrier_failures(
return num_tolerated_disk_barrier_failures; return num_tolerated_disk_barrier_failures;
} }
static int write_all_supers(struct btrfs_fs_info *fs_info, int max_mirrors) int write_all_supers(struct btrfs_fs_info *fs_info, int max_mirrors)
{ {
struct list_head *head; struct list_head *head;
struct btrfs_device *dev; struct btrfs_device *dev;
...@@ -3753,7 +3751,7 @@ static int write_all_supers(struct btrfs_fs_info *fs_info, int max_mirrors) ...@@ -3753,7 +3751,7 @@ static int write_all_supers(struct btrfs_fs_info *fs_info, int max_mirrors)
flags = btrfs_super_flags(sb); flags = btrfs_super_flags(sb);
btrfs_set_super_flags(sb, flags | BTRFS_HEADER_FLAG_WRITTEN); btrfs_set_super_flags(sb, flags | BTRFS_HEADER_FLAG_WRITTEN);
ret = write_dev_supers(dev, sb, do_barriers, 0, max_mirrors); ret = write_dev_supers(dev, sb, 0, max_mirrors);
if (ret) if (ret)
total_errors++; total_errors++;
} }
...@@ -3776,7 +3774,7 @@ static int write_all_supers(struct btrfs_fs_info *fs_info, int max_mirrors) ...@@ -3776,7 +3774,7 @@ static int write_all_supers(struct btrfs_fs_info *fs_info, int max_mirrors)
if (!dev->in_fs_metadata || !dev->writeable) if (!dev->in_fs_metadata || !dev->writeable)
continue; continue;
ret = write_dev_supers(dev, sb, do_barriers, 1, max_mirrors); ret = write_dev_supers(dev, sb, 1, max_mirrors);
if (ret) if (ret)
total_errors++; total_errors++;
} }
...@@ -3790,12 +3788,6 @@ static int write_all_supers(struct btrfs_fs_info *fs_info, int max_mirrors) ...@@ -3790,12 +3788,6 @@ static int write_all_supers(struct btrfs_fs_info *fs_info, int max_mirrors)
return 0; return 0;
} }
int write_ctree_super(struct btrfs_trans_handle *trans,
struct btrfs_fs_info *fs_info, int max_mirrors)
{
return write_all_supers(fs_info, max_mirrors);
}
/* Drop a fs root from the radix tree and free it. */ /* Drop a fs root from the radix tree and free it. */
void btrfs_drop_and_free_fs_root(struct btrfs_fs_info *fs_info, void btrfs_drop_and_free_fs_root(struct btrfs_fs_info *fs_info,
struct btrfs_root *root) struct btrfs_root *root)
...@@ -4122,8 +4114,7 @@ int btrfs_read_buffer(struct extent_buffer *buf, u64 parent_transid) ...@@ -4122,8 +4114,7 @@ int btrfs_read_buffer(struct extent_buffer *buf, u64 parent_transid)
return btree_read_extent_buffer_pages(fs_info, buf, parent_transid); return btree_read_extent_buffer_pages(fs_info, buf, parent_transid);
} }
static int btrfs_check_super_valid(struct btrfs_fs_info *fs_info, static int btrfs_check_super_valid(struct btrfs_fs_info *fs_info)
int read_only)
{ {
struct btrfs_super_block *sb = fs_info->super_copy; struct btrfs_super_block *sb = fs_info->super_copy;
u64 nodesize = btrfs_super_nodesize(sb); u64 nodesize = btrfs_super_nodesize(sb);
......
...@@ -52,14 +52,12 @@ int reada_tree_block_flagged(struct btrfs_fs_info *fs_info, u64 bytenr, ...@@ -52,14 +52,12 @@ int reada_tree_block_flagged(struct btrfs_fs_info *fs_info, u64 bytenr,
struct extent_buffer *btrfs_find_create_tree_block( struct extent_buffer *btrfs_find_create_tree_block(
struct btrfs_fs_info *fs_info, struct btrfs_fs_info *fs_info,
u64 bytenr); u64 bytenr);
void clean_tree_block(struct btrfs_trans_handle *trans, void clean_tree_block(struct btrfs_fs_info *fs_info, struct extent_buffer *buf);
struct btrfs_fs_info *fs_info, struct extent_buffer *buf);
int open_ctree(struct super_block *sb, int open_ctree(struct super_block *sb,
struct btrfs_fs_devices *fs_devices, struct btrfs_fs_devices *fs_devices,
char *options); char *options);
void close_ctree(struct btrfs_fs_info *fs_info); void close_ctree(struct btrfs_fs_info *fs_info);
int write_ctree_super(struct btrfs_trans_handle *trans, int write_all_supers(struct btrfs_fs_info *fs_info, int max_mirrors);
struct btrfs_fs_info *fs_info, int max_mirrors);
struct buffer_head *btrfs_read_dev_super(struct block_device *bdev); struct buffer_head *btrfs_read_dev_super(struct block_device *bdev);
int btrfs_read_dev_one_super(struct block_device *bdev, int copy_num, int btrfs_read_dev_one_super(struct block_device *bdev, int copy_num,
struct buffer_head **bh_ret); struct buffer_head **bh_ret);
......
...@@ -30,7 +30,7 @@ static int btrfs_encode_fh(struct inode *inode, u32 *fh, int *max_len, ...@@ -30,7 +30,7 @@ static int btrfs_encode_fh(struct inode *inode, u32 *fh, int *max_len,
len = BTRFS_FID_SIZE_NON_CONNECTABLE; len = BTRFS_FID_SIZE_NON_CONNECTABLE;
type = FILEID_BTRFS_WITHOUT_PARENT; type = FILEID_BTRFS_WITHOUT_PARENT;
fid->objectid = btrfs_ino(inode); fid->objectid = btrfs_ino(BTRFS_I(inode));
fid->root_objectid = BTRFS_I(inode)->root->objectid; fid->root_objectid = BTRFS_I(inode)->root->objectid;
fid->gen = inode->i_generation; fid->gen = inode->i_generation;
...@@ -166,13 +166,13 @@ static struct dentry *btrfs_get_parent(struct dentry *child) ...@@ -166,13 +166,13 @@ static struct dentry *btrfs_get_parent(struct dentry *child)
if (!path) if (!path)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
if (btrfs_ino(dir) == BTRFS_FIRST_FREE_OBJECTID) { if (btrfs_ino(BTRFS_I(dir)) == BTRFS_FIRST_FREE_OBJECTID) {
key.objectid = root->root_key.objectid; key.objectid = root->root_key.objectid;
key.type = BTRFS_ROOT_BACKREF_KEY; key.type = BTRFS_ROOT_BACKREF_KEY;
key.offset = (u64)-1; key.offset = (u64)-1;
root = fs_info->tree_root; root = fs_info->tree_root;
} else { } else {
key.objectid = btrfs_ino(dir); key.objectid = btrfs_ino(BTRFS_I(dir));
key.type = BTRFS_INODE_REF_KEY; key.type = BTRFS_INODE_REF_KEY;
key.offset = (u64)-1; key.offset = (u64)-1;
} }
...@@ -235,13 +235,10 @@ static int btrfs_get_name(struct dentry *parent, char *name, ...@@ -235,13 +235,10 @@ static int btrfs_get_name(struct dentry *parent, char *name,
int ret; int ret;
u64 ino; u64 ino;
if (!dir || !inode)
return -EINVAL;
if (!S_ISDIR(dir->i_mode)) if (!S_ISDIR(dir->i_mode))
return -EINVAL; return -EINVAL;
ino = btrfs_ino(inode); ino = btrfs_ino(BTRFS_I(inode));
path = btrfs_alloc_path(); path = btrfs_alloc_path();
if (!path) if (!path)
...@@ -255,7 +252,7 @@ static int btrfs_get_name(struct dentry *parent, char *name, ...@@ -255,7 +252,7 @@ static int btrfs_get_name(struct dentry *parent, char *name,
root = fs_info->tree_root; root = fs_info->tree_root;
} else { } else {
key.objectid = ino; key.objectid = ino;
key.offset = btrfs_ino(dir); key.offset = btrfs_ino(BTRFS_I(dir));
key.type = BTRFS_INODE_REF_KEY; key.type = BTRFS_INODE_REF_KEY;
} }
......
此差异已折叠。
...@@ -98,7 +98,7 @@ static inline void __btrfs_debug_check_extent_io_range(const char *caller, ...@@ -98,7 +98,7 @@ static inline void __btrfs_debug_check_extent_io_range(const char *caller,
if (end >= PAGE_SIZE && (end % 2) == 0 && end != isize - 1) { if (end >= PAGE_SIZE && (end % 2) == 0 && end != isize - 1) {
btrfs_debug_rl(BTRFS_I(inode)->root->fs_info, btrfs_debug_rl(BTRFS_I(inode)->root->fs_info,
"%s: ino %llu isize %llu odd range [%llu,%llu]", "%s: ino %llu isize %llu odd range [%llu,%llu]",
caller, btrfs_ino(inode), isize, start, end); caller, btrfs_ino(BTRFS_I(inode)), isize, start, end);
} }
} }
#else #else
...@@ -144,7 +144,7 @@ static void add_extent_changeset(struct extent_state *state, unsigned bits, ...@@ -144,7 +144,7 @@ static void add_extent_changeset(struct extent_state *state, unsigned bits,
if (!set && (state->state & bits) == 0) if (!set && (state->state & bits) == 0)
return; return;
changeset->bytes_changed += state->end - state->start + 1; changeset->bytes_changed += state->end - state->start + 1;
ret = ulist_add(changeset->range_changed, state->start, state->end, ret = ulist_add(&changeset->range_changed, state->start, state->end,
GFP_ATOMIC); GFP_ATOMIC);
/* ENOMEM */ /* ENOMEM */
BUG_ON(ret < 0); BUG_ON(ret < 0);
...@@ -226,6 +226,11 @@ static struct extent_state *alloc_extent_state(gfp_t mask) ...@@ -226,6 +226,11 @@ static struct extent_state *alloc_extent_state(gfp_t mask)
{ {
struct extent_state *state; struct extent_state *state;
/*
* The given mask might be not appropriate for the slab allocator,
* drop the unsupported bits
*/
mask &= ~(__GFP_DMA32|__GFP_HIGHMEM);
state = kmem_cache_alloc(extent_state_cache, mask); state = kmem_cache_alloc(extent_state_cache, mask);
if (!state) if (!state)
return state; return state;
...@@ -1549,33 +1554,24 @@ static noinline u64 find_delalloc_range(struct extent_io_tree *tree, ...@@ -1549,33 +1554,24 @@ static noinline u64 find_delalloc_range(struct extent_io_tree *tree,
return found; return found;
} }
static int __process_pages_contig(struct address_space *mapping,
struct page *locked_page,
pgoff_t start_index, pgoff_t end_index,
unsigned long page_ops, pgoff_t *index_ret);
static noinline void __unlock_for_delalloc(struct inode *inode, static noinline void __unlock_for_delalloc(struct inode *inode,
struct page *locked_page, struct page *locked_page,
u64 start, u64 end) u64 start, u64 end)
{ {
int ret;
struct page *pages[16];
unsigned long index = start >> PAGE_SHIFT; unsigned long index = start >> PAGE_SHIFT;
unsigned long end_index = end >> PAGE_SHIFT; unsigned long end_index = end >> PAGE_SHIFT;
unsigned long nr_pages = end_index - index + 1;
int i;
ASSERT(locked_page);
if (index == locked_page->index && end_index == index) if (index == locked_page->index && end_index == index)
return; return;
while (nr_pages > 0) { __process_pages_contig(inode->i_mapping, locked_page, index, end_index,
ret = find_get_pages_contig(inode->i_mapping, index, PAGE_UNLOCK, NULL);
min_t(unsigned long, nr_pages,
ARRAY_SIZE(pages)), pages);
for (i = 0; i < ret; i++) {
if (pages[i] != locked_page)
unlock_page(pages[i]);
put_page(pages[i]);
}
nr_pages -= ret;
index += ret;
cond_resched();
}
} }
static noinline int lock_delalloc_pages(struct inode *inode, static noinline int lock_delalloc_pages(struct inode *inode,
...@@ -1584,59 +1580,19 @@ static noinline int lock_delalloc_pages(struct inode *inode, ...@@ -1584,59 +1580,19 @@ static noinline int lock_delalloc_pages(struct inode *inode,
u64 delalloc_end) u64 delalloc_end)
{ {
unsigned long index = delalloc_start >> PAGE_SHIFT; unsigned long index = delalloc_start >> PAGE_SHIFT;
unsigned long start_index = index; unsigned long index_ret = index;
unsigned long end_index = delalloc_end >> PAGE_SHIFT; unsigned long end_index = delalloc_end >> PAGE_SHIFT;
unsigned long pages_locked = 0;
struct page *pages[16];
unsigned long nrpages;
int ret; int ret;
int i;
/* the caller is responsible for locking the start index */ ASSERT(locked_page);
if (index == locked_page->index && index == end_index) if (index == locked_page->index && index == end_index)
return 0; return 0;
/* skip the page at the start index */ ret = __process_pages_contig(inode->i_mapping, locked_page, index,
nrpages = end_index - index + 1; end_index, PAGE_LOCK, &index_ret);
while (nrpages > 0) { if (ret == -EAGAIN)
ret = find_get_pages_contig(inode->i_mapping, index, __unlock_for_delalloc(inode, locked_page, delalloc_start,
min_t(unsigned long, (u64)index_ret << PAGE_SHIFT);
nrpages, ARRAY_SIZE(pages)), pages);
if (ret == 0) {
ret = -EAGAIN;
goto done;
}
/* now we have an array of pages, lock them all */
for (i = 0; i < ret; i++) {
/*
* the caller is taking responsibility for
* locked_page
*/
if (pages[i] != locked_page) {
lock_page(pages[i]);
if (!PageDirty(pages[i]) ||
pages[i]->mapping != inode->i_mapping) {
ret = -EAGAIN;
unlock_page(pages[i]);
put_page(pages[i]);
goto done;
}
}
put_page(pages[i]);
pages_locked++;
}
nrpages -= ret;
index += ret;
cond_resched();
}
ret = 0;
done:
if (ret && pages_locked) {
__unlock_for_delalloc(inode, locked_page,
delalloc_start,
((u64)(start_index + pages_locked - 1)) <<
PAGE_SHIFT);
}
return ret; return ret;
} }
...@@ -1726,37 +1682,47 @@ STATIC u64 find_lock_delalloc_range(struct inode *inode, ...@@ -1726,37 +1682,47 @@ STATIC u64 find_lock_delalloc_range(struct inode *inode,
return found; return found;
} }
void extent_clear_unlock_delalloc(struct inode *inode, u64 start, u64 end, static int __process_pages_contig(struct address_space *mapping,
u64 delalloc_end, struct page *locked_page, struct page *locked_page,
unsigned clear_bits, pgoff_t start_index, pgoff_t end_index,
unsigned long page_ops) unsigned long page_ops, pgoff_t *index_ret)
{ {
struct extent_io_tree *tree = &BTRFS_I(inode)->io_tree; unsigned long nr_pages = end_index - start_index + 1;
int ret; unsigned long pages_locked = 0;
pgoff_t index = start_index;
struct page *pages[16]; struct page *pages[16];
unsigned long index = start >> PAGE_SHIFT; unsigned ret;
unsigned long end_index = end >> PAGE_SHIFT; int err = 0;
unsigned long nr_pages = end_index - index + 1;
int i; int i;
clear_extent_bit(tree, start, end, clear_bits, 1, 0, NULL, GFP_NOFS); if (page_ops & PAGE_LOCK) {
if (page_ops == 0) ASSERT(page_ops == PAGE_LOCK);
return; ASSERT(index_ret && *index_ret == start_index);
}
if ((page_ops & PAGE_SET_ERROR) && nr_pages > 0) if ((page_ops & PAGE_SET_ERROR) && nr_pages > 0)
mapping_set_error(inode->i_mapping, -EIO); mapping_set_error(mapping, -EIO);
while (nr_pages > 0) { while (nr_pages > 0) {
ret = find_get_pages_contig(inode->i_mapping, index, ret = find_get_pages_contig(mapping, index,
min_t(unsigned long, min_t(unsigned long,
nr_pages, ARRAY_SIZE(pages)), pages); nr_pages, ARRAY_SIZE(pages)), pages);
for (i = 0; i < ret; i++) { if (ret == 0) {
/*
* Only if we're going to lock these pages,
* can we find nothing at @index.
*/
ASSERT(page_ops & PAGE_LOCK);
return ret;
}
for (i = 0; i < ret; i++) {
if (page_ops & PAGE_SET_PRIVATE2) if (page_ops & PAGE_SET_PRIVATE2)
SetPagePrivate2(pages[i]); SetPagePrivate2(pages[i]);
if (pages[i] == locked_page) { if (pages[i] == locked_page) {
put_page(pages[i]); put_page(pages[i]);
pages_locked++;
continue; continue;
} }
if (page_ops & PAGE_CLEAR_DIRTY) if (page_ops & PAGE_CLEAR_DIRTY)
...@@ -1769,12 +1735,40 @@ void extent_clear_unlock_delalloc(struct inode *inode, u64 start, u64 end, ...@@ -1769,12 +1735,40 @@ void extent_clear_unlock_delalloc(struct inode *inode, u64 start, u64 end,
end_page_writeback(pages[i]); end_page_writeback(pages[i]);
if (page_ops & PAGE_UNLOCK) if (page_ops & PAGE_UNLOCK)
unlock_page(pages[i]); unlock_page(pages[i]);
if (page_ops & PAGE_LOCK) {
lock_page(pages[i]);
if (!PageDirty(pages[i]) ||
pages[i]->mapping != mapping) {
unlock_page(pages[i]);
put_page(pages[i]);
err = -EAGAIN;
goto out;
}
}
put_page(pages[i]); put_page(pages[i]);
pages_locked++;
} }
nr_pages -= ret; nr_pages -= ret;
index += ret; index += ret;
cond_resched(); cond_resched();
} }
out:
if (err && index_ret)
*index_ret = start_index + pages_locked - 1;
return err;
}
void extent_clear_unlock_delalloc(struct inode *inode, u64 start, u64 end,
u64 delalloc_end, struct page *locked_page,
unsigned clear_bits,
unsigned long page_ops)
{
clear_extent_bit(&BTRFS_I(inode)->io_tree, start, end, clear_bits, 1, 0,
NULL, GFP_NOFS);
__process_pages_contig(inode->i_mapping, locked_page,
start >> PAGE_SHIFT, end >> PAGE_SHIFT,
page_ops, NULL);
} }
/* /*
...@@ -2060,7 +2054,7 @@ int repair_io_failure(struct inode *inode, u64 start, u64 length, u64 logical, ...@@ -2060,7 +2054,7 @@ int repair_io_failure(struct inode *inode, u64 start, u64 length, u64 logical,
btrfs_info_rl_in_rcu(fs_info, btrfs_info_rl_in_rcu(fs_info,
"read error corrected: ino %llu off %llu (dev %s sector %llu)", "read error corrected: ino %llu off %llu (dev %s sector %llu)",
btrfs_ino(inode), start, btrfs_ino(BTRFS_I(inode)), start,
rcu_str_deref(dev->name), sector); rcu_str_deref(dev->name), sector);
btrfs_bio_counter_dec(fs_info); btrfs_bio_counter_dec(fs_info);
bio_put(bio); bio_put(bio);
...@@ -2765,7 +2759,6 @@ static int submit_extent_page(int op, int op_flags, struct extent_io_tree *tree, ...@@ -2765,7 +2759,6 @@ static int submit_extent_page(int op, int op_flags, struct extent_io_tree *tree,
size_t size, unsigned long offset, size_t size, unsigned long offset,
struct block_device *bdev, struct block_device *bdev,
struct bio **bio_ret, struct bio **bio_ret,
unsigned long max_pages,
bio_end_io_t end_io_func, bio_end_io_t end_io_func,
int mirror_num, int mirror_num,
unsigned long prev_bio_flags, unsigned long prev_bio_flags,
...@@ -2931,7 +2924,6 @@ static int __do_readpage(struct extent_io_tree *tree, ...@@ -2931,7 +2924,6 @@ static int __do_readpage(struct extent_io_tree *tree,
} }
} }
while (cur <= end) { while (cur <= end) {
unsigned long pnr = (last_byte >> PAGE_SHIFT) + 1;
bool force_bio_submit = false; bool force_bio_submit = false;
if (cur >= last_byte) { if (cur >= last_byte) {
...@@ -3066,10 +3058,9 @@ static int __do_readpage(struct extent_io_tree *tree, ...@@ -3066,10 +3058,9 @@ static int __do_readpage(struct extent_io_tree *tree,
continue; continue;
} }
pnr -= page->index;
ret = submit_extent_page(REQ_OP_READ, read_flags, tree, NULL, ret = submit_extent_page(REQ_OP_READ, read_flags, tree, NULL,
page, sector, disk_io_size, pg_offset, page, sector, disk_io_size, pg_offset,
bdev, bio, pnr, bdev, bio,
end_bio_extent_readpage, mirror_num, end_bio_extent_readpage, mirror_num,
*bio_flags, *bio_flags,
this_bio_flag, this_bio_flag,
...@@ -3210,7 +3201,7 @@ int extent_read_full_page(struct extent_io_tree *tree, struct page *page, ...@@ -3210,7 +3201,7 @@ int extent_read_full_page(struct extent_io_tree *tree, struct page *page,
return ret; return ret;
} }
static void update_nr_written(struct page *page, struct writeback_control *wbc, static void update_nr_written(struct writeback_control *wbc,
unsigned long nr_written) unsigned long nr_written)
{ {
wbc->nr_to_write -= nr_written; wbc->nr_to_write -= nr_written;
...@@ -3330,7 +3321,6 @@ static noinline_for_stack int __extent_writepage_io(struct inode *inode, ...@@ -3330,7 +3321,6 @@ static noinline_for_stack int __extent_writepage_io(struct inode *inode,
u64 block_start; u64 block_start;
u64 iosize; u64 iosize;
sector_t sector; sector_t sector;
struct extent_state *cached_state = NULL;
struct extent_map *em; struct extent_map *em;
struct block_device *bdev; struct block_device *bdev;
size_t pg_offset = 0; size_t pg_offset = 0;
...@@ -3349,10 +3339,9 @@ static noinline_for_stack int __extent_writepage_io(struct inode *inode, ...@@ -3349,10 +3339,9 @@ static noinline_for_stack int __extent_writepage_io(struct inode *inode,
else else
redirty_page_for_writepage(wbc, page); redirty_page_for_writepage(wbc, page);
update_nr_written(page, wbc, nr_written); update_nr_written(wbc, nr_written);
unlock_page(page); unlock_page(page);
ret = 1; return 1;
goto done_unlocked;
} }
} }
...@@ -3360,7 +3349,7 @@ static noinline_for_stack int __extent_writepage_io(struct inode *inode, ...@@ -3360,7 +3349,7 @@ static noinline_for_stack int __extent_writepage_io(struct inode *inode,
* we don't want to touch the inode after unlocking the page, * we don't want to touch the inode after unlocking the page,
* so we update the mapping writeback index now * so we update the mapping writeback index now
*/ */
update_nr_written(page, wbc, nr_written + 1); update_nr_written(wbc, nr_written + 1);
end = page_end; end = page_end;
if (i_size <= start) { if (i_size <= start) {
...@@ -3374,7 +3363,6 @@ static noinline_for_stack int __extent_writepage_io(struct inode *inode, ...@@ -3374,7 +3363,6 @@ static noinline_for_stack int __extent_writepage_io(struct inode *inode,
while (cur <= end) { while (cur <= end) {
u64 em_end; u64 em_end;
unsigned long max_nr;
if (cur >= i_size) { if (cur >= i_size) {
if (tree->ops && tree->ops->writepage_end_io_hook) if (tree->ops && tree->ops->writepage_end_io_hook)
...@@ -3431,8 +3419,6 @@ static noinline_for_stack int __extent_writepage_io(struct inode *inode, ...@@ -3431,8 +3419,6 @@ static noinline_for_stack int __extent_writepage_io(struct inode *inode,
continue; continue;
} }
max_nr = (i_size >> PAGE_SHIFT) + 1;
set_range_writeback(tree, cur, cur + iosize - 1); set_range_writeback(tree, cur, cur + iosize - 1);
if (!PageWriteback(page)) { if (!PageWriteback(page)) {
btrfs_err(BTRFS_I(inode)->root->fs_info, btrfs_err(BTRFS_I(inode)->root->fs_info,
...@@ -3442,11 +3428,14 @@ static noinline_for_stack int __extent_writepage_io(struct inode *inode, ...@@ -3442,11 +3428,14 @@ static noinline_for_stack int __extent_writepage_io(struct inode *inode,
ret = submit_extent_page(REQ_OP_WRITE, write_flags, tree, wbc, ret = submit_extent_page(REQ_OP_WRITE, write_flags, tree, wbc,
page, sector, iosize, pg_offset, page, sector, iosize, pg_offset,
bdev, &epd->bio, max_nr, bdev, &epd->bio,
end_bio_extent_writepage, end_bio_extent_writepage,
0, 0, 0, false); 0, 0, 0, false);
if (ret) if (ret) {
SetPageError(page); SetPageError(page);
if (PageWriteback(page))
end_page_writeback(page);
}
cur = cur + iosize; cur = cur + iosize;
pg_offset += iosize; pg_offset += iosize;
...@@ -3454,11 +3443,6 @@ static noinline_for_stack int __extent_writepage_io(struct inode *inode, ...@@ -3454,11 +3443,6 @@ static noinline_for_stack int __extent_writepage_io(struct inode *inode,
} }
done: done:
*nr_ret = nr; *nr_ret = nr;
done_unlocked:
/* drop our reference on any cached states */
free_extent_state(cached_state);
return ret; return ret;
} }
...@@ -3761,20 +3745,21 @@ static noinline_for_stack int write_one_eb(struct extent_buffer *eb, ...@@ -3761,20 +3745,21 @@ static noinline_for_stack int write_one_eb(struct extent_buffer *eb,
set_page_writeback(p); set_page_writeback(p);
ret = submit_extent_page(REQ_OP_WRITE, write_flags, tree, wbc, ret = submit_extent_page(REQ_OP_WRITE, write_flags, tree, wbc,
p, offset >> 9, PAGE_SIZE, 0, bdev, p, offset >> 9, PAGE_SIZE, 0, bdev,
&epd->bio, -1, &epd->bio,
end_bio_extent_buffer_writepage, end_bio_extent_buffer_writepage,
0, epd->bio_flags, bio_flags, false); 0, epd->bio_flags, bio_flags, false);
epd->bio_flags = bio_flags; epd->bio_flags = bio_flags;
if (ret) { if (ret) {
set_btree_ioerr(p); set_btree_ioerr(p);
end_page_writeback(p); if (PageWriteback(p))
end_page_writeback(p);
if (atomic_sub_and_test(num_pages - i, &eb->io_pages)) if (atomic_sub_and_test(num_pages - i, &eb->io_pages))
end_extent_buffer_writeback(eb); end_extent_buffer_writeback(eb);
ret = -EIO; ret = -EIO;
break; break;
} }
offset += PAGE_SIZE; offset += PAGE_SIZE;
update_nr_written(p, wbc, 1); update_nr_written(wbc, 1);
unlock_page(p); unlock_page(p);
} }
...@@ -3926,8 +3911,7 @@ int btree_write_cache_pages(struct address_space *mapping, ...@@ -3926,8 +3911,7 @@ int btree_write_cache_pages(struct address_space *mapping,
* WB_SYNC_ALL then we were called for data integrity and we must wait for * WB_SYNC_ALL then we were called for data integrity and we must wait for
* existing IO to complete. * existing IO to complete.
*/ */
static int extent_write_cache_pages(struct extent_io_tree *tree, static int extent_write_cache_pages(struct address_space *mapping,
struct address_space *mapping,
struct writeback_control *wbc, struct writeback_control *wbc,
writepage_t writepage, void *data, writepage_t writepage, void *data,
void (*flush_fn)(void *)) void (*flush_fn)(void *))
...@@ -4168,8 +4152,7 @@ int extent_writepages(struct extent_io_tree *tree, ...@@ -4168,8 +4152,7 @@ int extent_writepages(struct extent_io_tree *tree,
.bio_flags = 0, .bio_flags = 0,
}; };
ret = extent_write_cache_pages(tree, mapping, wbc, ret = extent_write_cache_pages(mapping, wbc, __extent_writepage, &epd,
__extent_writepage, &epd,
flush_write_bio); flush_write_bio);
flush_epd_write_bio(&epd); flush_epd_write_bio(&epd);
return ret; return ret;
...@@ -4264,8 +4247,6 @@ static int try_release_extent_state(struct extent_map_tree *map, ...@@ -4264,8 +4247,6 @@ static int try_release_extent_state(struct extent_map_tree *map,
EXTENT_IOBITS, 0, NULL)) EXTENT_IOBITS, 0, NULL))
ret = 0; ret = 0;
else { else {
if ((mask & GFP_NOFS) == GFP_NOFS)
mask = GFP_NOFS;
/* /*
* at this point we can safely clear everything except the * at this point we can safely clear everything except the
* locked bit and the nodatasum bit * locked bit and the nodatasum bit
...@@ -4410,8 +4391,8 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, ...@@ -4410,8 +4391,8 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
* lookup the last file extent. We're not using i_size here * lookup the last file extent. We're not using i_size here
* because there might be preallocation past i_size * because there might be preallocation past i_size
*/ */
ret = btrfs_lookup_file_extent(NULL, root, path, btrfs_ino(inode), -1, ret = btrfs_lookup_file_extent(NULL, root, path,
0); btrfs_ino(BTRFS_I(inode)), -1, 0);
if (ret < 0) { if (ret < 0) {
btrfs_free_path(path); btrfs_free_path(path);
return ret; return ret;
...@@ -4426,7 +4407,7 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, ...@@ -4426,7 +4407,7 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
found_type = found_key.type; found_type = found_key.type;
/* No extents, but there might be delalloc bits */ /* No extents, but there might be delalloc bits */
if (found_key.objectid != btrfs_ino(inode) || if (found_key.objectid != btrfs_ino(BTRFS_I(inode)) ||
found_type != BTRFS_EXTENT_DATA_KEY) { found_type != BTRFS_EXTENT_DATA_KEY) {
/* have to trust i_size as the end */ /* have to trust i_size as the end */
last = (u64)-1; last = (u64)-1;
...@@ -4535,8 +4516,8 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, ...@@ -4535,8 +4516,8 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
* lookup stuff. * lookup stuff.
*/ */
ret = btrfs_check_shared(trans, root->fs_info, ret = btrfs_check_shared(trans, root->fs_info,
root->objectid, root->objectid,
btrfs_ino(inode), bytenr); btrfs_ino(BTRFS_I(inode)), bytenr);
if (trans) if (trans)
btrfs_end_transaction(trans); btrfs_end_transaction(trans);
if (ret < 0) if (ret < 0)
......
...@@ -45,13 +45,14 @@ ...@@ -45,13 +45,14 @@
#define EXTENT_BUFFER_IN_TREE 10 #define EXTENT_BUFFER_IN_TREE 10
#define EXTENT_BUFFER_WRITE_ERR 11 /* write IO error */ #define EXTENT_BUFFER_WRITE_ERR 11 /* write IO error */
/* these are flags for extent_clear_unlock_delalloc */ /* these are flags for __process_pages_contig */
#define PAGE_UNLOCK (1 << 0) #define PAGE_UNLOCK (1 << 0)
#define PAGE_CLEAR_DIRTY (1 << 1) #define PAGE_CLEAR_DIRTY (1 << 1)
#define PAGE_SET_WRITEBACK (1 << 2) #define PAGE_SET_WRITEBACK (1 << 2)
#define PAGE_END_WRITEBACK (1 << 3) #define PAGE_END_WRITEBACK (1 << 3)
#define PAGE_SET_PRIVATE2 (1 << 4) #define PAGE_SET_PRIVATE2 (1 << 4)
#define PAGE_SET_ERROR (1 << 5) #define PAGE_SET_ERROR (1 << 5)
#define PAGE_LOCK (1 << 6)
/* /*
* page->private values. Every page that is controlled by the extent * page->private values. Every page that is controlled by the extent
...@@ -192,7 +193,7 @@ struct extent_changeset { ...@@ -192,7 +193,7 @@ struct extent_changeset {
u64 bytes_changed; u64 bytes_changed;
/* Changed ranges */ /* Changed ranges */
struct ulist *range_changed; struct ulist range_changed;
}; };
static inline void extent_set_compress_type(unsigned long *bio_flags, static inline void extent_set_compress_type(unsigned long *bio_flags,
......
...@@ -255,7 +255,7 @@ static int __btrfs_lookup_bio_sums(struct inode *inode, struct bio *bio, ...@@ -255,7 +255,7 @@ static int __btrfs_lookup_bio_sums(struct inode *inode, struct bio *bio,
} else { } else {
btrfs_info_rl(fs_info, btrfs_info_rl(fs_info,
"no csum found for inode %llu start %llu", "no csum found for inode %llu start %llu",
btrfs_ino(inode), offset); btrfs_ino(BTRFS_I(inode)), offset);
} }
item = NULL; item = NULL;
btrfs_release_path(path); btrfs_release_path(path);
...@@ -856,8 +856,8 @@ int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans, ...@@ -856,8 +856,8 @@ int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans,
tmp = min(tmp, (next_offset - file_key.offset) >> tmp = min(tmp, (next_offset - file_key.offset) >>
fs_info->sb->s_blocksize_bits); fs_info->sb->s_blocksize_bits);
tmp = max((u64)1, tmp); tmp = max_t(u64, 1, tmp);
tmp = min(tmp, (u64)MAX_CSUM_ITEMS(fs_info, csum_size)); tmp = min_t(u64, tmp, MAX_CSUM_ITEMS(fs_info, csum_size));
ins_size = csum_size * tmp; ins_size = csum_size * tmp;
} else { } else {
ins_size = csum_size; ins_size = csum_size;
...@@ -977,7 +977,7 @@ void btrfs_extent_item_to_extent_map(struct inode *inode, ...@@ -977,7 +977,7 @@ void btrfs_extent_item_to_extent_map(struct inode *inode,
} else { } else {
btrfs_err(fs_info, btrfs_err(fs_info,
"unknown file extent item type %d, inode %llu, offset %llu, root %llu", "unknown file extent item type %d, inode %llu, offset %llu, root %llu",
type, btrfs_ino(inode), extent_start, type, btrfs_ino(BTRFS_I(inode)), extent_start,
root->root_key.objectid); root->root_key.objectid);
} }
} }
...@@ -168,7 +168,7 @@ int btrfs_add_inode_defrag(struct btrfs_trans_handle *trans, ...@@ -168,7 +168,7 @@ int btrfs_add_inode_defrag(struct btrfs_trans_handle *trans,
if (!defrag) if (!defrag)
return -ENOMEM; return -ENOMEM;
defrag->ino = btrfs_ino(inode); defrag->ino = btrfs_ino(BTRFS_I(inode));
defrag->transid = transid; defrag->transid = transid;
defrag->root = root->root_key.objectid; defrag->root = root->root_key.objectid;
...@@ -702,7 +702,7 @@ int __btrfs_drop_extents(struct btrfs_trans_handle *trans, ...@@ -702,7 +702,7 @@ int __btrfs_drop_extents(struct btrfs_trans_handle *trans,
struct btrfs_file_extent_item *fi; struct btrfs_file_extent_item *fi;
struct btrfs_key key; struct btrfs_key key;
struct btrfs_key new_key; struct btrfs_key new_key;
u64 ino = btrfs_ino(inode); u64 ino = btrfs_ino(BTRFS_I(inode));
u64 search_start = start; u64 search_start = start;
u64 disk_bytenr = 0; u64 disk_bytenr = 0;
u64 num_bytes = 0; u64 num_bytes = 0;
...@@ -1102,7 +1102,7 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans, ...@@ -1102,7 +1102,7 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans,
int del_slot = 0; int del_slot = 0;
int recow; int recow;
int ret; int ret;
u64 ino = btrfs_ino(inode); u64 ino = btrfs_ino(BTRFS_I(inode));
path = btrfs_alloc_path(); path = btrfs_alloc_path();
if (!path) if (!path)
...@@ -2062,7 +2062,7 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) ...@@ -2062,7 +2062,7 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
* commit does not start nor waits for ordered extents to complete. * commit does not start nor waits for ordered extents to complete.
*/ */
smp_mb(); smp_mb();
if (btrfs_inode_in_log(inode, fs_info->generation) || if (btrfs_inode_in_log(BTRFS_I(inode), fs_info->generation) ||
(full_sync && BTRFS_I(inode)->last_trans <= (full_sync && BTRFS_I(inode)->last_trans <=
fs_info->last_trans_committed) || fs_info->last_trans_committed) ||
(!btrfs_have_ordered_extents_in_range(inode, start, len) && (!btrfs_have_ordered_extents_in_range(inode, start, len) &&
...@@ -2203,7 +2203,7 @@ static int hole_mergeable(struct inode *inode, struct extent_buffer *leaf, ...@@ -2203,7 +2203,7 @@ static int hole_mergeable(struct inode *inode, struct extent_buffer *leaf,
return 0; return 0;
btrfs_item_key_to_cpu(leaf, &key, slot); btrfs_item_key_to_cpu(leaf, &key, slot);
if (key.objectid != btrfs_ino(inode) || if (key.objectid != btrfs_ino(BTRFS_I(inode)) ||
key.type != BTRFS_EXTENT_DATA_KEY) key.type != BTRFS_EXTENT_DATA_KEY)
return 0; return 0;
...@@ -2237,7 +2237,7 @@ static int fill_holes(struct btrfs_trans_handle *trans, struct inode *inode, ...@@ -2237,7 +2237,7 @@ static int fill_holes(struct btrfs_trans_handle *trans, struct inode *inode,
if (btrfs_fs_incompat(fs_info, NO_HOLES)) if (btrfs_fs_incompat(fs_info, NO_HOLES))
goto out; goto out;
key.objectid = btrfs_ino(inode); key.objectid = btrfs_ino(BTRFS_I(inode));
key.type = BTRFS_EXTENT_DATA_KEY; key.type = BTRFS_EXTENT_DATA_KEY;
key.offset = offset; key.offset = offset;
...@@ -2285,9 +2285,8 @@ static int fill_holes(struct btrfs_trans_handle *trans, struct inode *inode, ...@@ -2285,9 +2285,8 @@ static int fill_holes(struct btrfs_trans_handle *trans, struct inode *inode,
} }
btrfs_release_path(path); btrfs_release_path(path);
ret = btrfs_insert_file_extent(trans, root, btrfs_ino(inode), offset, ret = btrfs_insert_file_extent(trans, root, btrfs_ino(BTRFS_I(inode)),
0, 0, end - offset, 0, end - offset, offset, 0, 0, end - offset, 0, end - offset, 0, 0, 0);
0, 0, 0);
if (ret) if (ret)
return ret; return ret;
......
...@@ -94,12 +94,11 @@ static struct inode *__lookup_free_space_inode(struct btrfs_root *root, ...@@ -94,12 +94,11 @@ static struct inode *__lookup_free_space_inode(struct btrfs_root *root,
return inode; return inode;
} }
struct inode *lookup_free_space_inode(struct btrfs_root *root, struct inode *lookup_free_space_inode(struct btrfs_fs_info *fs_info,
struct btrfs_block_group_cache struct btrfs_block_group_cache
*block_group, struct btrfs_path *path) *block_group, struct btrfs_path *path)
{ {
struct inode *inode = NULL; struct inode *inode = NULL;
struct btrfs_fs_info *fs_info = root->fs_info;
u32 flags = BTRFS_INODE_NODATASUM | BTRFS_INODE_NODATACOW; u32 flags = BTRFS_INODE_NODATASUM | BTRFS_INODE_NODATACOW;
spin_lock(&block_group->lock); spin_lock(&block_group->lock);
...@@ -109,7 +108,7 @@ struct inode *lookup_free_space_inode(struct btrfs_root *root, ...@@ -109,7 +108,7 @@ struct inode *lookup_free_space_inode(struct btrfs_root *root,
if (inode) if (inode)
return inode; return inode;
inode = __lookup_free_space_inode(root, path, inode = __lookup_free_space_inode(fs_info->tree_root, path,
block_group->key.objectid); block_group->key.objectid);
if (IS_ERR(inode)) if (IS_ERR(inode))
return inode; return inode;
...@@ -192,7 +191,7 @@ static int __create_free_space_inode(struct btrfs_root *root, ...@@ -192,7 +191,7 @@ static int __create_free_space_inode(struct btrfs_root *root,
return 0; return 0;
} }
int create_free_space_inode(struct btrfs_root *root, int create_free_space_inode(struct btrfs_fs_info *fs_info,
struct btrfs_trans_handle *trans, struct btrfs_trans_handle *trans,
struct btrfs_block_group_cache *block_group, struct btrfs_block_group_cache *block_group,
struct btrfs_path *path) struct btrfs_path *path)
...@@ -200,11 +199,11 @@ int create_free_space_inode(struct btrfs_root *root, ...@@ -200,11 +199,11 @@ int create_free_space_inode(struct btrfs_root *root,
int ret; int ret;
u64 ino; u64 ino;
ret = btrfs_find_free_objectid(root, &ino); ret = btrfs_find_free_objectid(fs_info->tree_root, &ino);
if (ret < 0) if (ret < 0)
return ret; return ret;
return __create_free_space_inode(root, trans, path, ino, return __create_free_space_inode(fs_info->tree_root, trans, path, ino,
block_group->key.objectid); block_group->key.objectid);
} }
...@@ -227,21 +226,21 @@ int btrfs_check_trunc_cache_free_space(struct btrfs_fs_info *fs_info, ...@@ -227,21 +226,21 @@ int btrfs_check_trunc_cache_free_space(struct btrfs_fs_info *fs_info,
return ret; return ret;
} }
int btrfs_truncate_free_space_cache(struct btrfs_root *root, int btrfs_truncate_free_space_cache(struct btrfs_trans_handle *trans,
struct btrfs_trans_handle *trans,
struct btrfs_block_group_cache *block_group, struct btrfs_block_group_cache *block_group,
struct inode *inode) struct inode *inode)
{ {
struct btrfs_root *root = BTRFS_I(inode)->root;
int ret = 0; int ret = 0;
struct btrfs_path *path = btrfs_alloc_path();
bool locked = false; bool locked = false;
if (!path) {
ret = -ENOMEM;
goto fail;
}
if (block_group) { if (block_group) {
struct btrfs_path *path = btrfs_alloc_path();
if (!path) {
ret = -ENOMEM;
goto fail;
}
locked = true; locked = true;
mutex_lock(&trans->transaction->cache_write_mutex); mutex_lock(&trans->transaction->cache_write_mutex);
if (!list_empty(&block_group->io_list)) { if (!list_empty(&block_group->io_list)) {
...@@ -258,8 +257,8 @@ int btrfs_truncate_free_space_cache(struct btrfs_root *root, ...@@ -258,8 +257,8 @@ int btrfs_truncate_free_space_cache(struct btrfs_root *root,
spin_lock(&block_group->lock); spin_lock(&block_group->lock);
block_group->disk_cache_state = BTRFS_DC_CLEAR; block_group->disk_cache_state = BTRFS_DC_CLEAR;
spin_unlock(&block_group->lock); spin_unlock(&block_group->lock);
btrfs_free_path(path);
} }
btrfs_free_path(path);
btrfs_i_size_write(inode, 0); btrfs_i_size_write(inode, 0);
truncate_pagecache(inode, 0); truncate_pagecache(inode, 0);
...@@ -286,14 +285,14 @@ int btrfs_truncate_free_space_cache(struct btrfs_root *root, ...@@ -286,14 +285,14 @@ int btrfs_truncate_free_space_cache(struct btrfs_root *root,
return ret; return ret;
} }
static int readahead_cache(struct inode *inode) static void readahead_cache(struct inode *inode)
{ {
struct file_ra_state *ra; struct file_ra_state *ra;
unsigned long last_index; unsigned long last_index;
ra = kzalloc(sizeof(*ra), GFP_NOFS); ra = kzalloc(sizeof(*ra), GFP_NOFS);
if (!ra) if (!ra)
return -ENOMEM; return;
file_ra_state_init(ra, inode->i_mapping); file_ra_state_init(ra, inode->i_mapping);
last_index = (i_size_read(inode) - 1) >> PAGE_SHIFT; last_index = (i_size_read(inode) - 1) >> PAGE_SHIFT;
...@@ -301,8 +300,6 @@ static int readahead_cache(struct inode *inode) ...@@ -301,8 +300,6 @@ static int readahead_cache(struct inode *inode)
page_cache_sync_readahead(inode->i_mapping, ra, NULL, 0, last_index); page_cache_sync_readahead(inode->i_mapping, ra, NULL, 0, last_index);
kfree(ra); kfree(ra);
return 0;
} }
static int io_ctl_init(struct btrfs_io_ctl *io_ctl, struct inode *inode, static int io_ctl_init(struct btrfs_io_ctl *io_ctl, struct inode *inode,
...@@ -313,7 +310,7 @@ static int io_ctl_init(struct btrfs_io_ctl *io_ctl, struct inode *inode, ...@@ -313,7 +310,7 @@ static int io_ctl_init(struct btrfs_io_ctl *io_ctl, struct inode *inode,
num_pages = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE); num_pages = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE);
if (btrfs_ino(inode) != BTRFS_FREE_INO_OBJECTID) if (btrfs_ino(BTRFS_I(inode)) != BTRFS_FREE_INO_OBJECTID)
check_crcs = 1; check_crcs = 1;
/* Make sure we can fit our crcs into the first page */ /* Make sure we can fit our crcs into the first page */
...@@ -730,9 +727,7 @@ static int __load_free_space_cache(struct btrfs_root *root, struct inode *inode, ...@@ -730,9 +727,7 @@ static int __load_free_space_cache(struct btrfs_root *root, struct inode *inode,
if (ret) if (ret)
return ret; return ret;
ret = readahead_cache(inode); readahead_cache(inode);
if (ret)
goto out;
ret = io_ctl_prepare_pages(&io_ctl, inode, 1); ret = io_ctl_prepare_pages(&io_ctl, inode, 1);
if (ret) if (ret)
...@@ -828,7 +823,6 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info, ...@@ -828,7 +823,6 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info,
struct btrfs_block_group_cache *block_group) struct btrfs_block_group_cache *block_group)
{ {
struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl;
struct btrfs_root *root = fs_info->tree_root;
struct inode *inode; struct inode *inode;
struct btrfs_path *path; struct btrfs_path *path;
int ret = 0; int ret = 0;
...@@ -852,7 +846,7 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info, ...@@ -852,7 +846,7 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info,
path->search_commit_root = 1; path->search_commit_root = 1;
path->skip_locking = 1; path->skip_locking = 1;
inode = lookup_free_space_inode(root, block_group, path); inode = lookup_free_space_inode(fs_info, block_group, path);
if (IS_ERR(inode)) { if (IS_ERR(inode)) {
btrfs_free_path(path); btrfs_free_path(path);
return 0; return 0;
...@@ -1128,8 +1122,7 @@ cleanup_bitmap_list(struct list_head *bitmap_list) ...@@ -1128,8 +1122,7 @@ cleanup_bitmap_list(struct list_head *bitmap_list)
static void noinline_for_stack static void noinline_for_stack
cleanup_write_cache_enospc(struct inode *inode, cleanup_write_cache_enospc(struct inode *inode,
struct btrfs_io_ctl *io_ctl, struct btrfs_io_ctl *io_ctl,
struct extent_state **cached_state, struct extent_state **cached_state)
struct list_head *bitmap_list)
{ {
io_ctl_drop_pages(io_ctl); io_ctl_drop_pages(io_ctl);
unlock_extent_cached(&BTRFS_I(inode)->io_tree, 0, unlock_extent_cached(&BTRFS_I(inode)->io_tree, 0,
...@@ -1225,8 +1218,6 @@ int btrfs_wait_cache_io(struct btrfs_trans_handle *trans, ...@@ -1225,8 +1218,6 @@ int btrfs_wait_cache_io(struct btrfs_trans_handle *trans,
* @ctl - the free space cache we are going to write out * @ctl - the free space cache we are going to write out
* @block_group - the block_group for this cache if it belongs to a block_group * @block_group - the block_group for this cache if it belongs to a block_group
* @trans - the trans handle * @trans - the trans handle
* @path - the path to use
* @offset - the offset for the key we'll insert
* *
* This function writes out a free space cache struct to disk for quick recovery * This function writes out a free space cache struct to disk for quick recovery
* on mount. This will return 0 if it was successful in writing the cache out, * on mount. This will return 0 if it was successful in writing the cache out,
...@@ -1236,8 +1227,7 @@ static int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode, ...@@ -1236,8 +1227,7 @@ static int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode,
struct btrfs_free_space_ctl *ctl, struct btrfs_free_space_ctl *ctl,
struct btrfs_block_group_cache *block_group, struct btrfs_block_group_cache *block_group,
struct btrfs_io_ctl *io_ctl, struct btrfs_io_ctl *io_ctl,
struct btrfs_trans_handle *trans, struct btrfs_trans_handle *trans)
struct btrfs_path *path, u64 offset)
{ {
struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_fs_info *fs_info = root->fs_info;
struct extent_state *cached_state = NULL; struct extent_state *cached_state = NULL;
...@@ -1365,7 +1355,7 @@ static int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode, ...@@ -1365,7 +1355,7 @@ static int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode,
mutex_unlock(&ctl->cache_writeout_mutex); mutex_unlock(&ctl->cache_writeout_mutex);
out_nospc: out_nospc:
cleanup_write_cache_enospc(inode, io_ctl, &cached_state, &bitmap_list); cleanup_write_cache_enospc(inode, io_ctl, &cached_state);
if (block_group && (block_group->flags & BTRFS_BLOCK_GROUP_DATA)) if (block_group && (block_group->flags & BTRFS_BLOCK_GROUP_DATA))
up_write(&block_group->data_rwsem); up_write(&block_group->data_rwsem);
...@@ -1378,7 +1368,6 @@ int btrfs_write_out_cache(struct btrfs_fs_info *fs_info, ...@@ -1378,7 +1368,6 @@ int btrfs_write_out_cache(struct btrfs_fs_info *fs_info,
struct btrfs_block_group_cache *block_group, struct btrfs_block_group_cache *block_group,
struct btrfs_path *path) struct btrfs_path *path)
{ {
struct btrfs_root *root = fs_info->tree_root;
struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl;
struct inode *inode; struct inode *inode;
int ret = 0; int ret = 0;
...@@ -1390,13 +1379,12 @@ int btrfs_write_out_cache(struct btrfs_fs_info *fs_info, ...@@ -1390,13 +1379,12 @@ int btrfs_write_out_cache(struct btrfs_fs_info *fs_info,
} }
spin_unlock(&block_group->lock); spin_unlock(&block_group->lock);
inode = lookup_free_space_inode(root, block_group, path); inode = lookup_free_space_inode(fs_info, block_group, path);
if (IS_ERR(inode)) if (IS_ERR(inode))
return 0; return 0;
ret = __btrfs_write_out_cache(root, inode, ctl, block_group, ret = __btrfs_write_out_cache(fs_info->tree_root, inode, ctl,
&block_group->io_ctl, trans, block_group, &block_group->io_ctl, trans);
path, block_group->key.objectid);
if (ret) { if (ret) {
#ifdef DEBUG #ifdef DEBUG
btrfs_err(fs_info, btrfs_err(fs_info,
...@@ -3543,8 +3531,7 @@ int btrfs_write_out_ino_cache(struct btrfs_root *root, ...@@ -3543,8 +3531,7 @@ int btrfs_write_out_ino_cache(struct btrfs_root *root,
return 0; return 0;
memset(&io_ctl, 0, sizeof(io_ctl)); memset(&io_ctl, 0, sizeof(io_ctl));
ret = __btrfs_write_out_cache(root, inode, ctl, NULL, &io_ctl, ret = __btrfs_write_out_cache(root, inode, ctl, NULL, &io_ctl, trans);
trans, path, 0);
if (!ret) { if (!ret) {
/* /*
* At this point writepages() didn't error out, so our metadata * At this point writepages() didn't error out, so our metadata
......
...@@ -51,18 +51,17 @@ struct btrfs_free_space_op { ...@@ -51,18 +51,17 @@ struct btrfs_free_space_op {
struct btrfs_io_ctl; struct btrfs_io_ctl;
struct inode *lookup_free_space_inode(struct btrfs_root *root, struct inode *lookup_free_space_inode(struct btrfs_fs_info *fs_info,
struct btrfs_block_group_cache struct btrfs_block_group_cache
*block_group, struct btrfs_path *path); *block_group, struct btrfs_path *path);
int create_free_space_inode(struct btrfs_root *root, int create_free_space_inode(struct btrfs_fs_info *fs_info,
struct btrfs_trans_handle *trans, struct btrfs_trans_handle *trans,
struct btrfs_block_group_cache *block_group, struct btrfs_block_group_cache *block_group,
struct btrfs_path *path); struct btrfs_path *path);
int btrfs_check_trunc_cache_free_space(struct btrfs_fs_info *fs_info, int btrfs_check_trunc_cache_free_space(struct btrfs_fs_info *fs_info,
struct btrfs_block_rsv *rsv); struct btrfs_block_rsv *rsv);
int btrfs_truncate_free_space_cache(struct btrfs_root *root, int btrfs_truncate_free_space_cache(struct btrfs_trans_handle *trans,
struct btrfs_trans_handle *trans,
struct btrfs_block_group_cache *block_group, struct btrfs_block_group_cache *block_group,
struct inode *inode); struct inode *inode);
int load_free_space_cache(struct btrfs_fs_info *fs_info, int load_free_space_cache(struct btrfs_fs_info *fs_info,
......
...@@ -1269,7 +1269,7 @@ int btrfs_clear_free_space_tree(struct btrfs_fs_info *fs_info) ...@@ -1269,7 +1269,7 @@ int btrfs_clear_free_space_tree(struct btrfs_fs_info *fs_info)
list_del(&free_space_root->dirty_list); list_del(&free_space_root->dirty_list);
btrfs_tree_lock(free_space_root->node); btrfs_tree_lock(free_space_root->node);
clean_tree_block(trans, fs_info, free_space_root->node); clean_tree_block(fs_info, free_space_root->node);
btrfs_tree_unlock(free_space_root->node); btrfs_tree_unlock(free_space_root->node);
btrfs_free_tree_block(trans, free_space_root, free_space_root->node, btrfs_free_tree_block(trans, free_space_root, free_space_root->node,
0, 1); 0, 1);
......
...@@ -467,7 +467,7 @@ int btrfs_save_ino_cache(struct btrfs_root *root, ...@@ -467,7 +467,7 @@ int btrfs_save_ino_cache(struct btrfs_root *root,
} }
if (i_size_read(inode) > 0) { if (i_size_read(inode) > 0) {
ret = btrfs_truncate_free_space_cache(root, trans, NULL, inode); ret = btrfs_truncate_free_space_cache(trans, NULL, inode);
if (ret) { if (ret) {
if (ret != -ENOSPC) if (ret != -ENOSPC)
btrfs_abort_transaction(trans, ret); btrfs_abort_transaction(trans, ret);
......
此差异已折叠。
...@@ -395,7 +395,7 @@ static noinline int btrfs_ioctl_fitrim(struct file *file, void __user *arg) ...@@ -395,7 +395,7 @@ static noinline int btrfs_ioctl_fitrim(struct file *file, void __user *arg)
q = bdev_get_queue(device->bdev); q = bdev_get_queue(device->bdev);
if (blk_queue_discard(q)) { if (blk_queue_discard(q)) {
num_devices++; num_devices++;
minlen = min((u64)q->limits.discard_granularity, minlen = min_t(u64, q->limits.discard_granularity,
minlen); minlen);
} }
} }
...@@ -487,8 +487,7 @@ static noinline int create_subvol(struct inode *dir, ...@@ -487,8 +487,7 @@ static noinline int create_subvol(struct inode *dir,
trans = btrfs_start_transaction(root, 0); trans = btrfs_start_transaction(root, 0);
if (IS_ERR(trans)) { if (IS_ERR(trans)) {
ret = PTR_ERR(trans); ret = PTR_ERR(trans);
btrfs_subvolume_release_metadata(fs_info, &block_rsv, btrfs_subvolume_release_metadata(fs_info, &block_rsv);
qgroup_reserved);
goto fail_free; goto fail_free;
} }
trans->block_rsv = &block_rsv; trans->block_rsv = &block_rsv;
...@@ -601,7 +600,7 @@ static noinline int create_subvol(struct inode *dir, ...@@ -601,7 +600,7 @@ static noinline int create_subvol(struct inode *dir,
ret = btrfs_add_root_ref(trans, fs_info, ret = btrfs_add_root_ref(trans, fs_info,
objectid, root->root_key.objectid, objectid, root->root_key.objectid,
btrfs_ino(dir), index, name, namelen); btrfs_ino(BTRFS_I(dir)), index, name, namelen);
BUG_ON(ret); BUG_ON(ret);
ret = btrfs_uuid_tree_add(trans, fs_info, root_item->uuid, ret = btrfs_uuid_tree_add(trans, fs_info, root_item->uuid,
...@@ -613,7 +612,7 @@ static noinline int create_subvol(struct inode *dir, ...@@ -613,7 +612,7 @@ static noinline int create_subvol(struct inode *dir,
kfree(root_item); kfree(root_item);
trans->block_rsv = NULL; trans->block_rsv = NULL;
trans->bytes_reserved = 0; trans->bytes_reserved = 0;
btrfs_subvolume_release_metadata(fs_info, &block_rsv, qgroup_reserved); btrfs_subvolume_release_metadata(fs_info, &block_rsv);
if (async_transid) { if (async_transid) {
*async_transid = trans->transid; *async_transid = trans->transid;
...@@ -657,7 +656,7 @@ static void btrfs_wait_for_no_snapshoting_writes(struct btrfs_root *root) ...@@ -657,7 +656,7 @@ static void btrfs_wait_for_no_snapshoting_writes(struct btrfs_root *root)
} }
static int create_snapshot(struct btrfs_root *root, struct inode *dir, static int create_snapshot(struct btrfs_root *root, struct inode *dir,
struct dentry *dentry, char *name, int namelen, struct dentry *dentry,
u64 *async_transid, bool readonly, u64 *async_transid, bool readonly,
struct btrfs_qgroup_inherit *inherit) struct btrfs_qgroup_inherit *inherit)
{ {
...@@ -670,12 +669,12 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir, ...@@ -670,12 +669,12 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir,
if (!test_bit(BTRFS_ROOT_REF_COWS, &root->state)) if (!test_bit(BTRFS_ROOT_REF_COWS, &root->state))
return -EINVAL; return -EINVAL;
pending_snapshot = kzalloc(sizeof(*pending_snapshot), GFP_NOFS); pending_snapshot = kzalloc(sizeof(*pending_snapshot), GFP_KERNEL);
if (!pending_snapshot) if (!pending_snapshot)
return -ENOMEM; return -ENOMEM;
pending_snapshot->root_item = kzalloc(sizeof(struct btrfs_root_item), pending_snapshot->root_item = kzalloc(sizeof(struct btrfs_root_item),
GFP_NOFS); GFP_KERNEL);
pending_snapshot->path = btrfs_alloc_path(); pending_snapshot->path = btrfs_alloc_path();
if (!pending_snapshot->root_item || !pending_snapshot->path) { if (!pending_snapshot->root_item || !pending_snapshot->path) {
ret = -ENOMEM; ret = -ENOMEM;
...@@ -753,9 +752,7 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir, ...@@ -753,9 +752,7 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir,
d_instantiate(dentry, inode); d_instantiate(dentry, inode);
ret = 0; ret = 0;
fail: fail:
btrfs_subvolume_release_metadata(fs_info, btrfs_subvolume_release_metadata(fs_info, &pending_snapshot->block_rsv);
&pending_snapshot->block_rsv,
pending_snapshot->qgroup_reserved);
dec_and_free: dec_and_free:
if (atomic_dec_and_test(&root->will_be_snapshoted)) if (atomic_dec_and_test(&root->will_be_snapshoted))
wake_up_atomic_t(&root->will_be_snapshoted); wake_up_atomic_t(&root->will_be_snapshoted);
...@@ -874,7 +871,7 @@ static noinline int btrfs_mksubvol(const struct path *parent, ...@@ -874,7 +871,7 @@ static noinline int btrfs_mksubvol(const struct path *parent,
goto out_up_read; goto out_up_read;
if (snap_src) { if (snap_src) {
error = create_snapshot(snap_src, dir, dentry, name, namelen, error = create_snapshot(snap_src, dir, dentry,
async_transid, readonly, inherit); async_transid, readonly, inherit);
} else { } else {
error = create_subvol(dir, dentry, name, namelen, error = create_subvol(dir, dentry, name, namelen,
...@@ -941,7 +938,7 @@ static int find_new_extents(struct btrfs_root *root, ...@@ -941,7 +938,7 @@ static int find_new_extents(struct btrfs_root *root,
struct btrfs_file_extent_item *extent; struct btrfs_file_extent_item *extent;
int type; int type;
int ret; int ret;
u64 ino = btrfs_ino(inode); u64 ino = btrfs_ino(BTRFS_I(inode));
path = btrfs_alloc_path(); path = btrfs_alloc_path();
if (!path) if (!path)
...@@ -1780,7 +1777,7 @@ static noinline int btrfs_ioctl_subvol_getflags(struct file *file, ...@@ -1780,7 +1777,7 @@ static noinline int btrfs_ioctl_subvol_getflags(struct file *file,
int ret = 0; int ret = 0;
u64 flags = 0; u64 flags = 0;
if (btrfs_ino(inode) != BTRFS_FIRST_FREE_OBJECTID) if (btrfs_ino(BTRFS_I(inode)) != BTRFS_FIRST_FREE_OBJECTID)
return -EINVAL; return -EINVAL;
down_read(&fs_info->subvol_sem); down_read(&fs_info->subvol_sem);
...@@ -1812,7 +1809,7 @@ static noinline int btrfs_ioctl_subvol_setflags(struct file *file, ...@@ -1812,7 +1809,7 @@ static noinline int btrfs_ioctl_subvol_setflags(struct file *file,
if (ret) if (ret)
goto out; goto out;
if (btrfs_ino(inode) != BTRFS_FIRST_FREE_OBJECTID) { if (btrfs_ino(BTRFS_I(inode)) != BTRFS_FIRST_FREE_OBJECTID) {
ret = -EINVAL; ret = -EINVAL;
goto out_drop_write; goto out_drop_write;
} }
...@@ -2446,7 +2443,7 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file, ...@@ -2446,7 +2443,7 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file,
if (err) if (err)
goto out_dput; goto out_dput;
if (btrfs_ino(inode) != BTRFS_FIRST_FREE_OBJECTID) { if (btrfs_ino(BTRFS_I(inode)) != BTRFS_FIRST_FREE_OBJECTID) {
err = -EINVAL; err = -EINVAL;
goto out_dput; goto out_dput;
} }
...@@ -2497,7 +2494,7 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file, ...@@ -2497,7 +2494,7 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file,
trans->block_rsv = &block_rsv; trans->block_rsv = &block_rsv;
trans->bytes_reserved = block_rsv.size; trans->bytes_reserved = block_rsv.size;
btrfs_record_snapshot_destroy(trans, dir); btrfs_record_snapshot_destroy(trans, BTRFS_I(dir));
ret = btrfs_unlink_subvol(trans, root, dir, ret = btrfs_unlink_subvol(trans, root, dir,
dest->root_key.objectid, dest->root_key.objectid,
...@@ -2555,7 +2552,7 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file, ...@@ -2555,7 +2552,7 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file,
err = ret; err = ret;
inode->i_flags |= S_DEAD; inode->i_flags |= S_DEAD;
out_release: out_release:
btrfs_subvolume_release_metadata(fs_info, &block_rsv, qgroup_reserved); btrfs_subvolume_release_metadata(fs_info, &block_rsv);
out_up_write: out_up_write:
up_write(&fs_info->subvol_sem); up_write(&fs_info->subvol_sem);
if (err) { if (err) {
...@@ -2613,9 +2610,6 @@ static int btrfs_ioctl_defrag(struct file *file, void __user *argp) ...@@ -2613,9 +2610,6 @@ static int btrfs_ioctl_defrag(struct file *file, void __user *argp)
goto out; goto out;
} }
ret = btrfs_defrag_root(root); ret = btrfs_defrag_root(root);
if (ret)
goto out;
ret = btrfs_defrag_root(root->fs_info->extent_root);
break; break;
case S_IFREG: case S_IFREG:
if (!(file->f_mode & FMODE_WRITE)) { if (!(file->f_mode & FMODE_WRITE)) {
...@@ -3047,11 +3041,21 @@ static int btrfs_cmp_data_prepare(struct inode *src, u64 loff, ...@@ -3047,11 +3041,21 @@ static int btrfs_cmp_data_prepare(struct inode *src, u64 loff,
cmp->src_pages = src_pgarr; cmp->src_pages = src_pgarr;
cmp->dst_pages = dst_pgarr; cmp->dst_pages = dst_pgarr;
ret = gather_extent_pages(src, cmp->src_pages, cmp->num_pages, loff); /*
* If deduping ranges in the same inode, locking rules make it mandatory
* to always lock pages in ascending order to avoid deadlocks with
* concurrent tasks (such as starting writeback/delalloc).
*/
if (src == dst && dst_loff < loff) {
swap(src_pgarr, dst_pgarr);
swap(loff, dst_loff);
}
ret = gather_extent_pages(src, src_pgarr, cmp->num_pages, loff);
if (ret) if (ret)
goto out; goto out;
ret = gather_extent_pages(dst, cmp->dst_pages, cmp->num_pages, dst_loff); ret = gather_extent_pages(dst, dst_pgarr, cmp->num_pages, dst_loff);
out: out:
if (ret) if (ret)
...@@ -3059,8 +3063,7 @@ static int btrfs_cmp_data_prepare(struct inode *src, u64 loff, ...@@ -3059,8 +3063,7 @@ static int btrfs_cmp_data_prepare(struct inode *src, u64 loff,
return 0; return 0;
} }
static int btrfs_cmp_data(struct inode *src, u64 loff, struct inode *dst, static int btrfs_cmp_data(u64 len, struct cmp_pages *cmp)
u64 dst_loff, u64 len, struct cmp_pages *cmp)
{ {
int ret = 0; int ret = 0;
int i; int i;
...@@ -3128,26 +3131,27 @@ static int btrfs_extent_same(struct inode *src, u64 loff, u64 olen, ...@@ -3128,26 +3131,27 @@ static int btrfs_extent_same(struct inode *src, u64 loff, u64 olen,
int ret; int ret;
u64 len = olen; u64 len = olen;
struct cmp_pages cmp; struct cmp_pages cmp;
int same_inode = 0; bool same_inode = (src == dst);
u64 same_lock_start = 0; u64 same_lock_start = 0;
u64 same_lock_len = 0; u64 same_lock_len = 0;
if (src == dst)
same_inode = 1;
if (len == 0) if (len == 0)
return 0; return 0;
if (same_inode) { if (same_inode)
inode_lock(src); inode_lock(src);
else
btrfs_double_inode_lock(src, dst);
ret = extent_same_check_offsets(src, loff, &len, olen); ret = extent_same_check_offsets(src, loff, &len, olen);
if (ret) if (ret)
goto out_unlock; goto out_unlock;
ret = extent_same_check_offsets(src, dst_loff, &len, olen);
if (ret) ret = extent_same_check_offsets(dst, dst_loff, &len, olen);
goto out_unlock; if (ret)
goto out_unlock;
if (same_inode) {
/* /*
* Single inode case wants the same checks, except we * Single inode case wants the same checks, except we
* don't want our length pushed out past i_size as * don't want our length pushed out past i_size as
...@@ -3175,16 +3179,6 @@ static int btrfs_extent_same(struct inode *src, u64 loff, u64 olen, ...@@ -3175,16 +3179,6 @@ static int btrfs_extent_same(struct inode *src, u64 loff, u64 olen,
same_lock_start = min_t(u64, loff, dst_loff); same_lock_start = min_t(u64, loff, dst_loff);
same_lock_len = max_t(u64, loff, dst_loff) + len - same_lock_start; same_lock_len = max_t(u64, loff, dst_loff) + len - same_lock_start;
} else {
btrfs_double_inode_lock(src, dst);
ret = extent_same_check_offsets(src, loff, &len, olen);
if (ret)
goto out_unlock;
ret = extent_same_check_offsets(dst, dst_loff, &len, olen);
if (ret)
goto out_unlock;
} }
/* don't make the dst file partly checksummed */ /* don't make the dst file partly checksummed */
...@@ -3236,7 +3230,7 @@ static int btrfs_extent_same(struct inode *src, u64 loff, u64 olen, ...@@ -3236,7 +3230,7 @@ static int btrfs_extent_same(struct inode *src, u64 loff, u64 olen,
} }
/* pass original length for comparison so we stay within i_size */ /* pass original length for comparison so we stay within i_size */
ret = btrfs_cmp_data(src, loff, dst, dst_loff, olen, &cmp); ret = btrfs_cmp_data(olen, &cmp);
if (ret == 0) if (ret == 0)
ret = btrfs_clone(src, dst, loff, olen, len, dst_loff, 1); ret = btrfs_clone(src, dst, loff, olen, len, dst_loff, 1);
...@@ -3399,8 +3393,7 @@ static void clone_update_extent_map(struct inode *inode, ...@@ -3399,8 +3393,7 @@ static void clone_update_extent_map(struct inode *inode,
* data into the destination inode's inline extent if the later is greater then * data into the destination inode's inline extent if the later is greater then
* the former. * the former.
*/ */
static int clone_copy_inline_extent(struct inode *src, static int clone_copy_inline_extent(struct inode *dst,
struct inode *dst,
struct btrfs_trans_handle *trans, struct btrfs_trans_handle *trans,
struct btrfs_path *path, struct btrfs_path *path,
struct btrfs_key *new_key, struct btrfs_key *new_key,
...@@ -3420,7 +3413,7 @@ static int clone_copy_inline_extent(struct inode *src, ...@@ -3420,7 +3413,7 @@ static int clone_copy_inline_extent(struct inode *src,
if (new_key->offset > 0) if (new_key->offset > 0)
return -EOPNOTSUPP; return -EOPNOTSUPP;
key.objectid = btrfs_ino(dst); key.objectid = btrfs_ino(BTRFS_I(dst));
key.type = BTRFS_EXTENT_DATA_KEY; key.type = BTRFS_EXTENT_DATA_KEY;
key.offset = 0; key.offset = 0;
ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
...@@ -3435,7 +3428,7 @@ static int clone_copy_inline_extent(struct inode *src, ...@@ -3435,7 +3428,7 @@ static int clone_copy_inline_extent(struct inode *src,
goto copy_inline_extent; goto copy_inline_extent;
} }
btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]); btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
if (key.objectid == btrfs_ino(dst) && if (key.objectid == btrfs_ino(BTRFS_I(dst)) &&
key.type == BTRFS_EXTENT_DATA_KEY) { key.type == BTRFS_EXTENT_DATA_KEY) {
ASSERT(key.offset > 0); ASSERT(key.offset > 0);
return -EOPNOTSUPP; return -EOPNOTSUPP;
...@@ -3469,7 +3462,7 @@ static int clone_copy_inline_extent(struct inode *src, ...@@ -3469,7 +3462,7 @@ static int clone_copy_inline_extent(struct inode *src,
} else if (ret == 0) { } else if (ret == 0) {
btrfs_item_key_to_cpu(path->nodes[0], &key, btrfs_item_key_to_cpu(path->nodes[0], &key,
path->slots[0]); path->slots[0]);
if (key.objectid == btrfs_ino(dst) && if (key.objectid == btrfs_ino(BTRFS_I(dst)) &&
key.type == BTRFS_EXTENT_DATA_KEY) key.type == BTRFS_EXTENT_DATA_KEY)
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
...@@ -3563,7 +3556,7 @@ static int btrfs_clone(struct inode *src, struct inode *inode, ...@@ -3563,7 +3556,7 @@ static int btrfs_clone(struct inode *src, struct inode *inode,
path->reada = READA_FORWARD; path->reada = READA_FORWARD;
/* clone data */ /* clone data */
key.objectid = btrfs_ino(src); key.objectid = btrfs_ino(BTRFS_I(src));
key.type = BTRFS_EXTENT_DATA_KEY; key.type = BTRFS_EXTENT_DATA_KEY;
key.offset = off; key.offset = off;
...@@ -3606,7 +3599,7 @@ static int btrfs_clone(struct inode *src, struct inode *inode, ...@@ -3606,7 +3599,7 @@ static int btrfs_clone(struct inode *src, struct inode *inode,
btrfs_item_key_to_cpu(leaf, &key, slot); btrfs_item_key_to_cpu(leaf, &key, slot);
if (key.type > BTRFS_EXTENT_DATA_KEY || if (key.type > BTRFS_EXTENT_DATA_KEY ||
key.objectid != btrfs_ino(src)) key.objectid != btrfs_ino(BTRFS_I(src)))
break; break;
if (key.type == BTRFS_EXTENT_DATA_KEY) { if (key.type == BTRFS_EXTENT_DATA_KEY) {
...@@ -3659,7 +3652,7 @@ static int btrfs_clone(struct inode *src, struct inode *inode, ...@@ -3659,7 +3652,7 @@ static int btrfs_clone(struct inode *src, struct inode *inode,
path->leave_spinning = 0; path->leave_spinning = 0;
memcpy(&new_key, &key, sizeof(new_key)); memcpy(&new_key, &key, sizeof(new_key));
new_key.objectid = btrfs_ino(inode); new_key.objectid = btrfs_ino(BTRFS_I(inode));
if (off <= key.offset) if (off <= key.offset)
new_key.offset = key.offset + destoff - off; new_key.offset = key.offset + destoff - off;
else else
...@@ -3749,7 +3742,7 @@ static int btrfs_clone(struct inode *src, struct inode *inode, ...@@ -3749,7 +3742,7 @@ static int btrfs_clone(struct inode *src, struct inode *inode,
fs_info, fs_info,
disko, diskl, 0, disko, diskl, 0,
root->root_key.objectid, root->root_key.objectid,
btrfs_ino(inode), btrfs_ino(BTRFS_I(inode)),
new_key.offset - datao); new_key.offset - datao);
if (ret) { if (ret) {
btrfs_abort_transaction(trans, btrfs_abort_transaction(trans,
...@@ -3779,7 +3772,7 @@ static int btrfs_clone(struct inode *src, struct inode *inode, ...@@ -3779,7 +3772,7 @@ static int btrfs_clone(struct inode *src, struct inode *inode,
size -= skip + trim; size -= skip + trim;
datal -= skip + trim; datal -= skip + trim;
ret = clone_copy_inline_extent(src, inode, ret = clone_copy_inline_extent(inode,
trans, path, trans, path,
&new_key, &new_key,
drop_start, drop_start,
...@@ -5129,7 +5122,7 @@ static long _btrfs_ioctl_set_received_subvol(struct file *file, ...@@ -5129,7 +5122,7 @@ static long _btrfs_ioctl_set_received_subvol(struct file *file,
down_write(&fs_info->subvol_sem); down_write(&fs_info->subvol_sem);
if (btrfs_ino(inode) != BTRFS_FIRST_FREE_OBJECTID) { if (btrfs_ino(BTRFS_I(inode)) != BTRFS_FIRST_FREE_OBJECTID) {
ret = -EINVAL; ret = -EINVAL;
goto out; goto out;
} }
......
...@@ -432,7 +432,7 @@ int btrfs_dec_test_ordered_pending(struct inode *inode, ...@@ -432,7 +432,7 @@ int btrfs_dec_test_ordered_pending(struct inode *inode,
} }
/* Needs to either be called under a log transaction or the log_mutex */ /* Needs to either be called under a log transaction or the log_mutex */
void btrfs_get_logged_extents(struct inode *inode, void btrfs_get_logged_extents(struct btrfs_inode *inode,
struct list_head *logged_list, struct list_head *logged_list,
const loff_t start, const loff_t start,
const loff_t end) const loff_t end)
...@@ -442,7 +442,7 @@ void btrfs_get_logged_extents(struct inode *inode, ...@@ -442,7 +442,7 @@ void btrfs_get_logged_extents(struct inode *inode,
struct rb_node *n; struct rb_node *n;
struct rb_node *prev; struct rb_node *prev;
tree = &BTRFS_I(inode)->ordered_tree; tree = &inode->ordered_tree;
spin_lock_irq(&tree->lock); spin_lock_irq(&tree->lock);
n = __tree_search(&tree->tree, end, &prev); n = __tree_search(&tree->tree, end, &prev);
if (!n) if (!n)
...@@ -984,8 +984,18 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset, ...@@ -984,8 +984,18 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset,
} }
disk_i_size = BTRFS_I(inode)->disk_i_size; disk_i_size = BTRFS_I(inode)->disk_i_size;
/* truncate file */ /*
if (disk_i_size > i_size) { * truncate file.
* If ordered is not NULL, then this is called from endio and
* disk_i_size will be updated by either truncate itself or any
* in-flight IOs which are inside the disk_i_size.
*
* Because btrfs_setsize() may set i_size with disk_i_size if truncate
* fails somehow, we need to make sure we have a precise disk_i_size by
* updating it as usual.
*
*/
if (!ordered && disk_i_size > i_size) {
BTRFS_I(inode)->disk_i_size = orig_offset; BTRFS_I(inode)->disk_i_size = orig_offset;
ret = 0; ret = 0;
goto out; goto out;
...@@ -1032,25 +1042,22 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset, ...@@ -1032,25 +1042,22 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset,
/* We treat this entry as if it doesn't exist */ /* We treat this entry as if it doesn't exist */
if (test_bit(BTRFS_ORDERED_UPDATED_ISIZE, &test->flags)) if (test_bit(BTRFS_ORDERED_UPDATED_ISIZE, &test->flags))
continue; continue;
if (test->file_offset + test->len <= disk_i_size)
if (entry_end(test) <= disk_i_size)
break; break;
if (test->file_offset >= i_size) if (test->file_offset >= i_size)
break; break;
if (entry_end(test) > disk_i_size) {
/* /*
* we don't update disk_i_size now, so record this * We don't update disk_i_size now, so record this undealt
* undealt i_size. Or we will not know the real * i_size. Or we will not know the real i_size.
* i_size. */
*/ if (test->outstanding_isize < offset)
if (test->outstanding_isize < offset) test->outstanding_isize = offset;
test->outstanding_isize = offset; if (ordered &&
if (ordered && ordered->outstanding_isize > test->outstanding_isize)
ordered->outstanding_isize > test->outstanding_isize = ordered->outstanding_isize;
test->outstanding_isize) goto out;
test->outstanding_isize =
ordered->outstanding_isize;
goto out;
}
} }
new_i_size = min_t(u64, offset, i_size); new_i_size = min_t(u64, offset, i_size);
......
...@@ -75,6 +75,8 @@ struct btrfs_ordered_sum { ...@@ -75,6 +75,8 @@ struct btrfs_ordered_sum {
* in the logging code. */ * in the logging code. */
#define BTRFS_ORDERED_PENDING 11 /* We are waiting for this ordered extent to #define BTRFS_ORDERED_PENDING 11 /* We are waiting for this ordered extent to
* complete in the current transaction. */ * complete in the current transaction. */
#define BTRFS_ORDERED_REGULAR 12 /* Regular IO for COW */
struct btrfs_ordered_extent { struct btrfs_ordered_extent {
/* logical offset in the file */ /* logical offset in the file */
u64 file_offset; u64 file_offset;
...@@ -201,7 +203,7 @@ int btrfs_wait_ordered_extents(struct btrfs_root *root, int nr, ...@@ -201,7 +203,7 @@ int btrfs_wait_ordered_extents(struct btrfs_root *root, int nr,
const u64 range_start, const u64 range_len); const u64 range_start, const u64 range_len);
int btrfs_wait_ordered_roots(struct btrfs_fs_info *fs_info, int nr, int btrfs_wait_ordered_roots(struct btrfs_fs_info *fs_info, int nr,
const u64 range_start, const u64 range_len); const u64 range_start, const u64 range_len);
void btrfs_get_logged_extents(struct inode *inode, void btrfs_get_logged_extents(struct btrfs_inode *inode,
struct list_head *logged_list, struct list_head *logged_list,
const loff_t start, const loff_t start,
const loff_t end); const loff_t end);
......
...@@ -279,7 +279,7 @@ static void inode_prop_iterator(void *ctx, ...@@ -279,7 +279,7 @@ static void inode_prop_iterator(void *ctx,
if (unlikely(ret)) if (unlikely(ret))
btrfs_warn(root->fs_info, btrfs_warn(root->fs_info,
"error applying prop %s to ino %llu (root %llu): %d", "error applying prop %s to ino %llu (root %llu): %d",
handler->xattr_name, btrfs_ino(inode), handler->xattr_name, btrfs_ino(BTRFS_I(inode)),
root->root_key.objectid, ret); root->root_key.objectid, ret);
else else
set_bit(BTRFS_INODE_HAS_PROPS, &BTRFS_I(inode)->runtime_flags); set_bit(BTRFS_INODE_HAS_PROPS, &BTRFS_I(inode)->runtime_flags);
...@@ -288,7 +288,7 @@ static void inode_prop_iterator(void *ctx, ...@@ -288,7 +288,7 @@ static void inode_prop_iterator(void *ctx,
int btrfs_load_inode_props(struct inode *inode, struct btrfs_path *path) int btrfs_load_inode_props(struct inode *inode, struct btrfs_path *path)
{ {
struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_root *root = BTRFS_I(inode)->root;
u64 ino = btrfs_ino(inode); u64 ino = btrfs_ino(BTRFS_I(inode));
int ret; int ret;
ret = iterate_object_props(root, path, ino, inode_prop_iterator, inode); ret = iterate_object_props(root, path, ino, inode_prop_iterator, inode);
......
...@@ -319,7 +319,7 @@ int btrfs_read_qgroup_config(struct btrfs_fs_info *fs_info) ...@@ -319,7 +319,7 @@ int btrfs_read_qgroup_config(struct btrfs_fs_info *fs_info)
if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags)) if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags))
return 0; return 0;
fs_info->qgroup_ulist = ulist_alloc(GFP_NOFS); fs_info->qgroup_ulist = ulist_alloc(GFP_KERNEL);
if (!fs_info->qgroup_ulist) { if (!fs_info->qgroup_ulist) {
ret = -ENOMEM; ret = -ENOMEM;
goto out; goto out;
...@@ -876,7 +876,7 @@ int btrfs_quota_enable(struct btrfs_trans_handle *trans, ...@@ -876,7 +876,7 @@ int btrfs_quota_enable(struct btrfs_trans_handle *trans,
goto out; goto out;
} }
fs_info->qgroup_ulist = ulist_alloc(GFP_NOFS); fs_info->qgroup_ulist = ulist_alloc(GFP_KERNEL);
if (!fs_info->qgroup_ulist) { if (!fs_info->qgroup_ulist) {
ret = -ENOMEM; ret = -ENOMEM;
goto out; goto out;
...@@ -1019,7 +1019,7 @@ int btrfs_quota_disable(struct btrfs_trans_handle *trans, ...@@ -1019,7 +1019,7 @@ int btrfs_quota_disable(struct btrfs_trans_handle *trans,
list_del(&quota_root->dirty_list); list_del(&quota_root->dirty_list);
btrfs_tree_lock(quota_root->node); btrfs_tree_lock(quota_root->node);
clean_tree_block(trans, fs_info, quota_root->node); clean_tree_block(fs_info, quota_root->node);
btrfs_tree_unlock(quota_root->node); btrfs_tree_unlock(quota_root->node);
btrfs_free_tree_block(trans, quota_root, quota_root->node, 0, 1); btrfs_free_tree_block(trans, quota_root, quota_root->node, 0, 1);
...@@ -1038,6 +1038,15 @@ static void qgroup_dirty(struct btrfs_fs_info *fs_info, ...@@ -1038,6 +1038,15 @@ static void qgroup_dirty(struct btrfs_fs_info *fs_info,
list_add(&qgroup->dirty, &fs_info->dirty_qgroups); list_add(&qgroup->dirty, &fs_info->dirty_qgroups);
} }
static void report_reserved_underflow(struct btrfs_fs_info *fs_info,
struct btrfs_qgroup *qgroup,
u64 num_bytes)
{
btrfs_warn(fs_info,
"qgroup %llu reserved space underflow, have: %llu, to free: %llu",
qgroup->qgroupid, qgroup->reserved, num_bytes);
qgroup->reserved = 0;
}
/* /*
* The easy accounting, if we are adding/removing the only ref for an extent * The easy accounting, if we are adding/removing the only ref for an extent
* then this qgroup and all of the parent qgroups get their reference and * then this qgroup and all of the parent qgroups get their reference and
...@@ -1065,8 +1074,12 @@ static int __qgroup_excl_accounting(struct btrfs_fs_info *fs_info, ...@@ -1065,8 +1074,12 @@ static int __qgroup_excl_accounting(struct btrfs_fs_info *fs_info,
WARN_ON(sign < 0 && qgroup->excl < num_bytes); WARN_ON(sign < 0 && qgroup->excl < num_bytes);
qgroup->excl += sign * num_bytes; qgroup->excl += sign * num_bytes;
qgroup->excl_cmpr += sign * num_bytes; qgroup->excl_cmpr += sign * num_bytes;
if (sign > 0) if (sign > 0) {
qgroup->reserved -= num_bytes; if (WARN_ON(qgroup->reserved < num_bytes))
report_reserved_underflow(fs_info, qgroup, num_bytes);
else
qgroup->reserved -= num_bytes;
}
qgroup_dirty(fs_info, qgroup); qgroup_dirty(fs_info, qgroup);
...@@ -1086,8 +1099,13 @@ static int __qgroup_excl_accounting(struct btrfs_fs_info *fs_info, ...@@ -1086,8 +1099,13 @@ static int __qgroup_excl_accounting(struct btrfs_fs_info *fs_info,
qgroup->rfer_cmpr += sign * num_bytes; qgroup->rfer_cmpr += sign * num_bytes;
WARN_ON(sign < 0 && qgroup->excl < num_bytes); WARN_ON(sign < 0 && qgroup->excl < num_bytes);
qgroup->excl += sign * num_bytes; qgroup->excl += sign * num_bytes;
if (sign > 0) if (sign > 0) {
qgroup->reserved -= num_bytes; if (WARN_ON(qgroup->reserved < num_bytes))
report_reserved_underflow(fs_info, qgroup,
num_bytes);
else
qgroup->reserved -= num_bytes;
}
qgroup->excl_cmpr += sign * num_bytes; qgroup->excl_cmpr += sign * num_bytes;
qgroup_dirty(fs_info, qgroup); qgroup_dirty(fs_info, qgroup);
...@@ -1156,7 +1174,7 @@ int btrfs_add_qgroup_relation(struct btrfs_trans_handle *trans, ...@@ -1156,7 +1174,7 @@ int btrfs_add_qgroup_relation(struct btrfs_trans_handle *trans,
if (btrfs_qgroup_level(src) >= btrfs_qgroup_level(dst)) if (btrfs_qgroup_level(src) >= btrfs_qgroup_level(dst))
return -EINVAL; return -EINVAL;
tmp = ulist_alloc(GFP_NOFS); tmp = ulist_alloc(GFP_KERNEL);
if (!tmp) if (!tmp)
return -ENOMEM; return -ENOMEM;
...@@ -1205,7 +1223,7 @@ int btrfs_add_qgroup_relation(struct btrfs_trans_handle *trans, ...@@ -1205,7 +1223,7 @@ int btrfs_add_qgroup_relation(struct btrfs_trans_handle *trans,
return ret; return ret;
} }
int __del_qgroup_relation(struct btrfs_trans_handle *trans, static int __del_qgroup_relation(struct btrfs_trans_handle *trans,
struct btrfs_fs_info *fs_info, u64 src, u64 dst) struct btrfs_fs_info *fs_info, u64 src, u64 dst)
{ {
struct btrfs_root *quota_root; struct btrfs_root *quota_root;
...@@ -1216,7 +1234,7 @@ int __del_qgroup_relation(struct btrfs_trans_handle *trans, ...@@ -1216,7 +1234,7 @@ int __del_qgroup_relation(struct btrfs_trans_handle *trans,
int ret = 0; int ret = 0;
int err; int err;
tmp = ulist_alloc(GFP_NOFS); tmp = ulist_alloc(GFP_KERNEL);
if (!tmp) if (!tmp)
return -ENOMEM; return -ENOMEM;
...@@ -1446,8 +1464,9 @@ int btrfs_qgroup_prepare_account_extents(struct btrfs_trans_handle *trans, ...@@ -1446,8 +1464,9 @@ int btrfs_qgroup_prepare_account_extents(struct btrfs_trans_handle *trans,
while (node) { while (node) {
record = rb_entry(node, struct btrfs_qgroup_extent_record, record = rb_entry(node, struct btrfs_qgroup_extent_record,
node); node);
ret = btrfs_find_all_roots(NULL, fs_info, record->bytenr, 0, if (WARN_ON(!record->old_roots))
&record->old_roots); ret = btrfs_find_all_roots(NULL, fs_info,
record->bytenr, 0, &record->old_roots);
if (ret < 0) if (ret < 0)
break; break;
if (qgroup_to_skip) if (qgroup_to_skip)
...@@ -1486,6 +1505,28 @@ int btrfs_qgroup_trace_extent_nolock(struct btrfs_fs_info *fs_info, ...@@ -1486,6 +1505,28 @@ int btrfs_qgroup_trace_extent_nolock(struct btrfs_fs_info *fs_info,
return 0; return 0;
} }
int btrfs_qgroup_trace_extent_post(struct btrfs_fs_info *fs_info,
struct btrfs_qgroup_extent_record *qrecord)
{
struct ulist *old_root;
u64 bytenr = qrecord->bytenr;
int ret;
ret = btrfs_find_all_roots(NULL, fs_info, bytenr, 0, &old_root);
if (ret < 0)
return ret;
/*
* Here we don't need to get the lock of
* trans->transaction->delayed_refs, since inserted qrecord won't
* be deleted, only qrecord->node may be modified (new qrecord insert)
*
* So modifying qrecord->old_roots is safe here
*/
qrecord->old_roots = old_root;
return 0;
}
int btrfs_qgroup_trace_extent(struct btrfs_trans_handle *trans, int btrfs_qgroup_trace_extent(struct btrfs_trans_handle *trans,
struct btrfs_fs_info *fs_info, u64 bytenr, u64 num_bytes, struct btrfs_fs_info *fs_info, u64 bytenr, u64 num_bytes,
gfp_t gfp_flag) gfp_t gfp_flag)
...@@ -1511,9 +1552,11 @@ int btrfs_qgroup_trace_extent(struct btrfs_trans_handle *trans, ...@@ -1511,9 +1552,11 @@ int btrfs_qgroup_trace_extent(struct btrfs_trans_handle *trans,
spin_lock(&delayed_refs->lock); spin_lock(&delayed_refs->lock);
ret = btrfs_qgroup_trace_extent_nolock(fs_info, delayed_refs, record); ret = btrfs_qgroup_trace_extent_nolock(fs_info, delayed_refs, record);
spin_unlock(&delayed_refs->lock); spin_unlock(&delayed_refs->lock);
if (ret > 0) if (ret > 0) {
kfree(record); kfree(record);
return 0; return 0;
}
return btrfs_qgroup_trace_extent_post(fs_info, record);
} }
int btrfs_qgroup_trace_leaf_items(struct btrfs_trans_handle *trans, int btrfs_qgroup_trace_leaf_items(struct btrfs_trans_handle *trans,
...@@ -1571,8 +1614,7 @@ int btrfs_qgroup_trace_leaf_items(struct btrfs_trans_handle *trans, ...@@ -1571,8 +1614,7 @@ int btrfs_qgroup_trace_leaf_items(struct btrfs_trans_handle *trans,
* If we increment the root nodes slot counter past the number of * If we increment the root nodes slot counter past the number of
* elements, 1 is returned to signal completion of the search. * elements, 1 is returned to signal completion of the search.
*/ */
static int adjust_slots_upwards(struct btrfs_root *root, static int adjust_slots_upwards(struct btrfs_path *path, int root_level)
struct btrfs_path *path, int root_level)
{ {
int level = 0; int level = 0;
int nr, slot; int nr, slot;
...@@ -1713,7 +1755,7 @@ int btrfs_qgroup_trace_subtree(struct btrfs_trans_handle *trans, ...@@ -1713,7 +1755,7 @@ int btrfs_qgroup_trace_subtree(struct btrfs_trans_handle *trans,
goto out; goto out;
/* Nonzero return here means we completed our search */ /* Nonzero return here means we completed our search */
ret = adjust_slots_upwards(root, path, root_level); ret = adjust_slots_upwards(path, root_level);
if (ret) if (ret)
break; break;
...@@ -1927,13 +1969,14 @@ btrfs_qgroup_account_extent(struct btrfs_trans_handle *trans, ...@@ -1927,13 +1969,14 @@ btrfs_qgroup_account_extent(struct btrfs_trans_handle *trans,
u64 nr_old_roots = 0; u64 nr_old_roots = 0;
int ret = 0; int ret = 0;
if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags))
return 0;
if (new_roots) if (new_roots)
nr_new_roots = new_roots->nnodes; nr_new_roots = new_roots->nnodes;
if (old_roots) if (old_roots)
nr_old_roots = old_roots->nnodes; nr_old_roots = old_roots->nnodes;
if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags))
goto out_free;
BUG_ON(!fs_info->quota_root); BUG_ON(!fs_info->quota_root);
trace_btrfs_qgroup_account_extent(fs_info, bytenr, num_bytes, trace_btrfs_qgroup_account_extent(fs_info, bytenr, num_bytes,
...@@ -2170,9 +2213,7 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, ...@@ -2170,9 +2213,7 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans,
goto out; goto out;
} }
rcu_read_lock();
level_size = fs_info->nodesize; level_size = fs_info->nodesize;
rcu_read_unlock();
} }
/* /*
...@@ -2306,7 +2347,20 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, ...@@ -2306,7 +2347,20 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans,
return ret; return ret;
} }
static int qgroup_reserve(struct btrfs_root *root, u64 num_bytes) static bool qgroup_check_limits(const struct btrfs_qgroup *qg, u64 num_bytes)
{
if ((qg->lim_flags & BTRFS_QGROUP_LIMIT_MAX_RFER) &&
qg->reserved + (s64)qg->rfer + num_bytes > qg->max_rfer)
return false;
if ((qg->lim_flags & BTRFS_QGROUP_LIMIT_MAX_EXCL) &&
qg->reserved + (s64)qg->excl + num_bytes > qg->max_excl)
return false;
return true;
}
static int qgroup_reserve(struct btrfs_root *root, u64 num_bytes, bool enforce)
{ {
struct btrfs_root *quota_root; struct btrfs_root *quota_root;
struct btrfs_qgroup *qgroup; struct btrfs_qgroup *qgroup;
...@@ -2347,16 +2401,7 @@ static int qgroup_reserve(struct btrfs_root *root, u64 num_bytes) ...@@ -2347,16 +2401,7 @@ static int qgroup_reserve(struct btrfs_root *root, u64 num_bytes)
qg = unode_aux_to_qgroup(unode); qg = unode_aux_to_qgroup(unode);
if ((qg->lim_flags & BTRFS_QGROUP_LIMIT_MAX_RFER) && if (enforce && !qgroup_check_limits(qg, num_bytes)) {
qg->reserved + (s64)qg->rfer + num_bytes >
qg->max_rfer) {
ret = -EDQUOT;
goto out;
}
if ((qg->lim_flags & BTRFS_QGROUP_LIMIT_MAX_EXCL) &&
qg->reserved + (s64)qg->excl + num_bytes >
qg->max_excl) {
ret = -EDQUOT; ret = -EDQUOT;
goto out; goto out;
} }
...@@ -2424,7 +2469,10 @@ void btrfs_qgroup_free_refroot(struct btrfs_fs_info *fs_info, ...@@ -2424,7 +2469,10 @@ void btrfs_qgroup_free_refroot(struct btrfs_fs_info *fs_info,
qg = unode_aux_to_qgroup(unode); qg = unode_aux_to_qgroup(unode);
qg->reserved -= num_bytes; if (WARN_ON(qg->reserved < num_bytes))
report_reserved_underflow(fs_info, qg, num_bytes);
else
qg->reserved -= num_bytes;
list_for_each_entry(glist, &qg->groups, next_group) { list_for_each_entry(glist, &qg->groups, next_group) {
ret = ulist_add(fs_info->qgroup_ulist, ret = ulist_add(fs_info->qgroup_ulist,
...@@ -2439,11 +2487,6 @@ void btrfs_qgroup_free_refroot(struct btrfs_fs_info *fs_info, ...@@ -2439,11 +2487,6 @@ void btrfs_qgroup_free_refroot(struct btrfs_fs_info *fs_info,
spin_unlock(&fs_info->qgroup_lock); spin_unlock(&fs_info->qgroup_lock);
} }
static inline void qgroup_free(struct btrfs_root *root, u64 num_bytes)
{
return btrfs_qgroup_free_refroot(root->fs_info, root->objectid,
num_bytes);
}
void assert_qgroups_uptodate(struct btrfs_trans_handle *trans) void assert_qgroups_uptodate(struct btrfs_trans_handle *trans)
{ {
if (list_empty(&trans->qgroup_ref_list) && !trans->delayed_ref_elem.seq) if (list_empty(&trans->qgroup_ref_list) && !trans->delayed_ref_elem.seq)
...@@ -2803,7 +2846,7 @@ int btrfs_qgroup_reserve_data(struct inode *inode, u64 start, u64 len) ...@@ -2803,7 +2846,7 @@ int btrfs_qgroup_reserve_data(struct inode *inode, u64 start, u64 len)
return 0; return 0;
changeset.bytes_changed = 0; changeset.bytes_changed = 0;
changeset.range_changed = ulist_alloc(GFP_NOFS); ulist_init(&changeset.range_changed);
ret = set_record_extent_bits(&BTRFS_I(inode)->io_tree, start, ret = set_record_extent_bits(&BTRFS_I(inode)->io_tree, start,
start + len -1, EXTENT_QGROUP_RESERVED, &changeset); start + len -1, EXTENT_QGROUP_RESERVED, &changeset);
trace_btrfs_qgroup_reserve_data(inode, start, len, trace_btrfs_qgroup_reserve_data(inode, start, len,
...@@ -2811,21 +2854,21 @@ int btrfs_qgroup_reserve_data(struct inode *inode, u64 start, u64 len) ...@@ -2811,21 +2854,21 @@ int btrfs_qgroup_reserve_data(struct inode *inode, u64 start, u64 len)
QGROUP_RESERVE); QGROUP_RESERVE);
if (ret < 0) if (ret < 0)
goto cleanup; goto cleanup;
ret = qgroup_reserve(root, changeset.bytes_changed); ret = qgroup_reserve(root, changeset.bytes_changed, true);
if (ret < 0) if (ret < 0)
goto cleanup; goto cleanup;
ulist_free(changeset.range_changed); ulist_release(&changeset.range_changed);
return ret; return ret;
cleanup: cleanup:
/* cleanup already reserved ranges */ /* cleanup already reserved ranges */
ULIST_ITER_INIT(&uiter); ULIST_ITER_INIT(&uiter);
while ((unode = ulist_next(changeset.range_changed, &uiter))) while ((unode = ulist_next(&changeset.range_changed, &uiter)))
clear_extent_bit(&BTRFS_I(inode)->io_tree, unode->val, clear_extent_bit(&BTRFS_I(inode)->io_tree, unode->val,
unode->aux, EXTENT_QGROUP_RESERVED, 0, 0, NULL, unode->aux, EXTENT_QGROUP_RESERVED, 0, 0, NULL,
GFP_NOFS); GFP_NOFS);
ulist_free(changeset.range_changed); ulist_release(&changeset.range_changed);
return ret; return ret;
} }
...@@ -2837,23 +2880,22 @@ static int __btrfs_qgroup_release_data(struct inode *inode, u64 start, u64 len, ...@@ -2837,23 +2880,22 @@ static int __btrfs_qgroup_release_data(struct inode *inode, u64 start, u64 len,
int ret; int ret;
changeset.bytes_changed = 0; changeset.bytes_changed = 0;
changeset.range_changed = ulist_alloc(GFP_NOFS); ulist_init(&changeset.range_changed);
if (!changeset.range_changed)
return -ENOMEM;
ret = clear_record_extent_bits(&BTRFS_I(inode)->io_tree, start, ret = clear_record_extent_bits(&BTRFS_I(inode)->io_tree, start,
start + len -1, EXTENT_QGROUP_RESERVED, &changeset); start + len -1, EXTENT_QGROUP_RESERVED, &changeset);
if (ret < 0) if (ret < 0)
goto out; goto out;
if (free) { if (free) {
qgroup_free(BTRFS_I(inode)->root, changeset.bytes_changed); btrfs_qgroup_free_refroot(BTRFS_I(inode)->root->fs_info,
BTRFS_I(inode)->root->objectid,
changeset.bytes_changed);
trace_op = QGROUP_FREE; trace_op = QGROUP_FREE;
} }
trace_btrfs_qgroup_release_data(inode, start, len, trace_btrfs_qgroup_release_data(inode, start, len,
changeset.bytes_changed, trace_op); changeset.bytes_changed, trace_op);
out: out:
ulist_free(changeset.range_changed); ulist_release(&changeset.range_changed);
return ret; return ret;
} }
...@@ -2892,7 +2934,8 @@ int btrfs_qgroup_release_data(struct inode *inode, u64 start, u64 len) ...@@ -2892,7 +2934,8 @@ int btrfs_qgroup_release_data(struct inode *inode, u64 start, u64 len)
return __btrfs_qgroup_release_data(inode, start, len, 0); return __btrfs_qgroup_release_data(inode, start, len, 0);
} }
int btrfs_qgroup_reserve_meta(struct btrfs_root *root, int num_bytes) int btrfs_qgroup_reserve_meta(struct btrfs_root *root, int num_bytes,
bool enforce)
{ {
struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_fs_info *fs_info = root->fs_info;
int ret; int ret;
...@@ -2902,7 +2945,7 @@ int btrfs_qgroup_reserve_meta(struct btrfs_root *root, int num_bytes) ...@@ -2902,7 +2945,7 @@ int btrfs_qgroup_reserve_meta(struct btrfs_root *root, int num_bytes)
return 0; return 0;
BUG_ON(num_bytes != round_down(num_bytes, fs_info->nodesize)); BUG_ON(num_bytes != round_down(num_bytes, fs_info->nodesize));
ret = qgroup_reserve(root, num_bytes); ret = qgroup_reserve(root, num_bytes, enforce);
if (ret < 0) if (ret < 0)
return ret; return ret;
atomic_add(num_bytes, &root->qgroup_meta_rsv); atomic_add(num_bytes, &root->qgroup_meta_rsv);
...@@ -2921,7 +2964,7 @@ void btrfs_qgroup_free_meta_all(struct btrfs_root *root) ...@@ -2921,7 +2964,7 @@ void btrfs_qgroup_free_meta_all(struct btrfs_root *root)
reserved = atomic_xchg(&root->qgroup_meta_rsv, 0); reserved = atomic_xchg(&root->qgroup_meta_rsv, 0);
if (reserved == 0) if (reserved == 0)
return; return;
qgroup_free(root, reserved); btrfs_qgroup_free_refroot(fs_info, root->objectid, reserved);
} }
void btrfs_qgroup_free_meta(struct btrfs_root *root, int num_bytes) void btrfs_qgroup_free_meta(struct btrfs_root *root, int num_bytes)
...@@ -2935,7 +2978,7 @@ void btrfs_qgroup_free_meta(struct btrfs_root *root, int num_bytes) ...@@ -2935,7 +2978,7 @@ void btrfs_qgroup_free_meta(struct btrfs_root *root, int num_bytes)
BUG_ON(num_bytes != round_down(num_bytes, fs_info->nodesize)); BUG_ON(num_bytes != round_down(num_bytes, fs_info->nodesize));
WARN_ON(atomic_read(&root->qgroup_meta_rsv) < num_bytes); WARN_ON(atomic_read(&root->qgroup_meta_rsv) < num_bytes);
atomic_sub(num_bytes, &root->qgroup_meta_rsv); atomic_sub(num_bytes, &root->qgroup_meta_rsv);
qgroup_free(root, num_bytes); btrfs_qgroup_free_refroot(fs_info, root->objectid, num_bytes);
} }
/* /*
...@@ -2950,22 +2993,22 @@ void btrfs_qgroup_check_reserved_leak(struct inode *inode) ...@@ -2950,22 +2993,22 @@ void btrfs_qgroup_check_reserved_leak(struct inode *inode)
int ret; int ret;
changeset.bytes_changed = 0; changeset.bytes_changed = 0;
changeset.range_changed = ulist_alloc(GFP_NOFS); ulist_init(&changeset.range_changed);
if (WARN_ON(!changeset.range_changed))
return;
ret = clear_record_extent_bits(&BTRFS_I(inode)->io_tree, 0, (u64)-1, ret = clear_record_extent_bits(&BTRFS_I(inode)->io_tree, 0, (u64)-1,
EXTENT_QGROUP_RESERVED, &changeset); EXTENT_QGROUP_RESERVED, &changeset);
WARN_ON(ret < 0); WARN_ON(ret < 0);
if (WARN_ON(changeset.bytes_changed)) { if (WARN_ON(changeset.bytes_changed)) {
ULIST_ITER_INIT(&iter); ULIST_ITER_INIT(&iter);
while ((unode = ulist_next(changeset.range_changed, &iter))) { while ((unode = ulist_next(&changeset.range_changed, &iter))) {
btrfs_warn(BTRFS_I(inode)->root->fs_info, btrfs_warn(BTRFS_I(inode)->root->fs_info,
"leaking qgroup reserved space, ino: %lu, start: %llu, end: %llu", "leaking qgroup reserved space, ino: %lu, start: %llu, end: %llu",
inode->i_ino, unode->val, unode->aux); inode->i_ino, unode->val, unode->aux);
} }
qgroup_free(BTRFS_I(inode)->root, changeset.bytes_changed); btrfs_qgroup_free_refroot(BTRFS_I(inode)->root->fs_info,
BTRFS_I(inode)->root->objectid,
changeset.bytes_changed);
} }
ulist_free(changeset.range_changed); ulist_release(&changeset.range_changed);
} }
此差异已折叠。
...@@ -677,11 +677,9 @@ static noinline int lock_stripe_add(struct btrfs_raid_bio *rbio) ...@@ -677,11 +677,9 @@ static noinline int lock_stripe_add(struct btrfs_raid_bio *rbio)
struct btrfs_raid_bio *freeit = NULL; struct btrfs_raid_bio *freeit = NULL;
struct btrfs_raid_bio *cache_drop = NULL; struct btrfs_raid_bio *cache_drop = NULL;
int ret = 0; int ret = 0;
int walk = 0;
spin_lock_irqsave(&h->lock, flags); spin_lock_irqsave(&h->lock, flags);
list_for_each_entry(cur, &h->hash_list, hash_list) { list_for_each_entry(cur, &h->hash_list, hash_list) {
walk++;
if (cur->bbio->raid_map[0] == rbio->bbio->raid_map[0]) { if (cur->bbio->raid_map[0] == rbio->bbio->raid_map[0]) {
spin_lock(&cur->bio_list_lock); spin_lock(&cur->bio_list_lock);
......
此差异已折叠。
...@@ -74,7 +74,7 @@ static void btrfs_read_root_item(struct extent_buffer *eb, int slot, ...@@ -74,7 +74,7 @@ static void btrfs_read_root_item(struct extent_buffer *eb, int slot,
* *
* If we find something return 0, otherwise > 0, < 0 on error. * If we find something return 0, otherwise > 0, < 0 on error.
*/ */
int btrfs_find_root(struct btrfs_root *root, struct btrfs_key *search_key, int btrfs_find_root(struct btrfs_root *root, const struct btrfs_key *search_key,
struct btrfs_path *path, struct btrfs_root_item *root_item, struct btrfs_path *path, struct btrfs_root_item *root_item,
struct btrfs_key *root_key) struct btrfs_key *root_key)
{ {
...@@ -207,7 +207,7 @@ int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root ...@@ -207,7 +207,7 @@ int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root
} }
int btrfs_insert_root(struct btrfs_trans_handle *trans, struct btrfs_root *root, int btrfs_insert_root(struct btrfs_trans_handle *trans, struct btrfs_root *root,
struct btrfs_key *key, struct btrfs_root_item *item) const struct btrfs_key *key, struct btrfs_root_item *item)
{ {
/* /*
* Make sure generation v1 and v2 match. See update_root for details. * Make sure generation v1 and v2 match. See update_root for details.
...@@ -337,7 +337,7 @@ int btrfs_find_orphan_roots(struct btrfs_fs_info *fs_info) ...@@ -337,7 +337,7 @@ int btrfs_find_orphan_roots(struct btrfs_fs_info *fs_info)
/* drop the root item for 'key' from 'root' */ /* drop the root item for 'key' from 'root' */
int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root, int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root,
struct btrfs_key *key) const struct btrfs_key *key)
{ {
struct btrfs_path *path; struct btrfs_path *path;
int ret; int ret;
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
...@@ -184,7 +184,7 @@ DEFINE_EVENT(btrfs__inode, btrfs_inode_evict, ...@@ -184,7 +184,7 @@ DEFINE_EVENT(btrfs__inode, btrfs_inode_evict,
TRACE_EVENT_CONDITION(btrfs_get_extent, TRACE_EVENT_CONDITION(btrfs_get_extent,
TP_PROTO(struct btrfs_root *root, struct inode *inode, TP_PROTO(struct btrfs_root *root, struct btrfs_inode *inode,
struct extent_map *map), struct extent_map *map),
TP_ARGS(root, inode, map), TP_ARGS(root, inode, map),
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册