mirror of
https://github.com/torvalds/linux.git
synced 2024-11-11 06:31:49 +00:00
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 ...
This commit is contained in:
commit
9003ed1fed
@ -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
|
||||
*/
|
||||
static int __add_inline_refs(struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_path *path, u64 bytenr,
|
||||
static int __add_inline_refs(struct btrfs_path *path, u64 bytenr,
|
||||
int *info_level, struct list_head *prefs,
|
||||
struct ref_root *ref_tree,
|
||||
u64 *total_refs, u64 inum)
|
||||
@ -1284,7 +1283,7 @@ again:
|
||||
*/
|
||||
delayed_refs = &trans->transaction->delayed_refs;
|
||||
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 (!mutex_trylock(&head->mutex)) {
|
||||
atomic_inc(&head->node.refs);
|
||||
@ -1354,7 +1353,7 @@ again:
|
||||
if (key.objectid == bytenr &&
|
||||
(key.type == BTRFS_EXTENT_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,
|
||||
ref_tree, &total_refs,
|
||||
inum);
|
||||
|
@ -224,16 +224,16 @@ static inline void btrfs_insert_inode_hash(struct inode *inode)
|
||||
__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
|
||||
* type == BTRFS_ROOT_ITEM_KEY: subvol dir
|
||||
*/
|
||||
if (!ino || BTRFS_I(inode)->location.type == BTRFS_ROOT_ITEM_KEY)
|
||||
ino = inode->i_ino;
|
||||
if (!ino || inode->location.type == BTRFS_ROOT_ITEM_KEY)
|
||||
ino = inode->vfs_inode.i_ino;
|
||||
return ino;
|
||||
}
|
||||
|
||||
@ -248,23 +248,21 @@ static inline bool btrfs_is_free_space_inode(struct inode *inode)
|
||||
struct btrfs_root *root = BTRFS_I(inode)->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;
|
||||
if (BTRFS_I(inode)->location.objectid == BTRFS_FREE_INO_OBJECTID)
|
||||
return true;
|
||||
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;
|
||||
|
||||
spin_lock(&BTRFS_I(inode)->lock);
|
||||
if (BTRFS_I(inode)->logged_trans == generation &&
|
||||
BTRFS_I(inode)->last_sub_trans <=
|
||||
BTRFS_I(inode)->last_log_commit &&
|
||||
BTRFS_I(inode)->last_sub_trans <=
|
||||
BTRFS_I(inode)->root->last_log_commit) {
|
||||
spin_lock(&inode->lock);
|
||||
if (inode->logged_trans == generation &&
|
||||
inode->last_sub_trans <= inode->last_log_commit &&
|
||||
inode->last_sub_trans <= inode->root->last_log_commit) {
|
||||
/*
|
||||
* After a ranged fsync we might have left some extent maps
|
||||
* (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)
|
||||
* will be called and process those extent maps.
|
||||
*/
|
||||
smp_mb();
|
||||
if (list_empty(&BTRFS_I(inode)->extent_tree.modified_extents))
|
||||
if (list_empty(&inode->extent_tree.modified_extents))
|
||||
ret = 1;
|
||||
}
|
||||
spin_unlock(&BTRFS_I(inode)->lock);
|
||||
spin_unlock(&inode->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -326,6 +324,24 @@ static inline void btrfs_inode_resume_unlocked_dio(struct inode *inode)
|
||||
&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);
|
||||
|
||||
#endif
|
||||
|
@ -124,10 +124,8 @@ static int check_compressed_csum(struct inode *inode,
|
||||
kunmap_atomic(kaddr);
|
||||
|
||||
if (csum != *cb_sum) {
|
||||
btrfs_info(BTRFS_I(inode)->root->fs_info,
|
||||
"csum failed ino %llu extent %llu csum %u wanted %u mirror %d",
|
||||
btrfs_ino(inode), disk_start, csum, *cb_sum,
|
||||
cb->mirror_num);
|
||||
btrfs_print_data_csum_error(inode, disk_start, csum,
|
||||
*cb_sum, cb->mirror_num);
|
||||
ret = -EIO;
|
||||
goto fail;
|
||||
}
|
||||
|
128
fs/btrfs/ctree.c
128
fs/btrfs/ctree.c
@ -28,9 +28,9 @@
|
||||
|
||||
static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root
|
||||
*root, struct btrfs_path *path, int level);
|
||||
static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
|
||||
*root, struct btrfs_key *ins_key,
|
||||
struct btrfs_path *path, int data_size, int extend);
|
||||
static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root *root,
|
||||
const struct btrfs_key *ins_key, struct btrfs_path *path,
|
||||
int data_size, int extend);
|
||||
static int push_node_left(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_fs_info *fs_info,
|
||||
struct extent_buffer *dst,
|
||||
@ -426,7 +426,7 @@ void btrfs_put_tree_mod_seq(struct btrfs_fs_info *fs_info,
|
||||
tm_root = &fs_info->tree_mod_log;
|
||||
for (node = rb_first(tm_root); node; node = next) {
|
||||
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)
|
||||
continue;
|
||||
rb_erase(node, tm_root);
|
||||
@ -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;
|
||||
new = &tm_root->rb_node;
|
||||
while (*new) {
|
||||
cur = container_of(*new, struct tree_mod_elem, node);
|
||||
cur = rb_entry(*new, struct tree_mod_elem, node);
|
||||
parent = *new;
|
||||
if (cur->logical < tm->logical)
|
||||
new = &((*new)->rb_left);
|
||||
@ -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;
|
||||
node = tm_root->rb_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) {
|
||||
node = node->rb_left;
|
||||
} else if (cur->logical > start) {
|
||||
@ -1074,7 +1074,7 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans,
|
||||
ret = btrfs_dec_ref(trans, root, buf, 1);
|
||||
BUG_ON(ret); /* -ENOMEM */
|
||||
}
|
||||
clean_tree_block(trans, fs_info, buf);
|
||||
clean_tree_block(fs_info, buf);
|
||||
*last_ref = 1;
|
||||
}
|
||||
return 0;
|
||||
@ -1326,7 +1326,7 @@ __tree_mod_log_rewind(struct btrfs_fs_info *fs_info, struct extent_buffer *eb,
|
||||
next = rb_next(&tm->node);
|
||||
if (!next)
|
||||
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)
|
||||
break;
|
||||
}
|
||||
@ -1580,7 +1580,8 @@ static int close_blocks(u64 blocknr, u64 other, u32 blocksize)
|
||||
/*
|
||||
* 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;
|
||||
|
||||
@ -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
|
||||
*/
|
||||
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)
|
||||
return 1;
|
||||
@ -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
|
||||
*/
|
||||
static noinline int generic_bin_search(struct extent_buffer *eb,
|
||||
unsigned long p,
|
||||
int item_size, struct btrfs_key *key,
|
||||
unsigned long p, int item_size,
|
||||
const struct btrfs_key *key,
|
||||
int max, int *slot)
|
||||
{
|
||||
int low = 0;
|
||||
@ -1802,7 +1803,7 @@ static noinline int generic_bin_search(struct extent_buffer *eb,
|
||||
* simple bin_search frontend that does the right thing for
|
||||
* 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)
|
||||
{
|
||||
if (level == 0)
|
||||
@ -1819,7 +1820,7 @@ static int bin_search(struct extent_buffer *eb, struct btrfs_key *key,
|
||||
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)
|
||||
{
|
||||
return bin_search(eb, key, level, slot);
|
||||
@ -1937,7 +1938,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
|
||||
|
||||
path->locks[level] = 0;
|
||||
path->nodes[level] = NULL;
|
||||
clean_tree_block(trans, fs_info, mid);
|
||||
clean_tree_block(fs_info, mid);
|
||||
btrfs_tree_unlock(mid);
|
||||
/* once for the path */
|
||||
free_extent_buffer(mid);
|
||||
@ -1998,7 +1999,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
|
||||
if (wret < 0 && wret != -ENOSPC)
|
||||
ret = wret;
|
||||
if (btrfs_header_nritems(right) == 0) {
|
||||
clean_tree_block(trans, fs_info, right);
|
||||
clean_tree_block(fs_info, right);
|
||||
btrfs_tree_unlock(right);
|
||||
del_ptr(root, path, level + 1, pslot + 1);
|
||||
root_sub_used(root, right->len);
|
||||
@ -2042,7 +2043,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
|
||||
BUG_ON(wret == 1);
|
||||
}
|
||||
if (btrfs_header_nritems(mid) == 0) {
|
||||
clean_tree_block(trans, fs_info, mid);
|
||||
clean_tree_block(fs_info, mid);
|
||||
btrfs_tree_unlock(mid);
|
||||
del_ptr(root, path, level + 1, pslot);
|
||||
root_sub_used(root, mid->len);
|
||||
@ -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.
|
||||
*/
|
||||
static int
|
||||
read_block_for_search(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root, struct btrfs_path *p,
|
||||
struct extent_buffer **eb_ret, int level, int slot,
|
||||
struct btrfs_key *key, u64 time_seq)
|
||||
read_block_for_search(struct btrfs_root *root, struct btrfs_path *p,
|
||||
struct extent_buffer **eb_ret, int level, int slot,
|
||||
const struct btrfs_key *key)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = root->fs_info;
|
||||
u64 blocknr;
|
||||
@ -2587,7 +2587,7 @@ done:
|
||||
}
|
||||
|
||||
static void key_search_validate(struct extent_buffer *b,
|
||||
struct btrfs_key *key,
|
||||
const struct btrfs_key *key,
|
||||
int level)
|
||||
{
|
||||
#ifdef CONFIG_BTRFS_ASSERT
|
||||
@ -2606,7 +2606,7 @@ static void key_search_validate(struct extent_buffer *b,
|
||||
#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)
|
||||
{
|
||||
if (*prev_cmp != 0) {
|
||||
@ -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
|
||||
* possible)
|
||||
*/
|
||||
int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root
|
||||
*root, struct btrfs_key *key, struct btrfs_path *p, int
|
||||
ins_len, int cow)
|
||||
int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root *root,
|
||||
const struct btrfs_key *key, struct btrfs_path *p,
|
||||
int ins_len, int cow)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = root->fs_info;
|
||||
struct extent_buffer *b;
|
||||
@ -2870,8 +2870,8 @@ cow_done:
|
||||
goto done;
|
||||
}
|
||||
|
||||
err = read_block_for_search(trans, root, p,
|
||||
&b, level, slot, key, 0);
|
||||
err = read_block_for_search(root, p, &b, level,
|
||||
slot, key);
|
||||
if (err == -EAGAIN)
|
||||
goto again;
|
||||
if (err) {
|
||||
@ -2953,7 +2953,7 @@ done:
|
||||
* 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.
|
||||
*/
|
||||
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_fs_info *fs_info = root->fs_info;
|
||||
@ -3014,8 +3014,8 @@ again:
|
||||
goto done;
|
||||
}
|
||||
|
||||
err = read_block_for_search(NULL, root, p, &b, level,
|
||||
slot, key, time_seq);
|
||||
err = read_block_for_search(root, p, &b, level,
|
||||
slot, key);
|
||||
if (err == -EAGAIN)
|
||||
goto again;
|
||||
if (err) {
|
||||
@ -3067,8 +3067,9 @@ done:
|
||||
* < 0 on error
|
||||
*/
|
||||
int btrfs_search_slot_for_read(struct btrfs_root *root,
|
||||
struct btrfs_key *key, struct btrfs_path *p,
|
||||
int find_higher, int return_any)
|
||||
const struct btrfs_key *key,
|
||||
struct btrfs_path *p, int find_higher,
|
||||
int return_any)
|
||||
{
|
||||
int ret;
|
||||
struct extent_buffer *leaf;
|
||||
@ -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,
|
||||
struct btrfs_path *path,
|
||||
struct btrfs_key *new_key)
|
||||
const struct btrfs_key *new_key)
|
||||
{
|
||||
struct btrfs_disk_key disk_key;
|
||||
struct extent_buffer *eb;
|
||||
@ -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
|
||||
* right. We'll push up to and including min_slot, but no lower
|
||||
*/
|
||||
static noinline int __push_leaf_right(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_fs_info *fs_info,
|
||||
static noinline int __push_leaf_right(struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_path *path,
|
||||
int data_size, int empty,
|
||||
struct extent_buffer *right,
|
||||
@ -3704,7 +3704,7 @@ static noinline int __push_leaf_right(struct btrfs_trans_handle *trans,
|
||||
if (left_nritems)
|
||||
btrfs_mark_buffer_dirty(left);
|
||||
else
|
||||
clean_tree_block(trans, fs_info, left);
|
||||
clean_tree_block(fs_info, left);
|
||||
|
||||
btrfs_mark_buffer_dirty(right);
|
||||
|
||||
@ -3716,7 +3716,7 @@ static noinline int __push_leaf_right(struct btrfs_trans_handle *trans,
|
||||
if (path->slots[0] >= left_nritems) {
|
||||
path->slots[0] -= left_nritems;
|
||||
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]);
|
||||
free_extent_buffer(path->nodes[0]);
|
||||
path->nodes[0] = right;
|
||||
@ -3809,7 +3809,7 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
|
||||
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);
|
||||
out_unlock:
|
||||
btrfs_tree_unlock(right);
|
||||
@ -3825,8 +3825,7 @@ out_unlock:
|
||||
* item at 'max_slot' won't be touched. Use (u32)-1 to make us do all the
|
||||
* items
|
||||
*/
|
||||
static noinline int __push_leaf_left(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_fs_info *fs_info,
|
||||
static noinline int __push_leaf_left(struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_path *path, int data_size,
|
||||
int empty, struct extent_buffer *left,
|
||||
int free_space, u32 right_nritems,
|
||||
@ -3945,7 +3944,7 @@ static noinline int __push_leaf_left(struct btrfs_trans_handle *trans,
|
||||
if (right_nritems)
|
||||
btrfs_mark_buffer_dirty(right);
|
||||
else
|
||||
clean_tree_block(trans, fs_info, right);
|
||||
clean_tree_block(fs_info, right);
|
||||
|
||||
btrfs_item_key(right, &disk_key, 0);
|
||||
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
|
||||
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,
|
||||
max_slot);
|
||||
out:
|
||||
@ -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,
|
||||
struct btrfs_root *root,
|
||||
struct btrfs_key *ins_key,
|
||||
const struct btrfs_key *ins_key,
|
||||
struct btrfs_path *path, int data_size,
|
||||
int extend)
|
||||
{
|
||||
@ -4412,10 +4411,9 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static noinline int split_item(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_fs_info *fs_info,
|
||||
static noinline int split_item(struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_path *path,
|
||||
struct btrfs_key *new_key,
|
||||
const struct btrfs_key *new_key,
|
||||
unsigned long split_offset)
|
||||
{
|
||||
struct extent_buffer *leaf;
|
||||
@ -4501,7 +4499,7 @@ static noinline int split_item(struct btrfs_trans_handle *trans,
|
||||
int btrfs_split_item(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
struct btrfs_path *path,
|
||||
struct btrfs_key *new_key,
|
||||
const struct btrfs_key *new_key,
|
||||
unsigned long split_offset)
|
||||
{
|
||||
int ret;
|
||||
@ -4510,7 +4508,7 @@ int btrfs_split_item(struct btrfs_trans_handle *trans,
|
||||
if (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;
|
||||
}
|
||||
|
||||
@ -4525,7 +4523,7 @@ int btrfs_split_item(struct btrfs_trans_handle *trans,
|
||||
int btrfs_duplicate_item(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
struct btrfs_path *path,
|
||||
struct btrfs_key *new_key)
|
||||
const struct btrfs_key *new_key)
|
||||
{
|
||||
struct extent_buffer *leaf;
|
||||
int ret;
|
||||
@ -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
|
||||
*/
|
||||
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)
|
||||
{
|
||||
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,
|
||||
int btrfs_insert_empty_items(struct btrfs_trans_handle *trans,
|
||||
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,
|
||||
int nr)
|
||||
{
|
||||
int ret = 0;
|
||||
@ -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.
|
||||
* 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
|
||||
*root, struct btrfs_key *cpu_key, void *data, u32
|
||||
data_size)
|
||||
int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root *root,
|
||||
const struct btrfs_key *cpu_key, void *data,
|
||||
u32 data_size)
|
||||
{
|
||||
int ret = 0;
|
||||
struct btrfs_path *path;
|
||||
@ -5008,7 +5006,7 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root,
|
||||
btrfs_set_header_level(leaf, 0);
|
||||
} else {
|
||||
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);
|
||||
}
|
||||
} else {
|
||||
@ -5243,7 +5241,7 @@ out:
|
||||
|
||||
static int tree_move_down(struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_path *path,
|
||||
int *level, int root_level)
|
||||
int *level)
|
||||
{
|
||||
struct extent_buffer *eb;
|
||||
|
||||
@ -5258,8 +5256,7 @@ static int tree_move_down(struct btrfs_fs_info *fs_info,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tree_move_next_or_upnext(struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_path *path,
|
||||
static int tree_move_next_or_upnext(struct btrfs_path *path,
|
||||
int *level, int root_level)
|
||||
{
|
||||
int ret = 0;
|
||||
@ -5298,10 +5295,9 @@ static int tree_advance(struct btrfs_fs_info *fs_info,
|
||||
int ret;
|
||||
|
||||
if (*level == 0 || !allow_down) {
|
||||
ret = tree_move_next_or_upnext(fs_info, path, level,
|
||||
root_level);
|
||||
ret = tree_move_next_or_upnext(path, level, root_level);
|
||||
} else {
|
||||
ret = tree_move_down(fs_info, path, level, root_level);
|
||||
ret = tree_move_down(fs_info, path, level);
|
||||
}
|
||||
if (ret >= 0) {
|
||||
if (*level == 0)
|
||||
@ -5784,8 +5780,8 @@ again:
|
||||
|
||||
next = c;
|
||||
next_rw_lock = path->locks[level];
|
||||
ret = read_block_for_search(NULL, root, path, &next, level,
|
||||
slot, &key, 0);
|
||||
ret = read_block_for_search(root, path, &next, level,
|
||||
slot, &key);
|
||||
if (ret == -EAGAIN)
|
||||
goto again;
|
||||
|
||||
@ -5834,8 +5830,8 @@ again:
|
||||
if (!level)
|
||||
break;
|
||||
|
||||
ret = read_block_for_search(NULL, root, path, &next, level,
|
||||
0, &key, 0);
|
||||
ret = read_block_for_search(root, path, &next, level,
|
||||
0, &key);
|
||||
if (ret == -EAGAIN)
|
||||
goto again;
|
||||
|
||||
|
@ -97,6 +97,14 @@ static const int btrfs_csum_sizes[] = { 4 };
|
||||
|
||||
#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 extent_map_tree map_tree;
|
||||
};
|
||||
@ -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);
|
||||
|
||||
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->type = disk->type;
|
||||
@ -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,
|
||||
struct btrfs_key *cpu)
|
||||
const struct btrfs_key *cpu)
|
||||
{
|
||||
disk->offset = cpu_to_le64(cpu->offset);
|
||||
disk->type = cpu->type;
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
static inline u8 btrfs_key_type(struct btrfs_key *key)
|
||||
static inline u8 btrfs_key_type(const struct btrfs_key *key)
|
||||
{
|
||||
return key->type;
|
||||
}
|
||||
@ -2577,8 +2584,7 @@ int btrfs_pin_extent_for_log_replay(struct btrfs_fs_info *fs_info,
|
||||
u64 bytenr, u64 num_bytes);
|
||||
int btrfs_exclude_logged_extents(struct btrfs_fs_info *fs_info,
|
||||
struct extent_buffer *eb);
|
||||
int btrfs_cross_ref_exist(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
int btrfs_cross_ref_exist(struct btrfs_root *root,
|
||||
u64 objectid, u64 offset, u64 bytenr);
|
||||
struct btrfs_block_group_cache *btrfs_lookup_block_group(
|
||||
struct btrfs_fs_info *info,
|
||||
@ -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);
|
||||
int get_block_group_index(struct btrfs_block_group_cache *cache);
|
||||
struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root, u64 parent,
|
||||
u64 root_objectid,
|
||||
struct btrfs_disk_key *key, int level,
|
||||
u64 hint, u64 empty_size);
|
||||
struct btrfs_root *root,
|
||||
u64 parent, u64 root_objectid,
|
||||
const struct btrfs_disk_key *key,
|
||||
int level, u64 hint,
|
||||
u64 empty_size);
|
||||
void btrfs_free_tree_block(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
struct extent_buffer *buf,
|
||||
@ -2623,8 +2630,7 @@ int btrfs_free_reserved_extent(struct btrfs_fs_info *fs_info,
|
||||
u64 start, u64 len, int delalloc);
|
||||
int btrfs_free_and_pin_reserved_extent(struct btrfs_fs_info *fs_info,
|
||||
u64 start, u64 len);
|
||||
void btrfs_prepare_extent_commit(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_fs_info *fs_info);
|
||||
void btrfs_prepare_extent_commit(struct btrfs_fs_info *fs_info);
|
||||
int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_fs_info *fs_info);
|
||||
int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
|
||||
@ -2696,8 +2702,7 @@ int btrfs_subvolume_reserve_metadata(struct btrfs_root *root,
|
||||
int nitems,
|
||||
u64 *qgroup_reserved, bool use_global_rsv);
|
||||
void btrfs_subvolume_release_metadata(struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_block_rsv *rsv,
|
||||
u64 qgroup_reserved);
|
||||
struct btrfs_block_rsv *rsv);
|
||||
int btrfs_delalloc_reserve_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);
|
||||
@ -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,
|
||||
struct btrfs_block_rsv *block_rsv,
|
||||
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);
|
||||
void btrfs_dec_block_group_ro(struct btrfs_block_group_cache *cache);
|
||||
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,
|
||||
struct btrfs_fs_info *info, u64 start, u64 end);
|
||||
|
||||
/* 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 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,
|
||||
struct btrfs_path *path, u64 min_objectid,
|
||||
int type);
|
||||
@ -2760,7 +2765,7 @@ int btrfs_previous_extent_item(struct btrfs_root *root,
|
||||
struct btrfs_path *path, u64 min_objectid);
|
||||
void btrfs_set_item_key_safe(struct btrfs_fs_info *fs_info,
|
||||
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_lock_root_node(struct btrfs_root *root);
|
||||
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,
|
||||
int btrfs_split_item(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
struct btrfs_path *path,
|
||||
struct btrfs_key *new_key,
|
||||
const struct btrfs_key *new_key,
|
||||
unsigned long split_offset);
|
||||
int btrfs_duplicate_item(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
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,
|
||||
u64 inum, u64 ioff, u8 key_type, struct btrfs_key *found_key);
|
||||
int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root
|
||||
*root, struct btrfs_key *key, struct btrfs_path *p, int
|
||||
ins_len, int cow);
|
||||
int btrfs_search_old_slot(struct btrfs_root *root, struct btrfs_key *key,
|
||||
int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root *root,
|
||||
const struct btrfs_key *key, struct btrfs_path *p,
|
||||
int ins_len, int cow);
|
||||
int btrfs_search_old_slot(struct btrfs_root *root, const struct btrfs_key *key,
|
||||
struct btrfs_path *p, u64 time_seq);
|
||||
int btrfs_search_slot_for_read(struct btrfs_root *root,
|
||||
struct btrfs_key *key, struct btrfs_path *p,
|
||||
int find_higher, int return_any);
|
||||
const struct btrfs_key *key,
|
||||
struct btrfs_path *p, int find_higher,
|
||||
int return_any);
|
||||
int btrfs_realloc_node(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root, struct extent_buffer *parent,
|
||||
int start_slot, u64 *last_ret,
|
||||
@ -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,
|
||||
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);
|
||||
int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root
|
||||
*root, struct btrfs_key *key, void *data, u32 data_size);
|
||||
int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root *root,
|
||||
const struct btrfs_key *key, void *data, u32 data_size);
|
||||
int btrfs_insert_empty_items(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
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,
|
||||
struct btrfs_root *root,
|
||||
struct btrfs_path *path,
|
||||
struct btrfs_key *key,
|
||||
const struct btrfs_key *key,
|
||||
u32 data_size)
|
||||
{
|
||||
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,
|
||||
u64 root_id, u64 ref_id, u64 dirid, u64 *sequence,
|
||||
const char *name, int name_len);
|
||||
int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root,
|
||||
struct btrfs_key *key);
|
||||
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);
|
||||
int btrfs_insert_root(struct btrfs_trans_handle *trans, struct btrfs_root *root,
|
||||
const struct btrfs_key *key,
|
||||
struct btrfs_root_item *item);
|
||||
int __must_check btrfs_update_root(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
struct btrfs_key *key,
|
||||
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_key *root_key);
|
||||
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);
|
||||
int btrfs_set_inode_index(struct inode *dir, u64 *index);
|
||||
int btrfs_unlink_inode(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
struct inode *dir, struct inode *inode,
|
||||
struct btrfs_inode *dir, struct btrfs_inode *inode,
|
||||
const char *name, int name_len);
|
||||
int btrfs_add_link(struct btrfs_trans_handle *trans,
|
||||
struct inode *parent_inode, struct inode *inode,
|
||||
@ -3447,7 +3454,8 @@ do { \
|
||||
"BTRFS: Transaction aborted (error %d)\n", \
|
||||
(errno)); \
|
||||
} else { \
|
||||
pr_debug("BTRFS: Transaction aborted (error %d)\n", \
|
||||
btrfs_debug((trans)->fs_info, \
|
||||
"Transaction aborted (error %d)", \
|
||||
(errno)); \
|
||||
} \
|
||||
} \
|
||||
|
@ -72,14 +72,14 @@ static inline int btrfs_is_continuous_delayed_item(
|
||||
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;
|
||||
u64 ino = btrfs_ino(inode);
|
||||
u64 ino = btrfs_ino(btrfs_inode);
|
||||
struct btrfs_delayed_node *node;
|
||||
|
||||
node = ACCESS_ONCE(btrfs_inode->delayed_node);
|
||||
node = READ_ONCE(btrfs_inode->delayed_node);
|
||||
if (node) {
|
||||
atomic_inc(&node->refs);
|
||||
return node;
|
||||
@ -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) */
|
||||
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_inode *btrfs_inode = BTRFS_I(inode);
|
||||
struct btrfs_root *root = btrfs_inode->root;
|
||||
u64 ino = btrfs_ino(inode);
|
||||
u64 ino = btrfs_ino(btrfs_inode);
|
||||
int ret;
|
||||
|
||||
again:
|
||||
node = btrfs_get_delayed_node(inode);
|
||||
node = btrfs_get_delayed_node(btrfs_inode);
|
||||
if (node)
|
||||
return node;
|
||||
|
||||
@ -574,7 +573,7 @@ static void btrfs_delayed_item_release_metadata(struct btrfs_fs_info *fs_info,
|
||||
static int btrfs_delayed_inode_reserve_metadata(
|
||||
struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
struct inode *inode,
|
||||
struct btrfs_inode *inode,
|
||||
struct btrfs_delayed_node *node)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = root->fs_info;
|
||||
@ -603,13 +602,13 @@ static int btrfs_delayed_inode_reserve_metadata(
|
||||
* worth which is less likely to hurt us.
|
||||
*/
|
||||
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,
|
||||
&BTRFS_I(inode)->runtime_flags))
|
||||
&inode->runtime_flags))
|
||||
release = true;
|
||||
else
|
||||
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,
|
||||
}
|
||||
|
||||
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_path *path;
|
||||
@ -1233,9 +1232,9 @@ int btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans,
|
||||
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_delayed_node *delayed_node = btrfs_get_delayed_node(inode);
|
||||
struct btrfs_path *path;
|
||||
@ -1288,15 +1287,15 @@ out:
|
||||
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;
|
||||
|
||||
delayed_node = ACCESS_ONCE(BTRFS_I(inode)->delayed_node);
|
||||
delayed_node = READ_ONCE(inode->delayed_node);
|
||||
if (!delayed_node)
|
||||
return;
|
||||
|
||||
BTRFS_I(inode)->delayed_node = NULL;
|
||||
inode->delayed_node = NULL;
|
||||
btrfs_release_delayed_node(delayed_node);
|
||||
}
|
||||
|
||||
@ -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,
|
||||
struct btrfs_fs_info *fs_info,
|
||||
const char *name, int name_len,
|
||||
struct inode *dir,
|
||||
struct btrfs_inode *dir,
|
||||
struct btrfs_disk_key *disk_key, u8 type,
|
||||
u64 index)
|
||||
{
|
||||
@ -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,
|
||||
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_item *item;
|
||||
@ -1558,7 +1557,7 @@ end:
|
||||
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);
|
||||
|
||||
@ -1575,7 +1574,7 @@ int btrfs_inode_delayed_dir_index_count(struct inode *inode)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
BTRFS_I(inode)->index_cnt = delayed_node->index_cnt;
|
||||
inode->index_cnt = delayed_node->index_cnt;
|
||||
btrfs_release_delayed_node(delayed_node);
|
||||
return 0;
|
||||
}
|
||||
@ -1587,7 +1586,7 @@ bool btrfs_readdir_get_delayed_items(struct inode *inode,
|
||||
struct btrfs_delayed_node *delayed_node;
|
||||
struct btrfs_delayed_item *item;
|
||||
|
||||
delayed_node = btrfs_get_delayed_node(inode);
|
||||
delayed_node = btrfs_get_delayed_node(BTRFS_I(inode));
|
||||
if (!delayed_node)
|
||||
return false;
|
||||
|
||||
@ -1776,7 +1775,7 @@ int btrfs_fill_inode(struct inode *inode, u32 *rdev)
|
||||
struct btrfs_delayed_node *delayed_node;
|
||||
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)
|
||||
return -ENOENT;
|
||||
|
||||
@ -1831,7 +1830,7 @@ int btrfs_delayed_update_inode(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_delayed_node *delayed_node;
|
||||
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))
|
||||
return PTR_ERR(delayed_node);
|
||||
|
||||
@ -1841,7 +1840,7 @@ int btrfs_delayed_update_inode(struct btrfs_trans_handle *trans,
|
||||
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);
|
||||
if (ret)
|
||||
goto release_node;
|
||||
@ -1856,9 +1855,9 @@ release_node:
|
||||
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;
|
||||
|
||||
/*
|
||||
@ -1933,7 +1932,7 @@ static void __btrfs_kill_delayed_node(struct btrfs_delayed_node *delayed_node)
|
||||
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;
|
||||
|
||||
|
@ -101,15 +101,15 @@ static inline void btrfs_init_delayed_root(
|
||||
int btrfs_insert_delayed_dir_index(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_fs_info *fs_info,
|
||||
const char *name, int name_len,
|
||||
struct inode *dir,
|
||||
struct btrfs_inode *dir,
|
||||
struct btrfs_disk_key *disk_key, u8 type,
|
||||
u64 index);
|
||||
|
||||
int btrfs_delete_delayed_dir_index(struct btrfs_trans_handle *trans,
|
||||
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,
|
||||
struct btrfs_fs_info *fs_info);
|
||||
@ -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);
|
||||
|
||||
int btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans,
|
||||
struct inode *inode);
|
||||
struct btrfs_inode *inode);
|
||||
/* Used for evicting the inode. */
|
||||
void btrfs_remove_delayed_node(struct inode *inode);
|
||||
void btrfs_kill_delayed_inode_items(struct inode *inode);
|
||||
int btrfs_commit_inode_delayed_inode(struct inode *inode);
|
||||
void btrfs_remove_delayed_node(struct btrfs_inode *inode);
|
||||
void btrfs_kill_delayed_inode_items(struct btrfs_inode *inode);
|
||||
int btrfs_commit_inode_delayed_inode(struct btrfs_inode *inode);
|
||||
|
||||
|
||||
int btrfs_delayed_update_inode(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root, struct inode *inode);
|
||||
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 */
|
||||
void btrfs_kill_all_delayed_nodes(struct btrfs_root *root);
|
||||
|
@ -550,13 +550,14 @@ add_delayed_ref_head(struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_delayed_ref_node *ref,
|
||||
struct btrfs_qgroup_extent_record *qrecord,
|
||||
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 *head_ref = NULL;
|
||||
struct btrfs_delayed_ref_root *delayed_refs;
|
||||
int count_mod = 1;
|
||||
int must_insert_reserved = 0;
|
||||
int qrecord_inserted = 0;
|
||||
|
||||
/* If reserved is provided, it must be a data extent. */
|
||||
BUG_ON(!is_data && reserved);
|
||||
@ -623,6 +624,8 @@ add_delayed_ref_head(struct btrfs_fs_info *fs_info,
|
||||
if(btrfs_qgroup_trace_extent_nolock(fs_info,
|
||||
delayed_refs, qrecord))
|
||||
kfree(qrecord);
|
||||
else
|
||||
qrecord_inserted = 1;
|
||||
}
|
||||
|
||||
spin_lock_init(&head_ref->lock);
|
||||
@ -650,6 +653,8 @@ add_delayed_ref_head(struct btrfs_fs_info *fs_info,
|
||||
atomic_inc(&delayed_refs->num_entries);
|
||||
trans->delayed_ref_updates++;
|
||||
}
|
||||
if (qrecord_inserted_ret)
|
||||
*qrecord_inserted_ret = qrecord_inserted;
|
||||
return head_ref;
|
||||
}
|
||||
|
||||
@ -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_root *delayed_refs;
|
||||
struct btrfs_qgroup_extent_record *record = NULL;
|
||||
int qrecord_inserted;
|
||||
|
||||
BUG_ON(extent_op && extent_op->is_data);
|
||||
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,
|
||||
* the spin lock
|
||||
*/
|
||||
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,
|
||||
num_bytes, parent, ref_root, level, action);
|
||||
spin_unlock(&delayed_refs->lock);
|
||||
|
||||
if (qrecord_inserted)
|
||||
return btrfs_qgroup_trace_extent_post(fs_info, record);
|
||||
return 0;
|
||||
|
||||
free_head_ref:
|
||||
@ -829,15 +838,14 @@ int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_trans_handle *trans,
|
||||
u64 bytenr, u64 num_bytes,
|
||||
u64 parent, u64 ref_root,
|
||||
u64 owner, u64 offset, u64 reserved, int action,
|
||||
struct btrfs_delayed_extent_op *extent_op)
|
||||
u64 owner, u64 offset, u64 reserved, int action)
|
||||
{
|
||||
struct btrfs_delayed_data_ref *ref;
|
||||
struct btrfs_delayed_ref_head *head_ref;
|
||||
struct btrfs_delayed_ref_root *delayed_refs;
|
||||
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);
|
||||
if (!ref)
|
||||
return -ENOMEM;
|
||||
@ -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;
|
||||
spin_lock(&delayed_refs->lock);
|
||||
@ -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,
|
||||
bytenr, num_bytes, ref_root, reserved,
|
||||
action, 1);
|
||||
action, 1, &qrecord_inserted);
|
||||
|
||||
add_delayed_data_ref(fs_info, trans, head_ref, &ref->node, bytenr,
|
||||
num_bytes, parent, ref_root, owner, offset,
|
||||
action);
|
||||
spin_unlock(&delayed_refs->lock);
|
||||
|
||||
if (qrecord_inserted)
|
||||
return btrfs_qgroup_trace_extent_post(fs_info, record);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -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,
|
||||
num_bytes, 0, 0, BTRFS_UPDATE_DELAYED_HEAD,
|
||||
extent_op->is_data);
|
||||
extent_op->is_data, NULL);
|
||||
|
||||
spin_unlock(&delayed_refs->lock);
|
||||
return 0;
|
||||
@ -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.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -250,8 +250,7 @@ int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_trans_handle *trans,
|
||||
u64 bytenr, u64 num_bytes,
|
||||
u64 parent, u64 ref_root,
|
||||
u64 owner, u64 offset, u64 reserved, int action,
|
||||
struct btrfs_delayed_extent_op *extent_op);
|
||||
u64 owner, u64 offset, u64 reserved, int action);
|
||||
int btrfs_add_delayed_extent_op(struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_trans_handle *trans,
|
||||
u64 bytenr, u64 num_bytes,
|
||||
@ -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 *
|
||||
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,
|
||||
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
|
||||
struct btrfs_disk_key disk_key;
|
||||
u32 data_size;
|
||||
|
||||
key.objectid = btrfs_ino(dir);
|
||||
key.objectid = btrfs_ino(BTRFS_I(dir));
|
||||
key.type = BTRFS_DIR_ITEM_KEY;
|
||||
key.offset = btrfs_name_hash(name, name_len);
|
||||
|
||||
@ -174,8 +174,7 @@ second_insert:
|
||||
btrfs_release_path(path);
|
||||
|
||||
ret2 = btrfs_insert_delayed_dir_index(trans, root->fs_info, name,
|
||||
name_len, dir, &disk_key, type,
|
||||
index);
|
||||
name_len, BTRFS_I(dir), &disk_key, type, index);
|
||||
out_free:
|
||||
btrfs_free_path(path);
|
||||
if (ret)
|
||||
|
@ -64,8 +64,7 @@
|
||||
static const struct extent_io_ops btree_extent_io_ops;
|
||||
static void end_workqueue_fn(struct btrfs_work *work);
|
||||
static void free_fs_root(struct btrfs_root *root);
|
||||
static int btrfs_check_super_valid(struct btrfs_fs_info *fs_info,
|
||||
int read_only);
|
||||
static int btrfs_check_super_valid(struct btrfs_fs_info *fs_info);
|
||||
static void btrfs_destroy_ordered_extents(struct btrfs_root *root);
|
||||
static int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans,
|
||||
struct btrfs_fs_info *fs_info);
|
||||
@ -1005,7 +1004,7 @@ static int __btree_submit_bio_done(struct inode *inode, struct bio *bio,
|
||||
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)
|
||||
return 0;
|
||||
@ -1021,7 +1020,7 @@ static int btree_submit_bio_hook(struct inode *inode, struct bio *bio,
|
||||
u64 bio_offset)
|
||||
{
|
||||
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;
|
||||
|
||||
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,
|
||||
|
||||
}
|
||||
|
||||
void clean_tree_block(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_fs_info *fs_info,
|
||||
void clean_tree_block(struct btrfs_fs_info *fs_info,
|
||||
struct extent_buffer *buf)
|
||||
{
|
||||
if (btrfs_header_generation(buf) ==
|
||||
@ -2802,7 +2800,7 @@ int open_ctree(struct super_block *sb,
|
||||
|
||||
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) {
|
||||
btrfs_err(fs_info, "superblock contains fatal errors");
|
||||
err = -EINVAL;
|
||||
@ -3411,7 +3409,7 @@ struct buffer_head *btrfs_read_dev_super(struct block_device *bdev)
|
||||
*/
|
||||
static int write_dev_supers(struct btrfs_device *device,
|
||||
struct btrfs_super_block *sb,
|
||||
int do_barriers, int wait, int max_mirrors)
|
||||
int wait, int max_mirrors)
|
||||
{
|
||||
struct buffer_head *bh;
|
||||
int i;
|
||||
@ -3696,7 +3694,7 @@ int btrfs_calc_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 btrfs_device *dev;
|
||||
@ -3753,7 +3751,7 @@ static int write_all_supers(struct btrfs_fs_info *fs_info, int max_mirrors)
|
||||
flags = btrfs_super_flags(sb);
|
||||
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)
|
||||
total_errors++;
|
||||
}
|
||||
@ -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)
|
||||
continue;
|
||||
|
||||
ret = write_dev_supers(dev, sb, do_barriers, 1, max_mirrors);
|
||||
ret = write_dev_supers(dev, sb, 1, max_mirrors);
|
||||
if (ret)
|
||||
total_errors++;
|
||||
}
|
||||
@ -3790,12 +3788,6 @@ static int write_all_supers(struct btrfs_fs_info *fs_info, int max_mirrors)
|
||||
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. */
|
||||
void btrfs_drop_and_free_fs_root(struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_root *root)
|
||||
@ -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);
|
||||
}
|
||||
|
||||
static int btrfs_check_super_valid(struct btrfs_fs_info *fs_info,
|
||||
int read_only)
|
||||
static int btrfs_check_super_valid(struct btrfs_fs_info *fs_info)
|
||||
{
|
||||
struct btrfs_super_block *sb = fs_info->super_copy;
|
||||
u64 nodesize = btrfs_super_nodesize(sb);
|
||||
|
@ -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 btrfs_fs_info *fs_info,
|
||||
u64 bytenr);
|
||||
void clean_tree_block(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_fs_info *fs_info, struct extent_buffer *buf);
|
||||
void clean_tree_block(struct btrfs_fs_info *fs_info, struct extent_buffer *buf);
|
||||
int open_ctree(struct super_block *sb,
|
||||
struct btrfs_fs_devices *fs_devices,
|
||||
char *options);
|
||||
void close_ctree(struct btrfs_fs_info *fs_info);
|
||||
int write_ctree_super(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_fs_info *fs_info, int max_mirrors);
|
||||
int write_all_supers(struct btrfs_fs_info *fs_info, int max_mirrors);
|
||||
struct buffer_head *btrfs_read_dev_super(struct block_device *bdev);
|
||||
int btrfs_read_dev_one_super(struct block_device *bdev, int copy_num,
|
||||
struct buffer_head **bh_ret);
|
||||
|
@ -30,7 +30,7 @@ static int btrfs_encode_fh(struct inode *inode, u32 *fh, int *max_len,
|
||||
len = BTRFS_FID_SIZE_NON_CONNECTABLE;
|
||||
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->gen = inode->i_generation;
|
||||
|
||||
@ -166,13 +166,13 @@ static struct dentry *btrfs_get_parent(struct dentry *child)
|
||||
if (!path)
|
||||
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.type = BTRFS_ROOT_BACKREF_KEY;
|
||||
key.offset = (u64)-1;
|
||||
root = fs_info->tree_root;
|
||||
} else {
|
||||
key.objectid = btrfs_ino(dir);
|
||||
key.objectid = btrfs_ino(BTRFS_I(dir));
|
||||
key.type = BTRFS_INODE_REF_KEY;
|
||||
key.offset = (u64)-1;
|
||||
}
|
||||
@ -235,13 +235,10 @@ static int btrfs_get_name(struct dentry *parent, char *name,
|
||||
int ret;
|
||||
u64 ino;
|
||||
|
||||
if (!dir || !inode)
|
||||
return -EINVAL;
|
||||
|
||||
if (!S_ISDIR(dir->i_mode))
|
||||
return -EINVAL;
|
||||
|
||||
ino = btrfs_ino(inode);
|
||||
ino = btrfs_ino(BTRFS_I(inode));
|
||||
|
||||
path = btrfs_alloc_path();
|
||||
if (!path)
|
||||
@ -255,7 +252,7 @@ static int btrfs_get_name(struct dentry *parent, char *name,
|
||||
root = fs_info->tree_root;
|
||||
} else {
|
||||
key.objectid = ino;
|
||||
key.offset = btrfs_ino(dir);
|
||||
key.offset = btrfs_ino(BTRFS_I(dir));
|
||||
key.type = BTRFS_INODE_REF_KEY;
|
||||
}
|
||||
|
||||
|
@ -888,7 +888,7 @@ search_again:
|
||||
|
||||
delayed_refs = &trans->transaction->delayed_refs;
|
||||
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 (!mutex_trylock(&head->mutex)) {
|
||||
atomic_inc(&head->node.refs);
|
||||
@ -1035,10 +1035,11 @@ out_free:
|
||||
|
||||
#ifdef BTRFS_COMPAT_EXTENT_TREE_V0
|
||||
static int convert_extent_item_v0(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_path *path,
|
||||
u64 owner, u32 extra_size)
|
||||
{
|
||||
struct btrfs_root *root = fs_info->extent_root;
|
||||
struct btrfs_extent_item *item;
|
||||
struct btrfs_extent_item_v0 *ei0;
|
||||
struct btrfs_extent_ref_v0 *ref0;
|
||||
@ -1092,7 +1093,7 @@ static int convert_extent_item_v0(struct btrfs_trans_handle *trans,
|
||||
return ret;
|
||||
BUG_ON(ret); /* Corruption */
|
||||
|
||||
btrfs_extend_item(root->fs_info, path, new_size);
|
||||
btrfs_extend_item(fs_info, path, new_size);
|
||||
|
||||
leaf = path->nodes[0];
|
||||
item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_item);
|
||||
@ -1151,12 +1152,13 @@ static int match_extent_data_ref(struct extent_buffer *leaf,
|
||||
}
|
||||
|
||||
static noinline int lookup_extent_data_ref(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_path *path,
|
||||
u64 bytenr, u64 parent,
|
||||
u64 root_objectid,
|
||||
u64 owner, u64 offset)
|
||||
{
|
||||
struct btrfs_root *root = fs_info->extent_root;
|
||||
struct btrfs_key key;
|
||||
struct btrfs_extent_data_ref *ref;
|
||||
struct extent_buffer *leaf;
|
||||
@ -1238,12 +1240,13 @@ fail:
|
||||
}
|
||||
|
||||
static noinline int insert_extent_data_ref(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_path *path,
|
||||
u64 bytenr, u64 parent,
|
||||
u64 root_objectid, u64 owner,
|
||||
u64 offset, int refs_to_add)
|
||||
{
|
||||
struct btrfs_root *root = fs_info->extent_root;
|
||||
struct btrfs_key key;
|
||||
struct extent_buffer *leaf;
|
||||
u32 size;
|
||||
@ -1317,7 +1320,7 @@ fail:
|
||||
}
|
||||
|
||||
static noinline int remove_extent_data_ref(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_path *path,
|
||||
int refs_to_drop, int *last_ref)
|
||||
{
|
||||
@ -1354,7 +1357,7 @@ static noinline int remove_extent_data_ref(struct btrfs_trans_handle *trans,
|
||||
num_refs -= refs_to_drop;
|
||||
|
||||
if (num_refs == 0) {
|
||||
ret = btrfs_del_item(trans, root, path);
|
||||
ret = btrfs_del_item(trans, fs_info->extent_root, path);
|
||||
*last_ref = 1;
|
||||
} else {
|
||||
if (key.type == BTRFS_EXTENT_DATA_REF_KEY)
|
||||
@ -1416,11 +1419,12 @@ static noinline u32 extent_data_ref_count(struct btrfs_path *path,
|
||||
}
|
||||
|
||||
static noinline int lookup_tree_block_ref(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_path *path,
|
||||
u64 bytenr, u64 parent,
|
||||
u64 root_objectid)
|
||||
{
|
||||
struct btrfs_root *root = fs_info->extent_root;
|
||||
struct btrfs_key key;
|
||||
int ret;
|
||||
|
||||
@ -1449,7 +1453,7 @@ static noinline int lookup_tree_block_ref(struct btrfs_trans_handle *trans,
|
||||
}
|
||||
|
||||
static noinline int insert_tree_block_ref(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_path *path,
|
||||
u64 bytenr, u64 parent,
|
||||
u64 root_objectid)
|
||||
@ -1466,7 +1470,8 @@ static noinline int insert_tree_block_ref(struct btrfs_trans_handle *trans,
|
||||
key.offset = root_objectid;
|
||||
}
|
||||
|
||||
ret = btrfs_insert_empty_item(trans, root, path, &key, 0);
|
||||
ret = btrfs_insert_empty_item(trans, fs_info->extent_root,
|
||||
path, &key, 0);
|
||||
btrfs_release_path(path);
|
||||
return ret;
|
||||
}
|
||||
@ -1524,14 +1529,14 @@ static int find_next_key(struct btrfs_path *path, int level,
|
||||
*/
|
||||
static noinline_for_stack
|
||||
int lookup_inline_extent_backref(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_path *path,
|
||||
struct btrfs_extent_inline_ref **ref_ret,
|
||||
u64 bytenr, u64 num_bytes,
|
||||
u64 parent, u64 root_objectid,
|
||||
u64 owner, u64 offset, int insert)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = root->fs_info;
|
||||
struct btrfs_root *root = fs_info->extent_root;
|
||||
struct btrfs_key key;
|
||||
struct extent_buffer *leaf;
|
||||
struct btrfs_extent_item *ei;
|
||||
@ -1614,7 +1619,7 @@ again:
|
||||
err = -ENOENT;
|
||||
goto out;
|
||||
}
|
||||
ret = convert_extent_item_v0(trans, root, path, owner,
|
||||
ret = convert_extent_item_v0(trans, fs_info, path, owner,
|
||||
extra_size);
|
||||
if (ret < 0) {
|
||||
err = ret;
|
||||
@ -1716,7 +1721,7 @@ out:
|
||||
* helper to add new inline back ref
|
||||
*/
|
||||
static noinline_for_stack
|
||||
void setup_inline_extent_backref(struct btrfs_root *root,
|
||||
void setup_inline_extent_backref(struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_path *path,
|
||||
struct btrfs_extent_inline_ref *iref,
|
||||
u64 parent, u64 root_objectid,
|
||||
@ -1739,7 +1744,7 @@ void setup_inline_extent_backref(struct btrfs_root *root,
|
||||
type = extent_ref_type(parent, owner);
|
||||
size = btrfs_extent_inline_ref_size(type);
|
||||
|
||||
btrfs_extend_item(root->fs_info, path, size);
|
||||
btrfs_extend_item(fs_info, path, size);
|
||||
|
||||
ei = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_item);
|
||||
refs = btrfs_extent_refs(leaf, ei);
|
||||
@ -1777,7 +1782,7 @@ void setup_inline_extent_backref(struct btrfs_root *root,
|
||||
}
|
||||
|
||||
static int lookup_extent_backref(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_path *path,
|
||||
struct btrfs_extent_inline_ref **ref_ret,
|
||||
u64 bytenr, u64 num_bytes, u64 parent,
|
||||
@ -1785,7 +1790,7 @@ static int lookup_extent_backref(struct btrfs_trans_handle *trans,
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = lookup_inline_extent_backref(trans, root, path, ref_ret,
|
||||
ret = lookup_inline_extent_backref(trans, fs_info, path, ref_ret,
|
||||
bytenr, num_bytes, parent,
|
||||
root_objectid, owner, offset, 0);
|
||||
if (ret != -ENOENT)
|
||||
@ -1795,11 +1800,12 @@ static int lookup_extent_backref(struct btrfs_trans_handle *trans,
|
||||
*ref_ret = NULL;
|
||||
|
||||
if (owner < BTRFS_FIRST_FREE_OBJECTID) {
|
||||
ret = lookup_tree_block_ref(trans, root, path, bytenr, parent,
|
||||
root_objectid);
|
||||
ret = lookup_tree_block_ref(trans, fs_info, path, bytenr,
|
||||
parent, root_objectid);
|
||||
} else {
|
||||
ret = lookup_extent_data_ref(trans, root, path, bytenr, parent,
|
||||
root_objectid, owner, offset);
|
||||
ret = lookup_extent_data_ref(trans, fs_info, path, bytenr,
|
||||
parent, root_objectid, owner,
|
||||
offset);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -1808,7 +1814,7 @@ static int lookup_extent_backref(struct btrfs_trans_handle *trans,
|
||||
* helper to update/remove inline back ref
|
||||
*/
|
||||
static noinline_for_stack
|
||||
void update_inline_extent_backref(struct btrfs_root *root,
|
||||
void update_inline_extent_backref(struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_path *path,
|
||||
struct btrfs_extent_inline_ref *iref,
|
||||
int refs_to_mod,
|
||||
@ -1866,14 +1872,14 @@ void update_inline_extent_backref(struct btrfs_root *root,
|
||||
memmove_extent_buffer(leaf, ptr, ptr + size,
|
||||
end - ptr - size);
|
||||
item_size -= size;
|
||||
btrfs_truncate_item(root->fs_info, path, item_size, 1);
|
||||
btrfs_truncate_item(fs_info, path, item_size, 1);
|
||||
}
|
||||
btrfs_mark_buffer_dirty(leaf);
|
||||
}
|
||||
|
||||
static noinline_for_stack
|
||||
int insert_inline_extent_backref(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_path *path,
|
||||
u64 bytenr, u64 num_bytes, u64 parent,
|
||||
u64 root_objectid, u64 owner,
|
||||
@ -1883,15 +1889,15 @@ int insert_inline_extent_backref(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_extent_inline_ref *iref;
|
||||
int ret;
|
||||
|
||||
ret = lookup_inline_extent_backref(trans, root, path, &iref,
|
||||
ret = lookup_inline_extent_backref(trans, fs_info, path, &iref,
|
||||
bytenr, num_bytes, parent,
|
||||
root_objectid, owner, offset, 1);
|
||||
if (ret == 0) {
|
||||
BUG_ON(owner < BTRFS_FIRST_FREE_OBJECTID);
|
||||
update_inline_extent_backref(root, path, iref,
|
||||
update_inline_extent_backref(fs_info, path, iref,
|
||||
refs_to_add, extent_op, NULL);
|
||||
} else if (ret == -ENOENT) {
|
||||
setup_inline_extent_backref(root, path, iref, parent,
|
||||
setup_inline_extent_backref(fs_info, path, iref, parent,
|
||||
root_objectid, owner, offset,
|
||||
refs_to_add, extent_op);
|
||||
ret = 0;
|
||||
@ -1900,7 +1906,7 @@ int insert_inline_extent_backref(struct btrfs_trans_handle *trans,
|
||||
}
|
||||
|
||||
static int insert_extent_backref(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_path *path,
|
||||
u64 bytenr, u64 parent, u64 root_objectid,
|
||||
u64 owner, u64 offset, int refs_to_add)
|
||||
@ -1908,10 +1914,10 @@ static int insert_extent_backref(struct btrfs_trans_handle *trans,
|
||||
int ret;
|
||||
if (owner < BTRFS_FIRST_FREE_OBJECTID) {
|
||||
BUG_ON(refs_to_add != 1);
|
||||
ret = insert_tree_block_ref(trans, root, path, bytenr,
|
||||
ret = insert_tree_block_ref(trans, fs_info, path, bytenr,
|
||||
parent, root_objectid);
|
||||
} else {
|
||||
ret = insert_extent_data_ref(trans, root, path, bytenr,
|
||||
ret = insert_extent_data_ref(trans, fs_info, path, bytenr,
|
||||
parent, root_objectid,
|
||||
owner, offset, refs_to_add);
|
||||
}
|
||||
@ -1919,7 +1925,7 @@ static int insert_extent_backref(struct btrfs_trans_handle *trans,
|
||||
}
|
||||
|
||||
static int remove_extent_backref(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_path *path,
|
||||
struct btrfs_extent_inline_ref *iref,
|
||||
int refs_to_drop, int is_data, int *last_ref)
|
||||
@ -1928,14 +1934,14 @@ static int remove_extent_backref(struct btrfs_trans_handle *trans,
|
||||
|
||||
BUG_ON(!is_data && refs_to_drop != 1);
|
||||
if (iref) {
|
||||
update_inline_extent_backref(root, path, iref,
|
||||
update_inline_extent_backref(fs_info, path, iref,
|
||||
-refs_to_drop, NULL, last_ref);
|
||||
} else if (is_data) {
|
||||
ret = remove_extent_data_ref(trans, root, path, refs_to_drop,
|
||||
ret = remove_extent_data_ref(trans, fs_info, path, refs_to_drop,
|
||||
last_ref);
|
||||
} else {
|
||||
*last_ref = 1;
|
||||
ret = btrfs_del_item(trans, root, path);
|
||||
ret = btrfs_del_item(trans, fs_info->extent_root, path);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -2089,7 +2095,7 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
|
||||
ret = btrfs_add_delayed_data_ref(fs_info, trans, bytenr,
|
||||
num_bytes, parent, root_objectid,
|
||||
owner, offset, 0,
|
||||
BTRFS_ADD_DELAYED_REF, NULL);
|
||||
BTRFS_ADD_DELAYED_REF);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -2117,9 +2123,9 @@ static int __btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
|
||||
path->reada = READA_FORWARD;
|
||||
path->leave_spinning = 1;
|
||||
/* this will setup the path even if it fails to insert the back ref */
|
||||
ret = insert_inline_extent_backref(trans, fs_info->extent_root, path,
|
||||
bytenr, num_bytes, parent,
|
||||
root_objectid, owner, offset,
|
||||
ret = insert_inline_extent_backref(trans, fs_info, path, bytenr,
|
||||
num_bytes, parent, root_objectid,
|
||||
owner, offset,
|
||||
refs_to_add, extent_op);
|
||||
if ((ret < 0 && ret != -EAGAIN) || !ret)
|
||||
goto out;
|
||||
@ -2143,9 +2149,8 @@ static int __btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
|
||||
path->reada = READA_FORWARD;
|
||||
path->leave_spinning = 1;
|
||||
/* now insert the actual backref */
|
||||
ret = insert_extent_backref(trans, fs_info->extent_root,
|
||||
path, bytenr, parent, root_objectid,
|
||||
owner, offset, refs_to_add);
|
||||
ret = insert_extent_backref(trans, fs_info, path, bytenr, parent,
|
||||
root_objectid, owner, offset, refs_to_add);
|
||||
if (ret)
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
out:
|
||||
@ -2290,8 +2295,7 @@ again:
|
||||
item_size = btrfs_item_size_nr(leaf, path->slots[0]);
|
||||
#ifdef BTRFS_COMPAT_EXTENT_TREE_V0
|
||||
if (item_size < sizeof(*ei)) {
|
||||
ret = convert_extent_item_v0(trans, fs_info->extent_root,
|
||||
path, (u64)-1, 0);
|
||||
ret = convert_extent_item_v0(trans, fs_info, path, (u64)-1, 0);
|
||||
if (ret < 0) {
|
||||
err = ret;
|
||||
goto out;
|
||||
@ -3028,8 +3032,7 @@ int btrfs_set_disk_extent_flags(struct btrfs_trans_handle *trans,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static noinline int check_delayed_ref(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
static noinline int check_delayed_ref(struct btrfs_root *root,
|
||||
struct btrfs_path *path,
|
||||
u64 objectid, u64 offset, u64 bytenr)
|
||||
{
|
||||
@ -3037,11 +3040,16 @@ static noinline int check_delayed_ref(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_delayed_ref_node *ref;
|
||||
struct btrfs_delayed_data_ref *data_ref;
|
||||
struct btrfs_delayed_ref_root *delayed_refs;
|
||||
struct btrfs_transaction *cur_trans;
|
||||
int ret = 0;
|
||||
|
||||
delayed_refs = &trans->transaction->delayed_refs;
|
||||
cur_trans = root->fs_info->running_transaction;
|
||||
if (!cur_trans)
|
||||
return 0;
|
||||
|
||||
delayed_refs = &cur_trans->delayed_refs;
|
||||
spin_lock(&delayed_refs->lock);
|
||||
head = btrfs_find_delayed_ref_head(trans, bytenr);
|
||||
head = btrfs_find_delayed_ref_head(delayed_refs, bytenr);
|
||||
if (!head) {
|
||||
spin_unlock(&delayed_refs->lock);
|
||||
return 0;
|
||||
@ -3090,8 +3098,7 @@ static noinline int check_delayed_ref(struct btrfs_trans_handle *trans,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static noinline int check_committed_ref(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
static noinline int check_committed_ref(struct btrfs_root *root,
|
||||
struct btrfs_path *path,
|
||||
u64 objectid, u64 offset, u64 bytenr)
|
||||
{
|
||||
@ -3162,9 +3169,8 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int btrfs_cross_ref_exist(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
u64 objectid, u64 offset, u64 bytenr)
|
||||
int btrfs_cross_ref_exist(struct btrfs_root *root, u64 objectid, u64 offset,
|
||||
u64 bytenr)
|
||||
{
|
||||
struct btrfs_path *path;
|
||||
int ret;
|
||||
@ -3175,12 +3181,12 @@ int btrfs_cross_ref_exist(struct btrfs_trans_handle *trans,
|
||||
return -ENOENT;
|
||||
|
||||
do {
|
||||
ret = check_committed_ref(trans, root, path, objectid,
|
||||
ret = check_committed_ref(root, path, objectid,
|
||||
offset, bytenr);
|
||||
if (ret && ret != -ENOENT)
|
||||
goto out;
|
||||
|
||||
ret2 = check_delayed_ref(trans, root, path, objectid,
|
||||
ret2 = check_delayed_ref(root, path, objectid,
|
||||
offset, bytenr);
|
||||
} while (ret2 == -EAGAIN);
|
||||
|
||||
@ -3368,7 +3374,7 @@ static int cache_save_setup(struct btrfs_block_group_cache *block_group,
|
||||
if (trans->aborted)
|
||||
return 0;
|
||||
again:
|
||||
inode = lookup_free_space_inode(root, block_group, path);
|
||||
inode = lookup_free_space_inode(fs_info, block_group, path);
|
||||
if (IS_ERR(inode) && PTR_ERR(inode) != -ENOENT) {
|
||||
ret = PTR_ERR(inode);
|
||||
btrfs_release_path(path);
|
||||
@ -3382,7 +3388,8 @@ again:
|
||||
if (block_group->ro)
|
||||
goto out_free;
|
||||
|
||||
ret = create_free_space_inode(root, trans, block_group, path);
|
||||
ret = create_free_space_inode(fs_info, trans, block_group,
|
||||
path);
|
||||
if (ret)
|
||||
goto out_free;
|
||||
goto again;
|
||||
@ -3424,7 +3431,7 @@ again:
|
||||
if (ret)
|
||||
goto out_put;
|
||||
|
||||
ret = btrfs_truncate_free_space_cache(root, trans, NULL, inode);
|
||||
ret = btrfs_truncate_free_space_cache(trans, NULL, inode);
|
||||
if (ret)
|
||||
goto out_put;
|
||||
}
|
||||
@ -4119,6 +4126,15 @@ u64 btrfs_get_alloc_profile(struct btrfs_root *root, int data)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static u64 btrfs_space_info_used(struct btrfs_space_info *s_info,
|
||||
bool may_use_included)
|
||||
{
|
||||
ASSERT(s_info);
|
||||
return s_info->bytes_used + s_info->bytes_reserved +
|
||||
s_info->bytes_pinned + s_info->bytes_readonly +
|
||||
(may_use_included ? s_info->bytes_may_use : 0);
|
||||
}
|
||||
|
||||
int btrfs_alloc_data_chunk_ondemand(struct inode *inode, u64 bytes)
|
||||
{
|
||||
struct btrfs_space_info *data_sinfo;
|
||||
@ -4144,9 +4160,7 @@ int btrfs_alloc_data_chunk_ondemand(struct inode *inode, u64 bytes)
|
||||
again:
|
||||
/* make sure we have enough space to handle the data first */
|
||||
spin_lock(&data_sinfo->lock);
|
||||
used = data_sinfo->bytes_used + data_sinfo->bytes_reserved +
|
||||
data_sinfo->bytes_pinned + data_sinfo->bytes_readonly +
|
||||
data_sinfo->bytes_may_use;
|
||||
used = btrfs_space_info_used(data_sinfo, true);
|
||||
|
||||
if (used + bytes > data_sinfo->total_bytes) {
|
||||
struct btrfs_trans_handle *trans;
|
||||
@ -4421,9 +4435,7 @@ void check_system_chunk(struct btrfs_trans_handle *trans,
|
||||
|
||||
info = __find_space_info(fs_info, BTRFS_BLOCK_GROUP_SYSTEM);
|
||||
spin_lock(&info->lock);
|
||||
left = info->total_bytes - info->bytes_used - info->bytes_pinned -
|
||||
info->bytes_reserved - info->bytes_readonly -
|
||||
info->bytes_may_use;
|
||||
left = info->total_bytes - btrfs_space_info_used(info, true);
|
||||
spin_unlock(&info->lock);
|
||||
|
||||
num_devs = get_profile_num_devs(fs_info, type);
|
||||
@ -4606,8 +4618,7 @@ static int can_overcommit(struct btrfs_root *root,
|
||||
return 0;
|
||||
|
||||
profile = btrfs_get_alloc_profile(root, 0);
|
||||
used = space_info->bytes_used + space_info->bytes_reserved +
|
||||
space_info->bytes_pinned + space_info->bytes_readonly;
|
||||
used = btrfs_space_info_used(space_info, false);
|
||||
|
||||
/*
|
||||
* We only want to allow over committing if we have lots of actual space
|
||||
@ -4787,11 +4798,10 @@ skip_async:
|
||||
* get us somewhere and then commit the transaction if it does. Otherwise it
|
||||
* will return -ENOSPC.
|
||||
*/
|
||||
static int may_commit_transaction(struct btrfs_root *root,
|
||||
static int may_commit_transaction(struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_space_info *space_info,
|
||||
u64 bytes, int force)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = root->fs_info;
|
||||
struct btrfs_block_rsv *delayed_rsv = &fs_info->delayed_block_rsv;
|
||||
struct btrfs_trans_handle *trans;
|
||||
|
||||
@ -4823,7 +4833,7 @@ static int may_commit_transaction(struct btrfs_root *root,
|
||||
spin_unlock(&delayed_rsv->lock);
|
||||
|
||||
commit:
|
||||
trans = btrfs_join_transaction(root);
|
||||
trans = btrfs_join_transaction(fs_info->fs_root);
|
||||
if (IS_ERR(trans))
|
||||
return -ENOSPC;
|
||||
|
||||
@ -4837,11 +4847,11 @@ struct reserve_ticket {
|
||||
wait_queue_head_t wait;
|
||||
};
|
||||
|
||||
static int flush_space(struct btrfs_root *root,
|
||||
static int flush_space(struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_space_info *space_info, u64 num_bytes,
|
||||
u64 orig_bytes, int state)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = root->fs_info;
|
||||
struct btrfs_root *root = fs_info->fs_root;
|
||||
struct btrfs_trans_handle *trans;
|
||||
int nr;
|
||||
int ret = 0;
|
||||
@ -4881,7 +4891,8 @@ static int flush_space(struct btrfs_root *root,
|
||||
ret = 0;
|
||||
break;
|
||||
case COMMIT_TRANS:
|
||||
ret = may_commit_transaction(root, space_info, orig_bytes, 0);
|
||||
ret = may_commit_transaction(fs_info, space_info,
|
||||
orig_bytes, 0);
|
||||
break;
|
||||
default:
|
||||
ret = -ENOSPC;
|
||||
@ -4993,8 +5004,8 @@ static void btrfs_async_reclaim_metadata_space(struct work_struct *work)
|
||||
struct reserve_ticket *ticket;
|
||||
int ret;
|
||||
|
||||
ret = flush_space(fs_info->fs_root, space_info, to_reclaim,
|
||||
to_reclaim, flush_state);
|
||||
ret = flush_space(fs_info, space_info, to_reclaim, to_reclaim,
|
||||
flush_state);
|
||||
spin_lock(&space_info->lock);
|
||||
if (list_empty(&space_info->tickets)) {
|
||||
space_info->flush = 0;
|
||||
@ -5049,8 +5060,8 @@ static void priority_reclaim_metadata_space(struct btrfs_fs_info *fs_info,
|
||||
spin_unlock(&space_info->lock);
|
||||
|
||||
do {
|
||||
flush_space(fs_info->fs_root, space_info, to_reclaim,
|
||||
to_reclaim, flush_state);
|
||||
flush_space(fs_info, space_info, to_reclaim, to_reclaim,
|
||||
flush_state);
|
||||
flush_state++;
|
||||
spin_lock(&space_info->lock);
|
||||
if (ticket->bytes == 0) {
|
||||
@ -5135,9 +5146,7 @@ static int __reserve_metadata_bytes(struct btrfs_root *root,
|
||||
|
||||
spin_lock(&space_info->lock);
|
||||
ret = -ENOSPC;
|
||||
used = space_info->bytes_used + space_info->bytes_reserved +
|
||||
space_info->bytes_pinned + space_info->bytes_readonly +
|
||||
space_info->bytes_may_use;
|
||||
used = btrfs_space_info_used(space_info, true);
|
||||
|
||||
/*
|
||||
* If we have enough space then hooray, make our reservation and carry
|
||||
@ -5630,9 +5639,7 @@ static void update_global_block_rsv(struct btrfs_fs_info *fs_info)
|
||||
block_rsv->size = min_t(u64, num_bytes, SZ_512M);
|
||||
|
||||
if (block_rsv->reserved < block_rsv->size) {
|
||||
num_bytes = sinfo->bytes_used + sinfo->bytes_pinned +
|
||||
sinfo->bytes_reserved + sinfo->bytes_readonly +
|
||||
sinfo->bytes_may_use;
|
||||
num_bytes = btrfs_space_info_used(sinfo, true);
|
||||
if (sinfo->total_bytes > num_bytes) {
|
||||
num_bytes = sinfo->total_bytes - num_bytes;
|
||||
num_bytes = min(num_bytes,
|
||||
@ -5756,7 +5763,7 @@ int btrfs_orphan_reserve_metadata(struct btrfs_trans_handle *trans,
|
||||
u64 num_bytes = btrfs_calc_trans_metadata_size(fs_info, 1);
|
||||
|
||||
trace_btrfs_space_reservation(fs_info, "orphan",
|
||||
btrfs_ino(inode), num_bytes, 1);
|
||||
btrfs_ino(BTRFS_I(inode)), num_bytes, 1);
|
||||
return btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes, 1);
|
||||
}
|
||||
|
||||
@ -5767,7 +5774,7 @@ void btrfs_orphan_release_metadata(struct inode *inode)
|
||||
u64 num_bytes = btrfs_calc_trans_metadata_size(fs_info, 1);
|
||||
|
||||
trace_btrfs_space_reservation(fs_info, "orphan",
|
||||
btrfs_ino(inode), num_bytes, 0);
|
||||
btrfs_ino(BTRFS_I(inode)), num_bytes, 0);
|
||||
btrfs_block_rsv_release(fs_info, root->orphan_block_rsv, num_bytes);
|
||||
}
|
||||
|
||||
@ -5799,7 +5806,7 @@ int btrfs_subvolume_reserve_metadata(struct btrfs_root *root,
|
||||
if (test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags)) {
|
||||
/* One for parent inode, two for dir entries */
|
||||
num_bytes = 3 * fs_info->nodesize;
|
||||
ret = btrfs_qgroup_reserve_meta(root, num_bytes);
|
||||
ret = btrfs_qgroup_reserve_meta(root, num_bytes, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else {
|
||||
@ -5824,8 +5831,7 @@ int btrfs_subvolume_reserve_metadata(struct btrfs_root *root,
|
||||
}
|
||||
|
||||
void btrfs_subvolume_release_metadata(struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_block_rsv *rsv,
|
||||
u64 qgroup_reserved)
|
||||
struct btrfs_block_rsv *rsv)
|
||||
{
|
||||
btrfs_block_rsv_release(fs_info, rsv, (u64)-1);
|
||||
}
|
||||
@ -5844,11 +5850,9 @@ static unsigned drop_outstanding_extent(struct inode *inode, u64 num_bytes)
|
||||
{
|
||||
unsigned drop_inode_space = 0;
|
||||
unsigned dropped_extents = 0;
|
||||
unsigned num_extents = 0;
|
||||
unsigned num_extents;
|
||||
|
||||
num_extents = (unsigned)div64_u64(num_bytes +
|
||||
BTRFS_MAX_EXTENT_SIZE - 1,
|
||||
BTRFS_MAX_EXTENT_SIZE);
|
||||
num_extents = count_max_extents(num_bytes);
|
||||
ASSERT(num_extents);
|
||||
ASSERT(BTRFS_I(inode)->outstanding_extents >= num_extents);
|
||||
BTRFS_I(inode)->outstanding_extents -= num_extents;
|
||||
@ -5927,7 +5931,7 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes)
|
||||
struct btrfs_block_rsv *block_rsv = &fs_info->delalloc_block_rsv;
|
||||
u64 to_reserve = 0;
|
||||
u64 csum_bytes;
|
||||
unsigned nr_extents = 0;
|
||||
unsigned nr_extents;
|
||||
enum btrfs_reserve_flush_enum flush = BTRFS_RESERVE_FLUSH_ALL;
|
||||
int ret = 0;
|
||||
bool delalloc_lock = true;
|
||||
@ -5960,9 +5964,7 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes)
|
||||
num_bytes = ALIGN(num_bytes, fs_info->sectorsize);
|
||||
|
||||
spin_lock(&BTRFS_I(inode)->lock);
|
||||
nr_extents = (unsigned)div64_u64(num_bytes +
|
||||
BTRFS_MAX_EXTENT_SIZE - 1,
|
||||
BTRFS_MAX_EXTENT_SIZE);
|
||||
nr_extents = count_max_extents(num_bytes);
|
||||
BTRFS_I(inode)->outstanding_extents += nr_extents;
|
||||
|
||||
nr_extents = 0;
|
||||
@ -5979,7 +5981,7 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes)
|
||||
|
||||
if (test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags)) {
|
||||
ret = btrfs_qgroup_reserve_meta(root,
|
||||
nr_extents * fs_info->nodesize);
|
||||
nr_extents * fs_info->nodesize, true);
|
||||
if (ret)
|
||||
goto out_fail;
|
||||
}
|
||||
@ -6005,7 +6007,7 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes)
|
||||
|
||||
if (to_reserve)
|
||||
trace_btrfs_space_reservation(fs_info, "delalloc",
|
||||
btrfs_ino(inode), to_reserve, 1);
|
||||
btrfs_ino(BTRFS_I(inode)), to_reserve, 1);
|
||||
if (release_extra)
|
||||
btrfs_block_rsv_release(fs_info, block_rsv,
|
||||
btrfs_calc_trans_metadata_size(fs_info, 1));
|
||||
@ -6068,7 +6070,7 @@ out_fail:
|
||||
if (to_free) {
|
||||
btrfs_block_rsv_release(fs_info, block_rsv, to_free);
|
||||
trace_btrfs_space_reservation(fs_info, "delalloc",
|
||||
btrfs_ino(inode), to_free, 0);
|
||||
btrfs_ino(BTRFS_I(inode)), to_free, 0);
|
||||
}
|
||||
if (delalloc_lock)
|
||||
mutex_unlock(&BTRFS_I(inode)->delalloc_mutex);
|
||||
@ -6104,7 +6106,7 @@ void btrfs_delalloc_release_metadata(struct inode *inode, u64 num_bytes)
|
||||
return;
|
||||
|
||||
trace_btrfs_space_reservation(fs_info, "delalloc",
|
||||
btrfs_ino(inode), to_free, 0);
|
||||
btrfs_ino(BTRFS_I(inode)), to_free, 0);
|
||||
|
||||
btrfs_block_rsv_release(fs_info, &fs_info->delalloc_block_rsv, to_free);
|
||||
}
|
||||
@ -6561,8 +6563,7 @@ static int btrfs_free_reserved_bytes(struct btrfs_block_group_cache *cache,
|
||||
spin_unlock(&space_info->lock);
|
||||
return ret;
|
||||
}
|
||||
void btrfs_prepare_extent_commit(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_fs_info *fs_info)
|
||||
void btrfs_prepare_extent_commit(struct btrfs_fs_info *fs_info)
|
||||
{
|
||||
struct btrfs_caching_control *next;
|
||||
struct btrfs_caching_control *caching_ctl;
|
||||
@ -6845,7 +6846,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
|
||||
if (is_data)
|
||||
skinny_metadata = 0;
|
||||
|
||||
ret = lookup_extent_backref(trans, extent_root, path, &iref,
|
||||
ret = lookup_extent_backref(trans, info, path, &iref,
|
||||
bytenr, num_bytes, parent,
|
||||
root_objectid, owner_objectid,
|
||||
owner_offset);
|
||||
@ -6877,8 +6878,8 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
|
||||
#endif
|
||||
if (!found_extent) {
|
||||
BUG_ON(iref);
|
||||
ret = remove_extent_backref(trans, extent_root, path,
|
||||
NULL, refs_to_drop,
|
||||
ret = remove_extent_backref(trans, info, path, NULL,
|
||||
refs_to_drop,
|
||||
is_data, &last_ref);
|
||||
if (ret) {
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
@ -6953,8 +6954,8 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
|
||||
#ifdef BTRFS_COMPAT_EXTENT_TREE_V0
|
||||
if (item_size < sizeof(*ei)) {
|
||||
BUG_ON(found_extent || extent_slot != path->slots[0]);
|
||||
ret = convert_extent_item_v0(trans, extent_root, path,
|
||||
owner_objectid, 0);
|
||||
ret = convert_extent_item_v0(trans, info, path, owner_objectid,
|
||||
0);
|
||||
if (ret < 0) {
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
goto out;
|
||||
@ -7021,7 +7022,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
|
||||
btrfs_mark_buffer_dirty(leaf);
|
||||
}
|
||||
if (found_extent) {
|
||||
ret = remove_extent_backref(trans, extent_root, path,
|
||||
ret = remove_extent_backref(trans, info, path,
|
||||
iref, refs_to_drop,
|
||||
is_data, &last_ref);
|
||||
if (ret) {
|
||||
@ -7095,7 +7096,7 @@ static noinline int check_ref_cleanup(struct btrfs_trans_handle *trans,
|
||||
|
||||
delayed_refs = &trans->transaction->delayed_refs;
|
||||
spin_lock(&delayed_refs->lock);
|
||||
head = btrfs_find_delayed_ref_head(trans, bytenr);
|
||||
head = btrfs_find_delayed_ref_head(delayed_refs, bytenr);
|
||||
if (!head)
|
||||
goto out_delayed_unlock;
|
||||
|
||||
@ -7244,7 +7245,7 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans,
|
||||
num_bytes,
|
||||
parent, root_objectid, owner,
|
||||
offset, 0,
|
||||
BTRFS_DROP_DELAYED_REF, NULL);
|
||||
BTRFS_DROP_DELAYED_REF);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -7419,12 +7420,11 @@ btrfs_release_block_group(struct btrfs_block_group_cache *cache,
|
||||
* If there is no suitable free space, we will record the max size of
|
||||
* the free space extent currently.
|
||||
*/
|
||||
static noinline int find_free_extent(struct btrfs_root *orig_root,
|
||||
static noinline int find_free_extent(struct btrfs_fs_info *fs_info,
|
||||
u64 ram_bytes, u64 num_bytes, u64 empty_size,
|
||||
u64 hint_byte, struct btrfs_key *ins,
|
||||
u64 flags, int delalloc)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = orig_root->fs_info;
|
||||
int ret = 0;
|
||||
struct btrfs_root *root = fs_info->extent_root;
|
||||
struct btrfs_free_cluster *last_ptr = NULL;
|
||||
@ -7716,18 +7716,20 @@ unclustered_alloc:
|
||||
last_ptr->fragmented = 1;
|
||||
spin_unlock(&last_ptr->lock);
|
||||
}
|
||||
spin_lock(&block_group->free_space_ctl->tree_lock);
|
||||
if (cached &&
|
||||
block_group->free_space_ctl->free_space <
|
||||
num_bytes + empty_cluster + empty_size) {
|
||||
if (block_group->free_space_ctl->free_space >
|
||||
max_extent_size)
|
||||
max_extent_size =
|
||||
block_group->free_space_ctl->free_space;
|
||||
spin_unlock(&block_group->free_space_ctl->tree_lock);
|
||||
goto loop;
|
||||
if (cached) {
|
||||
struct btrfs_free_space_ctl *ctl =
|
||||
block_group->free_space_ctl;
|
||||
|
||||
spin_lock(&ctl->tree_lock);
|
||||
if (ctl->free_space <
|
||||
num_bytes + empty_cluster + empty_size) {
|
||||
if (ctl->free_space > max_extent_size)
|
||||
max_extent_size = ctl->free_space;
|
||||
spin_unlock(&ctl->tree_lock);
|
||||
goto loop;
|
||||
}
|
||||
spin_unlock(&ctl->tree_lock);
|
||||
}
|
||||
spin_unlock(&block_group->free_space_ctl->tree_lock);
|
||||
|
||||
offset = btrfs_find_space_for_alloc(block_group, search_start,
|
||||
num_bytes, empty_size,
|
||||
@ -7908,9 +7910,8 @@ static void dump_space_info(struct btrfs_fs_info *fs_info,
|
||||
spin_lock(&info->lock);
|
||||
btrfs_info(fs_info, "space_info %llu has %llu free, is %sfull",
|
||||
info->flags,
|
||||
info->total_bytes - info->bytes_used - info->bytes_pinned -
|
||||
info->bytes_reserved - info->bytes_readonly -
|
||||
info->bytes_may_use, (info->full) ? "" : "not ");
|
||||
info->total_bytes - btrfs_space_info_used(info, true),
|
||||
info->full ? "" : "not ");
|
||||
btrfs_info(fs_info,
|
||||
"space_info total=%llu, used=%llu, pinned=%llu, reserved=%llu, may_use=%llu, readonly=%llu",
|
||||
info->total_bytes, info->bytes_used, info->bytes_pinned,
|
||||
@ -7951,7 +7952,7 @@ int btrfs_reserve_extent(struct btrfs_root *root, u64 ram_bytes,
|
||||
flags = btrfs_get_alloc_profile(root, is_data);
|
||||
again:
|
||||
WARN_ON(num_bytes < fs_info->sectorsize);
|
||||
ret = find_free_extent(root, ram_bytes, num_bytes, empty_size,
|
||||
ret = find_free_extent(fs_info, ram_bytes, num_bytes, empty_size,
|
||||
hint_byte, ins, flags, delalloc);
|
||||
if (!ret && !is_data) {
|
||||
btrfs_dec_block_group_reservations(fs_info, ins->objectid);
|
||||
@ -8194,8 +8195,7 @@ int btrfs_alloc_reserved_file_extent(struct btrfs_trans_handle *trans,
|
||||
ret = btrfs_add_delayed_data_ref(fs_info, trans, ins->objectid,
|
||||
ins->offset, 0,
|
||||
root_objectid, owner, offset,
|
||||
ram_bytes, BTRFS_ADD_DELAYED_EXTENT,
|
||||
NULL);
|
||||
ram_bytes, BTRFS_ADD_DELAYED_EXTENT);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -8256,7 +8256,7 @@ btrfs_init_new_buffer(struct btrfs_trans_handle *trans, struct btrfs_root *root,
|
||||
btrfs_set_header_generation(buf, trans->transid);
|
||||
btrfs_set_buffer_lockdep_class(root->root_key.objectid, buf, level);
|
||||
btrfs_tree_lock(buf);
|
||||
clean_tree_block(trans, fs_info, buf);
|
||||
clean_tree_block(fs_info, buf);
|
||||
clear_bit(EXTENT_BUFFER_STALE, &buf->bflags);
|
||||
|
||||
btrfs_set_lock_blocking(buf);
|
||||
@ -8351,10 +8351,11 @@ static void unuse_block_rsv(struct btrfs_fs_info *fs_info,
|
||||
* returns the tree buffer or an ERR_PTR on error.
|
||||
*/
|
||||
struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
u64 parent, u64 root_objectid,
|
||||
struct btrfs_disk_key *key, int level,
|
||||
u64 hint, u64 empty_size)
|
||||
struct btrfs_root *root,
|
||||
u64 parent, u64 root_objectid,
|
||||
const struct btrfs_disk_key *key,
|
||||
int level, u64 hint,
|
||||
u64 empty_size)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = root->fs_info;
|
||||
struct btrfs_key ins;
|
||||
@ -8876,7 +8877,7 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans,
|
||||
btrfs_set_lock_blocking(eb);
|
||||
path->locks[level] = BTRFS_WRITE_LOCK_BLOCKING;
|
||||
}
|
||||
clean_tree_block(trans, fs_info, eb);
|
||||
clean_tree_block(fs_info, eb);
|
||||
}
|
||||
|
||||
if (eb == root->node) {
|
||||
@ -9346,8 +9347,7 @@ static int inc_block_group_ro(struct btrfs_block_group_cache *cache, int force)
|
||||
num_bytes = cache->key.offset - cache->reserved - cache->pinned -
|
||||
cache->bytes_super - btrfs_block_group_used(&cache->item);
|
||||
|
||||
if (sinfo->bytes_used + sinfo->bytes_reserved + sinfo->bytes_pinned +
|
||||
sinfo->bytes_may_use + sinfo->bytes_readonly + num_bytes +
|
||||
if (btrfs_space_info_used(sinfo, true) + num_bytes +
|
||||
min_allocable_bytes <= sinfo->total_bytes) {
|
||||
sinfo->bytes_readonly += num_bytes;
|
||||
cache->ro++;
|
||||
@ -9360,17 +9360,16 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
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_fs_info *fs_info = root->fs_info;
|
||||
struct btrfs_trans_handle *trans;
|
||||
u64 alloc_flags;
|
||||
int ret;
|
||||
|
||||
again:
|
||||
trans = btrfs_join_transaction(root);
|
||||
trans = btrfs_join_transaction(fs_info->extent_root);
|
||||
if (IS_ERR(trans))
|
||||
return PTR_ERR(trans);
|
||||
|
||||
@ -9557,9 +9556,8 @@ int btrfs_can_relocate(struct btrfs_fs_info *fs_info, u64 bytenr)
|
||||
* all of the extents from this block group. If we can, we're good
|
||||
*/
|
||||
if ((space_info->total_bytes != block_group->key.offset) &&
|
||||
(space_info->bytes_used + space_info->bytes_reserved +
|
||||
space_info->bytes_pinned + space_info->bytes_readonly +
|
||||
min_free < space_info->total_bytes)) {
|
||||
(btrfs_space_info_used(space_info, false) + min_free <
|
||||
space_info->total_bytes)) {
|
||||
spin_unlock(&space_info->lock);
|
||||
goto out;
|
||||
}
|
||||
@ -10317,7 +10315,7 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
|
||||
* get the inode first so any iput calls done for the io_list
|
||||
* aren't the final iput (no unlinks allowed now)
|
||||
*/
|
||||
inode = lookup_free_space_inode(tree_root, block_group, path);
|
||||
inode = lookup_free_space_inode(fs_info, block_group, path);
|
||||
|
||||
mutex_lock(&trans->transaction->cache_write_mutex);
|
||||
/*
|
||||
|
@ -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) {
|
||||
btrfs_debug_rl(BTRFS_I(inode)->root->fs_info,
|
||||
"%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
|
||||
@ -144,7 +144,7 @@ static void add_extent_changeset(struct extent_state *state, unsigned bits,
|
||||
if (!set && (state->state & bits) == 0)
|
||||
return;
|
||||
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);
|
||||
/* ENOMEM */
|
||||
BUG_ON(ret < 0);
|
||||
@ -226,6 +226,11 @@ static struct extent_state *alloc_extent_state(gfp_t mask)
|
||||
{
|
||||
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);
|
||||
if (!state)
|
||||
return state;
|
||||
@ -1549,33 +1554,24 @@ out:
|
||||
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,
|
||||
struct page *locked_page,
|
||||
u64 start, u64 end)
|
||||
{
|
||||
int ret;
|
||||
struct page *pages[16];
|
||||
unsigned long index = start >> 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)
|
||||
return;
|
||||
|
||||
while (nr_pages > 0) {
|
||||
ret = find_get_pages_contig(inode->i_mapping, index,
|
||||
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();
|
||||
}
|
||||
__process_pages_contig(inode->i_mapping, locked_page, index, end_index,
|
||||
PAGE_UNLOCK, NULL);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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 pages_locked = 0;
|
||||
struct page *pages[16];
|
||||
unsigned long nrpages;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
/* the caller is responsible for locking the start index */
|
||||
ASSERT(locked_page);
|
||||
if (index == locked_page->index && index == end_index)
|
||||
return 0;
|
||||
|
||||
/* skip the page at the start index */
|
||||
nrpages = end_index - index + 1;
|
||||
while (nrpages > 0) {
|
||||
ret = find_get_pages_contig(inode->i_mapping, index,
|
||||
min_t(unsigned long,
|
||||
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);
|
||||
}
|
||||
ret = __process_pages_contig(inode->i_mapping, locked_page, index,
|
||||
end_index, PAGE_LOCK, &index_ret);
|
||||
if (ret == -EAGAIN)
|
||||
__unlock_for_delalloc(inode, locked_page, delalloc_start,
|
||||
(u64)index_ret << PAGE_SHIFT);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1726,37 +1682,47 @@ out_failed:
|
||||
return found;
|
||||
}
|
||||
|
||||
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)
|
||||
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)
|
||||
{
|
||||
struct extent_io_tree *tree = &BTRFS_I(inode)->io_tree;
|
||||
int ret;
|
||||
unsigned long nr_pages = end_index - start_index + 1;
|
||||
unsigned long pages_locked = 0;
|
||||
pgoff_t index = start_index;
|
||||
struct page *pages[16];
|
||||
unsigned long index = start >> PAGE_SHIFT;
|
||||
unsigned long end_index = end >> PAGE_SHIFT;
|
||||
unsigned long nr_pages = end_index - index + 1;
|
||||
unsigned ret;
|
||||
int err = 0;
|
||||
int i;
|
||||
|
||||
clear_extent_bit(tree, start, end, clear_bits, 1, 0, NULL, GFP_NOFS);
|
||||
if (page_ops == 0)
|
||||
return;
|
||||
if (page_ops & PAGE_LOCK) {
|
||||
ASSERT(page_ops == PAGE_LOCK);
|
||||
ASSERT(index_ret && *index_ret == start_index);
|
||||
}
|
||||
|
||||
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) {
|
||||
ret = find_get_pages_contig(inode->i_mapping, index,
|
||||
ret = find_get_pages_contig(mapping, index,
|
||||
min_t(unsigned long,
|
||||
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)
|
||||
SetPagePrivate2(pages[i]);
|
||||
|
||||
if (pages[i] == locked_page) {
|
||||
put_page(pages[i]);
|
||||
pages_locked++;
|
||||
continue;
|
||||
}
|
||||
if (page_ops & PAGE_CLEAR_DIRTY)
|
||||
@ -1769,12 +1735,40 @@ void extent_clear_unlock_delalloc(struct inode *inode, u64 start, u64 end,
|
||||
end_page_writeback(pages[i]);
|
||||
if (page_ops & PAGE_UNLOCK)
|
||||
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]);
|
||||
pages_locked++;
|
||||
}
|
||||
nr_pages -= ret;
|
||||
index += ret;
|
||||
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,
|
||||
|
||||
btrfs_info_rl_in_rcu(fs_info,
|
||||
"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);
|
||||
btrfs_bio_counter_dec(fs_info);
|
||||
bio_put(bio);
|
||||
@ -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,
|
||||
struct block_device *bdev,
|
||||
struct bio **bio_ret,
|
||||
unsigned long max_pages,
|
||||
bio_end_io_t end_io_func,
|
||||
int mirror_num,
|
||||
unsigned long prev_bio_flags,
|
||||
@ -2931,7 +2924,6 @@ static int __do_readpage(struct extent_io_tree *tree,
|
||||
}
|
||||
}
|
||||
while (cur <= end) {
|
||||
unsigned long pnr = (last_byte >> PAGE_SHIFT) + 1;
|
||||
bool force_bio_submit = false;
|
||||
|
||||
if (cur >= last_byte) {
|
||||
@ -3066,10 +3058,9 @@ static int __do_readpage(struct extent_io_tree *tree,
|
||||
continue;
|
||||
}
|
||||
|
||||
pnr -= page->index;
|
||||
ret = submit_extent_page(REQ_OP_READ, read_flags, tree, NULL,
|
||||
page, sector, disk_io_size, pg_offset,
|
||||
bdev, bio, pnr,
|
||||
bdev, bio,
|
||||
end_bio_extent_readpage, mirror_num,
|
||||
*bio_flags,
|
||||
this_bio_flag,
|
||||
@ -3210,7 +3201,7 @@ int extent_read_full_page(struct extent_io_tree *tree, struct page *page,
|
||||
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)
|
||||
{
|
||||
wbc->nr_to_write -= nr_written;
|
||||
@ -3330,7 +3321,6 @@ static noinline_for_stack int __extent_writepage_io(struct inode *inode,
|
||||
u64 block_start;
|
||||
u64 iosize;
|
||||
sector_t sector;
|
||||
struct extent_state *cached_state = NULL;
|
||||
struct extent_map *em;
|
||||
struct block_device *bdev;
|
||||
size_t pg_offset = 0;
|
||||
@ -3349,10 +3339,9 @@ static noinline_for_stack int __extent_writepage_io(struct inode *inode,
|
||||
else
|
||||
redirty_page_for_writepage(wbc, page);
|
||||
|
||||
update_nr_written(page, wbc, nr_written);
|
||||
update_nr_written(wbc, nr_written);
|
||||
unlock_page(page);
|
||||
ret = 1;
|
||||
goto done_unlocked;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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,
|
||||
* 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;
|
||||
if (i_size <= start) {
|
||||
@ -3374,7 +3363,6 @@ static noinline_for_stack int __extent_writepage_io(struct inode *inode,
|
||||
|
||||
while (cur <= end) {
|
||||
u64 em_end;
|
||||
unsigned long max_nr;
|
||||
|
||||
if (cur >= i_size) {
|
||||
if (tree->ops && tree->ops->writepage_end_io_hook)
|
||||
@ -3431,8 +3419,6 @@ static noinline_for_stack int __extent_writepage_io(struct inode *inode,
|
||||
continue;
|
||||
}
|
||||
|
||||
max_nr = (i_size >> PAGE_SHIFT) + 1;
|
||||
|
||||
set_range_writeback(tree, cur, cur + iosize - 1);
|
||||
if (!PageWriteback(page)) {
|
||||
btrfs_err(BTRFS_I(inode)->root->fs_info,
|
||||
@ -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,
|
||||
page, sector, iosize, pg_offset,
|
||||
bdev, &epd->bio, max_nr,
|
||||
bdev, &epd->bio,
|
||||
end_bio_extent_writepage,
|
||||
0, 0, 0, false);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
SetPageError(page);
|
||||
if (PageWriteback(page))
|
||||
end_page_writeback(page);
|
||||
}
|
||||
|
||||
cur = cur + iosize;
|
||||
pg_offset += iosize;
|
||||
@ -3454,11 +3443,6 @@ static noinline_for_stack int __extent_writepage_io(struct inode *inode,
|
||||
}
|
||||
done:
|
||||
*nr_ret = nr;
|
||||
|
||||
done_unlocked:
|
||||
|
||||
/* drop our reference on any cached states */
|
||||
free_extent_state(cached_state);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -3761,20 +3745,21 @@ static noinline_for_stack int write_one_eb(struct extent_buffer *eb,
|
||||
set_page_writeback(p);
|
||||
ret = submit_extent_page(REQ_OP_WRITE, write_flags, tree, wbc,
|
||||
p, offset >> 9, PAGE_SIZE, 0, bdev,
|
||||
&epd->bio, -1,
|
||||
&epd->bio,
|
||||
end_bio_extent_buffer_writepage,
|
||||
0, epd->bio_flags, bio_flags, false);
|
||||
epd->bio_flags = bio_flags;
|
||||
if (ret) {
|
||||
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))
|
||||
end_extent_buffer_writeback(eb);
|
||||
ret = -EIO;
|
||||
break;
|
||||
}
|
||||
offset += PAGE_SIZE;
|
||||
update_nr_written(p, wbc, 1);
|
||||
update_nr_written(wbc, 1);
|
||||
unlock_page(p);
|
||||
}
|
||||
|
||||
@ -3926,8 +3911,7 @@ retry:
|
||||
* WB_SYNC_ALL then we were called for data integrity and we must wait for
|
||||
* existing IO to complete.
|
||||
*/
|
||||
static int extent_write_cache_pages(struct extent_io_tree *tree,
|
||||
struct address_space *mapping,
|
||||
static int extent_write_cache_pages(struct address_space *mapping,
|
||||
struct writeback_control *wbc,
|
||||
writepage_t writepage, void *data,
|
||||
void (*flush_fn)(void *))
|
||||
@ -4168,8 +4152,7 @@ int extent_writepages(struct extent_io_tree *tree,
|
||||
.bio_flags = 0,
|
||||
};
|
||||
|
||||
ret = extent_write_cache_pages(tree, mapping, wbc,
|
||||
__extent_writepage, &epd,
|
||||
ret = extent_write_cache_pages(mapping, wbc, __extent_writepage, &epd,
|
||||
flush_write_bio);
|
||||
flush_epd_write_bio(&epd);
|
||||
return ret;
|
||||
@ -4264,8 +4247,6 @@ static int try_release_extent_state(struct extent_map_tree *map,
|
||||
EXTENT_IOBITS, 0, NULL))
|
||||
ret = 0;
|
||||
else {
|
||||
if ((mask & GFP_NOFS) == GFP_NOFS)
|
||||
mask = GFP_NOFS;
|
||||
/*
|
||||
* at this point we can safely clear everything except the
|
||||
* locked bit and the nodatasum bit
|
||||
@ -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
|
||||
* because there might be preallocation past i_size
|
||||
*/
|
||||
ret = btrfs_lookup_file_extent(NULL, root, path, btrfs_ino(inode), -1,
|
||||
0);
|
||||
ret = btrfs_lookup_file_extent(NULL, root, path,
|
||||
btrfs_ino(BTRFS_I(inode)), -1, 0);
|
||||
if (ret < 0) {
|
||||
btrfs_free_path(path);
|
||||
return ret;
|
||||
@ -4426,7 +4407,7 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
|
||||
found_type = found_key.type;
|
||||
|
||||
/* 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) {
|
||||
/* have to trust i_size as the end */
|
||||
last = (u64)-1;
|
||||
@ -4535,8 +4516,8 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
|
||||
* lookup stuff.
|
||||
*/
|
||||
ret = btrfs_check_shared(trans, root->fs_info,
|
||||
root->objectid,
|
||||
btrfs_ino(inode), bytenr);
|
||||
root->objectid,
|
||||
btrfs_ino(BTRFS_I(inode)), bytenr);
|
||||
if (trans)
|
||||
btrfs_end_transaction(trans);
|
||||
if (ret < 0)
|
||||
|
@ -45,13 +45,14 @@
|
||||
#define EXTENT_BUFFER_IN_TREE 10
|
||||
#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_CLEAR_DIRTY (1 << 1)
|
||||
#define PAGE_SET_WRITEBACK (1 << 2)
|
||||
#define PAGE_END_WRITEBACK (1 << 3)
|
||||
#define PAGE_SET_PRIVATE2 (1 << 4)
|
||||
#define PAGE_SET_ERROR (1 << 5)
|
||||
#define PAGE_LOCK (1 << 6)
|
||||
|
||||
/*
|
||||
* page->private values. Every page that is controlled by the extent
|
||||
@ -192,7 +193,7 @@ struct extent_changeset {
|
||||
u64 bytes_changed;
|
||||
|
||||
/* Changed ranges */
|
||||
struct ulist *range_changed;
|
||||
struct ulist range_changed;
|
||||
};
|
||||
|
||||
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,
|
||||
} else {
|
||||
btrfs_info_rl(fs_info,
|
||||
"no csum found for inode %llu start %llu",
|
||||
btrfs_ino(inode), offset);
|
||||
btrfs_ino(BTRFS_I(inode)), offset);
|
||||
}
|
||||
item = NULL;
|
||||
btrfs_release_path(path);
|
||||
@ -856,8 +856,8 @@ insert:
|
||||
tmp = min(tmp, (next_offset - file_key.offset) >>
|
||||
fs_info->sb->s_blocksize_bits);
|
||||
|
||||
tmp = max((u64)1, tmp);
|
||||
tmp = min(tmp, (u64)MAX_CSUM_ITEMS(fs_info, csum_size));
|
||||
tmp = max_t(u64, 1, tmp);
|
||||
tmp = min_t(u64, tmp, MAX_CSUM_ITEMS(fs_info, csum_size));
|
||||
ins_size = csum_size * tmp;
|
||||
} else {
|
||||
ins_size = csum_size;
|
||||
@ -977,7 +977,7 @@ void btrfs_extent_item_to_extent_map(struct inode *inode,
|
||||
} else {
|
||||
btrfs_err(fs_info,
|
||||
"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);
|
||||
}
|
||||
}
|
||||
|
@ -168,7 +168,7 @@ int btrfs_add_inode_defrag(struct btrfs_trans_handle *trans,
|
||||
if (!defrag)
|
||||
return -ENOMEM;
|
||||
|
||||
defrag->ino = btrfs_ino(inode);
|
||||
defrag->ino = btrfs_ino(BTRFS_I(inode));
|
||||
defrag->transid = transid;
|
||||
defrag->root = root->root_key.objectid;
|
||||
|
||||
@ -702,7 +702,7 @@ int __btrfs_drop_extents(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_file_extent_item *fi;
|
||||
struct btrfs_key key;
|
||||
struct btrfs_key new_key;
|
||||
u64 ino = btrfs_ino(inode);
|
||||
u64 ino = btrfs_ino(BTRFS_I(inode));
|
||||
u64 search_start = start;
|
||||
u64 disk_bytenr = 0;
|
||||
u64 num_bytes = 0;
|
||||
@ -1102,7 +1102,7 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans,
|
||||
int del_slot = 0;
|
||||
int recow;
|
||||
int ret;
|
||||
u64 ino = btrfs_ino(inode);
|
||||
u64 ino = btrfs_ino(BTRFS_I(inode));
|
||||
|
||||
path = btrfs_alloc_path();
|
||||
if (!path)
|
||||
@ -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.
|
||||
*/
|
||||
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 <=
|
||||
fs_info->last_trans_committed) ||
|
||||
(!btrfs_have_ordered_extents_in_range(inode, start, len) &&
|
||||
@ -2203,7 +2203,7 @@ static int hole_mergeable(struct inode *inode, struct extent_buffer *leaf,
|
||||
return 0;
|
||||
|
||||
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)
|
||||
return 0;
|
||||
|
||||
@ -2237,7 +2237,7 @@ static int fill_holes(struct btrfs_trans_handle *trans, struct inode *inode,
|
||||
if (btrfs_fs_incompat(fs_info, NO_HOLES))
|
||||
goto out;
|
||||
|
||||
key.objectid = btrfs_ino(inode);
|
||||
key.objectid = btrfs_ino(BTRFS_I(inode));
|
||||
key.type = BTRFS_EXTENT_DATA_KEY;
|
||||
key.offset = offset;
|
||||
|
||||
@ -2285,9 +2285,8 @@ static int fill_holes(struct btrfs_trans_handle *trans, struct inode *inode,
|
||||
}
|
||||
btrfs_release_path(path);
|
||||
|
||||
ret = btrfs_insert_file_extent(trans, root, btrfs_ino(inode), offset,
|
||||
0, 0, end - offset, 0, end - offset,
|
||||
0, 0, 0);
|
||||
ret = btrfs_insert_file_extent(trans, root, btrfs_ino(BTRFS_I(inode)),
|
||||
offset, 0, 0, end - offset, 0, end - offset, 0, 0, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -94,12 +94,11 @@ static struct inode *__lookup_free_space_inode(struct btrfs_root *root,
|
||||
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
|
||||
*block_group, struct btrfs_path *path)
|
||||
{
|
||||
struct inode *inode = NULL;
|
||||
struct btrfs_fs_info *fs_info = root->fs_info;
|
||||
u32 flags = BTRFS_INODE_NODATASUM | BTRFS_INODE_NODATACOW;
|
||||
|
||||
spin_lock(&block_group->lock);
|
||||
@ -109,7 +108,7 @@ struct inode *lookup_free_space_inode(struct btrfs_root *root,
|
||||
if (inode)
|
||||
return inode;
|
||||
|
||||
inode = __lookup_free_space_inode(root, path,
|
||||
inode = __lookup_free_space_inode(fs_info->tree_root, path,
|
||||
block_group->key.objectid);
|
||||
if (IS_ERR(inode))
|
||||
return inode;
|
||||
@ -192,7 +191,7 @@ static int __create_free_space_inode(struct btrfs_root *root,
|
||||
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_block_group_cache *block_group,
|
||||
struct btrfs_path *path)
|
||||
@ -200,11 +199,11 @@ int create_free_space_inode(struct btrfs_root *root,
|
||||
int ret;
|
||||
u64 ino;
|
||||
|
||||
ret = btrfs_find_free_objectid(root, &ino);
|
||||
ret = btrfs_find_free_objectid(fs_info->tree_root, &ino);
|
||||
if (ret < 0)
|
||||
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);
|
||||
}
|
||||
|
||||
@ -227,21 +226,21 @@ int btrfs_check_trunc_cache_free_space(struct btrfs_fs_info *fs_info,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int btrfs_truncate_free_space_cache(struct btrfs_root *root,
|
||||
struct btrfs_trans_handle *trans,
|
||||
int btrfs_truncate_free_space_cache(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_block_group_cache *block_group,
|
||||
struct inode *inode)
|
||||
{
|
||||
struct btrfs_root *root = BTRFS_I(inode)->root;
|
||||
int ret = 0;
|
||||
struct btrfs_path *path = btrfs_alloc_path();
|
||||
bool locked = false;
|
||||
|
||||
if (!path) {
|
||||
ret = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (block_group) {
|
||||
struct btrfs_path *path = btrfs_alloc_path();
|
||||
|
||||
if (!path) {
|
||||
ret = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
locked = true;
|
||||
mutex_lock(&trans->transaction->cache_write_mutex);
|
||||
if (!list_empty(&block_group->io_list)) {
|
||||
@ -258,8 +257,8 @@ int btrfs_truncate_free_space_cache(struct btrfs_root *root,
|
||||
spin_lock(&block_group->lock);
|
||||
block_group->disk_cache_state = BTRFS_DC_CLEAR;
|
||||
spin_unlock(&block_group->lock);
|
||||
btrfs_free_path(path);
|
||||
}
|
||||
btrfs_free_path(path);
|
||||
|
||||
btrfs_i_size_write(inode, 0);
|
||||
truncate_pagecache(inode, 0);
|
||||
@ -286,14 +285,14 @@ fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int readahead_cache(struct inode *inode)
|
||||
static void readahead_cache(struct inode *inode)
|
||||
{
|
||||
struct file_ra_state *ra;
|
||||
unsigned long last_index;
|
||||
|
||||
ra = kzalloc(sizeof(*ra), GFP_NOFS);
|
||||
if (!ra)
|
||||
return -ENOMEM;
|
||||
return;
|
||||
|
||||
file_ra_state_init(ra, inode->i_mapping);
|
||||
last_index = (i_size_read(inode) - 1) >> PAGE_SHIFT;
|
||||
@ -301,8 +300,6 @@ static int readahead_cache(struct inode *inode)
|
||||
page_cache_sync_readahead(inode->i_mapping, ra, NULL, 0, last_index);
|
||||
|
||||
kfree(ra);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (btrfs_ino(inode) != BTRFS_FREE_INO_OBJECTID)
|
||||
if (btrfs_ino(BTRFS_I(inode)) != BTRFS_FREE_INO_OBJECTID)
|
||||
check_crcs = 1;
|
||||
|
||||
/* 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,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = readahead_cache(inode);
|
||||
if (ret)
|
||||
goto out;
|
||||
readahead_cache(inode);
|
||||
|
||||
ret = io_ctl_prepare_pages(&io_ctl, inode, 1);
|
||||
if (ret)
|
||||
@ -828,7 +823,6 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_block_group_cache *block_group)
|
||||
{
|
||||
struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl;
|
||||
struct btrfs_root *root = fs_info->tree_root;
|
||||
struct inode *inode;
|
||||
struct btrfs_path *path;
|
||||
int ret = 0;
|
||||
@ -852,7 +846,7 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info,
|
||||
path->search_commit_root = 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)) {
|
||||
btrfs_free_path(path);
|
||||
return 0;
|
||||
@ -1128,8 +1122,7 @@ cleanup_bitmap_list(struct list_head *bitmap_list)
|
||||
static void noinline_for_stack
|
||||
cleanup_write_cache_enospc(struct inode *inode,
|
||||
struct btrfs_io_ctl *io_ctl,
|
||||
struct extent_state **cached_state,
|
||||
struct list_head *bitmap_list)
|
||||
struct extent_state **cached_state)
|
||||
{
|
||||
io_ctl_drop_pages(io_ctl);
|
||||
unlock_extent_cached(&BTRFS_I(inode)->io_tree, 0,
|
||||
@ -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
|
||||
* @block_group - the block_group for this cache if it belongs to a block_group
|
||||
* @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
|
||||
* 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,
|
||||
struct btrfs_free_space_ctl *ctl,
|
||||
struct btrfs_block_group_cache *block_group,
|
||||
struct btrfs_io_ctl *io_ctl,
|
||||
struct btrfs_trans_handle *trans,
|
||||
struct btrfs_path *path, u64 offset)
|
||||
struct btrfs_trans_handle *trans)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = root->fs_info;
|
||||
struct extent_state *cached_state = NULL;
|
||||
@ -1365,7 +1355,7 @@ out_nospc_locked:
|
||||
mutex_unlock(&ctl->cache_writeout_mutex);
|
||||
|
||||
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))
|
||||
up_write(&block_group->data_rwsem);
|
||||
@ -1378,7 +1368,6 @@ int btrfs_write_out_cache(struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_block_group_cache *block_group,
|
||||
struct btrfs_path *path)
|
||||
{
|
||||
struct btrfs_root *root = fs_info->tree_root;
|
||||
struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl;
|
||||
struct inode *inode;
|
||||
int ret = 0;
|
||||
@ -1390,13 +1379,12 @@ int btrfs_write_out_cache(struct btrfs_fs_info *fs_info,
|
||||
}
|
||||
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))
|
||||
return 0;
|
||||
|
||||
ret = __btrfs_write_out_cache(root, inode, ctl, block_group,
|
||||
&block_group->io_ctl, trans,
|
||||
path, block_group->key.objectid);
|
||||
ret = __btrfs_write_out_cache(fs_info->tree_root, inode, ctl,
|
||||
block_group, &block_group->io_ctl, trans);
|
||||
if (ret) {
|
||||
#ifdef DEBUG
|
||||
btrfs_err(fs_info,
|
||||
@ -3543,8 +3531,7 @@ int btrfs_write_out_ino_cache(struct btrfs_root *root,
|
||||
return 0;
|
||||
|
||||
memset(&io_ctl, 0, sizeof(io_ctl));
|
||||
ret = __btrfs_write_out_cache(root, inode, ctl, NULL, &io_ctl,
|
||||
trans, path, 0);
|
||||
ret = __btrfs_write_out_cache(root, inode, ctl, NULL, &io_ctl, trans);
|
||||
if (!ret) {
|
||||
/*
|
||||
* At this point writepages() didn't error out, so our metadata
|
||||
|
@ -51,18 +51,17 @@ struct btrfs_free_space_op {
|
||||
|
||||
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
|
||||
*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_block_group_cache *block_group,
|
||||
struct btrfs_path *path);
|
||||
|
||||
int btrfs_check_trunc_cache_free_space(struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_block_rsv *rsv);
|
||||
int btrfs_truncate_free_space_cache(struct btrfs_root *root,
|
||||
struct btrfs_trans_handle *trans,
|
||||
int btrfs_truncate_free_space_cache(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_block_group_cache *block_group,
|
||||
struct inode *inode);
|
||||
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)
|
||||
list_del(&free_space_root->dirty_list);
|
||||
|
||||
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_free_tree_block(trans, free_space_root, free_space_root->node,
|
||||
0, 1);
|
||||
|
@ -467,7 +467,7 @@ again:
|
||||
}
|
||||
|
||||
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 != -ENOSPC)
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
|
582
fs/btrfs/inode.c
582
fs/btrfs/inode.c
File diff suppressed because it is too large
Load Diff
109
fs/btrfs/ioctl.c
109
fs/btrfs/ioctl.c
@ -395,7 +395,7 @@ static noinline int btrfs_ioctl_fitrim(struct file *file, void __user *arg)
|
||||
q = bdev_get_queue(device->bdev);
|
||||
if (blk_queue_discard(q)) {
|
||||
num_devices++;
|
||||
minlen = min((u64)q->limits.discard_granularity,
|
||||
minlen = min_t(u64, q->limits.discard_granularity,
|
||||
minlen);
|
||||
}
|
||||
}
|
||||
@ -487,8 +487,7 @@ static noinline int create_subvol(struct inode *dir,
|
||||
trans = btrfs_start_transaction(root, 0);
|
||||
if (IS_ERR(trans)) {
|
||||
ret = PTR_ERR(trans);
|
||||
btrfs_subvolume_release_metadata(fs_info, &block_rsv,
|
||||
qgroup_reserved);
|
||||
btrfs_subvolume_release_metadata(fs_info, &block_rsv);
|
||||
goto fail_free;
|
||||
}
|
||||
trans->block_rsv = &block_rsv;
|
||||
@ -601,7 +600,7 @@ static noinline int create_subvol(struct inode *dir,
|
||||
|
||||
ret = btrfs_add_root_ref(trans, fs_info,
|
||||
objectid, root->root_key.objectid,
|
||||
btrfs_ino(dir), index, name, namelen);
|
||||
btrfs_ino(BTRFS_I(dir)), index, name, namelen);
|
||||
BUG_ON(ret);
|
||||
|
||||
ret = btrfs_uuid_tree_add(trans, fs_info, root_item->uuid,
|
||||
@ -613,7 +612,7 @@ fail:
|
||||
kfree(root_item);
|
||||
trans->block_rsv = NULL;
|
||||
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) {
|
||||
*async_transid = trans->transid;
|
||||
@ -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,
|
||||
struct dentry *dentry, char *name, int namelen,
|
||||
struct dentry *dentry,
|
||||
u64 *async_transid, bool readonly,
|
||||
struct btrfs_qgroup_inherit *inherit)
|
||||
{
|
||||
@ -670,12 +669,12 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir,
|
||||
if (!test_bit(BTRFS_ROOT_REF_COWS, &root->state))
|
||||
return -EINVAL;
|
||||
|
||||
pending_snapshot = kzalloc(sizeof(*pending_snapshot), GFP_NOFS);
|
||||
pending_snapshot = kzalloc(sizeof(*pending_snapshot), GFP_KERNEL);
|
||||
if (!pending_snapshot)
|
||||
return -ENOMEM;
|
||||
|
||||
pending_snapshot->root_item = kzalloc(sizeof(struct btrfs_root_item),
|
||||
GFP_NOFS);
|
||||
GFP_KERNEL);
|
||||
pending_snapshot->path = btrfs_alloc_path();
|
||||
if (!pending_snapshot->root_item || !pending_snapshot->path) {
|
||||
ret = -ENOMEM;
|
||||
@ -753,9 +752,7 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir,
|
||||
d_instantiate(dentry, inode);
|
||||
ret = 0;
|
||||
fail:
|
||||
btrfs_subvolume_release_metadata(fs_info,
|
||||
&pending_snapshot->block_rsv,
|
||||
pending_snapshot->qgroup_reserved);
|
||||
btrfs_subvolume_release_metadata(fs_info, &pending_snapshot->block_rsv);
|
||||
dec_and_free:
|
||||
if (atomic_dec_and_test(&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,
|
||||
goto out_up_read;
|
||||
|
||||
if (snap_src) {
|
||||
error = create_snapshot(snap_src, dir, dentry, name, namelen,
|
||||
error = create_snapshot(snap_src, dir, dentry,
|
||||
async_transid, readonly, inherit);
|
||||
} else {
|
||||
error = create_subvol(dir, dentry, name, namelen,
|
||||
@ -941,7 +938,7 @@ static int find_new_extents(struct btrfs_root *root,
|
||||
struct btrfs_file_extent_item *extent;
|
||||
int type;
|
||||
int ret;
|
||||
u64 ino = btrfs_ino(inode);
|
||||
u64 ino = btrfs_ino(BTRFS_I(inode));
|
||||
|
||||
path = btrfs_alloc_path();
|
||||
if (!path)
|
||||
@ -1780,7 +1777,7 @@ static noinline int btrfs_ioctl_subvol_getflags(struct file *file,
|
||||
int ret = 0;
|
||||
u64 flags = 0;
|
||||
|
||||
if (btrfs_ino(inode) != BTRFS_FIRST_FREE_OBJECTID)
|
||||
if (btrfs_ino(BTRFS_I(inode)) != BTRFS_FIRST_FREE_OBJECTID)
|
||||
return -EINVAL;
|
||||
|
||||
down_read(&fs_info->subvol_sem);
|
||||
@ -1812,7 +1809,7 @@ static noinline int btrfs_ioctl_subvol_setflags(struct file *file,
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
if (btrfs_ino(inode) != BTRFS_FIRST_FREE_OBJECTID) {
|
||||
if (btrfs_ino(BTRFS_I(inode)) != BTRFS_FIRST_FREE_OBJECTID) {
|
||||
ret = -EINVAL;
|
||||
goto out_drop_write;
|
||||
}
|
||||
@ -2446,7 +2443,7 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file,
|
||||
if (err)
|
||||
goto out_dput;
|
||||
|
||||
if (btrfs_ino(inode) != BTRFS_FIRST_FREE_OBJECTID) {
|
||||
if (btrfs_ino(BTRFS_I(inode)) != BTRFS_FIRST_FREE_OBJECTID) {
|
||||
err = -EINVAL;
|
||||
goto out_dput;
|
||||
}
|
||||
@ -2497,7 +2494,7 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file,
|
||||
trans->block_rsv = &block_rsv;
|
||||
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,
|
||||
dest->root_key.objectid,
|
||||
@ -2555,7 +2552,7 @@ out_end_trans:
|
||||
err = ret;
|
||||
inode->i_flags |= S_DEAD;
|
||||
out_release:
|
||||
btrfs_subvolume_release_metadata(fs_info, &block_rsv, qgroup_reserved);
|
||||
btrfs_subvolume_release_metadata(fs_info, &block_rsv);
|
||||
out_up_write:
|
||||
up_write(&fs_info->subvol_sem);
|
||||
if (err) {
|
||||
@ -2613,9 +2610,6 @@ static int btrfs_ioctl_defrag(struct file *file, void __user *argp)
|
||||
goto out;
|
||||
}
|
||||
ret = btrfs_defrag_root(root);
|
||||
if (ret)
|
||||
goto out;
|
||||
ret = btrfs_defrag_root(root->fs_info->extent_root);
|
||||
break;
|
||||
case S_IFREG:
|
||||
if (!(file->f_mode & FMODE_WRITE)) {
|
||||
@ -3047,11 +3041,21 @@ static int btrfs_cmp_data_prepare(struct inode *src, u64 loff,
|
||||
cmp->src_pages = src_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)
|
||||
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:
|
||||
if (ret)
|
||||
@ -3059,8 +3063,7 @@ out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int btrfs_cmp_data(struct inode *src, u64 loff, struct inode *dst,
|
||||
u64 dst_loff, u64 len, struct cmp_pages *cmp)
|
||||
static int btrfs_cmp_data(u64 len, struct cmp_pages *cmp)
|
||||
{
|
||||
int ret = 0;
|
||||
int i;
|
||||
@ -3128,26 +3131,27 @@ static int btrfs_extent_same(struct inode *src, u64 loff, u64 olen,
|
||||
int ret;
|
||||
u64 len = olen;
|
||||
struct cmp_pages cmp;
|
||||
int same_inode = 0;
|
||||
bool same_inode = (src == dst);
|
||||
u64 same_lock_start = 0;
|
||||
u64 same_lock_len = 0;
|
||||
|
||||
if (src == dst)
|
||||
same_inode = 1;
|
||||
|
||||
if (len == 0)
|
||||
return 0;
|
||||
|
||||
if (same_inode) {
|
||||
if (same_inode)
|
||||
inode_lock(src);
|
||||
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(src, dst_loff, &len, olen);
|
||||
if (ret)
|
||||
goto out_unlock;
|
||||
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;
|
||||
|
||||
if (same_inode) {
|
||||
/*
|
||||
* Single inode case wants the same checks, except we
|
||||
* 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,
|
||||
|
||||
same_lock_start = min_t(u64, loff, dst_loff);
|
||||
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 */
|
||||
@ -3236,7 +3230,7 @@ again:
|
||||
}
|
||||
|
||||
/* 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)
|
||||
ret = btrfs_clone(src, dst, loff, olen, len, dst_loff, 1);
|
||||
|
||||
@ -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
|
||||
* the former.
|
||||
*/
|
||||
static int clone_copy_inline_extent(struct inode *src,
|
||||
struct inode *dst,
|
||||
static int clone_copy_inline_extent(struct inode *dst,
|
||||
struct btrfs_trans_handle *trans,
|
||||
struct btrfs_path *path,
|
||||
struct btrfs_key *new_key,
|
||||
@ -3420,7 +3413,7 @@ static int clone_copy_inline_extent(struct inode *src,
|
||||
if (new_key->offset > 0)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
key.objectid = btrfs_ino(dst);
|
||||
key.objectid = btrfs_ino(BTRFS_I(dst));
|
||||
key.type = BTRFS_EXTENT_DATA_KEY;
|
||||
key.offset = 0;
|
||||
ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
|
||||
@ -3435,7 +3428,7 @@ static int clone_copy_inline_extent(struct inode *src,
|
||||
goto copy_inline_extent;
|
||||
}
|
||||
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) {
|
||||
ASSERT(key.offset > 0);
|
||||
return -EOPNOTSUPP;
|
||||
@ -3469,7 +3462,7 @@ static int clone_copy_inline_extent(struct inode *src,
|
||||
} else if (ret == 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)
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
@ -3563,7 +3556,7 @@ static int btrfs_clone(struct inode *src, struct inode *inode,
|
||||
|
||||
path->reada = READA_FORWARD;
|
||||
/* clone data */
|
||||
key.objectid = btrfs_ino(src);
|
||||
key.objectid = btrfs_ino(BTRFS_I(src));
|
||||
key.type = BTRFS_EXTENT_DATA_KEY;
|
||||
key.offset = off;
|
||||
|
||||
@ -3606,7 +3599,7 @@ process_slot:
|
||||
|
||||
btrfs_item_key_to_cpu(leaf, &key, slot);
|
||||
if (key.type > BTRFS_EXTENT_DATA_KEY ||
|
||||
key.objectid != btrfs_ino(src))
|
||||
key.objectid != btrfs_ino(BTRFS_I(src)))
|
||||
break;
|
||||
|
||||
if (key.type == BTRFS_EXTENT_DATA_KEY) {
|
||||
@ -3659,7 +3652,7 @@ process_slot:
|
||||
path->leave_spinning = 0;
|
||||
|
||||
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)
|
||||
new_key.offset = key.offset + destoff - off;
|
||||
else
|
||||
@ -3749,7 +3742,7 @@ process_slot:
|
||||
fs_info,
|
||||
disko, diskl, 0,
|
||||
root->root_key.objectid,
|
||||
btrfs_ino(inode),
|
||||
btrfs_ino(BTRFS_I(inode)),
|
||||
new_key.offset - datao);
|
||||
if (ret) {
|
||||
btrfs_abort_transaction(trans,
|
||||
@ -3779,7 +3772,7 @@ process_slot:
|
||||
size -= skip + trim;
|
||||
datal -= skip + trim;
|
||||
|
||||
ret = clone_copy_inline_extent(src, inode,
|
||||
ret = clone_copy_inline_extent(inode,
|
||||
trans, path,
|
||||
&new_key,
|
||||
drop_start,
|
||||
@ -5129,7 +5122,7 @@ static long _btrfs_ioctl_set_received_subvol(struct file *file,
|
||||
|
||||
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;
|
||||
goto out;
|
||||
}
|
||||
|
@ -432,7 +432,7 @@ out:
|
||||
}
|
||||
|
||||
/* 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,
|
||||
const loff_t start,
|
||||
const loff_t end)
|
||||
@ -442,7 +442,7 @@ void btrfs_get_logged_extents(struct inode *inode,
|
||||
struct rb_node *n;
|
||||
struct rb_node *prev;
|
||||
|
||||
tree = &BTRFS_I(inode)->ordered_tree;
|
||||
tree = &inode->ordered_tree;
|
||||
spin_lock_irq(&tree->lock);
|
||||
n = __tree_search(&tree->tree, end, &prev);
|
||||
if (!n)
|
||||
@ -984,8 +984,18 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset,
|
||||
}
|
||||
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;
|
||||
ret = 0;
|
||||
goto out;
|
||||
@ -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 */
|
||||
if (test_bit(BTRFS_ORDERED_UPDATED_ISIZE, &test->flags))
|
||||
continue;
|
||||
if (test->file_offset + test->len <= disk_i_size)
|
||||
|
||||
if (entry_end(test) <= disk_i_size)
|
||||
break;
|
||||
if (test->file_offset >= i_size)
|
||||
break;
|
||||
if (entry_end(test) > disk_i_size) {
|
||||
/*
|
||||
* we don't update disk_i_size now, so record this
|
||||
* undealt i_size. Or we will not know the real
|
||||
* i_size.
|
||||
*/
|
||||
if (test->outstanding_isize < offset)
|
||||
test->outstanding_isize = offset;
|
||||
if (ordered &&
|
||||
ordered->outstanding_isize >
|
||||
test->outstanding_isize)
|
||||
test->outstanding_isize =
|
||||
ordered->outstanding_isize;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* We don't update disk_i_size now, so record this undealt
|
||||
* i_size. Or we will not know the real i_size.
|
||||
*/
|
||||
if (test->outstanding_isize < offset)
|
||||
test->outstanding_isize = offset;
|
||||
if (ordered &&
|
||||
ordered->outstanding_isize > test->outstanding_isize)
|
||||
test->outstanding_isize = ordered->outstanding_isize;
|
||||
goto out;
|
||||
}
|
||||
new_i_size = min_t(u64, offset, i_size);
|
||||
|
||||
|
@ -75,6 +75,8 @@ struct btrfs_ordered_sum {
|
||||
* in the logging code. */
|
||||
#define BTRFS_ORDERED_PENDING 11 /* We are waiting for this ordered extent to
|
||||
* complete in the current transaction. */
|
||||
#define BTRFS_ORDERED_REGULAR 12 /* Regular IO for COW */
|
||||
|
||||
struct btrfs_ordered_extent {
|
||||
/* logical offset in the file */
|
||||
u64 file_offset;
|
||||
@ -201,7 +203,7 @@ int btrfs_wait_ordered_extents(struct btrfs_root *root, int nr,
|
||||
const u64 range_start, const u64 range_len);
|
||||
int btrfs_wait_ordered_roots(struct btrfs_fs_info *fs_info, int nr,
|
||||
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,
|
||||
const loff_t start,
|
||||
const loff_t end);
|
||||
|
@ -279,7 +279,7 @@ static void inode_prop_iterator(void *ctx,
|
||||
if (unlikely(ret))
|
||||
btrfs_warn(root->fs_info,
|
||||
"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);
|
||||
else
|
||||
set_bit(BTRFS_INODE_HAS_PROPS, &BTRFS_I(inode)->runtime_flags);
|
||||
@ -288,7 +288,7 @@ static void inode_prop_iterator(void *ctx,
|
||||
int btrfs_load_inode_props(struct inode *inode, struct btrfs_path *path)
|
||||
{
|
||||
struct btrfs_root *root = BTRFS_I(inode)->root;
|
||||
u64 ino = btrfs_ino(inode);
|
||||
u64 ino = btrfs_ino(BTRFS_I(inode));
|
||||
int ret;
|
||||
|
||||
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)
|
||||
if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags))
|
||||
return 0;
|
||||
|
||||
fs_info->qgroup_ulist = ulist_alloc(GFP_NOFS);
|
||||
fs_info->qgroup_ulist = ulist_alloc(GFP_KERNEL);
|
||||
if (!fs_info->qgroup_ulist) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
@ -876,7 +876,7 @@ int btrfs_quota_enable(struct btrfs_trans_handle *trans,
|
||||
goto out;
|
||||
}
|
||||
|
||||
fs_info->qgroup_ulist = ulist_alloc(GFP_NOFS);
|
||||
fs_info->qgroup_ulist = ulist_alloc(GFP_KERNEL);
|
||||
if (!fs_info->qgroup_ulist) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
@ -1019,7 +1019,7 @@ int btrfs_quota_disable(struct btrfs_trans_handle *trans,
|
||||
list_del("a_root->dirty_list);
|
||||
|
||||
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_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,
|
||||
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
|
||||
* 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,
|
||||
WARN_ON(sign < 0 && qgroup->excl < num_bytes);
|
||||
qgroup->excl += sign * num_bytes;
|
||||
qgroup->excl_cmpr += sign * num_bytes;
|
||||
if (sign > 0)
|
||||
qgroup->reserved -= num_bytes;
|
||||
if (sign > 0) {
|
||||
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);
|
||||
|
||||
@ -1086,8 +1099,13 @@ static int __qgroup_excl_accounting(struct btrfs_fs_info *fs_info,
|
||||
qgroup->rfer_cmpr += sign * num_bytes;
|
||||
WARN_ON(sign < 0 && qgroup->excl < num_bytes);
|
||||
qgroup->excl += sign * num_bytes;
|
||||
if (sign > 0)
|
||||
qgroup->reserved -= num_bytes;
|
||||
if (sign > 0) {
|
||||
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_dirty(fs_info, qgroup);
|
||||
|
||||
@ -1156,7 +1174,7 @@ int btrfs_add_qgroup_relation(struct btrfs_trans_handle *trans,
|
||||
if (btrfs_qgroup_level(src) >= btrfs_qgroup_level(dst))
|
||||
return -EINVAL;
|
||||
|
||||
tmp = ulist_alloc(GFP_NOFS);
|
||||
tmp = ulist_alloc(GFP_KERNEL);
|
||||
if (!tmp)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -1205,7 +1223,7 @@ out:
|
||||
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_root *quota_root;
|
||||
@ -1216,7 +1234,7 @@ int __del_qgroup_relation(struct btrfs_trans_handle *trans,
|
||||
int ret = 0;
|
||||
int err;
|
||||
|
||||
tmp = ulist_alloc(GFP_NOFS);
|
||||
tmp = ulist_alloc(GFP_KERNEL);
|
||||
if (!tmp)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -1446,8 +1464,9 @@ int btrfs_qgroup_prepare_account_extents(struct btrfs_trans_handle *trans,
|
||||
while (node) {
|
||||
record = rb_entry(node, struct btrfs_qgroup_extent_record,
|
||||
node);
|
||||
ret = btrfs_find_all_roots(NULL, fs_info, record->bytenr, 0,
|
||||
&record->old_roots);
|
||||
if (WARN_ON(!record->old_roots))
|
||||
ret = btrfs_find_all_roots(NULL, fs_info,
|
||||
record->bytenr, 0, &record->old_roots);
|
||||
if (ret < 0)
|
||||
break;
|
||||
if (qgroup_to_skip)
|
||||
@ -1486,6 +1505,28 @@ int btrfs_qgroup_trace_extent_nolock(struct btrfs_fs_info *fs_info,
|
||||
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,
|
||||
struct btrfs_fs_info *fs_info, u64 bytenr, u64 num_bytes,
|
||||
gfp_t gfp_flag)
|
||||
@ -1511,9 +1552,11 @@ int btrfs_qgroup_trace_extent(struct btrfs_trans_handle *trans,
|
||||
spin_lock(&delayed_refs->lock);
|
||||
ret = btrfs_qgroup_trace_extent_nolock(fs_info, delayed_refs, record);
|
||||
spin_unlock(&delayed_refs->lock);
|
||||
if (ret > 0)
|
||||
if (ret > 0) {
|
||||
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,
|
||||
@ -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
|
||||
* elements, 1 is returned to signal completion of the search.
|
||||
*/
|
||||
static int adjust_slots_upwards(struct btrfs_root *root,
|
||||
struct btrfs_path *path, int root_level)
|
||||
static int adjust_slots_upwards(struct btrfs_path *path, int root_level)
|
||||
{
|
||||
int level = 0;
|
||||
int nr, slot;
|
||||
@ -1713,7 +1755,7 @@ walk_down:
|
||||
goto out;
|
||||
|
||||
/* 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)
|
||||
break;
|
||||
|
||||
@ -1927,13 +1969,14 @@ btrfs_qgroup_account_extent(struct btrfs_trans_handle *trans,
|
||||
u64 nr_old_roots = 0;
|
||||
int ret = 0;
|
||||
|
||||
if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags))
|
||||
return 0;
|
||||
|
||||
if (new_roots)
|
||||
nr_new_roots = new_roots->nnodes;
|
||||
if (old_roots)
|
||||
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);
|
||||
|
||||
trace_btrfs_qgroup_account_extent(fs_info, bytenr, num_bytes,
|
||||
@ -2170,9 +2213,7 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans,
|
||||
goto out;
|
||||
}
|
||||
|
||||
rcu_read_lock();
|
||||
level_size = fs_info->nodesize;
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2306,7 +2347,20 @@ out:
|
||||
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_qgroup *qgroup;
|
||||
@ -2347,16 +2401,7 @@ static int qgroup_reserve(struct btrfs_root *root, u64 num_bytes)
|
||||
|
||||
qg = unode_aux_to_qgroup(unode);
|
||||
|
||||
if ((qg->lim_flags & BTRFS_QGROUP_LIMIT_MAX_RFER) &&
|
||||
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) {
|
||||
if (enforce && !qgroup_check_limits(qg, num_bytes)) {
|
||||
ret = -EDQUOT;
|
||||
goto out;
|
||||
}
|
||||
@ -2424,7 +2469,10 @@ void btrfs_qgroup_free_refroot(struct btrfs_fs_info *fs_info,
|
||||
|
||||
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) {
|
||||
ret = ulist_add(fs_info->qgroup_ulist,
|
||||
@ -2439,11 +2487,6 @@ out:
|
||||
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)
|
||||
{
|
||||
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)
|
||||
return 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,
|
||||
start + len -1, EXTENT_QGROUP_RESERVED, &changeset);
|
||||
trace_btrfs_qgroup_reserve_data(inode, start, len,
|
||||
@ -2811,21 +2854,21 @@ int btrfs_qgroup_reserve_data(struct inode *inode, u64 start, u64 len)
|
||||
QGROUP_RESERVE);
|
||||
if (ret < 0)
|
||||
goto cleanup;
|
||||
ret = qgroup_reserve(root, changeset.bytes_changed);
|
||||
ret = qgroup_reserve(root, changeset.bytes_changed, true);
|
||||
if (ret < 0)
|
||||
goto cleanup;
|
||||
|
||||
ulist_free(changeset.range_changed);
|
||||
ulist_release(&changeset.range_changed);
|
||||
return ret;
|
||||
|
||||
cleanup:
|
||||
/* cleanup already reserved ranges */
|
||||
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,
|
||||
unode->aux, EXTENT_QGROUP_RESERVED, 0, 0, NULL,
|
||||
GFP_NOFS);
|
||||
ulist_free(changeset.range_changed);
|
||||
ulist_release(&changeset.range_changed);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -2837,23 +2880,22 @@ static int __btrfs_qgroup_release_data(struct inode *inode, u64 start, u64 len,
|
||||
int ret;
|
||||
|
||||
changeset.bytes_changed = 0;
|
||||
changeset.range_changed = ulist_alloc(GFP_NOFS);
|
||||
if (!changeset.range_changed)
|
||||
return -ENOMEM;
|
||||
|
||||
ulist_init(&changeset.range_changed);
|
||||
ret = clear_record_extent_bits(&BTRFS_I(inode)->io_tree, start,
|
||||
start + len -1, EXTENT_QGROUP_RESERVED, &changeset);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
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_btrfs_qgroup_release_data(inode, start, len,
|
||||
changeset.bytes_changed, trace_op);
|
||||
out:
|
||||
ulist_free(changeset.range_changed);
|
||||
ulist_release(&changeset.range_changed);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
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;
|
||||
int ret;
|
||||
@ -2902,7 +2945,7 @@ int btrfs_qgroup_reserve_meta(struct btrfs_root *root, int num_bytes)
|
||||
return 0;
|
||||
|
||||
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)
|
||||
return ret;
|
||||
atomic_add(num_bytes, &root->qgroup_meta_rsv);
|
||||
@ -2921,7 +2964,7 @@ void btrfs_qgroup_free_meta_all(struct btrfs_root *root)
|
||||
reserved = atomic_xchg(&root->qgroup_meta_rsv, 0);
|
||||
if (reserved == 0)
|
||||
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)
|
||||
@ -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));
|
||||
WARN_ON(atomic_read(&root->qgroup_meta_rsv) < num_bytes);
|
||||
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)
|
||||
int ret;
|
||||
|
||||
changeset.bytes_changed = 0;
|
||||
changeset.range_changed = ulist_alloc(GFP_NOFS);
|
||||
if (WARN_ON(!changeset.range_changed))
|
||||
return;
|
||||
|
||||
ulist_init(&changeset.range_changed);
|
||||
ret = clear_record_extent_bits(&BTRFS_I(inode)->io_tree, 0, (u64)-1,
|
||||
EXTENT_QGROUP_RESERVED, &changeset);
|
||||
|
||||
WARN_ON(ret < 0);
|
||||
if (WARN_ON(changeset.bytes_changed)) {
|
||||
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,
|
||||
"leaking qgroup reserved space, ino: %lu, start: %llu, end: %llu",
|
||||
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);
|
||||
}
|
||||
|
@ -94,9 +94,10 @@ int btrfs_qgroup_prepare_account_extents(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_fs_info *fs_info);
|
||||
/*
|
||||
* Inform qgroup to trace one dirty extent, its info is recorded in @record.
|
||||
* So qgroup can account it at commit trans time.
|
||||
* So qgroup can account it at transaction committing time.
|
||||
*
|
||||
* No lock version, caller must acquire delayed ref lock and allocate memory.
|
||||
* No lock version, caller must acquire delayed ref lock and allocated memory,
|
||||
* then call btrfs_qgroup_trace_extent_post() after exiting lock context.
|
||||
*
|
||||
* Return 0 for success insert
|
||||
* Return >0 for existing record, caller can free @record safely.
|
||||
@ -107,12 +108,38 @@ int btrfs_qgroup_trace_extent_nolock(
|
||||
struct btrfs_delayed_ref_root *delayed_refs,
|
||||
struct btrfs_qgroup_extent_record *record);
|
||||
|
||||
/*
|
||||
* Post handler after qgroup_trace_extent_nolock().
|
||||
*
|
||||
* NOTE: Current qgroup does the expensive backref walk at transaction
|
||||
* committing time with TRANS_STATE_COMMIT_DOING, this blocks incoming
|
||||
* new transaction.
|
||||
* This is designed to allow btrfs_find_all_roots() to get correct new_roots
|
||||
* result.
|
||||
*
|
||||
* However for old_roots there is no need to do backref walk at that time,
|
||||
* since we search commit roots to walk backref and result will always be
|
||||
* correct.
|
||||
*
|
||||
* Due to the nature of no lock version, we can't do backref there.
|
||||
* So we must call btrfs_qgroup_trace_extent_post() after exiting
|
||||
* spinlock context.
|
||||
*
|
||||
* TODO: If we can fix and prove btrfs_find_all_roots() can get correct result
|
||||
* using current root, then we can move all expensive backref walk out of
|
||||
* transaction committing, but not now as qgroup accounting will be wrong again.
|
||||
*/
|
||||
int btrfs_qgroup_trace_extent_post(struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_qgroup_extent_record *qrecord);
|
||||
|
||||
/*
|
||||
* Inform qgroup to trace one dirty extent, specified by @bytenr and
|
||||
* @num_bytes.
|
||||
* So qgroup can account it at commit trans time.
|
||||
*
|
||||
* Better encapsulated version.
|
||||
* Better encapsulated version, with memory allocation and backref walk for
|
||||
* commit roots.
|
||||
* So this can sleep.
|
||||
*
|
||||
* Return 0 if the operation is done.
|
||||
* Return <0 for error, like memory allocation failure or invalid parameter
|
||||
@ -181,7 +208,8 @@ int btrfs_qgroup_reserve_data(struct inode *inode, u64 start, u64 len);
|
||||
int btrfs_qgroup_release_data(struct inode *inode, u64 start, u64 len);
|
||||
int btrfs_qgroup_free_data(struct inode *inode, u64 start, u64 len);
|
||||
|
||||
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);
|
||||
void btrfs_qgroup_free_meta_all(struct btrfs_root *root);
|
||||
void btrfs_qgroup_free_meta(struct btrfs_root *root, int num_bytes);
|
||||
void btrfs_qgroup_check_reserved_leak(struct inode *inode);
|
||||
|
@ -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 *cache_drop = NULL;
|
||||
int ret = 0;
|
||||
int walk = 0;
|
||||
|
||||
spin_lock_irqsave(&h->lock, flags);
|
||||
list_for_each_entry(cur, &h->hash_list, hash_list) {
|
||||
walk++;
|
||||
if (cur->bbio->raid_map[0] == rbio->bbio->raid_map[0]) {
|
||||
spin_lock(&cur->bio_list_lock);
|
||||
|
||||
|
@ -1548,9 +1548,9 @@ again:
|
||||
prev = node;
|
||||
entry = rb_entry(node, struct btrfs_inode, rb_node);
|
||||
|
||||
if (objectid < btrfs_ino(&entry->vfs_inode))
|
||||
if (objectid < btrfs_ino(entry))
|
||||
node = node->rb_left;
|
||||
else if (objectid > btrfs_ino(&entry->vfs_inode))
|
||||
else if (objectid > btrfs_ino(entry))
|
||||
node = node->rb_right;
|
||||
else
|
||||
break;
|
||||
@ -1558,7 +1558,7 @@ again:
|
||||
if (!node) {
|
||||
while (prev) {
|
||||
entry = rb_entry(prev, struct btrfs_inode, rb_node);
|
||||
if (objectid <= btrfs_ino(&entry->vfs_inode)) {
|
||||
if (objectid <= btrfs_ino(entry)) {
|
||||
node = prev;
|
||||
break;
|
||||
}
|
||||
@ -1573,7 +1573,7 @@ again:
|
||||
return inode;
|
||||
}
|
||||
|
||||
objectid = btrfs_ino(&entry->vfs_inode) + 1;
|
||||
objectid = btrfs_ino(entry) + 1;
|
||||
if (cond_resched_lock(&root->inode_lock))
|
||||
goto again;
|
||||
|
||||
@ -1609,8 +1609,8 @@ static int get_new_location(struct inode *reloc_inode, u64 *new_bytenr,
|
||||
return -ENOMEM;
|
||||
|
||||
bytenr -= BTRFS_I(reloc_inode)->index_cnt;
|
||||
ret = btrfs_lookup_file_extent(NULL, root, path, btrfs_ino(reloc_inode),
|
||||
bytenr, 0);
|
||||
ret = btrfs_lookup_file_extent(NULL, root, path,
|
||||
btrfs_ino(BTRFS_I(reloc_inode)), bytenr, 0);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
if (ret > 0) {
|
||||
@ -1698,11 +1698,11 @@ int replace_file_extents(struct btrfs_trans_handle *trans,
|
||||
if (first) {
|
||||
inode = find_next_inode(root, key.objectid);
|
||||
first = 0;
|
||||
} else if (inode && btrfs_ino(inode) < key.objectid) {
|
||||
} else if (inode && btrfs_ino(BTRFS_I(inode)) < key.objectid) {
|
||||
btrfs_add_delayed_iput(inode);
|
||||
inode = find_next_inode(root, key.objectid);
|
||||
}
|
||||
if (inode && btrfs_ino(inode) == key.objectid) {
|
||||
if (inode && btrfs_ino(BTRFS_I(inode)) == key.objectid) {
|
||||
end = key.offset +
|
||||
btrfs_file_extent_num_bytes(leaf, fi);
|
||||
WARN_ON(!IS_ALIGNED(key.offset,
|
||||
@ -2088,7 +2088,7 @@ static int invalidate_extent_cache(struct btrfs_root *root,
|
||||
inode = find_next_inode(root, objectid);
|
||||
if (!inode)
|
||||
break;
|
||||
ino = btrfs_ino(inode);
|
||||
ino = btrfs_ino(BTRFS_I(inode));
|
||||
|
||||
if (ino > max_key->objectid) {
|
||||
iput(inode);
|
||||
@ -3543,7 +3543,7 @@ truncate:
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = btrfs_truncate_free_space_cache(root, trans, block_group, inode);
|
||||
ret = btrfs_truncate_free_space_cache(trans, block_group, inode);
|
||||
|
||||
btrfs_end_transaction(trans);
|
||||
btrfs_btree_balance_dirty(fs_info);
|
||||
@ -4334,7 +4334,7 @@ int btrfs_relocate_block_group(struct btrfs_fs_info *fs_info, u64 group_start)
|
||||
rc->block_group = btrfs_lookup_block_group(fs_info, group_start);
|
||||
BUG_ON(!rc->block_group);
|
||||
|
||||
ret = btrfs_inc_block_group_ro(extent_root, rc->block_group);
|
||||
ret = btrfs_inc_block_group_ro(fs_info, rc->block_group);
|
||||
if (ret) {
|
||||
err = ret;
|
||||
goto out;
|
||||
@ -4347,8 +4347,7 @@ int btrfs_relocate_block_group(struct btrfs_fs_info *fs_info, u64 group_start)
|
||||
goto out;
|
||||
}
|
||||
|
||||
inode = lookup_free_space_inode(fs_info->tree_root, rc->block_group,
|
||||
path);
|
||||
inode = lookup_free_space_inode(fs_info, rc->block_group, path);
|
||||
btrfs_free_path(path);
|
||||
|
||||
if (!IS_ERR(inode))
|
||||
|
@ -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.
|
||||
*/
|
||||
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_key *root_key)
|
||||
{
|
||||
@ -207,7 +207,7 @@ out:
|
||||
}
|
||||
|
||||
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.
|
||||
@ -337,7 +337,7 @@ int btrfs_find_orphan_roots(struct btrfs_fs_info *fs_info)
|
||||
|
||||
/* drop the root item for 'key' from 'root' */
|
||||
int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root,
|
||||
struct btrfs_key *key)
|
||||
const struct btrfs_key *key)
|
||||
{
|
||||
struct btrfs_path *path;
|
||||
int ret;
|
||||
|
@ -282,9 +282,7 @@ static void scrub_remap_extent(struct btrfs_fs_info *fs_info,
|
||||
u64 *extent_physical,
|
||||
struct btrfs_device **extent_dev,
|
||||
int *extent_mirror_num);
|
||||
static int scrub_setup_wr_ctx(struct scrub_ctx *sctx,
|
||||
struct scrub_wr_ctx *wr_ctx,
|
||||
struct btrfs_fs_info *fs_info,
|
||||
static int scrub_setup_wr_ctx(struct scrub_wr_ctx *wr_ctx,
|
||||
struct btrfs_device *dev,
|
||||
int is_dev_replace);
|
||||
static void scrub_free_wr_ctx(struct scrub_wr_ctx *wr_ctx);
|
||||
@ -501,7 +499,7 @@ struct scrub_ctx *scrub_setup_ctx(struct btrfs_device *dev, int is_dev_replace)
|
||||
spin_lock_init(&sctx->stat_lock);
|
||||
init_waitqueue_head(&sctx->list_wait);
|
||||
|
||||
ret = scrub_setup_wr_ctx(sctx, &sctx->wr_ctx, fs_info,
|
||||
ret = scrub_setup_wr_ctx(&sctx->wr_ctx,
|
||||
fs_info->dev_replace.tgtdev, is_dev_replace);
|
||||
if (ret) {
|
||||
scrub_free_ctx(sctx);
|
||||
@ -3584,7 +3582,7 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx,
|
||||
* -> btrfs_scrub_pause()
|
||||
*/
|
||||
scrub_pause_on(fs_info);
|
||||
ret = btrfs_inc_block_group_ro(root, cache);
|
||||
ret = btrfs_inc_block_group_ro(fs_info, cache);
|
||||
if (!ret && is_dev_replace) {
|
||||
/*
|
||||
* If we are doing a device replace wait for any tasks
|
||||
@ -4084,9 +4082,7 @@ static void scrub_remap_extent(struct btrfs_fs_info *fs_info,
|
||||
btrfs_put_bbio(bbio);
|
||||
}
|
||||
|
||||
static int scrub_setup_wr_ctx(struct scrub_ctx *sctx,
|
||||
struct scrub_wr_ctx *wr_ctx,
|
||||
struct btrfs_fs_info *fs_info,
|
||||
static int scrub_setup_wr_ctx(struct scrub_wr_ctx *wr_ctx,
|
||||
struct btrfs_device *dev,
|
||||
int is_dev_replace)
|
||||
{
|
||||
|
@ -265,7 +265,7 @@ void __btrfs_abort_transaction(struct btrfs_trans_handle *trans,
|
||||
function, line, errstr);
|
||||
return;
|
||||
}
|
||||
ACCESS_ONCE(trans->transaction->aborted) = errno;
|
||||
WRITE_ONCE(trans->transaction->aborted, errno);
|
||||
/* Wake up anybody who may be waiting on this transaction */
|
||||
wake_up(&fs_info->transaction_wait);
|
||||
wake_up(&fs_info->transaction_blocked_wait);
|
||||
@ -1114,7 +1114,7 @@ static int get_default_subvol_objectid(struct btrfs_fs_info *fs_info, u64 *objec
|
||||
|
||||
static int btrfs_fill_super(struct super_block *sb,
|
||||
struct btrfs_fs_devices *fs_devices,
|
||||
void *data, int silent)
|
||||
void *data)
|
||||
{
|
||||
struct inode *inode;
|
||||
struct btrfs_fs_info *fs_info = btrfs_sb(sb);
|
||||
@ -1611,8 +1611,7 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
|
||||
} else {
|
||||
snprintf(s->s_id, sizeof(s->s_id), "%pg", bdev);
|
||||
btrfs_sb(s)->bdev_holder = fs_type;
|
||||
error = btrfs_fill_super(s, fs_devices, data,
|
||||
flags & MS_SILENT ? 1 : 0);
|
||||
error = btrfs_fill_super(s, fs_devices, data);
|
||||
}
|
||||
if (error) {
|
||||
deactivate_locked_super(s);
|
||||
|
@ -474,7 +474,8 @@ static inline bool need_reserve_reloc_root(struct btrfs_root *root)
|
||||
|
||||
static struct btrfs_trans_handle *
|
||||
start_transaction(struct btrfs_root *root, unsigned int num_items,
|
||||
unsigned int type, enum btrfs_reserve_flush_enum flush)
|
||||
unsigned int type, enum btrfs_reserve_flush_enum flush,
|
||||
bool enforce_qgroups)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = root->fs_info;
|
||||
|
||||
@ -505,9 +506,10 @@ start_transaction(struct btrfs_root *root, unsigned int num_items,
|
||||
* Do the reservation before we join the transaction so we can do all
|
||||
* the appropriate flushing if need be.
|
||||
*/
|
||||
if (num_items > 0 && root != fs_info->chunk_root) {
|
||||
if (num_items && root != fs_info->chunk_root) {
|
||||
qgroup_reserved = num_items * fs_info->nodesize;
|
||||
ret = btrfs_qgroup_reserve_meta(root, qgroup_reserved);
|
||||
ret = btrfs_qgroup_reserve_meta(root, qgroup_reserved,
|
||||
enforce_qgroups);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
@ -613,8 +615,9 @@ struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root,
|
||||
unsigned int num_items)
|
||||
{
|
||||
return start_transaction(root, num_items, TRANS_START,
|
||||
BTRFS_RESERVE_FLUSH_ALL);
|
||||
BTRFS_RESERVE_FLUSH_ALL, true);
|
||||
}
|
||||
|
||||
struct btrfs_trans_handle *btrfs_start_transaction_fallback_global_rsv(
|
||||
struct btrfs_root *root,
|
||||
unsigned int num_items,
|
||||
@ -625,7 +628,14 @@ struct btrfs_trans_handle *btrfs_start_transaction_fallback_global_rsv(
|
||||
u64 num_bytes;
|
||||
int ret;
|
||||
|
||||
trans = btrfs_start_transaction(root, num_items);
|
||||
/*
|
||||
* We have two callers: unlink and block group removal. The
|
||||
* former should succeed even if we will temporarily exceed
|
||||
* quota and the latter operates on the extent root so
|
||||
* qgroup enforcement is ignored anyway.
|
||||
*/
|
||||
trans = start_transaction(root, num_items, TRANS_START,
|
||||
BTRFS_RESERVE_FLUSH_ALL, false);
|
||||
if (!IS_ERR(trans) || PTR_ERR(trans) != -ENOSPC)
|
||||
return trans;
|
||||
|
||||
@ -654,25 +664,25 @@ struct btrfs_trans_handle *btrfs_start_transaction_lflush(
|
||||
unsigned int num_items)
|
||||
{
|
||||
return start_transaction(root, num_items, TRANS_START,
|
||||
BTRFS_RESERVE_FLUSH_LIMIT);
|
||||
BTRFS_RESERVE_FLUSH_LIMIT, true);
|
||||
}
|
||||
|
||||
struct btrfs_trans_handle *btrfs_join_transaction(struct btrfs_root *root)
|
||||
{
|
||||
return start_transaction(root, 0, TRANS_JOIN,
|
||||
BTRFS_RESERVE_NO_FLUSH);
|
||||
return start_transaction(root, 0, TRANS_JOIN, BTRFS_RESERVE_NO_FLUSH,
|
||||
true);
|
||||
}
|
||||
|
||||
struct btrfs_trans_handle *btrfs_join_transaction_nolock(struct btrfs_root *root)
|
||||
{
|
||||
return start_transaction(root, 0, TRANS_JOIN_NOLOCK,
|
||||
BTRFS_RESERVE_NO_FLUSH);
|
||||
BTRFS_RESERVE_NO_FLUSH, true);
|
||||
}
|
||||
|
||||
struct btrfs_trans_handle *btrfs_start_ioctl_transaction(struct btrfs_root *root)
|
||||
{
|
||||
return start_transaction(root, 0, TRANS_USERSPACE,
|
||||
BTRFS_RESERVE_NO_FLUSH);
|
||||
BTRFS_RESERVE_NO_FLUSH, true);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -691,7 +701,7 @@ struct btrfs_trans_handle *btrfs_start_ioctl_transaction(struct btrfs_root *root
|
||||
struct btrfs_trans_handle *btrfs_attach_transaction(struct btrfs_root *root)
|
||||
{
|
||||
return start_transaction(root, 0, TRANS_ATTACH,
|
||||
BTRFS_RESERVE_NO_FLUSH);
|
||||
BTRFS_RESERVE_NO_FLUSH, true);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -707,7 +717,7 @@ btrfs_attach_transaction_barrier(struct btrfs_root *root)
|
||||
struct btrfs_trans_handle *trans;
|
||||
|
||||
trans = start_transaction(root, 0, TRANS_ATTACH,
|
||||
BTRFS_RESERVE_NO_FLUSH);
|
||||
BTRFS_RESERVE_NO_FLUSH, true);
|
||||
if (IS_ERR(trans) && PTR_ERR(trans) == -ENOENT)
|
||||
btrfs_wait_for_commit(root->fs_info, 0);
|
||||
|
||||
@ -866,14 +876,14 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
|
||||
|
||||
if (lock && !atomic_read(&info->open_ioctl_trans) &&
|
||||
should_end_transaction(trans) &&
|
||||
ACCESS_ONCE(cur_trans->state) == TRANS_STATE_RUNNING) {
|
||||
READ_ONCE(cur_trans->state) == TRANS_STATE_RUNNING) {
|
||||
spin_lock(&info->trans_lock);
|
||||
if (cur_trans->state == TRANS_STATE_RUNNING)
|
||||
cur_trans->state = TRANS_STATE_BLOCKED;
|
||||
spin_unlock(&info->trans_lock);
|
||||
}
|
||||
|
||||
if (lock && ACCESS_ONCE(cur_trans->state) == TRANS_STATE_BLOCKED) {
|
||||
if (lock && READ_ONCE(cur_trans->state) == TRANS_STATE_BLOCKED) {
|
||||
if (throttle)
|
||||
return btrfs_commit_transaction(trans);
|
||||
else
|
||||
@ -1354,12 +1364,8 @@ static int qgroup_account_snapshot(struct btrfs_trans_handle *trans,
|
||||
* enabled. If this check races with the ioctl, rescan will
|
||||
* kick in anyway.
|
||||
*/
|
||||
mutex_lock(&fs_info->qgroup_ioctl_lock);
|
||||
if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags)) {
|
||||
mutex_unlock(&fs_info->qgroup_ioctl_lock);
|
||||
if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags))
|
||||
return 0;
|
||||
}
|
||||
mutex_unlock(&fs_info->qgroup_ioctl_lock);
|
||||
|
||||
/*
|
||||
* We are going to commit transaction, see btrfs_commit_transaction()
|
||||
@ -1504,7 +1510,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
|
||||
|
||||
/* check if there is a file/dir which has the same name. */
|
||||
dir_item = btrfs_lookup_dir_item(NULL, parent_root, path,
|
||||
btrfs_ino(parent_inode),
|
||||
btrfs_ino(BTRFS_I(parent_inode)),
|
||||
dentry->d_name.name,
|
||||
dentry->d_name.len, 0);
|
||||
if (dir_item != NULL && !IS_ERR(dir_item)) {
|
||||
@ -1598,7 +1604,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
|
||||
*/
|
||||
ret = btrfs_add_root_ref(trans, fs_info, objectid,
|
||||
parent_root->root_key.objectid,
|
||||
btrfs_ino(parent_inode), index,
|
||||
btrfs_ino(BTRFS_I(parent_inode)), index,
|
||||
dentry->d_name.name, dentry->d_name.len);
|
||||
if (ret) {
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
@ -1940,7 +1946,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
|
||||
int ret;
|
||||
|
||||
/* Stop the commit early if ->aborted is set */
|
||||
if (unlikely(ACCESS_ONCE(cur_trans->aborted))) {
|
||||
if (unlikely(READ_ONCE(cur_trans->aborted))) {
|
||||
ret = cur_trans->aborted;
|
||||
btrfs_end_transaction(trans);
|
||||
return ret;
|
||||
@ -2080,7 +2086,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
|
||||
atomic_read(&cur_trans->num_writers) == 1);
|
||||
|
||||
/* ->aborted might be set after the previous check, so check it */
|
||||
if (unlikely(ACCESS_ONCE(cur_trans->aborted))) {
|
||||
if (unlikely(READ_ONCE(cur_trans->aborted))) {
|
||||
ret = cur_trans->aborted;
|
||||
goto scrub_continue;
|
||||
}
|
||||
@ -2194,14 +2200,14 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
|
||||
* The tasks which save the space cache and inode cache may also
|
||||
* update ->aborted, check it.
|
||||
*/
|
||||
if (unlikely(ACCESS_ONCE(cur_trans->aborted))) {
|
||||
if (unlikely(READ_ONCE(cur_trans->aborted))) {
|
||||
ret = cur_trans->aborted;
|
||||
mutex_unlock(&fs_info->tree_log_mutex);
|
||||
mutex_unlock(&fs_info->reloc_mutex);
|
||||
goto scrub_continue;
|
||||
}
|
||||
|
||||
btrfs_prepare_extent_commit(trans, fs_info);
|
||||
btrfs_prepare_extent_commit(fs_info);
|
||||
|
||||
cur_trans = fs_info->running_transaction;
|
||||
|
||||
@ -2251,7 +2257,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
|
||||
goto scrub_continue;
|
||||
}
|
||||
|
||||
ret = write_ctree_super(trans, fs_info, 0);
|
||||
ret = write_all_supers(fs_info, 0);
|
||||
if (ret) {
|
||||
mutex_unlock(&fs_info->tree_log_mutex);
|
||||
goto scrub_continue;
|
||||
|
@ -97,7 +97,7 @@
|
||||
#define LOG_WALK_REPLAY_ALL 3
|
||||
|
||||
static int btrfs_log_inode(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root, struct inode *inode,
|
||||
struct btrfs_root *root, struct btrfs_inode *inode,
|
||||
int inode_only,
|
||||
const loff_t start,
|
||||
const loff_t end,
|
||||
@ -631,8 +631,8 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans,
|
||||
* file. This must be done before the btrfs_drop_extents run
|
||||
* so we don't try to drop this extent.
|
||||
*/
|
||||
ret = btrfs_lookup_file_extent(trans, root, path, btrfs_ino(inode),
|
||||
start, 0);
|
||||
ret = btrfs_lookup_file_extent(trans, root, path,
|
||||
btrfs_ino(BTRFS_I(inode)), start, 0);
|
||||
|
||||
if (ret == 0 &&
|
||||
(found_type == BTRFS_FILE_EXTENT_REG ||
|
||||
@ -843,7 +843,7 @@ out:
|
||||
static noinline int drop_one_dir_item(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
struct btrfs_path *path,
|
||||
struct inode *dir,
|
||||
struct btrfs_inode *dir,
|
||||
struct btrfs_dir_item *di)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = root->fs_info;
|
||||
@ -875,7 +875,8 @@ static noinline int drop_one_dir_item(struct btrfs_trans_handle *trans,
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = btrfs_unlink_inode(trans, root, dir, inode, name, name_len);
|
||||
ret = btrfs_unlink_inode(trans, root, dir, BTRFS_I(inode), name,
|
||||
name_len);
|
||||
if (ret)
|
||||
goto out;
|
||||
else
|
||||
@ -991,8 +992,8 @@ static inline int __add_inode_ref(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
struct btrfs_path *path,
|
||||
struct btrfs_root *log_root,
|
||||
struct inode *dir, struct inode *inode,
|
||||
struct extent_buffer *eb,
|
||||
struct btrfs_inode *dir,
|
||||
struct btrfs_inode *inode,
|
||||
u64 inode_objectid, u64 parent_objectid,
|
||||
u64 ref_index, char *name, int namelen,
|
||||
int *search_done)
|
||||
@ -1047,12 +1048,11 @@ again:
|
||||
parent_objectid,
|
||||
victim_name,
|
||||
victim_name_len)) {
|
||||
inc_nlink(inode);
|
||||
inc_nlink(&inode->vfs_inode);
|
||||
btrfs_release_path(path);
|
||||
|
||||
ret = btrfs_unlink_inode(trans, root, dir,
|
||||
inode, victim_name,
|
||||
victim_name_len);
|
||||
ret = btrfs_unlink_inode(trans, root, dir, inode,
|
||||
victim_name, victim_name_len);
|
||||
kfree(victim_name);
|
||||
if (ret)
|
||||
return ret;
|
||||
@ -1115,16 +1115,16 @@ again:
|
||||
victim_name_len)) {
|
||||
ret = -ENOENT;
|
||||
victim_parent = read_one_inode(root,
|
||||
parent_objectid);
|
||||
parent_objectid);
|
||||
if (victim_parent) {
|
||||
inc_nlink(inode);
|
||||
inc_nlink(&inode->vfs_inode);
|
||||
btrfs_release_path(path);
|
||||
|
||||
ret = btrfs_unlink_inode(trans, root,
|
||||
victim_parent,
|
||||
inode,
|
||||
victim_name,
|
||||
victim_name_len);
|
||||
BTRFS_I(victim_parent),
|
||||
inode,
|
||||
victim_name,
|
||||
victim_name_len);
|
||||
if (!ret)
|
||||
ret = btrfs_run_delayed_items(
|
||||
trans,
|
||||
@ -1295,8 +1295,9 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans,
|
||||
goto out;
|
||||
|
||||
/* if we already have a perfect match, we're done */
|
||||
if (!inode_in_dir(root, path, btrfs_ino(dir), btrfs_ino(inode),
|
||||
ref_index, name, namelen)) {
|
||||
if (!inode_in_dir(root, path, btrfs_ino(BTRFS_I(dir)),
|
||||
btrfs_ino(BTRFS_I(inode)), ref_index,
|
||||
name, namelen)) {
|
||||
/*
|
||||
* look for a conflicting back reference in the
|
||||
* metadata. if we find one we have to unlink that name
|
||||
@ -1307,7 +1308,8 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans,
|
||||
|
||||
if (!search_done) {
|
||||
ret = __add_inode_ref(trans, root, path, log,
|
||||
dir, inode, eb,
|
||||
BTRFS_I(dir),
|
||||
BTRFS_I(inode),
|
||||
inode_objectid,
|
||||
parent_objectid,
|
||||
ref_index, name, namelen,
|
||||
@ -1360,7 +1362,7 @@ static int insert_orphan_item(struct btrfs_trans_handle *trans,
|
||||
}
|
||||
|
||||
static int count_inode_extrefs(struct btrfs_root *root,
|
||||
struct inode *inode, struct btrfs_path *path)
|
||||
struct btrfs_inode *inode, struct btrfs_path *path)
|
||||
{
|
||||
int ret = 0;
|
||||
int name_len;
|
||||
@ -1404,7 +1406,7 @@ static int count_inode_extrefs(struct btrfs_root *root,
|
||||
}
|
||||
|
||||
static int count_inode_refs(struct btrfs_root *root,
|
||||
struct inode *inode, struct btrfs_path *path)
|
||||
struct btrfs_inode *inode, struct btrfs_path *path)
|
||||
{
|
||||
int ret;
|
||||
struct btrfs_key key;
|
||||
@ -1477,19 +1479,19 @@ static noinline int fixup_inode_link_count(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_path *path;
|
||||
int ret;
|
||||
u64 nlink = 0;
|
||||
u64 ino = btrfs_ino(inode);
|
||||
u64 ino = btrfs_ino(BTRFS_I(inode));
|
||||
|
||||
path = btrfs_alloc_path();
|
||||
if (!path)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = count_inode_refs(root, inode, path);
|
||||
ret = count_inode_refs(root, BTRFS_I(inode), path);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
nlink = ret;
|
||||
|
||||
ret = count_inode_extrefs(root, inode, path);
|
||||
ret = count_inode_extrefs(root, BTRFS_I(inode), path);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
@ -1769,7 +1771,7 @@ static noinline int replay_one_name(struct btrfs_trans_handle *trans,
|
||||
if (!exists)
|
||||
goto out;
|
||||
|
||||
ret = drop_one_dir_item(trans, root, path, dir, dst_di);
|
||||
ret = drop_one_dir_item(trans, root, path, BTRFS_I(dir), dst_di);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
@ -2052,8 +2054,8 @@ again:
|
||||
}
|
||||
|
||||
inc_nlink(inode);
|
||||
ret = btrfs_unlink_inode(trans, root, dir, inode,
|
||||
name, name_len);
|
||||
ret = btrfs_unlink_inode(trans, root, BTRFS_I(dir),
|
||||
BTRFS_I(inode), name, name_len);
|
||||
if (!ret)
|
||||
ret = btrfs_run_delayed_items(trans, fs_info);
|
||||
kfree(name);
|
||||
@ -2469,7 +2471,7 @@ static noinline int walk_down_log_tree(struct btrfs_trans_handle *trans,
|
||||
if (trans) {
|
||||
btrfs_tree_lock(next);
|
||||
btrfs_set_lock_blocking(next);
|
||||
clean_tree_block(trans, fs_info, next);
|
||||
clean_tree_block(fs_info, next);
|
||||
btrfs_wait_tree_block_writeback(next);
|
||||
btrfs_tree_unlock(next);
|
||||
}
|
||||
@ -2549,7 +2551,7 @@ static noinline int walk_up_log_tree(struct btrfs_trans_handle *trans,
|
||||
if (trans) {
|
||||
btrfs_tree_lock(next);
|
||||
btrfs_set_lock_blocking(next);
|
||||
clean_tree_block(trans, fs_info, next);
|
||||
clean_tree_block(fs_info, next);
|
||||
btrfs_wait_tree_block_writeback(next);
|
||||
btrfs_tree_unlock(next);
|
||||
}
|
||||
@ -2627,7 +2629,7 @@ static int walk_log_tree(struct btrfs_trans_handle *trans,
|
||||
if (trans) {
|
||||
btrfs_tree_lock(next);
|
||||
btrfs_set_lock_blocking(next);
|
||||
clean_tree_block(trans, fs_info, next);
|
||||
clean_tree_block(fs_info, next);
|
||||
btrfs_wait_tree_block_writeback(next);
|
||||
btrfs_tree_unlock(next);
|
||||
}
|
||||
@ -2958,7 +2960,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
|
||||
* the running transaction open, so a full commit can't hop
|
||||
* in and cause problems either.
|
||||
*/
|
||||
ret = write_ctree_super(trans, fs_info, 1);
|
||||
ret = write_all_supers(fs_info, 1);
|
||||
if (ret) {
|
||||
btrfs_set_log_full_commit(fs_info, trans);
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
@ -3084,7 +3086,7 @@ int btrfs_free_log_root_tree(struct btrfs_trans_handle *trans,
|
||||
int btrfs_del_dir_entries_in_log(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
const char *name, int name_len,
|
||||
struct inode *dir, u64 index)
|
||||
struct btrfs_inode *dir, u64 index)
|
||||
{
|
||||
struct btrfs_root *log;
|
||||
struct btrfs_dir_item *di;
|
||||
@ -3094,14 +3096,14 @@ int btrfs_del_dir_entries_in_log(struct btrfs_trans_handle *trans,
|
||||
int bytes_del = 0;
|
||||
u64 dir_ino = btrfs_ino(dir);
|
||||
|
||||
if (BTRFS_I(dir)->logged_trans < trans->transid)
|
||||
if (dir->logged_trans < trans->transid)
|
||||
return 0;
|
||||
|
||||
ret = join_running_log_trans(root);
|
||||
if (ret)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&BTRFS_I(dir)->log_mutex);
|
||||
mutex_lock(&dir->log_mutex);
|
||||
|
||||
log = root->log_root;
|
||||
path = btrfs_alloc_path();
|
||||
@ -3176,7 +3178,7 @@ int btrfs_del_dir_entries_in_log(struct btrfs_trans_handle *trans,
|
||||
fail:
|
||||
btrfs_free_path(path);
|
||||
out_unlock:
|
||||
mutex_unlock(&BTRFS_I(dir)->log_mutex);
|
||||
mutex_unlock(&dir->log_mutex);
|
||||
if (ret == -ENOSPC) {
|
||||
btrfs_set_log_full_commit(root->fs_info, trans);
|
||||
ret = 0;
|
||||
@ -3192,25 +3194,25 @@ out_unlock:
|
||||
int btrfs_del_inode_ref_in_log(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
const char *name, int name_len,
|
||||
struct inode *inode, u64 dirid)
|
||||
struct btrfs_inode *inode, u64 dirid)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = root->fs_info;
|
||||
struct btrfs_root *log;
|
||||
u64 index;
|
||||
int ret;
|
||||
|
||||
if (BTRFS_I(inode)->logged_trans < trans->transid)
|
||||
if (inode->logged_trans < trans->transid)
|
||||
return 0;
|
||||
|
||||
ret = join_running_log_trans(root);
|
||||
if (ret)
|
||||
return 0;
|
||||
log = root->log_root;
|
||||
mutex_lock(&BTRFS_I(inode)->log_mutex);
|
||||
mutex_lock(&inode->log_mutex);
|
||||
|
||||
ret = btrfs_del_inode_ref(trans, log, name, name_len, btrfs_ino(inode),
|
||||
dirid, &index);
|
||||
mutex_unlock(&BTRFS_I(inode)->log_mutex);
|
||||
mutex_unlock(&inode->log_mutex);
|
||||
if (ret == -ENOSPC) {
|
||||
btrfs_set_log_full_commit(fs_info, trans);
|
||||
ret = 0;
|
||||
@ -3260,7 +3262,7 @@ static noinline int insert_dir_log_key(struct btrfs_trans_handle *trans,
|
||||
* to replay anything deleted before the fsync
|
||||
*/
|
||||
static noinline int log_dir_items(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root, struct inode *inode,
|
||||
struct btrfs_root *root, struct btrfs_inode *inode,
|
||||
struct btrfs_path *path,
|
||||
struct btrfs_path *dst_path, int key_type,
|
||||
struct btrfs_log_ctx *ctx,
|
||||
@ -3450,7 +3452,7 @@ done:
|
||||
* key logged by this transaction.
|
||||
*/
|
||||
static noinline int log_directory_changes(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root, struct inode *inode,
|
||||
struct btrfs_root *root, struct btrfs_inode *inode,
|
||||
struct btrfs_path *path,
|
||||
struct btrfs_path *dst_path,
|
||||
struct btrfs_log_ctx *ctx)
|
||||
@ -3464,9 +3466,8 @@ again:
|
||||
min_key = 0;
|
||||
max_key = 0;
|
||||
while (1) {
|
||||
ret = log_dir_items(trans, root, inode, path,
|
||||
dst_path, key_type, ctx, min_key,
|
||||
&max_key);
|
||||
ret = log_dir_items(trans, root, inode, path, dst_path, key_type,
|
||||
ctx, min_key, &max_key);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (max_key == (u64)-1)
|
||||
@ -3595,34 +3596,34 @@ static void fill_inode_item(struct btrfs_trans_handle *trans,
|
||||
|
||||
static int log_inode_item(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *log, struct btrfs_path *path,
|
||||
struct inode *inode)
|
||||
struct btrfs_inode *inode)
|
||||
{
|
||||
struct btrfs_inode_item *inode_item;
|
||||
int ret;
|
||||
|
||||
ret = btrfs_insert_empty_item(trans, log, path,
|
||||
&BTRFS_I(inode)->location,
|
||||
sizeof(*inode_item));
|
||||
&inode->location, sizeof(*inode_item));
|
||||
if (ret && ret != -EEXIST)
|
||||
return ret;
|
||||
inode_item = btrfs_item_ptr(path->nodes[0], path->slots[0],
|
||||
struct btrfs_inode_item);
|
||||
fill_inode_item(trans, path->nodes[0], inode_item, inode, 0, 0);
|
||||
fill_inode_item(trans, path->nodes[0], inode_item, &inode->vfs_inode,
|
||||
0, 0);
|
||||
btrfs_release_path(path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static noinline int copy_items(struct btrfs_trans_handle *trans,
|
||||
struct inode *inode,
|
||||
struct btrfs_inode *inode,
|
||||
struct btrfs_path *dst_path,
|
||||
struct btrfs_path *src_path, u64 *last_extent,
|
||||
int start_slot, int nr, int inode_only,
|
||||
u64 logged_isize)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
|
||||
struct btrfs_fs_info *fs_info = btrfs_sb(inode->vfs_inode.i_sb);
|
||||
unsigned long src_offset;
|
||||
unsigned long dst_offset;
|
||||
struct btrfs_root *log = BTRFS_I(inode)->root->log_root;
|
||||
struct btrfs_root *log = inode->root->log_root;
|
||||
struct btrfs_file_extent_item *extent;
|
||||
struct btrfs_inode_item *inode_item;
|
||||
struct extent_buffer *src = src_path->nodes[0];
|
||||
@ -3633,7 +3634,7 @@ static noinline int copy_items(struct btrfs_trans_handle *trans,
|
||||
char *ins_data;
|
||||
int i;
|
||||
struct list_head ordered_sums;
|
||||
int skip_csum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM;
|
||||
int skip_csum = inode->flags & BTRFS_INODE_NODATASUM;
|
||||
bool has_extents = false;
|
||||
bool need_find_last_extent = true;
|
||||
bool done = false;
|
||||
@ -3675,7 +3676,8 @@ static noinline int copy_items(struct btrfs_trans_handle *trans,
|
||||
dst_path->slots[0],
|
||||
struct btrfs_inode_item);
|
||||
fill_inode_item(trans, dst_path->nodes[0], inode_item,
|
||||
inode, inode_only == LOG_INODE_EXISTS,
|
||||
&inode->vfs_inode,
|
||||
inode_only == LOG_INODE_EXISTS,
|
||||
logged_isize);
|
||||
} else {
|
||||
copy_extent_buffer(dst_path->nodes[0], src, dst_offset,
|
||||
@ -3783,7 +3785,7 @@ static noinline int copy_items(struct btrfs_trans_handle *trans,
|
||||
if (need_find_last_extent) {
|
||||
u64 len;
|
||||
|
||||
ret = btrfs_prev_leaf(BTRFS_I(inode)->root, src_path);
|
||||
ret = btrfs_prev_leaf(inode->root, src_path);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (ret)
|
||||
@ -3825,8 +3827,8 @@ fill_holes:
|
||||
if (need_find_last_extent) {
|
||||
/* btrfs_prev_leaf could return 1 without releasing the path */
|
||||
btrfs_release_path(src_path);
|
||||
ret = btrfs_search_slot(NULL, BTRFS_I(inode)->root, &first_key,
|
||||
src_path, 0, 0);
|
||||
ret = btrfs_search_slot(NULL, inode->root, &first_key,
|
||||
src_path, 0, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ASSERT(ret == 0);
|
||||
@ -3846,7 +3848,7 @@ fill_holes:
|
||||
u64 extent_end;
|
||||
|
||||
if (i >= btrfs_header_nritems(src_path->nodes[0])) {
|
||||
ret = btrfs_next_leaf(BTRFS_I(inode)->root, src_path);
|
||||
ret = btrfs_next_leaf(inode->root, src_path);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ASSERT(ret == 0);
|
||||
@ -3881,8 +3883,7 @@ fill_holes:
|
||||
offset = *last_extent;
|
||||
len = key.offset - *last_extent;
|
||||
ret = btrfs_insert_file_extent(trans, log, btrfs_ino(inode),
|
||||
offset, 0, 0, len, 0, len, 0,
|
||||
0, 0);
|
||||
offset, 0, 0, len, 0, len, 0, 0, 0);
|
||||
if (ret)
|
||||
break;
|
||||
*last_extent = extent_end;
|
||||
@ -4055,7 +4056,7 @@ static int wait_ordered_extents(struct btrfs_trans_handle *trans,
|
||||
}
|
||||
|
||||
static int log_one_extent(struct btrfs_trans_handle *trans,
|
||||
struct inode *inode, struct btrfs_root *root,
|
||||
struct btrfs_inode *inode, struct btrfs_root *root,
|
||||
const struct extent_map *em,
|
||||
struct btrfs_path *path,
|
||||
const struct list_head *logged_list,
|
||||
@ -4072,8 +4073,8 @@ static int log_one_extent(struct btrfs_trans_handle *trans,
|
||||
int extent_inserted = 0;
|
||||
bool ordered_io_err = false;
|
||||
|
||||
ret = wait_ordered_extents(trans, inode, root, em, logged_list,
|
||||
&ordered_io_err);
|
||||
ret = wait_ordered_extents(trans, &inode->vfs_inode, root, em,
|
||||
logged_list, &ordered_io_err);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -4084,7 +4085,7 @@ static int log_one_extent(struct btrfs_trans_handle *trans,
|
||||
|
||||
btrfs_init_map_token(&token);
|
||||
|
||||
ret = __btrfs_drop_extents(trans, log, inode, path, em->start,
|
||||
ret = __btrfs_drop_extents(trans, log, &inode->vfs_inode, path, em->start,
|
||||
em->start + em->len, NULL, 0, 1,
|
||||
sizeof(*fi), &extent_inserted);
|
||||
if (ret)
|
||||
@ -4150,7 +4151,7 @@ static int log_one_extent(struct btrfs_trans_handle *trans,
|
||||
|
||||
static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
struct inode *inode,
|
||||
struct btrfs_inode *inode,
|
||||
struct btrfs_path *path,
|
||||
struct list_head *logged_list,
|
||||
struct btrfs_log_ctx *ctx,
|
||||
@ -4159,14 +4160,14 @@ static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans,
|
||||
{
|
||||
struct extent_map *em, *n;
|
||||
struct list_head extents;
|
||||
struct extent_map_tree *tree = &BTRFS_I(inode)->extent_tree;
|
||||
struct extent_map_tree *tree = &inode->extent_tree;
|
||||
u64 test_gen;
|
||||
int ret = 0;
|
||||
int num = 0;
|
||||
|
||||
INIT_LIST_HEAD(&extents);
|
||||
|
||||
down_write(&BTRFS_I(inode)->dio_sem);
|
||||
down_write(&inode->dio_sem);
|
||||
write_lock(&tree->lock);
|
||||
test_gen = root->fs_info->last_trans_committed;
|
||||
|
||||
@ -4206,7 +4207,7 @@ static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans,
|
||||
* without writing to the log tree and the fsync must report the
|
||||
* file data write error and not commit the current transaction.
|
||||
*/
|
||||
ret = filemap_check_errors(inode->i_mapping);
|
||||
ret = filemap_check_errors(inode->vfs_inode.i_mapping);
|
||||
if (ret)
|
||||
ctx->io_err = ret;
|
||||
process:
|
||||
@ -4235,13 +4236,13 @@ process:
|
||||
}
|
||||
WARN_ON(!list_empty(&extents));
|
||||
write_unlock(&tree->lock);
|
||||
up_write(&BTRFS_I(inode)->dio_sem);
|
||||
up_write(&inode->dio_sem);
|
||||
|
||||
btrfs_release_path(path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int logged_inode_size(struct btrfs_root *log, struct inode *inode,
|
||||
static int logged_inode_size(struct btrfs_root *log, struct btrfs_inode *inode,
|
||||
struct btrfs_path *path, u64 *size_ret)
|
||||
{
|
||||
struct btrfs_key key;
|
||||
@ -4279,7 +4280,7 @@ static int logged_inode_size(struct btrfs_root *log, struct inode *inode,
|
||||
*/
|
||||
static int btrfs_log_all_xattrs(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
struct inode *inode,
|
||||
struct btrfs_inode *inode,
|
||||
struct btrfs_path *path,
|
||||
struct btrfs_path *dst_path)
|
||||
{
|
||||
@ -4374,7 +4375,7 @@ static int btrfs_log_all_xattrs(struct btrfs_trans_handle *trans,
|
||||
*/
|
||||
static int btrfs_log_trailing_hole(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
struct inode *inode,
|
||||
struct btrfs_inode *inode,
|
||||
struct btrfs_path *path)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = root->fs_info;
|
||||
@ -4385,7 +4386,7 @@ static int btrfs_log_trailing_hole(struct btrfs_trans_handle *trans,
|
||||
struct extent_buffer *leaf;
|
||||
struct btrfs_root *log = root->log_root;
|
||||
const u64 ino = btrfs_ino(inode);
|
||||
const u64 i_size = i_size_read(inode);
|
||||
const u64 i_size = i_size_read(&inode->vfs_inode);
|
||||
|
||||
if (!btrfs_fs_incompat(fs_info, NO_HOLES))
|
||||
return 0;
|
||||
@ -4495,7 +4496,7 @@ static int btrfs_log_trailing_hole(struct btrfs_trans_handle *trans,
|
||||
static int btrfs_check_ref_name_override(struct extent_buffer *eb,
|
||||
const int slot,
|
||||
const struct btrfs_key *key,
|
||||
struct inode *inode,
|
||||
struct btrfs_inode *inode,
|
||||
u64 *other_ino)
|
||||
{
|
||||
int ret;
|
||||
@ -4551,9 +4552,8 @@ static int btrfs_check_ref_name_override(struct extent_buffer *eb,
|
||||
}
|
||||
|
||||
read_extent_buffer(eb, name, name_ptr, this_name_len);
|
||||
di = btrfs_lookup_dir_item(NULL, BTRFS_I(inode)->root,
|
||||
search_path, parent,
|
||||
name, this_name_len, 0);
|
||||
di = btrfs_lookup_dir_item(NULL, inode->root, search_path,
|
||||
parent, name, this_name_len, 0);
|
||||
if (di && !IS_ERR(di)) {
|
||||
struct btrfs_key di_key;
|
||||
|
||||
@ -4596,7 +4596,7 @@ out:
|
||||
* This handles both files and directories.
|
||||
*/
|
||||
static int btrfs_log_inode(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root, struct inode *inode,
|
||||
struct btrfs_root *root, struct btrfs_inode *inode,
|
||||
int inode_only,
|
||||
const loff_t start,
|
||||
const loff_t end,
|
||||
@ -4618,7 +4618,7 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
|
||||
int ins_nr;
|
||||
bool fast_search = false;
|
||||
u64 ino = btrfs_ino(inode);
|
||||
struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;
|
||||
struct extent_map_tree *em_tree = &inode->extent_tree;
|
||||
u64 logged_isize = 0;
|
||||
bool need_log_inode_item = true;
|
||||
|
||||
@ -4639,9 +4639,9 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
|
||||
|
||||
|
||||
/* today the code can only do partial logging of directories */
|
||||
if (S_ISDIR(inode->i_mode) ||
|
||||
if (S_ISDIR(inode->vfs_inode.i_mode) ||
|
||||
(!test_bit(BTRFS_INODE_NEEDS_FULL_SYNC,
|
||||
&BTRFS_I(inode)->runtime_flags) &&
|
||||
&inode->runtime_flags) &&
|
||||
inode_only >= LOG_INODE_EXISTS))
|
||||
max_key.type = BTRFS_XATTR_ITEM_KEY;
|
||||
else
|
||||
@ -4654,8 +4654,8 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
|
||||
* order for the log replay code to mark inodes for link count
|
||||
* fixup (create temporary BTRFS_TREE_LOG_FIXUP_OBJECTID items).
|
||||
*/
|
||||
if (S_ISDIR(inode->i_mode) ||
|
||||
BTRFS_I(inode)->generation > fs_info->last_trans_committed)
|
||||
if (S_ISDIR(inode->vfs_inode.i_mode) ||
|
||||
inode->generation > fs_info->last_trans_committed)
|
||||
ret = btrfs_commit_inode_delayed_items(trans, inode);
|
||||
else
|
||||
ret = btrfs_commit_inode_delayed_inode(inode);
|
||||
@ -4668,17 +4668,16 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
|
||||
|
||||
if (inode_only == LOG_OTHER_INODE) {
|
||||
inode_only = LOG_INODE_EXISTS;
|
||||
mutex_lock_nested(&BTRFS_I(inode)->log_mutex,
|
||||
SINGLE_DEPTH_NESTING);
|
||||
mutex_lock_nested(&inode->log_mutex, SINGLE_DEPTH_NESTING);
|
||||
} else {
|
||||
mutex_lock(&BTRFS_I(inode)->log_mutex);
|
||||
mutex_lock(&inode->log_mutex);
|
||||
}
|
||||
|
||||
/*
|
||||
* a brute force approach to making sure we get the most uptodate
|
||||
* copies of everything.
|
||||
*/
|
||||
if (S_ISDIR(inode->i_mode)) {
|
||||
if (S_ISDIR(inode->vfs_inode.i_mode)) {
|
||||
int max_key_type = BTRFS_DIR_LOG_INDEX_KEY;
|
||||
|
||||
if (inode_only == LOG_INODE_EXISTS)
|
||||
@ -4699,31 +4698,30 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
|
||||
* (zeroes), as if an expanding truncate happened,
|
||||
* instead of getting a file of 4Kb only.
|
||||
*/
|
||||
err = logged_inode_size(log, inode, path,
|
||||
&logged_isize);
|
||||
err = logged_inode_size(log, inode, path, &logged_isize);
|
||||
if (err)
|
||||
goto out_unlock;
|
||||
}
|
||||
if (test_bit(BTRFS_INODE_NEEDS_FULL_SYNC,
|
||||
&BTRFS_I(inode)->runtime_flags)) {
|
||||
&inode->runtime_flags)) {
|
||||
if (inode_only == LOG_INODE_EXISTS) {
|
||||
max_key.type = BTRFS_XATTR_ITEM_KEY;
|
||||
ret = drop_objectid_items(trans, log, path, ino,
|
||||
max_key.type);
|
||||
} else {
|
||||
clear_bit(BTRFS_INODE_NEEDS_FULL_SYNC,
|
||||
&BTRFS_I(inode)->runtime_flags);
|
||||
&inode->runtime_flags);
|
||||
clear_bit(BTRFS_INODE_COPY_EVERYTHING,
|
||||
&BTRFS_I(inode)->runtime_flags);
|
||||
&inode->runtime_flags);
|
||||
while(1) {
|
||||
ret = btrfs_truncate_inode_items(trans,
|
||||
log, inode, 0, 0);
|
||||
log, &inode->vfs_inode, 0, 0);
|
||||
if (ret != -EAGAIN)
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (test_and_clear_bit(BTRFS_INODE_COPY_EVERYTHING,
|
||||
&BTRFS_I(inode)->runtime_flags) ||
|
||||
&inode->runtime_flags) ||
|
||||
inode_only == LOG_INODE_EXISTS) {
|
||||
if (inode_only == LOG_INODE_ALL)
|
||||
fast_search = true;
|
||||
@ -4764,18 +4762,17 @@ again:
|
||||
|
||||
if ((min_key.type == BTRFS_INODE_REF_KEY ||
|
||||
min_key.type == BTRFS_INODE_EXTREF_KEY) &&
|
||||
BTRFS_I(inode)->generation == trans->transid) {
|
||||
inode->generation == trans->transid) {
|
||||
u64 other_ino = 0;
|
||||
|
||||
ret = btrfs_check_ref_name_override(path->nodes[0],
|
||||
path->slots[0],
|
||||
&min_key, inode,
|
||||
&other_ino);
|
||||
path->slots[0], &min_key, inode,
|
||||
&other_ino);
|
||||
if (ret < 0) {
|
||||
err = ret;
|
||||
goto out_unlock;
|
||||
} else if (ret > 0 && ctx &&
|
||||
other_ino != btrfs_ino(ctx->inode)) {
|
||||
other_ino != btrfs_ino(BTRFS_I(ctx->inode))) {
|
||||
struct btrfs_key inode_key;
|
||||
struct inode *other_inode;
|
||||
|
||||
@ -4823,9 +4820,10 @@ again:
|
||||
* update the log with the new name before we
|
||||
* unpin it.
|
||||
*/
|
||||
err = btrfs_log_inode(trans, root, other_inode,
|
||||
LOG_OTHER_INODE,
|
||||
0, LLONG_MAX, ctx);
|
||||
err = btrfs_log_inode(trans, root,
|
||||
BTRFS_I(other_inode),
|
||||
LOG_OTHER_INODE, 0, LLONG_MAX,
|
||||
ctx);
|
||||
iput(other_inode);
|
||||
if (err)
|
||||
goto out_unlock;
|
||||
@ -4979,25 +4977,25 @@ log_extents:
|
||||
write_unlock(&em_tree->lock);
|
||||
}
|
||||
|
||||
if (inode_only == LOG_INODE_ALL && S_ISDIR(inode->i_mode)) {
|
||||
if (inode_only == LOG_INODE_ALL && S_ISDIR(inode->vfs_inode.i_mode)) {
|
||||
ret = log_directory_changes(trans, root, inode, path, dst_path,
|
||||
ctx);
|
||||
ctx);
|
||||
if (ret) {
|
||||
err = ret;
|
||||
goto out_unlock;
|
||||
}
|
||||
}
|
||||
|
||||
spin_lock(&BTRFS_I(inode)->lock);
|
||||
BTRFS_I(inode)->logged_trans = trans->transid;
|
||||
BTRFS_I(inode)->last_log_commit = BTRFS_I(inode)->last_sub_trans;
|
||||
spin_unlock(&BTRFS_I(inode)->lock);
|
||||
spin_lock(&inode->lock);
|
||||
inode->logged_trans = trans->transid;
|
||||
inode->last_log_commit = inode->last_sub_trans;
|
||||
spin_unlock(&inode->lock);
|
||||
out_unlock:
|
||||
if (unlikely(err))
|
||||
btrfs_put_logged_extents(&logged_list);
|
||||
else
|
||||
btrfs_submit_logged_extents(&logged_list, log);
|
||||
mutex_unlock(&BTRFS_I(inode)->log_mutex);
|
||||
mutex_unlock(&inode->log_mutex);
|
||||
|
||||
btrfs_free_path(path);
|
||||
btrfs_free_path(dst_path);
|
||||
@ -5021,13 +5019,13 @@ out_unlock:
|
||||
* we logged the inode or it might have also done the unlink).
|
||||
*/
|
||||
static bool btrfs_must_commit_transaction(struct btrfs_trans_handle *trans,
|
||||
struct inode *inode)
|
||||
struct btrfs_inode *inode)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = BTRFS_I(inode)->root->fs_info;
|
||||
struct btrfs_fs_info *fs_info = inode->root->fs_info;
|
||||
bool ret = false;
|
||||
|
||||
mutex_lock(&BTRFS_I(inode)->log_mutex);
|
||||
if (BTRFS_I(inode)->last_unlink_trans > fs_info->last_trans_committed) {
|
||||
mutex_lock(&inode->log_mutex);
|
||||
if (inode->last_unlink_trans > fs_info->last_trans_committed) {
|
||||
/*
|
||||
* Make sure any commits to the log are forced to be full
|
||||
* commits.
|
||||
@ -5035,7 +5033,7 @@ static bool btrfs_must_commit_transaction(struct btrfs_trans_handle *trans,
|
||||
btrfs_set_log_full_commit(fs_info, trans);
|
||||
ret = true;
|
||||
}
|
||||
mutex_unlock(&BTRFS_I(inode)->log_mutex);
|
||||
mutex_unlock(&inode->log_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -5084,7 +5082,7 @@ static noinline int check_parent_dirs_for_sync(struct btrfs_trans_handle *trans,
|
||||
BTRFS_I(inode)->logged_trans = trans->transid;
|
||||
smp_mb();
|
||||
|
||||
if (btrfs_must_commit_transaction(trans, inode)) {
|
||||
if (btrfs_must_commit_transaction(trans, BTRFS_I(inode))) {
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
@ -5094,7 +5092,7 @@ static noinline int check_parent_dirs_for_sync(struct btrfs_trans_handle *trans,
|
||||
|
||||
if (IS_ROOT(parent)) {
|
||||
inode = d_inode(parent);
|
||||
if (btrfs_must_commit_transaction(trans, inode))
|
||||
if (btrfs_must_commit_transaction(trans, BTRFS_I(inode)))
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
@ -5159,7 +5157,7 @@ struct btrfs_dir_list {
|
||||
*/
|
||||
static int log_new_dir_dentries(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
struct inode *start_inode,
|
||||
struct btrfs_inode *start_inode,
|
||||
struct btrfs_log_ctx *ctx)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = root->fs_info;
|
||||
@ -5237,7 +5235,7 @@ process_leaf:
|
||||
goto next_dir_inode;
|
||||
}
|
||||
|
||||
if (btrfs_inode_in_log(di_inode, trans->transid)) {
|
||||
if (btrfs_inode_in_log(BTRFS_I(di_inode), trans->transid)) {
|
||||
iput(di_inode);
|
||||
break;
|
||||
}
|
||||
@ -5245,10 +5243,10 @@ process_leaf:
|
||||
ctx->log_new_dentries = false;
|
||||
if (type == BTRFS_FT_DIR || type == BTRFS_FT_SYMLINK)
|
||||
log_mode = LOG_INODE_ALL;
|
||||
ret = btrfs_log_inode(trans, root, di_inode,
|
||||
ret = btrfs_log_inode(trans, root, BTRFS_I(di_inode),
|
||||
log_mode, 0, LLONG_MAX, ctx);
|
||||
if (!ret &&
|
||||
btrfs_must_commit_transaction(trans, di_inode))
|
||||
btrfs_must_commit_transaction(trans, BTRFS_I(di_inode)))
|
||||
ret = 1;
|
||||
iput(di_inode);
|
||||
if (ret)
|
||||
@ -5297,7 +5295,7 @@ static int btrfs_log_all_parents(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_path *path;
|
||||
struct btrfs_key key;
|
||||
struct btrfs_root *root = BTRFS_I(inode)->root;
|
||||
const u64 ino = btrfs_ino(inode);
|
||||
const u64 ino = btrfs_ino(BTRFS_I(inode));
|
||||
|
||||
path = btrfs_alloc_path();
|
||||
if (!path)
|
||||
@ -5365,14 +5363,14 @@ static int btrfs_log_all_parents(struct btrfs_trans_handle *trans,
|
||||
|
||||
if (ctx)
|
||||
ctx->log_new_dentries = false;
|
||||
ret = btrfs_log_inode(trans, root, dir_inode,
|
||||
ret = btrfs_log_inode(trans, root, BTRFS_I(dir_inode),
|
||||
LOG_INODE_ALL, 0, LLONG_MAX, ctx);
|
||||
if (!ret &&
|
||||
btrfs_must_commit_transaction(trans, dir_inode))
|
||||
btrfs_must_commit_transaction(trans, BTRFS_I(dir_inode)))
|
||||
ret = 1;
|
||||
if (!ret && ctx && ctx->log_new_dentries)
|
||||
ret = log_new_dir_dentries(trans, root,
|
||||
dir_inode, ctx);
|
||||
BTRFS_I(dir_inode), ctx);
|
||||
iput(dir_inode);
|
||||
if (ret)
|
||||
goto out;
|
||||
@ -5436,7 +5434,7 @@ static int btrfs_log_inode_parent(struct btrfs_trans_handle *trans,
|
||||
if (ret)
|
||||
goto end_no_trans;
|
||||
|
||||
if (btrfs_inode_in_log(inode, trans->transid)) {
|
||||
if (btrfs_inode_in_log(BTRFS_I(inode), trans->transid)) {
|
||||
ret = BTRFS_NO_LOG_SYNC;
|
||||
goto end_no_trans;
|
||||
}
|
||||
@ -5445,7 +5443,8 @@ static int btrfs_log_inode_parent(struct btrfs_trans_handle *trans,
|
||||
if (ret)
|
||||
goto end_no_trans;
|
||||
|
||||
ret = btrfs_log_inode(trans, root, inode, inode_only, start, end, ctx);
|
||||
ret = btrfs_log_inode(trans, root, BTRFS_I(inode), inode_only,
|
||||
start, end, ctx);
|
||||
if (ret)
|
||||
goto end_trans;
|
||||
|
||||
@ -5521,7 +5520,7 @@ static int btrfs_log_inode_parent(struct btrfs_trans_handle *trans,
|
||||
break;
|
||||
|
||||
if (BTRFS_I(inode)->generation > last_committed) {
|
||||
ret = btrfs_log_inode(trans, root, inode,
|
||||
ret = btrfs_log_inode(trans, root, BTRFS_I(inode),
|
||||
LOG_INODE_EXISTS,
|
||||
0, LLONG_MAX, ctx);
|
||||
if (ret)
|
||||
@ -5535,7 +5534,7 @@ static int btrfs_log_inode_parent(struct btrfs_trans_handle *trans,
|
||||
old_parent = parent;
|
||||
}
|
||||
if (log_dentries)
|
||||
ret = log_new_dir_dentries(trans, root, orig_inode, ctx);
|
||||
ret = log_new_dir_dentries(trans, root, BTRFS_I(orig_inode), ctx);
|
||||
else
|
||||
ret = 0;
|
||||
end_trans:
|
||||
@ -5730,7 +5729,7 @@ error:
|
||||
* inodes, etc) are done.
|
||||
*/
|
||||
void btrfs_record_unlink_dir(struct btrfs_trans_handle *trans,
|
||||
struct inode *dir, struct inode *inode,
|
||||
struct btrfs_inode *dir, struct btrfs_inode *inode,
|
||||
int for_rename)
|
||||
{
|
||||
/*
|
||||
@ -5743,23 +5742,23 @@ void btrfs_record_unlink_dir(struct btrfs_trans_handle *trans,
|
||||
* into the file. When the file is logged we check it and
|
||||
* don't log the parents if the file is fully on disk.
|
||||
*/
|
||||
mutex_lock(&BTRFS_I(inode)->log_mutex);
|
||||
BTRFS_I(inode)->last_unlink_trans = trans->transid;
|
||||
mutex_unlock(&BTRFS_I(inode)->log_mutex);
|
||||
mutex_lock(&inode->log_mutex);
|
||||
inode->last_unlink_trans = trans->transid;
|
||||
mutex_unlock(&inode->log_mutex);
|
||||
|
||||
/*
|
||||
* if this directory was already logged any new
|
||||
* names for this file/dir will get recorded
|
||||
*/
|
||||
smp_mb();
|
||||
if (BTRFS_I(dir)->logged_trans == trans->transid)
|
||||
if (dir->logged_trans == trans->transid)
|
||||
return;
|
||||
|
||||
/*
|
||||
* if the inode we're about to unlink was logged,
|
||||
* the log will be properly updated for any new names
|
||||
*/
|
||||
if (BTRFS_I(inode)->logged_trans == trans->transid)
|
||||
if (inode->logged_trans == trans->transid)
|
||||
return;
|
||||
|
||||
/*
|
||||
@ -5776,9 +5775,9 @@ void btrfs_record_unlink_dir(struct btrfs_trans_handle *trans,
|
||||
return;
|
||||
|
||||
record:
|
||||
mutex_lock(&BTRFS_I(dir)->log_mutex);
|
||||
BTRFS_I(dir)->last_unlink_trans = trans->transid;
|
||||
mutex_unlock(&BTRFS_I(dir)->log_mutex);
|
||||
mutex_lock(&dir->log_mutex);
|
||||
dir->last_unlink_trans = trans->transid;
|
||||
mutex_unlock(&dir->log_mutex);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -5794,11 +5793,11 @@ record:
|
||||
* parent root and tree of tree roots trees, etc) are done.
|
||||
*/
|
||||
void btrfs_record_snapshot_destroy(struct btrfs_trans_handle *trans,
|
||||
struct inode *dir)
|
||||
struct btrfs_inode *dir)
|
||||
{
|
||||
mutex_lock(&BTRFS_I(dir)->log_mutex);
|
||||
BTRFS_I(dir)->last_unlink_trans = trans->transid;
|
||||
mutex_unlock(&BTRFS_I(dir)->log_mutex);
|
||||
mutex_lock(&dir->log_mutex);
|
||||
dir->last_unlink_trans = trans->transid;
|
||||
mutex_unlock(&dir->log_mutex);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -5809,30 +5808,28 @@ void btrfs_record_snapshot_destroy(struct btrfs_trans_handle *trans,
|
||||
* full transaction commit is required.
|
||||
*/
|
||||
int btrfs_log_new_name(struct btrfs_trans_handle *trans,
|
||||
struct inode *inode, struct inode *old_dir,
|
||||
struct btrfs_inode *inode, struct btrfs_inode *old_dir,
|
||||
struct dentry *parent)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
|
||||
struct btrfs_root * root = BTRFS_I(inode)->root;
|
||||
struct btrfs_fs_info *fs_info = btrfs_sb(inode->vfs_inode.i_sb);
|
||||
struct btrfs_root *root = inode->root;
|
||||
|
||||
/*
|
||||
* this will force the logging code to walk the dentry chain
|
||||
* up for the file
|
||||
*/
|
||||
if (S_ISREG(inode->i_mode))
|
||||
BTRFS_I(inode)->last_unlink_trans = trans->transid;
|
||||
if (S_ISREG(inode->vfs_inode.i_mode))
|
||||
inode->last_unlink_trans = trans->transid;
|
||||
|
||||
/*
|
||||
* if this inode hasn't been logged and directory we're renaming it
|
||||
* from hasn't been logged, we don't need to log it
|
||||
*/
|
||||
if (BTRFS_I(inode)->logged_trans <=
|
||||
fs_info->last_trans_committed &&
|
||||
(!old_dir || BTRFS_I(old_dir)->logged_trans <=
|
||||
fs_info->last_trans_committed))
|
||||
if (inode->logged_trans <= fs_info->last_trans_committed &&
|
||||
(!old_dir || old_dir->logged_trans <= fs_info->last_trans_committed))
|
||||
return 0;
|
||||
|
||||
return btrfs_log_inode_parent(trans, root, inode, parent, 0,
|
||||
return btrfs_log_inode_parent(trans, root, &inode->vfs_inode, parent, 0,
|
||||
LLONG_MAX, 1, NULL);
|
||||
}
|
||||
|
||||
|
@ -48,13 +48,13 @@ static inline void btrfs_init_log_ctx(struct btrfs_log_ctx *ctx,
|
||||
static inline void btrfs_set_log_full_commit(struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_trans_handle *trans)
|
||||
{
|
||||
ACCESS_ONCE(fs_info->last_trans_log_full_commit) = trans->transid;
|
||||
WRITE_ONCE(fs_info->last_trans_log_full_commit, trans->transid);
|
||||
}
|
||||
|
||||
static inline int btrfs_need_log_full_commit(struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_trans_handle *trans)
|
||||
{
|
||||
return ACCESS_ONCE(fs_info->last_trans_log_full_commit) ==
|
||||
return READ_ONCE(fs_info->last_trans_log_full_commit) ==
|
||||
trans->transid;
|
||||
}
|
||||
|
||||
@ -72,19 +72,19 @@ int btrfs_log_dentry_safe(struct btrfs_trans_handle *trans,
|
||||
int btrfs_del_dir_entries_in_log(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
const char *name, int name_len,
|
||||
struct inode *dir, u64 index);
|
||||
struct btrfs_inode *dir, u64 index);
|
||||
int btrfs_del_inode_ref_in_log(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
const char *name, int name_len,
|
||||
struct inode *inode, u64 dirid);
|
||||
struct btrfs_inode *inode, u64 dirid);
|
||||
void btrfs_end_log_trans(struct btrfs_root *root);
|
||||
int btrfs_pin_log_trans(struct btrfs_root *root);
|
||||
void btrfs_record_unlink_dir(struct btrfs_trans_handle *trans,
|
||||
struct inode *dir, struct inode *inode,
|
||||
struct btrfs_inode *dir, struct btrfs_inode *inode,
|
||||
int for_rename);
|
||||
void btrfs_record_snapshot_destroy(struct btrfs_trans_handle *trans,
|
||||
struct inode *dir);
|
||||
struct btrfs_inode *dir);
|
||||
int btrfs_log_new_name(struct btrfs_trans_handle *trans,
|
||||
struct inode *inode, struct inode *old_dir,
|
||||
struct btrfs_inode *inode, struct btrfs_inode *old_dir,
|
||||
struct dentry *parent);
|
||||
#endif
|
||||
|
@ -52,13 +52,13 @@ void ulist_init(struct ulist *ulist)
|
||||
}
|
||||
|
||||
/**
|
||||
* ulist_fini - free up additionally allocated memory for the ulist
|
||||
* ulist_release - free up additionally allocated memory for the ulist
|
||||
* @ulist: the ulist from which to free the additional memory
|
||||
*
|
||||
* This is useful in cases where the base 'struct ulist' has been statically
|
||||
* allocated.
|
||||
*/
|
||||
static void ulist_fini(struct ulist *ulist)
|
||||
void ulist_release(struct ulist *ulist)
|
||||
{
|
||||
struct ulist_node *node;
|
||||
struct ulist_node *next;
|
||||
@ -79,7 +79,7 @@ static void ulist_fini(struct ulist *ulist)
|
||||
*/
|
||||
void ulist_reinit(struct ulist *ulist)
|
||||
{
|
||||
ulist_fini(ulist);
|
||||
ulist_release(ulist);
|
||||
ulist_init(ulist);
|
||||
}
|
||||
|
||||
@ -105,13 +105,13 @@ struct ulist *ulist_alloc(gfp_t gfp_mask)
|
||||
* ulist_free - free dynamically allocated ulist
|
||||
* @ulist: ulist to free
|
||||
*
|
||||
* It is not necessary to call ulist_fini before.
|
||||
* It is not necessary to call ulist_release before.
|
||||
*/
|
||||
void ulist_free(struct ulist *ulist)
|
||||
{
|
||||
if (!ulist)
|
||||
return;
|
||||
ulist_fini(ulist);
|
||||
ulist_release(ulist);
|
||||
kfree(ulist);
|
||||
}
|
||||
|
||||
|
@ -19,9 +19,6 @@
|
||||
*
|
||||
*/
|
||||
struct ulist_iterator {
|
||||
#ifdef CONFIG_BTRFS_DEBUG
|
||||
int i;
|
||||
#endif
|
||||
struct list_head *cur_list; /* hint to start search */
|
||||
};
|
||||
|
||||
@ -32,10 +29,6 @@ struct ulist_node {
|
||||
u64 val; /* value to store */
|
||||
u64 aux; /* auxiliary value saved along with the val */
|
||||
|
||||
#ifdef CONFIG_BTRFS_DEBUG
|
||||
int seqnum; /* sequence number this node is added */
|
||||
#endif
|
||||
|
||||
struct list_head list; /* used to link node */
|
||||
struct rb_node rb_node; /* used to speed up search */
|
||||
};
|
||||
@ -51,6 +44,7 @@ struct ulist {
|
||||
};
|
||||
|
||||
void ulist_init(struct ulist *ulist);
|
||||
void ulist_release(struct ulist *ulist);
|
||||
void ulist_reinit(struct ulist *ulist);
|
||||
struct ulist *ulist_alloc(gfp_t gfp_mask);
|
||||
void ulist_free(struct ulist *ulist);
|
||||
|
@ -134,8 +134,7 @@ const int btrfs_raid_mindev_error[BTRFS_NR_RAID_TYPES] = {
|
||||
};
|
||||
|
||||
static int init_first_rw_device(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_device *device);
|
||||
struct btrfs_fs_info *fs_info);
|
||||
static int btrfs_relocate_sys_chunks(struct btrfs_fs_info *fs_info);
|
||||
static void __btrfs_reset_dev_stats(struct btrfs_device *dev);
|
||||
static void btrfs_dev_stat_print_on_error(struct btrfs_device *dev);
|
||||
@ -2440,7 +2439,7 @@ int btrfs_init_new_device(struct btrfs_fs_info *fs_info, char *device_path)
|
||||
|
||||
if (seeding_dev) {
|
||||
mutex_lock(&fs_info->chunk_mutex);
|
||||
ret = init_first_rw_device(trans, fs_info, device);
|
||||
ret = init_first_rw_device(trans, fs_info);
|
||||
mutex_unlock(&fs_info->chunk_mutex);
|
||||
if (ret) {
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
@ -4584,8 +4583,7 @@ static void check_raid56_incompat_flag(struct btrfs_fs_info *info, u64 type)
|
||||
/ sizeof(struct btrfs_stripe) + 1)
|
||||
|
||||
static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_fs_info *fs_info, u64 start,
|
||||
u64 type)
|
||||
u64 start, u64 type)
|
||||
{
|
||||
struct btrfs_fs_info *info = trans->fs_info;
|
||||
struct btrfs_fs_devices *fs_devices = info->fs_devices;
|
||||
@ -5009,12 +5007,11 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
|
||||
|
||||
ASSERT(mutex_is_locked(&fs_info->chunk_mutex));
|
||||
chunk_offset = find_next_chunk(fs_info);
|
||||
return __btrfs_alloc_chunk(trans, fs_info, chunk_offset, type);
|
||||
return __btrfs_alloc_chunk(trans, chunk_offset, type);
|
||||
}
|
||||
|
||||
static noinline int init_first_rw_device(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_device *device)
|
||||
struct btrfs_fs_info *fs_info)
|
||||
{
|
||||
struct btrfs_root *extent_root = fs_info->extent_root;
|
||||
u64 chunk_offset;
|
||||
@ -5024,14 +5021,13 @@ static noinline int init_first_rw_device(struct btrfs_trans_handle *trans,
|
||||
|
||||
chunk_offset = find_next_chunk(fs_info);
|
||||
alloc_profile = btrfs_get_alloc_profile(extent_root, 0);
|
||||
ret = __btrfs_alloc_chunk(trans, fs_info, chunk_offset, alloc_profile);
|
||||
ret = __btrfs_alloc_chunk(trans, chunk_offset, alloc_profile);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
sys_chunk_offset = find_next_chunk(fs_info);
|
||||
alloc_profile = btrfs_get_alloc_profile(fs_info->chunk_root, 0);
|
||||
ret = __btrfs_alloc_chunk(trans, fs_info, sys_chunk_offset,
|
||||
alloc_profile);
|
||||
ret = __btrfs_alloc_chunk(trans, sys_chunk_offset, alloc_profile);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -47,8 +47,8 @@ ssize_t __btrfs_getxattr(struct inode *inode, const char *name,
|
||||
return -ENOMEM;
|
||||
|
||||
/* lookup the xattr by name */
|
||||
di = btrfs_lookup_xattr(NULL, root, path, btrfs_ino(inode), name,
|
||||
strlen(name), 0);
|
||||
di = btrfs_lookup_xattr(NULL, root, path, btrfs_ino(BTRFS_I(inode)),
|
||||
name, strlen(name), 0);
|
||||
if (!di) {
|
||||
ret = -ENODATA;
|
||||
goto out;
|
||||
@ -108,8 +108,8 @@ static int do_setxattr(struct btrfs_trans_handle *trans,
|
||||
path->skip_release_on_error = 1;
|
||||
|
||||
if (!value) {
|
||||
di = btrfs_lookup_xattr(trans, root, path, btrfs_ino(inode),
|
||||
name, name_len, -1);
|
||||
di = btrfs_lookup_xattr(trans, root, path,
|
||||
btrfs_ino(BTRFS_I(inode)), name, name_len, -1);
|
||||
if (!di && (flags & XATTR_REPLACE))
|
||||
ret = -ENODATA;
|
||||
else if (IS_ERR(di))
|
||||
@ -128,8 +128,8 @@ static int do_setxattr(struct btrfs_trans_handle *trans,
|
||||
*/
|
||||
if (flags & XATTR_REPLACE) {
|
||||
ASSERT(inode_is_locked(inode));
|
||||
di = btrfs_lookup_xattr(NULL, root, path, btrfs_ino(inode),
|
||||
name, name_len, 0);
|
||||
di = btrfs_lookup_xattr(NULL, root, path,
|
||||
btrfs_ino(BTRFS_I(inode)), name, name_len, 0);
|
||||
if (!di)
|
||||
ret = -ENODATA;
|
||||
else if (IS_ERR(di))
|
||||
@ -140,7 +140,7 @@ static int do_setxattr(struct btrfs_trans_handle *trans,
|
||||
di = NULL;
|
||||
}
|
||||
|
||||
ret = btrfs_insert_xattr_item(trans, root, path, btrfs_ino(inode),
|
||||
ret = btrfs_insert_xattr_item(trans, root, path, btrfs_ino(BTRFS_I(inode)),
|
||||
name, name_len, value, size);
|
||||
if (ret == -EOVERFLOW) {
|
||||
/*
|
||||
@ -278,7 +278,7 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
|
||||
* NOTE: we set key.offset = 0; because we want to start with the
|
||||
* first xattr that we find and walk forward
|
||||
*/
|
||||
key.objectid = btrfs_ino(inode);
|
||||
key.objectid = btrfs_ino(BTRFS_I(inode));
|
||||
key.type = BTRFS_XATTR_ITEM_KEY;
|
||||
key.offset = 0;
|
||||
|
||||
|
@ -184,7 +184,7 @@ DEFINE_EVENT(btrfs__inode, btrfs_inode_evict,
|
||||
|
||||
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),
|
||||
|
||||
TP_ARGS(root, inode, map),
|
||||
|
Loading…
Reference in New Issue
Block a user