You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'for-chris' of
git://git.kernel.org/pub/scm/linux/kernel/git/josef/btrfs-work into for-linus Conflicts: fs/btrfs/disk-io.c fs/btrfs/extent-tree.c fs/btrfs/free-space-cache.c fs/btrfs/inode.c fs/btrfs/transaction.c Signed-off-by: Chris Mason <chris.mason@oracle.com>
This commit is contained in:
@@ -121,9 +121,6 @@ struct btrfs_inode {
|
|||||||
*/
|
*/
|
||||||
u64 index_cnt;
|
u64 index_cnt;
|
||||||
|
|
||||||
/* the start of block group preferred for allocations. */
|
|
||||||
u64 block_group;
|
|
||||||
|
|
||||||
/* the fsync log has some corner cases that mean we have to check
|
/* the fsync log has some corner cases that mean we have to check
|
||||||
* directories to see if any unlinks have been done before
|
* directories to see if any unlinks have been done before
|
||||||
* the directory was logged. See tree-log.c for all the
|
* the directory was logged. See tree-log.c for all the
|
||||||
|
|||||||
+21
-7
@@ -43,8 +43,6 @@ struct btrfs_path *btrfs_alloc_path(void)
|
|||||||
{
|
{
|
||||||
struct btrfs_path *path;
|
struct btrfs_path *path;
|
||||||
path = kmem_cache_zalloc(btrfs_path_cachep, GFP_NOFS);
|
path = kmem_cache_zalloc(btrfs_path_cachep, GFP_NOFS);
|
||||||
if (path)
|
|
||||||
path->reada = 1;
|
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1224,6 +1222,7 @@ static void reada_for_search(struct btrfs_root *root,
|
|||||||
u64 search;
|
u64 search;
|
||||||
u64 target;
|
u64 target;
|
||||||
u64 nread = 0;
|
u64 nread = 0;
|
||||||
|
u64 gen;
|
||||||
int direction = path->reada;
|
int direction = path->reada;
|
||||||
struct extent_buffer *eb;
|
struct extent_buffer *eb;
|
||||||
u32 nr;
|
u32 nr;
|
||||||
@@ -1251,6 +1250,15 @@ static void reada_for_search(struct btrfs_root *root,
|
|||||||
nritems = btrfs_header_nritems(node);
|
nritems = btrfs_header_nritems(node);
|
||||||
nr = slot;
|
nr = slot;
|
||||||
while (1) {
|
while (1) {
|
||||||
|
if (!node->map_token) {
|
||||||
|
unsigned long offset = btrfs_node_key_ptr_offset(nr);
|
||||||
|
map_private_extent_buffer(node, offset,
|
||||||
|
sizeof(struct btrfs_key_ptr),
|
||||||
|
&node->map_token,
|
||||||
|
&node->kaddr,
|
||||||
|
&node->map_start,
|
||||||
|
&node->map_len, KM_USER1);
|
||||||
|
}
|
||||||
if (direction < 0) {
|
if (direction < 0) {
|
||||||
if (nr == 0)
|
if (nr == 0)
|
||||||
break;
|
break;
|
||||||
@@ -1268,14 +1276,23 @@ static void reada_for_search(struct btrfs_root *root,
|
|||||||
search = btrfs_node_blockptr(node, nr);
|
search = btrfs_node_blockptr(node, nr);
|
||||||
if ((search <= target && target - search <= 65536) ||
|
if ((search <= target && target - search <= 65536) ||
|
||||||
(search > target && search - target <= 65536)) {
|
(search > target && search - target <= 65536)) {
|
||||||
readahead_tree_block(root, search, blocksize,
|
gen = btrfs_node_ptr_generation(node, nr);
|
||||||
btrfs_node_ptr_generation(node, nr));
|
if (node->map_token) {
|
||||||
|
unmap_extent_buffer(node, node->map_token,
|
||||||
|
KM_USER1);
|
||||||
|
node->map_token = NULL;
|
||||||
|
}
|
||||||
|
readahead_tree_block(root, search, blocksize, gen);
|
||||||
nread += blocksize;
|
nread += blocksize;
|
||||||
}
|
}
|
||||||
nscan++;
|
nscan++;
|
||||||
if ((nread > 65536 || nscan > 32))
|
if ((nread > 65536 || nscan > 32))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (node->map_token) {
|
||||||
|
unmap_extent_buffer(node, node->map_token, KM_USER1);
|
||||||
|
node->map_token = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1648,9 +1665,6 @@ again:
|
|||||||
}
|
}
|
||||||
cow_done:
|
cow_done:
|
||||||
BUG_ON(!cow && ins_len);
|
BUG_ON(!cow && ins_len);
|
||||||
if (level != btrfs_header_level(b))
|
|
||||||
WARN_ON(1);
|
|
||||||
level = btrfs_header_level(b);
|
|
||||||
|
|
||||||
p->nodes[level] = b;
|
p->nodes[level] = b;
|
||||||
if (!p->skip_locking)
|
if (!p->skip_locking)
|
||||||
|
|||||||
+7
-5
@@ -930,7 +930,6 @@ struct btrfs_fs_info {
|
|||||||
* is required instead of the faster short fsync log commits
|
* is required instead of the faster short fsync log commits
|
||||||
*/
|
*/
|
||||||
u64 last_trans_log_full_commit;
|
u64 last_trans_log_full_commit;
|
||||||
u64 open_ioctl_trans;
|
|
||||||
unsigned long mount_opt:20;
|
unsigned long mount_opt:20;
|
||||||
unsigned long compress_type:4;
|
unsigned long compress_type:4;
|
||||||
u64 max_inline;
|
u64 max_inline;
|
||||||
@@ -947,7 +946,6 @@ struct btrfs_fs_info {
|
|||||||
struct super_block *sb;
|
struct super_block *sb;
|
||||||
struct inode *btree_inode;
|
struct inode *btree_inode;
|
||||||
struct backing_dev_info bdi;
|
struct backing_dev_info bdi;
|
||||||
struct mutex trans_mutex;
|
|
||||||
struct mutex tree_log_mutex;
|
struct mutex tree_log_mutex;
|
||||||
struct mutex transaction_kthread_mutex;
|
struct mutex transaction_kthread_mutex;
|
||||||
struct mutex cleaner_mutex;
|
struct mutex cleaner_mutex;
|
||||||
@@ -968,6 +966,7 @@ struct btrfs_fs_info {
|
|||||||
struct rw_semaphore subvol_sem;
|
struct rw_semaphore subvol_sem;
|
||||||
struct srcu_struct subvol_srcu;
|
struct srcu_struct subvol_srcu;
|
||||||
|
|
||||||
|
spinlock_t trans_lock;
|
||||||
struct list_head trans_list;
|
struct list_head trans_list;
|
||||||
struct list_head hashers;
|
struct list_head hashers;
|
||||||
struct list_head dead_roots;
|
struct list_head dead_roots;
|
||||||
@@ -980,6 +979,7 @@ struct btrfs_fs_info {
|
|||||||
atomic_t async_submit_draining;
|
atomic_t async_submit_draining;
|
||||||
atomic_t nr_async_bios;
|
atomic_t nr_async_bios;
|
||||||
atomic_t async_delalloc_pages;
|
atomic_t async_delalloc_pages;
|
||||||
|
atomic_t open_ioctl_trans;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* this is used by the balancing code to wait for all the pending
|
* this is used by the balancing code to wait for all the pending
|
||||||
@@ -1044,6 +1044,7 @@ struct btrfs_fs_info {
|
|||||||
int closing;
|
int closing;
|
||||||
int log_root_recovering;
|
int log_root_recovering;
|
||||||
int enospc_unlink;
|
int enospc_unlink;
|
||||||
|
int trans_no_join;
|
||||||
|
|
||||||
u64 total_pinned;
|
u64 total_pinned;
|
||||||
|
|
||||||
@@ -1065,7 +1066,6 @@ struct btrfs_fs_info {
|
|||||||
struct reloc_control *reloc_ctl;
|
struct reloc_control *reloc_ctl;
|
||||||
|
|
||||||
spinlock_t delalloc_lock;
|
spinlock_t delalloc_lock;
|
||||||
spinlock_t new_trans_lock;
|
|
||||||
u64 delalloc_bytes;
|
u64 delalloc_bytes;
|
||||||
|
|
||||||
/* data_alloc_cluster is only used in ssd mode */
|
/* data_alloc_cluster is only used in ssd mode */
|
||||||
@@ -2238,6 +2238,9 @@ int btrfs_block_rsv_migrate(struct btrfs_block_rsv *src_rsv,
|
|||||||
void btrfs_block_rsv_release(struct btrfs_root *root,
|
void btrfs_block_rsv_release(struct btrfs_root *root,
|
||||||
struct btrfs_block_rsv *block_rsv,
|
struct btrfs_block_rsv *block_rsv,
|
||||||
u64 num_bytes);
|
u64 num_bytes);
|
||||||
|
int btrfs_truncate_reserve_metadata(struct btrfs_trans_handle *trans,
|
||||||
|
struct btrfs_root *root,
|
||||||
|
struct btrfs_block_rsv *rsv);
|
||||||
int btrfs_set_block_group_ro(struct btrfs_root *root,
|
int btrfs_set_block_group_ro(struct btrfs_root *root,
|
||||||
struct btrfs_block_group_cache *cache);
|
struct btrfs_block_group_cache *cache);
|
||||||
int btrfs_set_block_group_rw(struct btrfs_root *root,
|
int btrfs_set_block_group_rw(struct btrfs_root *root,
|
||||||
@@ -2512,8 +2515,7 @@ int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end,
|
|||||||
int btrfs_writepages(struct address_space *mapping,
|
int btrfs_writepages(struct address_space *mapping,
|
||||||
struct writeback_control *wbc);
|
struct writeback_control *wbc);
|
||||||
int btrfs_create_subvol_root(struct btrfs_trans_handle *trans,
|
int btrfs_create_subvol_root(struct btrfs_trans_handle *trans,
|
||||||
struct btrfs_root *new_root,
|
struct btrfs_root *new_root, u64 new_dirid);
|
||||||
u64 new_dirid, u64 alloc_hint);
|
|
||||||
int btrfs_merge_bio_hook(struct page *page, unsigned long offset,
|
int btrfs_merge_bio_hook(struct page *page, unsigned long offset,
|
||||||
size_t size, struct bio *bio, unsigned long bio_flags);
|
size_t size, struct bio *bio, unsigned long bio_flags);
|
||||||
|
|
||||||
|
|||||||
@@ -1129,7 +1129,7 @@ static void btrfs_async_run_delayed_node_done(struct btrfs_work *work)
|
|||||||
delayed_node = async_node->delayed_node;
|
delayed_node = async_node->delayed_node;
|
||||||
root = delayed_node->root;
|
root = delayed_node->root;
|
||||||
|
|
||||||
trans = btrfs_join_transaction(root, 0);
|
trans = btrfs_join_transaction(root);
|
||||||
if (IS_ERR(trans))
|
if (IS_ERR(trans))
|
||||||
goto free_path;
|
goto free_path;
|
||||||
|
|
||||||
@@ -1572,8 +1572,7 @@ static void fill_stack_inode_item(struct btrfs_trans_handle *trans,
|
|||||||
btrfs_set_stack_inode_transid(inode_item, trans->transid);
|
btrfs_set_stack_inode_transid(inode_item, trans->transid);
|
||||||
btrfs_set_stack_inode_rdev(inode_item, inode->i_rdev);
|
btrfs_set_stack_inode_rdev(inode_item, inode->i_rdev);
|
||||||
btrfs_set_stack_inode_flags(inode_item, BTRFS_I(inode)->flags);
|
btrfs_set_stack_inode_flags(inode_item, BTRFS_I(inode)->flags);
|
||||||
btrfs_set_stack_inode_block_group(inode_item,
|
btrfs_set_stack_inode_block_group(inode_item, 0);
|
||||||
BTRFS_I(inode)->block_group);
|
|
||||||
|
|
||||||
btrfs_set_stack_timespec_sec(btrfs_inode_atime(inode_item),
|
btrfs_set_stack_timespec_sec(btrfs_inode_atime(inode_item),
|
||||||
inode->i_atime.tv_sec);
|
inode->i_atime.tv_sec);
|
||||||
|
|||||||
+18
-18
@@ -1505,24 +1505,24 @@ static int transaction_kthread(void *arg)
|
|||||||
vfs_check_frozen(root->fs_info->sb, SB_FREEZE_WRITE);
|
vfs_check_frozen(root->fs_info->sb, SB_FREEZE_WRITE);
|
||||||
mutex_lock(&root->fs_info->transaction_kthread_mutex);
|
mutex_lock(&root->fs_info->transaction_kthread_mutex);
|
||||||
|
|
||||||
spin_lock(&root->fs_info->new_trans_lock);
|
spin_lock(&root->fs_info->trans_lock);
|
||||||
cur = root->fs_info->running_transaction;
|
cur = root->fs_info->running_transaction;
|
||||||
if (!cur) {
|
if (!cur) {
|
||||||
spin_unlock(&root->fs_info->new_trans_lock);
|
spin_unlock(&root->fs_info->trans_lock);
|
||||||
goto sleep;
|
goto sleep;
|
||||||
}
|
}
|
||||||
|
|
||||||
now = get_seconds();
|
now = get_seconds();
|
||||||
if (!cur->blocked &&
|
if (!cur->blocked &&
|
||||||
(now < cur->start_time || now - cur->start_time < 30)) {
|
(now < cur->start_time || now - cur->start_time < 30)) {
|
||||||
spin_unlock(&root->fs_info->new_trans_lock);
|
spin_unlock(&root->fs_info->trans_lock);
|
||||||
delay = HZ * 5;
|
delay = HZ * 5;
|
||||||
goto sleep;
|
goto sleep;
|
||||||
}
|
}
|
||||||
transid = cur->transid;
|
transid = cur->transid;
|
||||||
spin_unlock(&root->fs_info->new_trans_lock);
|
spin_unlock(&root->fs_info->trans_lock);
|
||||||
|
|
||||||
trans = btrfs_join_transaction(root, 1);
|
trans = btrfs_join_transaction(root);
|
||||||
BUG_ON(IS_ERR(trans));
|
BUG_ON(IS_ERR(trans));
|
||||||
if (transid == trans->transid) {
|
if (transid == trans->transid) {
|
||||||
ret = btrfs_commit_transaction(trans, root);
|
ret = btrfs_commit_transaction(trans, root);
|
||||||
@@ -1613,7 +1613,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
|
|||||||
INIT_LIST_HEAD(&fs_info->ordered_operations);
|
INIT_LIST_HEAD(&fs_info->ordered_operations);
|
||||||
INIT_LIST_HEAD(&fs_info->caching_block_groups);
|
INIT_LIST_HEAD(&fs_info->caching_block_groups);
|
||||||
spin_lock_init(&fs_info->delalloc_lock);
|
spin_lock_init(&fs_info->delalloc_lock);
|
||||||
spin_lock_init(&fs_info->new_trans_lock);
|
spin_lock_init(&fs_info->trans_lock);
|
||||||
spin_lock_init(&fs_info->ref_cache_lock);
|
spin_lock_init(&fs_info->ref_cache_lock);
|
||||||
spin_lock_init(&fs_info->fs_roots_radix_lock);
|
spin_lock_init(&fs_info->fs_roots_radix_lock);
|
||||||
spin_lock_init(&fs_info->delayed_iput_lock);
|
spin_lock_init(&fs_info->delayed_iput_lock);
|
||||||
@@ -1645,6 +1645,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
|
|||||||
fs_info->max_inline = 8192 * 1024;
|
fs_info->max_inline = 8192 * 1024;
|
||||||
fs_info->metadata_ratio = 0;
|
fs_info->metadata_ratio = 0;
|
||||||
fs_info->defrag_inodes = RB_ROOT;
|
fs_info->defrag_inodes = RB_ROOT;
|
||||||
|
fs_info->trans_no_join = 0;
|
||||||
|
|
||||||
fs_info->thread_pool_size = min_t(unsigned long,
|
fs_info->thread_pool_size = min_t(unsigned long,
|
||||||
num_online_cpus() + 2, 8);
|
num_online_cpus() + 2, 8);
|
||||||
@@ -1709,7 +1710,6 @@ struct btrfs_root *open_ctree(struct super_block *sb,
|
|||||||
fs_info->do_barriers = 1;
|
fs_info->do_barriers = 1;
|
||||||
|
|
||||||
|
|
||||||
mutex_init(&fs_info->trans_mutex);
|
|
||||||
mutex_init(&fs_info->ordered_operations_mutex);
|
mutex_init(&fs_info->ordered_operations_mutex);
|
||||||
mutex_init(&fs_info->tree_log_mutex);
|
mutex_init(&fs_info->tree_log_mutex);
|
||||||
mutex_init(&fs_info->chunk_mutex);
|
mutex_init(&fs_info->chunk_mutex);
|
||||||
@@ -2479,13 +2479,13 @@ int btrfs_commit_super(struct btrfs_root *root)
|
|||||||
down_write(&root->fs_info->cleanup_work_sem);
|
down_write(&root->fs_info->cleanup_work_sem);
|
||||||
up_write(&root->fs_info->cleanup_work_sem);
|
up_write(&root->fs_info->cleanup_work_sem);
|
||||||
|
|
||||||
trans = btrfs_join_transaction(root, 1);
|
trans = btrfs_join_transaction(root);
|
||||||
if (IS_ERR(trans))
|
if (IS_ERR(trans))
|
||||||
return PTR_ERR(trans);
|
return PTR_ERR(trans);
|
||||||
ret = btrfs_commit_transaction(trans, root);
|
ret = btrfs_commit_transaction(trans, root);
|
||||||
BUG_ON(ret);
|
BUG_ON(ret);
|
||||||
/* run commit again to drop the original snapshot */
|
/* run commit again to drop the original snapshot */
|
||||||
trans = btrfs_join_transaction(root, 1);
|
trans = btrfs_join_transaction(root);
|
||||||
if (IS_ERR(trans))
|
if (IS_ERR(trans))
|
||||||
return PTR_ERR(trans);
|
return PTR_ERR(trans);
|
||||||
btrfs_commit_transaction(trans, root);
|
btrfs_commit_transaction(trans, root);
|
||||||
@@ -3024,10 +3024,13 @@ static int btrfs_cleanup_transaction(struct btrfs_root *root)
|
|||||||
|
|
||||||
WARN_ON(1);
|
WARN_ON(1);
|
||||||
|
|
||||||
mutex_lock(&root->fs_info->trans_mutex);
|
|
||||||
mutex_lock(&root->fs_info->transaction_kthread_mutex);
|
mutex_lock(&root->fs_info->transaction_kthread_mutex);
|
||||||
|
|
||||||
|
spin_lock(&root->fs_info->trans_lock);
|
||||||
list_splice_init(&root->fs_info->trans_list, &list);
|
list_splice_init(&root->fs_info->trans_list, &list);
|
||||||
|
root->fs_info->trans_no_join = 1;
|
||||||
|
spin_unlock(&root->fs_info->trans_lock);
|
||||||
|
|
||||||
while (!list_empty(&list)) {
|
while (!list_empty(&list)) {
|
||||||
t = list_entry(list.next, struct btrfs_transaction, list);
|
t = list_entry(list.next, struct btrfs_transaction, list);
|
||||||
if (!t)
|
if (!t)
|
||||||
@@ -3052,23 +3055,18 @@ static int btrfs_cleanup_transaction(struct btrfs_root *root)
|
|||||||
t->blocked = 0;
|
t->blocked = 0;
|
||||||
if (waitqueue_active(&root->fs_info->transaction_wait))
|
if (waitqueue_active(&root->fs_info->transaction_wait))
|
||||||
wake_up(&root->fs_info->transaction_wait);
|
wake_up(&root->fs_info->transaction_wait);
|
||||||
mutex_unlock(&root->fs_info->trans_mutex);
|
|
||||||
|
|
||||||
mutex_lock(&root->fs_info->trans_mutex);
|
|
||||||
t->commit_done = 1;
|
t->commit_done = 1;
|
||||||
if (waitqueue_active(&t->commit_wait))
|
if (waitqueue_active(&t->commit_wait))
|
||||||
wake_up(&t->commit_wait);
|
wake_up(&t->commit_wait);
|
||||||
mutex_unlock(&root->fs_info->trans_mutex);
|
|
||||||
|
|
||||||
mutex_lock(&root->fs_info->trans_mutex);
|
|
||||||
|
|
||||||
btrfs_destroy_pending_snapshots(t);
|
btrfs_destroy_pending_snapshots(t);
|
||||||
|
|
||||||
btrfs_destroy_delalloc_inodes(root);
|
btrfs_destroy_delalloc_inodes(root);
|
||||||
|
|
||||||
spin_lock(&root->fs_info->new_trans_lock);
|
spin_lock(&root->fs_info->trans_lock);
|
||||||
root->fs_info->running_transaction = NULL;
|
root->fs_info->running_transaction = NULL;
|
||||||
spin_unlock(&root->fs_info->new_trans_lock);
|
spin_unlock(&root->fs_info->trans_lock);
|
||||||
|
|
||||||
btrfs_destroy_marked_extents(root, &t->dirty_pages,
|
btrfs_destroy_marked_extents(root, &t->dirty_pages,
|
||||||
EXTENT_DIRTY);
|
EXTENT_DIRTY);
|
||||||
@@ -3082,8 +3080,10 @@ static int btrfs_cleanup_transaction(struct btrfs_root *root)
|
|||||||
kmem_cache_free(btrfs_transaction_cachep, t);
|
kmem_cache_free(btrfs_transaction_cachep, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spin_lock(&root->fs_info->trans_lock);
|
||||||
|
root->fs_info->trans_no_join = 0;
|
||||||
|
spin_unlock(&root->fs_info->trans_lock);
|
||||||
mutex_unlock(&root->fs_info->transaction_kthread_mutex);
|
mutex_unlock(&root->fs_info->transaction_kthread_mutex);
|
||||||
mutex_unlock(&root->fs_info->trans_mutex);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
+67
-33
@@ -348,7 +348,7 @@ static int caching_kthread(void *data)
|
|||||||
*/
|
*/
|
||||||
path->skip_locking = 1;
|
path->skip_locking = 1;
|
||||||
path->search_commit_root = 1;
|
path->search_commit_root = 1;
|
||||||
path->reada = 2;
|
path->reada = 1;
|
||||||
|
|
||||||
key.objectid = last;
|
key.objectid = last;
|
||||||
key.offset = 0;
|
key.offset = 0;
|
||||||
@@ -379,15 +379,18 @@ again:
|
|||||||
if (ret)
|
if (ret)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
caching_ctl->progress = last;
|
if (need_resched() ||
|
||||||
btrfs_release_path(path);
|
btrfs_next_leaf(extent_root, path)) {
|
||||||
up_read(&fs_info->extent_commit_sem);
|
caching_ctl->progress = last;
|
||||||
mutex_unlock(&caching_ctl->mutex);
|
btrfs_release_path(path);
|
||||||
if (btrfs_transaction_in_commit(fs_info))
|
up_read(&fs_info->extent_commit_sem);
|
||||||
schedule_timeout(1);
|
mutex_unlock(&caching_ctl->mutex);
|
||||||
else
|
|
||||||
cond_resched();
|
cond_resched();
|
||||||
goto again;
|
goto again;
|
||||||
|
}
|
||||||
|
leaf = path->nodes[0];
|
||||||
|
nritems = btrfs_header_nritems(leaf);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key.objectid < block_group->key.objectid) {
|
if (key.objectid < block_group->key.objectid) {
|
||||||
@@ -3065,7 +3068,7 @@ again:
|
|||||||
spin_unlock(&data_sinfo->lock);
|
spin_unlock(&data_sinfo->lock);
|
||||||
alloc:
|
alloc:
|
||||||
alloc_target = btrfs_get_alloc_profile(root, 1);
|
alloc_target = btrfs_get_alloc_profile(root, 1);
|
||||||
trans = btrfs_join_transaction(root, 1);
|
trans = btrfs_join_transaction(root);
|
||||||
if (IS_ERR(trans))
|
if (IS_ERR(trans))
|
||||||
return PTR_ERR(trans);
|
return PTR_ERR(trans);
|
||||||
|
|
||||||
@@ -3091,9 +3094,10 @@ alloc:
|
|||||||
|
|
||||||
/* commit the current transaction and try again */
|
/* commit the current transaction and try again */
|
||||||
commit_trans:
|
commit_trans:
|
||||||
if (!committed && !root->fs_info->open_ioctl_trans) {
|
if (!committed &&
|
||||||
|
!atomic_read(&root->fs_info->open_ioctl_trans)) {
|
||||||
committed = 1;
|
committed = 1;
|
||||||
trans = btrfs_join_transaction(root, 1);
|
trans = btrfs_join_transaction(root);
|
||||||
if (IS_ERR(trans))
|
if (IS_ERR(trans))
|
||||||
return PTR_ERR(trans);
|
return PTR_ERR(trans);
|
||||||
ret = btrfs_commit_transaction(trans, root);
|
ret = btrfs_commit_transaction(trans, root);
|
||||||
@@ -3472,7 +3476,7 @@ again:
|
|||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ret = -ENOSPC;
|
ret = -ENOSPC;
|
||||||
trans = btrfs_join_transaction(root, 1);
|
trans = btrfs_join_transaction(root);
|
||||||
if (IS_ERR(trans))
|
if (IS_ERR(trans))
|
||||||
goto out;
|
goto out;
|
||||||
ret = btrfs_commit_transaction(trans, root);
|
ret = btrfs_commit_transaction(trans, root);
|
||||||
@@ -3699,7 +3703,7 @@ int btrfs_block_rsv_check(struct btrfs_trans_handle *trans,
|
|||||||
if (trans)
|
if (trans)
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
|
|
||||||
trans = btrfs_join_transaction(root, 1);
|
trans = btrfs_join_transaction(root);
|
||||||
BUG_ON(IS_ERR(trans));
|
BUG_ON(IS_ERR(trans));
|
||||||
ret = btrfs_commit_transaction(trans, root);
|
ret = btrfs_commit_transaction(trans, root);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -3837,6 +3841,37 @@ static void release_global_block_rsv(struct btrfs_fs_info *fs_info)
|
|||||||
WARN_ON(fs_info->chunk_block_rsv.reserved > 0);
|
WARN_ON(fs_info->chunk_block_rsv.reserved > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int btrfs_truncate_reserve_metadata(struct btrfs_trans_handle *trans,
|
||||||
|
struct btrfs_root *root,
|
||||||
|
struct btrfs_block_rsv *rsv)
|
||||||
|
{
|
||||||
|
struct btrfs_block_rsv *trans_rsv = &root->fs_info->trans_block_rsv;
|
||||||
|
u64 num_bytes;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Truncate should be freeing data, but give us 2 items just in case it
|
||||||
|
* needs to use some space. We may want to be smarter about this in the
|
||||||
|
* future.
|
||||||
|
*/
|
||||||
|
num_bytes = btrfs_calc_trans_metadata_size(root, 2);
|
||||||
|
|
||||||
|
/* We already have enough bytes, just return */
|
||||||
|
if (rsv->reserved >= num_bytes)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
num_bytes -= rsv->reserved;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* You should have reserved enough space before hand to do this, so this
|
||||||
|
* should not fail.
|
||||||
|
*/
|
||||||
|
ret = block_rsv_migrate_bytes(trans_rsv, rsv, num_bytes);
|
||||||
|
BUG_ON(ret);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int btrfs_trans_reserve_metadata(struct btrfs_trans_handle *trans,
|
int btrfs_trans_reserve_metadata(struct btrfs_trans_handle *trans,
|
||||||
struct btrfs_root *root,
|
struct btrfs_root *root,
|
||||||
int num_items)
|
int num_items)
|
||||||
@@ -3877,23 +3912,18 @@ int btrfs_orphan_reserve_metadata(struct btrfs_trans_handle *trans,
|
|||||||
struct btrfs_block_rsv *dst_rsv = root->orphan_block_rsv;
|
struct btrfs_block_rsv *dst_rsv = root->orphan_block_rsv;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* one for deleting orphan item, one for updating inode and
|
* We need to hold space in order to delete our orphan item once we've
|
||||||
* two for calling btrfs_truncate_inode_items.
|
* added it, so this takes the reservation so we can release it later
|
||||||
*
|
* when we are truly done with the orphan item.
|
||||||
* btrfs_truncate_inode_items is a delete operation, it frees
|
|
||||||
* more space than it uses in most cases. So two units of
|
|
||||||
* metadata space should be enough for calling it many times.
|
|
||||||
* If all of the metadata space is used, we can commit
|
|
||||||
* transaction and use space it freed.
|
|
||||||
*/
|
*/
|
||||||
u64 num_bytes = btrfs_calc_trans_metadata_size(root, 4);
|
u64 num_bytes = btrfs_calc_trans_metadata_size(root, 1);
|
||||||
return block_rsv_migrate_bytes(src_rsv, dst_rsv, num_bytes);
|
return block_rsv_migrate_bytes(src_rsv, dst_rsv, num_bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
void btrfs_orphan_release_metadata(struct inode *inode)
|
void btrfs_orphan_release_metadata(struct inode *inode)
|
||||||
{
|
{
|
||||||
struct btrfs_root *root = BTRFS_I(inode)->root;
|
struct btrfs_root *root = BTRFS_I(inode)->root;
|
||||||
u64 num_bytes = btrfs_calc_trans_metadata_size(root, 4);
|
u64 num_bytes = btrfs_calc_trans_metadata_size(root, 1);
|
||||||
btrfs_block_rsv_release(root, root->orphan_block_rsv, num_bytes);
|
btrfs_block_rsv_release(root, root->orphan_block_rsv, num_bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4987,6 +5017,15 @@ have_block_group:
|
|||||||
if (unlikely(block_group->ro))
|
if (unlikely(block_group->ro))
|
||||||
goto loop;
|
goto loop;
|
||||||
|
|
||||||
|
spin_lock(&block_group->free_space_ctl->tree_lock);
|
||||||
|
if (cached &&
|
||||||
|
block_group->free_space_ctl->free_space <
|
||||||
|
num_bytes + empty_size) {
|
||||||
|
spin_unlock(&block_group->free_space_ctl->tree_lock);
|
||||||
|
goto loop;
|
||||||
|
}
|
||||||
|
spin_unlock(&block_group->free_space_ctl->tree_lock);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ok we want to try and use the cluster allocator, so lets look
|
* Ok we want to try and use the cluster allocator, so lets look
|
||||||
* there, unless we are on LOOP_NO_EMPTY_SIZE, since we will
|
* there, unless we are on LOOP_NO_EMPTY_SIZE, since we will
|
||||||
@@ -5150,6 +5189,7 @@ checks:
|
|||||||
btrfs_add_free_space(block_group, offset,
|
btrfs_add_free_space(block_group, offset,
|
||||||
search_start - offset);
|
search_start - offset);
|
||||||
BUG_ON(offset > search_start);
|
BUG_ON(offset > search_start);
|
||||||
|
btrfs_put_block_group(block_group);
|
||||||
break;
|
break;
|
||||||
loop:
|
loop:
|
||||||
failed_cluster_refill = false;
|
failed_cluster_refill = false;
|
||||||
@@ -5242,14 +5282,7 @@ loop:
|
|||||||
ret = -ENOSPC;
|
ret = -ENOSPC;
|
||||||
} else if (!ins->objectid) {
|
} else if (!ins->objectid) {
|
||||||
ret = -ENOSPC;
|
ret = -ENOSPC;
|
||||||
}
|
} else if (ins->objectid) {
|
||||||
|
|
||||||
/* we found what we needed */
|
|
||||||
if (ins->objectid) {
|
|
||||||
if (!(data & BTRFS_BLOCK_GROUP_DATA))
|
|
||||||
trans->block_group = block_group->key.objectid;
|
|
||||||
|
|
||||||
btrfs_put_block_group(block_group);
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6526,7 +6559,7 @@ int btrfs_set_block_group_ro(struct btrfs_root *root,
|
|||||||
|
|
||||||
BUG_ON(cache->ro);
|
BUG_ON(cache->ro);
|
||||||
|
|
||||||
trans = btrfs_join_transaction(root, 1);
|
trans = btrfs_join_transaction(root);
|
||||||
BUG_ON(IS_ERR(trans));
|
BUG_ON(IS_ERR(trans));
|
||||||
|
|
||||||
alloc_flags = update_block_group_flags(root, cache->flags);
|
alloc_flags = update_block_group_flags(root, cache->flags);
|
||||||
@@ -6882,6 +6915,7 @@ int btrfs_read_block_groups(struct btrfs_root *root)
|
|||||||
path = btrfs_alloc_path();
|
path = btrfs_alloc_path();
|
||||||
if (!path)
|
if (!path)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
path->reada = 1;
|
||||||
|
|
||||||
cache_gen = btrfs_super_cache_generation(&root->fs_info->super_copy);
|
cache_gen = btrfs_super_cache_generation(&root->fs_info->super_copy);
|
||||||
if (cache_gen != 0 &&
|
if (cache_gen != 0 &&
|
||||||
|
|||||||
@@ -1474,7 +1474,7 @@ u64 count_range_bits(struct extent_io_tree *tree,
|
|||||||
if (total_bytes >= max_bytes)
|
if (total_bytes >= max_bytes)
|
||||||
break;
|
break;
|
||||||
if (!found) {
|
if (!found) {
|
||||||
*start = state->start;
|
*start = max(cur_start, state->start);
|
||||||
found = 1;
|
found = 1;
|
||||||
}
|
}
|
||||||
last = state->end;
|
last = state->end;
|
||||||
|
|||||||
+1
-3
@@ -1480,14 +1480,12 @@ int btrfs_sync_file(struct file *file, int datasync)
|
|||||||
* the current transaction, we can bail out now without any
|
* the current transaction, we can bail out now without any
|
||||||
* syncing
|
* syncing
|
||||||
*/
|
*/
|
||||||
mutex_lock(&root->fs_info->trans_mutex);
|
smp_mb();
|
||||||
if (BTRFS_I(inode)->last_trans <=
|
if (BTRFS_I(inode)->last_trans <=
|
||||||
root->fs_info->last_trans_committed) {
|
root->fs_info->last_trans_committed) {
|
||||||
BTRFS_I(inode)->last_trans = 0;
|
BTRFS_I(inode)->last_trans = 0;
|
||||||
mutex_unlock(&root->fs_info->trans_mutex);
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
mutex_unlock(&root->fs_info->trans_mutex);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ok we haven't committed the transaction yet, lets do a commit
|
* ok we haven't committed the transaction yet, lets do a commit
|
||||||
|
|||||||
@@ -402,7 +402,14 @@ int __load_free_space_cache(struct btrfs_root *root, struct inode *inode,
|
|||||||
spin_lock(&ctl->tree_lock);
|
spin_lock(&ctl->tree_lock);
|
||||||
ret = link_free_space(ctl, e);
|
ret = link_free_space(ctl, e);
|
||||||
spin_unlock(&ctl->tree_lock);
|
spin_unlock(&ctl->tree_lock);
|
||||||
BUG_ON(ret);
|
if (ret) {
|
||||||
|
printk(KERN_ERR "Duplicate entries in "
|
||||||
|
"free space cache, dumping\n");
|
||||||
|
kunmap(page);
|
||||||
|
unlock_page(page);
|
||||||
|
page_cache_release(page);
|
||||||
|
goto free_cache;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
e->bitmap = kzalloc(PAGE_CACHE_SIZE, GFP_NOFS);
|
e->bitmap = kzalloc(PAGE_CACHE_SIZE, GFP_NOFS);
|
||||||
if (!e->bitmap) {
|
if (!e->bitmap) {
|
||||||
@@ -419,6 +426,14 @@ int __load_free_space_cache(struct btrfs_root *root, struct inode *inode,
|
|||||||
ctl->op->recalc_thresholds(ctl);
|
ctl->op->recalc_thresholds(ctl);
|
||||||
spin_unlock(&ctl->tree_lock);
|
spin_unlock(&ctl->tree_lock);
|
||||||
list_add_tail(&e->list, &bitmaps);
|
list_add_tail(&e->list, &bitmaps);
|
||||||
|
if (ret) {
|
||||||
|
printk(KERN_ERR "Duplicate entries in "
|
||||||
|
"free space cache, dumping\n");
|
||||||
|
kunmap(page);
|
||||||
|
unlock_page(page);
|
||||||
|
page_cache_release(page);
|
||||||
|
goto free_cache;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
num_entries--;
|
num_entries--;
|
||||||
@@ -963,10 +978,16 @@ static int tree_insert_offset(struct rb_root *root, u64 offset,
|
|||||||
* logically.
|
* logically.
|
||||||
*/
|
*/
|
||||||
if (bitmap) {
|
if (bitmap) {
|
||||||
WARN_ON(info->bitmap);
|
if (info->bitmap) {
|
||||||
|
WARN_ON_ONCE(1);
|
||||||
|
return -EEXIST;
|
||||||
|
}
|
||||||
p = &(*p)->rb_right;
|
p = &(*p)->rb_right;
|
||||||
} else {
|
} else {
|
||||||
WARN_ON(!info->bitmap);
|
if (!info->bitmap) {
|
||||||
|
WARN_ON_ONCE(1);
|
||||||
|
return -EEXIST;
|
||||||
|
}
|
||||||
p = &(*p)->rb_left;
|
p = &(*p)->rb_left;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+136
-122
File diff suppressed because it is too large
Load Diff
+6
-13
@@ -243,7 +243,7 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg)
|
|||||||
ip->flags &= ~(BTRFS_INODE_COMPRESS | BTRFS_INODE_NOCOMPRESS);
|
ip->flags &= ~(BTRFS_INODE_COMPRESS | BTRFS_INODE_NOCOMPRESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
trans = btrfs_join_transaction(root, 1);
|
trans = btrfs_join_transaction(root);
|
||||||
BUG_ON(IS_ERR(trans));
|
BUG_ON(IS_ERR(trans));
|
||||||
|
|
||||||
ret = btrfs_update_inode(trans, root, inode);
|
ret = btrfs_update_inode(trans, root, inode);
|
||||||
@@ -414,8 +414,7 @@ static noinline int create_subvol(struct btrfs_root *root,
|
|||||||
|
|
||||||
btrfs_record_root_in_trans(trans, new_root);
|
btrfs_record_root_in_trans(trans, new_root);
|
||||||
|
|
||||||
ret = btrfs_create_subvol_root(trans, new_root, new_dirid,
|
ret = btrfs_create_subvol_root(trans, new_root, new_dirid);
|
||||||
BTRFS_I(dir)->block_group);
|
|
||||||
/*
|
/*
|
||||||
* insert the directory item
|
* insert the directory item
|
||||||
*/
|
*/
|
||||||
@@ -2489,12 +2488,10 @@ static long btrfs_ioctl_trans_start(struct file *file)
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
mutex_lock(&root->fs_info->trans_mutex);
|
atomic_inc(&root->fs_info->open_ioctl_trans);
|
||||||
root->fs_info->open_ioctl_trans++;
|
|
||||||
mutex_unlock(&root->fs_info->trans_mutex);
|
|
||||||
|
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
trans = btrfs_start_ioctl_transaction(root, 0);
|
trans = btrfs_start_ioctl_transaction(root);
|
||||||
if (IS_ERR(trans))
|
if (IS_ERR(trans))
|
||||||
goto out_drop;
|
goto out_drop;
|
||||||
|
|
||||||
@@ -2502,9 +2499,7 @@ static long btrfs_ioctl_trans_start(struct file *file)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out_drop:
|
out_drop:
|
||||||
mutex_lock(&root->fs_info->trans_mutex);
|
atomic_dec(&root->fs_info->open_ioctl_trans);
|
||||||
root->fs_info->open_ioctl_trans--;
|
|
||||||
mutex_unlock(&root->fs_info->trans_mutex);
|
|
||||||
mnt_drop_write(file->f_path.mnt);
|
mnt_drop_write(file->f_path.mnt);
|
||||||
out:
|
out:
|
||||||
return ret;
|
return ret;
|
||||||
@@ -2738,9 +2733,7 @@ long btrfs_ioctl_trans_end(struct file *file)
|
|||||||
|
|
||||||
btrfs_end_transaction(trans, root);
|
btrfs_end_transaction(trans, root);
|
||||||
|
|
||||||
mutex_lock(&root->fs_info->trans_mutex);
|
atomic_dec(&root->fs_info->open_ioctl_trans);
|
||||||
root->fs_info->open_ioctl_trans--;
|
|
||||||
mutex_unlock(&root->fs_info->trans_mutex);
|
|
||||||
|
|
||||||
mnt_drop_write(file->f_path.mnt);
|
mnt_drop_write(file->f_path.mnt);
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
+20
-14
@@ -677,6 +677,8 @@ struct backref_node *build_backref_tree(struct reloc_control *rc,
|
|||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
path1->reada = 1;
|
||||||
|
path2->reada = 2;
|
||||||
|
|
||||||
node = alloc_backref_node(cache);
|
node = alloc_backref_node(cache);
|
||||||
if (!node) {
|
if (!node) {
|
||||||
@@ -1999,6 +2001,7 @@ static noinline_for_stack int merge_reloc_root(struct reloc_control *rc,
|
|||||||
path = btrfs_alloc_path();
|
path = btrfs_alloc_path();
|
||||||
if (!path)
|
if (!path)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
path->reada = 1;
|
||||||
|
|
||||||
reloc_root = root->reloc_root;
|
reloc_root = root->reloc_root;
|
||||||
root_item = &reloc_root->root_item;
|
root_item = &reloc_root->root_item;
|
||||||
@@ -2139,10 +2142,10 @@ int prepare_to_merge(struct reloc_control *rc, int err)
|
|||||||
u64 num_bytes = 0;
|
u64 num_bytes = 0;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
mutex_lock(&root->fs_info->trans_mutex);
|
spin_lock(&root->fs_info->trans_lock);
|
||||||
rc->merging_rsv_size += root->nodesize * (BTRFS_MAX_LEVEL - 1) * 2;
|
rc->merging_rsv_size += root->nodesize * (BTRFS_MAX_LEVEL - 1) * 2;
|
||||||
rc->merging_rsv_size += rc->nodes_relocated * 2;
|
rc->merging_rsv_size += rc->nodes_relocated * 2;
|
||||||
mutex_unlock(&root->fs_info->trans_mutex);
|
spin_unlock(&root->fs_info->trans_lock);
|
||||||
again:
|
again:
|
||||||
if (!err) {
|
if (!err) {
|
||||||
num_bytes = rc->merging_rsv_size;
|
num_bytes = rc->merging_rsv_size;
|
||||||
@@ -2152,7 +2155,7 @@ again:
|
|||||||
err = ret;
|
err = ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
trans = btrfs_join_transaction(rc->extent_root, 1);
|
trans = btrfs_join_transaction(rc->extent_root);
|
||||||
if (IS_ERR(trans)) {
|
if (IS_ERR(trans)) {
|
||||||
if (!err)
|
if (!err)
|
||||||
btrfs_block_rsv_release(rc->extent_root,
|
btrfs_block_rsv_release(rc->extent_root,
|
||||||
@@ -2211,9 +2214,9 @@ int merge_reloc_roots(struct reloc_control *rc)
|
|||||||
int ret;
|
int ret;
|
||||||
again:
|
again:
|
||||||
root = rc->extent_root;
|
root = rc->extent_root;
|
||||||
mutex_lock(&root->fs_info->trans_mutex);
|
spin_lock(&root->fs_info->trans_lock);
|
||||||
list_splice_init(&rc->reloc_roots, &reloc_roots);
|
list_splice_init(&rc->reloc_roots, &reloc_roots);
|
||||||
mutex_unlock(&root->fs_info->trans_mutex);
|
spin_unlock(&root->fs_info->trans_lock);
|
||||||
|
|
||||||
while (!list_empty(&reloc_roots)) {
|
while (!list_empty(&reloc_roots)) {
|
||||||
found = 1;
|
found = 1;
|
||||||
@@ -3236,7 +3239,7 @@ truncate:
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
trans = btrfs_join_transaction(root, 0);
|
trans = btrfs_join_transaction(root);
|
||||||
if (IS_ERR(trans)) {
|
if (IS_ERR(trans)) {
|
||||||
btrfs_free_path(path);
|
btrfs_free_path(path);
|
||||||
ret = PTR_ERR(trans);
|
ret = PTR_ERR(trans);
|
||||||
@@ -3300,6 +3303,7 @@ static int find_data_references(struct reloc_control *rc,
|
|||||||
path = btrfs_alloc_path();
|
path = btrfs_alloc_path();
|
||||||
if (!path)
|
if (!path)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
path->reada = 1;
|
||||||
|
|
||||||
root = read_fs_root(rc->extent_root->fs_info, ref_root);
|
root = read_fs_root(rc->extent_root->fs_info, ref_root);
|
||||||
if (IS_ERR(root)) {
|
if (IS_ERR(root)) {
|
||||||
@@ -3586,17 +3590,17 @@ next:
|
|||||||
static void set_reloc_control(struct reloc_control *rc)
|
static void set_reloc_control(struct reloc_control *rc)
|
||||||
{
|
{
|
||||||
struct btrfs_fs_info *fs_info = rc->extent_root->fs_info;
|
struct btrfs_fs_info *fs_info = rc->extent_root->fs_info;
|
||||||
mutex_lock(&fs_info->trans_mutex);
|
spin_lock(&fs_info->trans_lock);
|
||||||
fs_info->reloc_ctl = rc;
|
fs_info->reloc_ctl = rc;
|
||||||
mutex_unlock(&fs_info->trans_mutex);
|
spin_unlock(&fs_info->trans_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void unset_reloc_control(struct reloc_control *rc)
|
static void unset_reloc_control(struct reloc_control *rc)
|
||||||
{
|
{
|
||||||
struct btrfs_fs_info *fs_info = rc->extent_root->fs_info;
|
struct btrfs_fs_info *fs_info = rc->extent_root->fs_info;
|
||||||
mutex_lock(&fs_info->trans_mutex);
|
spin_lock(&fs_info->trans_lock);
|
||||||
fs_info->reloc_ctl = NULL;
|
fs_info->reloc_ctl = NULL;
|
||||||
mutex_unlock(&fs_info->trans_mutex);
|
spin_unlock(&fs_info->trans_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int check_extent_flags(u64 flags)
|
static int check_extent_flags(u64 flags)
|
||||||
@@ -3645,7 +3649,7 @@ int prepare_to_relocate(struct reloc_control *rc)
|
|||||||
rc->create_reloc_tree = 1;
|
rc->create_reloc_tree = 1;
|
||||||
set_reloc_control(rc);
|
set_reloc_control(rc);
|
||||||
|
|
||||||
trans = btrfs_join_transaction(rc->extent_root, 1);
|
trans = btrfs_join_transaction(rc->extent_root);
|
||||||
BUG_ON(IS_ERR(trans));
|
BUG_ON(IS_ERR(trans));
|
||||||
btrfs_commit_transaction(trans, rc->extent_root);
|
btrfs_commit_transaction(trans, rc->extent_root);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -3668,6 +3672,7 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc)
|
|||||||
path = btrfs_alloc_path();
|
path = btrfs_alloc_path();
|
||||||
if (!path)
|
if (!path)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
path->reada = 1;
|
||||||
|
|
||||||
ret = prepare_to_relocate(rc);
|
ret = prepare_to_relocate(rc);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
@@ -3834,7 +3839,7 @@ restart:
|
|||||||
btrfs_block_rsv_release(rc->extent_root, rc->block_rsv, (u64)-1);
|
btrfs_block_rsv_release(rc->extent_root, rc->block_rsv, (u64)-1);
|
||||||
|
|
||||||
/* get rid of pinned extents */
|
/* get rid of pinned extents */
|
||||||
trans = btrfs_join_transaction(rc->extent_root, 1);
|
trans = btrfs_join_transaction(rc->extent_root);
|
||||||
if (IS_ERR(trans))
|
if (IS_ERR(trans))
|
||||||
err = PTR_ERR(trans);
|
err = PTR_ERR(trans);
|
||||||
else
|
else
|
||||||
@@ -4093,6 +4098,7 @@ int btrfs_recover_relocation(struct btrfs_root *root)
|
|||||||
path = btrfs_alloc_path();
|
path = btrfs_alloc_path();
|
||||||
if (!path)
|
if (!path)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
path->reada = -1;
|
||||||
|
|
||||||
key.objectid = BTRFS_TREE_RELOC_OBJECTID;
|
key.objectid = BTRFS_TREE_RELOC_OBJECTID;
|
||||||
key.type = BTRFS_ROOT_ITEM_KEY;
|
key.type = BTRFS_ROOT_ITEM_KEY;
|
||||||
@@ -4159,7 +4165,7 @@ int btrfs_recover_relocation(struct btrfs_root *root)
|
|||||||
|
|
||||||
set_reloc_control(rc);
|
set_reloc_control(rc);
|
||||||
|
|
||||||
trans = btrfs_join_transaction(rc->extent_root, 1);
|
trans = btrfs_join_transaction(rc->extent_root);
|
||||||
if (IS_ERR(trans)) {
|
if (IS_ERR(trans)) {
|
||||||
unset_reloc_control(rc);
|
unset_reloc_control(rc);
|
||||||
err = PTR_ERR(trans);
|
err = PTR_ERR(trans);
|
||||||
@@ -4193,7 +4199,7 @@ int btrfs_recover_relocation(struct btrfs_root *root)
|
|||||||
|
|
||||||
unset_reloc_control(rc);
|
unset_reloc_control(rc);
|
||||||
|
|
||||||
trans = btrfs_join_transaction(rc->extent_root, 1);
|
trans = btrfs_join_transaction(rc->extent_root);
|
||||||
if (IS_ERR(trans))
|
if (IS_ERR(trans))
|
||||||
err = PTR_ERR(trans);
|
err = PTR_ERR(trans);
|
||||||
else
|
else
|
||||||
|
|||||||
+163
-137
File diff suppressed because it is too large
Load Diff
+8
-21
@@ -28,10 +28,12 @@ struct btrfs_transaction {
|
|||||||
* transaction can end
|
* transaction can end
|
||||||
*/
|
*/
|
||||||
atomic_t num_writers;
|
atomic_t num_writers;
|
||||||
|
atomic_t use_count;
|
||||||
|
|
||||||
unsigned long num_joined;
|
unsigned long num_joined;
|
||||||
|
|
||||||
|
spinlock_t commit_lock;
|
||||||
int in_commit;
|
int in_commit;
|
||||||
atomic_t use_count;
|
|
||||||
int commit_done;
|
int commit_done;
|
||||||
int blocked;
|
int blocked;
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
@@ -45,13 +47,14 @@ struct btrfs_transaction {
|
|||||||
|
|
||||||
struct btrfs_trans_handle {
|
struct btrfs_trans_handle {
|
||||||
u64 transid;
|
u64 transid;
|
||||||
u64 block_group;
|
|
||||||
u64 bytes_reserved;
|
u64 bytes_reserved;
|
||||||
|
unsigned long use_count;
|
||||||
unsigned long blocks_reserved;
|
unsigned long blocks_reserved;
|
||||||
unsigned long blocks_used;
|
unsigned long blocks_used;
|
||||||
unsigned long delayed_ref_updates;
|
unsigned long delayed_ref_updates;
|
||||||
struct btrfs_transaction *transaction;
|
struct btrfs_transaction *transaction;
|
||||||
struct btrfs_block_rsv *block_rsv;
|
struct btrfs_block_rsv *block_rsv;
|
||||||
|
struct btrfs_block_rsv *orig_rsv;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct btrfs_pending_snapshot {
|
struct btrfs_pending_snapshot {
|
||||||
@@ -66,19 +69,6 @@ struct btrfs_pending_snapshot {
|
|||||||
struct list_head list;
|
struct list_head list;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline void btrfs_set_trans_block_group(struct btrfs_trans_handle *trans,
|
|
||||||
struct inode *inode)
|
|
||||||
{
|
|
||||||
trans->block_group = BTRFS_I(inode)->block_group;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void btrfs_update_inode_block_group(
|
|
||||||
struct btrfs_trans_handle *trans,
|
|
||||||
struct inode *inode)
|
|
||||||
{
|
|
||||||
BTRFS_I(inode)->block_group = trans->block_group;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void btrfs_set_inode_last_trans(struct btrfs_trans_handle *trans,
|
static inline void btrfs_set_inode_last_trans(struct btrfs_trans_handle *trans,
|
||||||
struct inode *inode)
|
struct inode *inode)
|
||||||
{
|
{
|
||||||
@@ -92,12 +82,9 @@ int btrfs_end_transaction_nolock(struct btrfs_trans_handle *trans,
|
|||||||
struct btrfs_root *root);
|
struct btrfs_root *root);
|
||||||
struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root,
|
struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root,
|
||||||
int num_items);
|
int num_items);
|
||||||
struct btrfs_trans_handle *btrfs_join_transaction(struct btrfs_root *root,
|
struct btrfs_trans_handle *btrfs_join_transaction(struct btrfs_root *root);
|
||||||
int num_blocks);
|
struct btrfs_trans_handle *btrfs_join_transaction_nolock(struct btrfs_root *root);
|
||||||
struct btrfs_trans_handle *btrfs_join_transaction_nolock(struct btrfs_root *root,
|
struct btrfs_trans_handle *btrfs_start_ioctl_transaction(struct btrfs_root *root);
|
||||||
int num_blocks);
|
|
||||||
struct btrfs_trans_handle *btrfs_start_ioctl_transaction(struct btrfs_root *r,
|
|
||||||
int num_blocks);
|
|
||||||
int btrfs_wait_for_commit(struct btrfs_root *root, u64 transid);
|
int btrfs_wait_for_commit(struct btrfs_root *root, u64 transid);
|
||||||
int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans,
|
int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans,
|
||||||
struct btrfs_root *root);
|
struct btrfs_root *root);
|
||||||
|
|||||||
@@ -158,8 +158,6 @@ int __btrfs_setxattr(struct btrfs_trans_handle *trans,
|
|||||||
if (IS_ERR(trans))
|
if (IS_ERR(trans))
|
||||||
return PTR_ERR(trans);
|
return PTR_ERR(trans);
|
||||||
|
|
||||||
btrfs_set_trans_block_group(trans, inode);
|
|
||||||
|
|
||||||
ret = do_setxattr(trans, inode, name, value, size, flags);
|
ret = do_setxattr(trans, inode, name, value, size, flags);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|||||||
Reference in New Issue
Block a user