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-linus-4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs
Pull btrfs updates from Chris Mason: "This is a big variety of fixes and cleanups. Liu Bo continues to fixup fuzzer related problems, and some of Josef's cleanups are prep for his bigger extent buffer changes (slated for v4.10)" * 'for-linus-4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs: (39 commits) Revert "btrfs: let btrfs_delete_unused_bgs() to clean relocated bgs" Btrfs: remove unnecessary btrfs_mark_buffer_dirty in split_leaf Btrfs: don't BUG() during drop snapshot btrfs: fix btrfs_no_printk stub helper Btrfs: memset to avoid stale content in btree leaf btrfs: parent_start initialization cleanup btrfs: Remove already completed TODO comment btrfs: Do not reassign count in btrfs_run_delayed_refs btrfs: fix a possible umount deadlock Btrfs: fix memory leak in do_walk_down btrfs: btrfs_debug should consume fs_info when DEBUG is not defined btrfs: convert send's verbose_printk to btrfs_debug btrfs: convert pr_* to btrfs_* where possible btrfs: convert printk(KERN_* to use pr_* calls btrfs: unsplit printed strings btrfs: clean the old superblocks before freeing the device Btrfs: kill BUG_ON in run_delayed_tree_ref Btrfs: don't leak reloc root nodes on error btrfs: squash lines for simple wrapper functions Btrfs: improve check_node to avoid reading corrupted nodes ...
This commit is contained in:
+379
-30
File diff suppressed because it is too large
Load Diff
@@ -44,17 +44,6 @@
|
||||
#define BTRFS_INODE_IN_DELALLOC_LIST 9
|
||||
#define BTRFS_INODE_READDIO_NEED_LOCK 10
|
||||
#define BTRFS_INODE_HAS_PROPS 11
|
||||
/*
|
||||
* The following 3 bits are meant only for the btree inode.
|
||||
* When any of them is set, it means an error happened while writing an
|
||||
* extent buffer belonging to:
|
||||
* 1) a non-log btree
|
||||
* 2) a log btree and first log sub-transaction
|
||||
* 3) a log btree and second log sub-transaction
|
||||
*/
|
||||
#define BTRFS_INODE_BTREE_ERR 12
|
||||
#define BTRFS_INODE_BTREE_LOG1_ERR 13
|
||||
#define BTRFS_INODE_BTREE_LOG2_ERR 14
|
||||
|
||||
/* in memory btrfs inode */
|
||||
struct btrfs_inode {
|
||||
|
||||
+108
-234
File diff suppressed because it is too large
Load Diff
@@ -783,8 +783,7 @@ void __init btrfs_init_compress(void)
|
||||
*/
|
||||
workspace = btrfs_compress_op[i]->alloc_workspace();
|
||||
if (IS_ERR(workspace)) {
|
||||
printk(KERN_WARNING
|
||||
"BTRFS: cannot preallocate compression workspace, will try later");
|
||||
pr_warn("BTRFS: cannot preallocate compression workspace, will try later\n");
|
||||
} else {
|
||||
atomic_set(&btrfs_comp_ws[i].total_ws, 1);
|
||||
btrfs_comp_ws[i].free_ws = 1;
|
||||
@@ -854,8 +853,7 @@ again:
|
||||
/* no burst */ 1);
|
||||
|
||||
if (__ratelimit(&_rs)) {
|
||||
printk(KERN_WARNING
|
||||
"no compression workspaces, low memory, retrying");
|
||||
pr_warn("BTRFS: no compression workspaces, low memory, retrying\n");
|
||||
}
|
||||
}
|
||||
goto again;
|
||||
|
||||
+16
-40
@@ -45,9 +45,7 @@ static int tree_mod_log_free_eb(struct btrfs_fs_info *fs_info,
|
||||
|
||||
struct btrfs_path *btrfs_alloc_path(void)
|
||||
{
|
||||
struct btrfs_path *path;
|
||||
path = kmem_cache_zalloc(btrfs_path_cachep, GFP_NOFS);
|
||||
return path;
|
||||
return kmem_cache_zalloc(btrfs_path_cachep, GFP_NOFS);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1102,7 +1100,7 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,
|
||||
int level, ret;
|
||||
int last_ref = 0;
|
||||
int unlock_orig = 0;
|
||||
u64 parent_start;
|
||||
u64 parent_start = 0;
|
||||
|
||||
if (*cow_ret == buf)
|
||||
unlock_orig = 1;
|
||||
@@ -1121,13 +1119,8 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,
|
||||
else
|
||||
btrfs_node_key(buf, &disk_key, 0);
|
||||
|
||||
if (root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID) {
|
||||
if (parent)
|
||||
parent_start = parent->start;
|
||||
else
|
||||
parent_start = 0;
|
||||
} else
|
||||
parent_start = 0;
|
||||
if ((root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID) && parent)
|
||||
parent_start = parent->start;
|
||||
|
||||
cow = btrfs_alloc_tree_block(trans, root, parent_start,
|
||||
root->root_key.objectid, &disk_key, level,
|
||||
@@ -1170,8 +1163,6 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,
|
||||
if (root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID ||
|
||||
btrfs_header_backref_rev(buf) < BTRFS_MIXED_BACKREF_REV)
|
||||
parent_start = buf->start;
|
||||
else
|
||||
parent_start = 0;
|
||||
|
||||
extent_buffer_get(cow);
|
||||
tree_mod_log_set_root_pointer(root, cow, 1);
|
||||
@@ -1182,11 +1173,6 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,
|
||||
free_extent_buffer(buf);
|
||||
add_root_to_dirty_list(root);
|
||||
} else {
|
||||
if (root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID)
|
||||
parent_start = parent->start;
|
||||
else
|
||||
parent_start = 0;
|
||||
|
||||
WARN_ON(trans->transid != btrfs_header_generation(parent));
|
||||
tree_mod_log_insert_key(root->fs_info, parent, parent_slot,
|
||||
MOD_LOG_KEY_REPLACE, GFP_NOFS);
|
||||
@@ -1729,20 +1715,6 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* The leaf data grows from end-to-front in the node.
|
||||
* this returns the address of the start of the last item,
|
||||
* which is the stop of the leaf data stack
|
||||
*/
|
||||
static inline unsigned int leaf_data_end(struct btrfs_root *root,
|
||||
struct extent_buffer *leaf)
|
||||
{
|
||||
u32 nr = btrfs_header_nritems(leaf);
|
||||
if (nr == 0)
|
||||
return BTRFS_LEAF_DATA_SIZE(root);
|
||||
return btrfs_item_offset_nr(leaf, nr - 1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* search for key in the extent_buffer. The items start at offset p,
|
||||
@@ -2268,7 +2240,6 @@ static void reada_for_search(struct btrfs_root *root,
|
||||
u64 search;
|
||||
u64 target;
|
||||
u64 nread = 0;
|
||||
u64 gen;
|
||||
struct extent_buffer *eb;
|
||||
u32 nr;
|
||||
u32 blocksize;
|
||||
@@ -2313,7 +2284,6 @@ static void reada_for_search(struct btrfs_root *root,
|
||||
search = btrfs_node_blockptr(node, nr);
|
||||
if ((search <= target && target - search <= 65536) ||
|
||||
(search > target && search - target <= 65536)) {
|
||||
gen = btrfs_node_ptr_generation(node, nr);
|
||||
readahead_tree_block(root, search);
|
||||
nread += blocksize;
|
||||
}
|
||||
@@ -4341,7 +4311,11 @@ again:
|
||||
if (path->slots[1] == 0)
|
||||
fixup_low_keys(fs_info, path, &disk_key, 1);
|
||||
}
|
||||
btrfs_mark_buffer_dirty(right);
|
||||
/*
|
||||
* We create a new leaf 'right' for the required ins_len and
|
||||
* we'll do btrfs_mark_buffer_dirty() on this leaf after copying
|
||||
* the content of ins_len to 'right'.
|
||||
*/
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -4772,8 +4746,9 @@ void setup_items_for_insert(struct btrfs_root *root, struct btrfs_path *path,
|
||||
|
||||
if (btrfs_leaf_free_space(root, leaf) < total_size) {
|
||||
btrfs_print_leaf(root, leaf);
|
||||
btrfs_crit(root->fs_info, "not enough freespace need %u have %d",
|
||||
total_size, btrfs_leaf_free_space(root, leaf));
|
||||
btrfs_crit(root->fs_info,
|
||||
"not enough freespace need %u have %d",
|
||||
total_size, btrfs_leaf_free_space(root, leaf));
|
||||
BUG();
|
||||
}
|
||||
|
||||
@@ -4782,8 +4757,9 @@ void setup_items_for_insert(struct btrfs_root *root, struct btrfs_path *path,
|
||||
|
||||
if (old_data < data_end) {
|
||||
btrfs_print_leaf(root, leaf);
|
||||
btrfs_crit(root->fs_info, "slot %d old_data %d data_end %d",
|
||||
slot, old_data, data_end);
|
||||
btrfs_crit(root->fs_info,
|
||||
"slot %d old_data %d data_end %d",
|
||||
slot, old_data, data_end);
|
||||
BUG_ON(1);
|
||||
}
|
||||
/*
|
||||
@@ -4793,7 +4769,7 @@ void setup_items_for_insert(struct btrfs_root *root, struct btrfs_path *path,
|
||||
for (i = slot; i < nritems; i++) {
|
||||
u32 ioff;
|
||||
|
||||
item = btrfs_item_nr( i);
|
||||
item = btrfs_item_nr(i);
|
||||
ioff = btrfs_token_item_offset(leaf, item, &token);
|
||||
btrfs_set_token_item_offset(leaf, item,
|
||||
ioff - total_data, &token);
|
||||
|
||||
+83
-33
@@ -37,6 +37,7 @@
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/security.h>
|
||||
#include <linux/sizes.h>
|
||||
#include <linux/dynamic_debug.h>
|
||||
#include "extent_io.h"
|
||||
#include "extent_map.h"
|
||||
#include "async-thread.h"
|
||||
@@ -676,9 +677,25 @@ struct btrfs_device;
|
||||
struct btrfs_fs_devices;
|
||||
struct btrfs_balance_control;
|
||||
struct btrfs_delayed_root;
|
||||
|
||||
#define BTRFS_FS_BARRIER 1
|
||||
#define BTRFS_FS_CLOSING_START 2
|
||||
#define BTRFS_FS_CLOSING_DONE 3
|
||||
#define BTRFS_FS_LOG_RECOVERING 4
|
||||
#define BTRFS_FS_OPEN 5
|
||||
#define BTRFS_FS_QUOTA_ENABLED 6
|
||||
#define BTRFS_FS_QUOTA_ENABLING 7
|
||||
#define BTRFS_FS_QUOTA_DISABLING 8
|
||||
#define BTRFS_FS_UPDATE_UUID_TREE_GEN 9
|
||||
#define BTRFS_FS_CREATING_FREE_SPACE_TREE 10
|
||||
#define BTRFS_FS_BTREE_ERR 11
|
||||
#define BTRFS_FS_LOG1_ERR 12
|
||||
#define BTRFS_FS_LOG2_ERR 13
|
||||
|
||||
struct btrfs_fs_info {
|
||||
u8 fsid[BTRFS_FSID_SIZE];
|
||||
u8 chunk_tree_uuid[BTRFS_UUID_SIZE];
|
||||
unsigned long flags;
|
||||
struct btrfs_root *extent_root;
|
||||
struct btrfs_root *tree_root;
|
||||
struct btrfs_root *chunk_root;
|
||||
@@ -907,10 +924,6 @@ struct btrfs_fs_info {
|
||||
int thread_pool_size;
|
||||
|
||||
struct kobject *space_info_kobj;
|
||||
int do_barriers;
|
||||
int closing;
|
||||
int log_root_recovering;
|
||||
int open;
|
||||
|
||||
u64 total_pinned;
|
||||
|
||||
@@ -987,17 +1000,6 @@ struct btrfs_fs_info {
|
||||
#ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY
|
||||
u32 check_integrity_print_mask;
|
||||
#endif
|
||||
/*
|
||||
* quota information
|
||||
*/
|
||||
unsigned int quota_enabled:1;
|
||||
|
||||
/*
|
||||
* quota_enabled only changes state after a commit. This holds the
|
||||
* next state.
|
||||
*/
|
||||
unsigned int pending_quota_state:1;
|
||||
|
||||
/* is qgroup tracking in a consistent state? */
|
||||
u64 qgroup_flags;
|
||||
|
||||
@@ -1061,7 +1063,6 @@ struct btrfs_fs_info {
|
||||
wait_queue_head_t replace_wait;
|
||||
|
||||
struct semaphore uuid_tree_rescan_sem;
|
||||
unsigned int update_uuid_tree_gen:1;
|
||||
|
||||
/* Used to reclaim the metadata space in the background. */
|
||||
struct work_struct async_reclaim_work;
|
||||
@@ -1080,7 +1081,6 @@ struct btrfs_fs_info {
|
||||
*/
|
||||
struct list_head pinned_chunks;
|
||||
|
||||
int creating_free_space_tree;
|
||||
/* Used to record internally whether fs has been frozen */
|
||||
int fs_frozen;
|
||||
};
|
||||
@@ -1435,13 +1435,13 @@ static inline void btrfs_init_map_token (struct btrfs_map_token *token)
|
||||
#define cpu_to_le8(v) (v)
|
||||
#define __le8 u8
|
||||
|
||||
#define read_eb_member(eb, ptr, type, member, result) ( \
|
||||
#define read_eb_member(eb, ptr, type, member, result) (\
|
||||
read_extent_buffer(eb, (char *)(result), \
|
||||
((unsigned long)(ptr)) + \
|
||||
offsetof(type, member), \
|
||||
sizeof(((type *)0)->member)))
|
||||
|
||||
#define write_eb_member(eb, ptr, type, member, result) ( \
|
||||
#define write_eb_member(eb, ptr, type, member, result) (\
|
||||
write_extent_buffer(eb, (char *)(result), \
|
||||
((unsigned long)(ptr)) + \
|
||||
offsetof(type, member), \
|
||||
@@ -2293,6 +2293,21 @@ static inline unsigned long btrfs_leaf_data(struct extent_buffer *l)
|
||||
return offsetof(struct btrfs_leaf, items);
|
||||
}
|
||||
|
||||
/*
|
||||
* The leaf data grows from end-to-front in the node.
|
||||
* this returns the address of the start of the last item,
|
||||
* which is the stop of the leaf data stack
|
||||
*/
|
||||
static inline unsigned int leaf_data_end(struct btrfs_root *root,
|
||||
struct extent_buffer *leaf)
|
||||
{
|
||||
u32 nr = btrfs_header_nritems(leaf);
|
||||
|
||||
if (nr == 0)
|
||||
return BTRFS_LEAF_DATA_SIZE(root);
|
||||
return btrfs_item_offset_nr(leaf, nr - 1);
|
||||
}
|
||||
|
||||
/* struct btrfs_file_extent_item */
|
||||
BTRFS_SETGET_FUNCS(file_extent_type, struct btrfs_file_extent_item, type, 8);
|
||||
BTRFS_SETGET_STACK_FUNCS(stack_file_extent_disk_bytenr,
|
||||
@@ -2867,10 +2882,14 @@ int btrfs_drop_subtree(struct btrfs_trans_handle *trans,
|
||||
static inline int btrfs_fs_closing(struct btrfs_fs_info *fs_info)
|
||||
{
|
||||
/*
|
||||
* Get synced with close_ctree()
|
||||
* Do it this way so we only ever do one test_bit in the normal case.
|
||||
*/
|
||||
smp_mb();
|
||||
return fs_info->closing;
|
||||
if (test_bit(BTRFS_FS_CLOSING_START, &fs_info->flags)) {
|
||||
if (test_bit(BTRFS_FS_CLOSING_DONE, &fs_info->flags))
|
||||
return 2;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3118,7 +3137,7 @@ int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput);
|
||||
int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, int delay_iput,
|
||||
int nr);
|
||||
int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end,
|
||||
struct extent_state **cached_state);
|
||||
struct extent_state **cached_state, int dedupe);
|
||||
int btrfs_create_subvol_root(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *new_root,
|
||||
struct btrfs_root *parent_root,
|
||||
@@ -3236,14 +3255,17 @@ int btrfs_parse_options(struct btrfs_root *root, char *options,
|
||||
unsigned long new_flags);
|
||||
int btrfs_sync_fs(struct super_block *sb, int wait);
|
||||
|
||||
static inline __printf(2, 3)
|
||||
void btrfs_no_printk(const struct btrfs_fs_info *fs_info, const char *fmt, ...)
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PRINTK
|
||||
__printf(2, 3)
|
||||
void btrfs_printk(const struct btrfs_fs_info *fs_info, const char *fmt, ...);
|
||||
#else
|
||||
static inline __printf(2, 3)
|
||||
void btrfs_printk(const struct btrfs_fs_info *fs_info, const char *fmt, ...)
|
||||
{
|
||||
}
|
||||
#define btrfs_printk(fs_info, fmt, args...) \
|
||||
btrfs_no_printk(fs_info, fmt, ##args)
|
||||
#endif
|
||||
|
||||
#define btrfs_emerg(fs_info, fmt, args...) \
|
||||
@@ -3314,7 +3336,35 @@ void btrfs_printk(const struct btrfs_fs_info *fs_info, const char *fmt, ...)
|
||||
btrfs_printk_ratelimited(fs_info, KERN_NOTICE fmt, ##args)
|
||||
#define btrfs_info_rl(fs_info, fmt, args...) \
|
||||
btrfs_printk_ratelimited(fs_info, KERN_INFO fmt, ##args)
|
||||
#ifdef DEBUG
|
||||
|
||||
#if defined(CONFIG_DYNAMIC_DEBUG)
|
||||
#define btrfs_debug(fs_info, fmt, args...) \
|
||||
do { \
|
||||
DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
|
||||
if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)) \
|
||||
btrfs_printk(fs_info, KERN_DEBUG fmt, ##args); \
|
||||
} while (0)
|
||||
#define btrfs_debug_in_rcu(fs_info, fmt, args...) \
|
||||
do { \
|
||||
DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
|
||||
if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)) \
|
||||
btrfs_printk_in_rcu(fs_info, KERN_DEBUG fmt, ##args); \
|
||||
} while (0)
|
||||
#define btrfs_debug_rl_in_rcu(fs_info, fmt, args...) \
|
||||
do { \
|
||||
DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
|
||||
if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)) \
|
||||
btrfs_printk_rl_in_rcu(fs_info, KERN_DEBUG fmt, \
|
||||
##args);\
|
||||
} while (0)
|
||||
#define btrfs_debug_rl(fs_info, fmt, args...) \
|
||||
do { \
|
||||
DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
|
||||
if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)) \
|
||||
btrfs_printk_ratelimited(fs_info, KERN_DEBUG fmt, \
|
||||
##args); \
|
||||
} while (0)
|
||||
#elif defined(DEBUG)
|
||||
#define btrfs_debug(fs_info, fmt, args...) \
|
||||
btrfs_printk(fs_info, KERN_DEBUG fmt, ##args)
|
||||
#define btrfs_debug_in_rcu(fs_info, fmt, args...) \
|
||||
@@ -3325,13 +3375,13 @@ void btrfs_printk(const struct btrfs_fs_info *fs_info, const char *fmt, ...)
|
||||
btrfs_printk_ratelimited(fs_info, KERN_DEBUG fmt, ##args)
|
||||
#else
|
||||
#define btrfs_debug(fs_info, fmt, args...) \
|
||||
no_printk(KERN_DEBUG fmt, ##args)
|
||||
btrfs_no_printk(fs_info, KERN_DEBUG fmt, ##args)
|
||||
#define btrfs_debug_in_rcu(fs_info, fmt, args...) \
|
||||
no_printk(KERN_DEBUG fmt, ##args)
|
||||
btrfs_no_printk(fs_info, KERN_DEBUG fmt, ##args)
|
||||
#define btrfs_debug_rl_in_rcu(fs_info, fmt, args...) \
|
||||
no_printk(KERN_DEBUG fmt, ##args)
|
||||
btrfs_no_printk(fs_info, KERN_DEBUG fmt, ##args)
|
||||
#define btrfs_debug_rl(fs_info, fmt, args...) \
|
||||
no_printk(KERN_DEBUG fmt, ##args)
|
||||
btrfs_no_printk(fs_info, KERN_DEBUG fmt, ##args)
|
||||
#endif
|
||||
|
||||
#define btrfs_printk_in_rcu(fs_info, fmt, args...) \
|
||||
@@ -3362,7 +3412,7 @@ do { \
|
||||
__cold
|
||||
static inline void assfail(char *expr, char *file, int line)
|
||||
{
|
||||
pr_err("BTRFS: assertion failed: %s, file: %s, line: %d",
|
||||
pr_err("assertion failed: %s, file: %s, line: %d\n",
|
||||
expr, file, line);
|
||||
BUG();
|
||||
}
|
||||
|
||||
+10
-15
@@ -385,11 +385,8 @@ static struct btrfs_delayed_item *__btrfs_lookup_delayed_insertion_item(
|
||||
struct btrfs_delayed_node *delayed_node,
|
||||
struct btrfs_key *key)
|
||||
{
|
||||
struct btrfs_delayed_item *item;
|
||||
|
||||
item = __btrfs_lookup_delayed_item(&delayed_node->ins_root, key,
|
||||
return __btrfs_lookup_delayed_item(&delayed_node->ins_root, key,
|
||||
NULL, NULL);
|
||||
return item;
|
||||
}
|
||||
|
||||
static int __btrfs_add_delayed_item(struct btrfs_delayed_node *delayed_node,
|
||||
@@ -1481,11 +1478,10 @@ int btrfs_insert_delayed_dir_index(struct btrfs_trans_handle *trans,
|
||||
mutex_lock(&delayed_node->mutex);
|
||||
ret = __btrfs_add_delayed_insertion_item(delayed_node, delayed_item);
|
||||
if (unlikely(ret)) {
|
||||
btrfs_err(root->fs_info, "err add delayed dir index item(name: %.*s) "
|
||||
"into the insertion tree of the delayed node"
|
||||
"(root id: %llu, inode id: %llu, errno: %d)",
|
||||
name_len, name, delayed_node->root->objectid,
|
||||
delayed_node->inode_id, ret);
|
||||
btrfs_err(root->fs_info,
|
||||
"err add delayed dir index item(name: %.*s) into the insertion tree of the delayed node(root id: %llu, inode id: %llu, errno: %d)",
|
||||
name_len, name, delayed_node->root->objectid,
|
||||
delayed_node->inode_id, ret);
|
||||
BUG();
|
||||
}
|
||||
mutex_unlock(&delayed_node->mutex);
|
||||
@@ -1553,11 +1549,9 @@ int btrfs_delete_delayed_dir_index(struct btrfs_trans_handle *trans,
|
||||
mutex_lock(&node->mutex);
|
||||
ret = __btrfs_add_delayed_deletion_item(node, item);
|
||||
if (unlikely(ret)) {
|
||||
btrfs_err(root->fs_info, "err add delayed dir index item(index: %llu) "
|
||||
"into the deletion tree of the delayed node"
|
||||
"(root id: %llu, inode id: %llu, errno: %d)",
|
||||
index, node->root->objectid, node->inode_id,
|
||||
ret);
|
||||
btrfs_err(root->fs_info,
|
||||
"err add delayed dir index item(index: %llu) into the deletion tree of the delayed node(root id: %llu, inode id: %llu, errno: %d)",
|
||||
index, node->root->objectid, node->inode_id, ret);
|
||||
BUG();
|
||||
}
|
||||
mutex_unlock(&node->mutex);
|
||||
@@ -1874,7 +1868,8 @@ int btrfs_delayed_delete_inode_ref(struct inode *inode)
|
||||
* leads to enospc problems. This means we also can't do
|
||||
* delayed inode refs
|
||||
*/
|
||||
if (BTRFS_I(inode)->root->fs_info->log_root_recovering)
|
||||
if (test_bit(BTRFS_FS_LOG_RECOVERING,
|
||||
&BTRFS_I(inode)->root->fs_info->flags))
|
||||
return -EAGAIN;
|
||||
|
||||
delayed_node = btrfs_get_or_create_delayed_node(inode);
|
||||
|
||||
@@ -322,10 +322,11 @@ int btrfs_check_delayed_seq(struct btrfs_fs_info *fs_info,
|
||||
elem = list_first_entry(&fs_info->tree_mod_seq_list,
|
||||
struct seq_list, list);
|
||||
if (seq >= elem->seq) {
|
||||
pr_debug("holding back delayed_ref %#x.%x, lowest is %#x.%x (%p)\n",
|
||||
(u32)(seq >> 32), (u32)seq,
|
||||
(u32)(elem->seq >> 32), (u32)elem->seq,
|
||||
delayed_refs);
|
||||
btrfs_debug(fs_info,
|
||||
"holding back delayed_ref %#x.%x, lowest is %#x.%x (%p)",
|
||||
(u32)(seq >> 32), (u32)seq,
|
||||
(u32)(elem->seq >> 32), (u32)elem->seq,
|
||||
delayed_refs);
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
@@ -770,7 +771,8 @@ int btrfs_add_delayed_tree_ref(struct btrfs_fs_info *fs_info,
|
||||
if (!head_ref)
|
||||
goto free_ref;
|
||||
|
||||
if (fs_info->quota_enabled && is_fstree(ref_root)) {
|
||||
if (test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags) &&
|
||||
is_fstree(ref_root)) {
|
||||
record = kmalloc(sizeof(*record), GFP_NOFS);
|
||||
if (!record)
|
||||
goto free_head_ref;
|
||||
@@ -828,7 +830,8 @@ int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info,
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (fs_info->quota_enabled && is_fstree(ref_root)) {
|
||||
if (test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags) &&
|
||||
is_fstree(ref_root)) {
|
||||
record = kmalloc(sizeof(*record), GFP_NOFS);
|
||||
if (!record) {
|
||||
kmem_cache_free(btrfs_delayed_data_ref_cachep, ref);
|
||||
|
||||
+12
-9
@@ -218,8 +218,9 @@ int btrfs_run_dev_replace(struct btrfs_trans_handle *trans,
|
||||
}
|
||||
ret = btrfs_search_slot(trans, dev_root, &key, path, -1, 1);
|
||||
if (ret < 0) {
|
||||
btrfs_warn(fs_info, "error %d while searching for dev_replace item!",
|
||||
ret);
|
||||
btrfs_warn(fs_info,
|
||||
"error %d while searching for dev_replace item!",
|
||||
ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -238,8 +239,9 @@ int btrfs_run_dev_replace(struct btrfs_trans_handle *trans,
|
||||
*/
|
||||
ret = btrfs_del_item(trans, dev_root, path);
|
||||
if (ret != 0) {
|
||||
btrfs_warn(fs_info, "delete too small dev_replace item failed %d!",
|
||||
ret);
|
||||
btrfs_warn(fs_info,
|
||||
"delete too small dev_replace item failed %d!",
|
||||
ret);
|
||||
goto out;
|
||||
}
|
||||
ret = 1;
|
||||
@@ -251,8 +253,8 @@ int btrfs_run_dev_replace(struct btrfs_trans_handle *trans,
|
||||
ret = btrfs_insert_empty_item(trans, dev_root, path,
|
||||
&key, sizeof(*ptr));
|
||||
if (ret < 0) {
|
||||
btrfs_warn(fs_info, "insert dev_replace item failed %d!",
|
||||
ret);
|
||||
btrfs_warn(fs_info,
|
||||
"insert dev_replace item failed %d!", ret);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
@@ -383,7 +385,7 @@ int btrfs_dev_replace_start(struct btrfs_root *root, char *tgtdev_name,
|
||||
|
||||
ret = btrfs_sysfs_add_device_link(tgt_device->fs_devices, tgt_device);
|
||||
if (ret)
|
||||
btrfs_err(fs_info, "kobj add dev failed %d\n", ret);
|
||||
btrfs_err(fs_info, "kobj add dev failed %d", ret);
|
||||
|
||||
btrfs_wait_ordered_roots(root->fs_info, -1, 0, (u64)-1);
|
||||
|
||||
@@ -772,9 +774,10 @@ int btrfs_resume_dev_replace_async(struct btrfs_fs_info *fs_info)
|
||||
break;
|
||||
}
|
||||
if (!dev_replace->tgtdev || !dev_replace->tgtdev->bdev) {
|
||||
btrfs_info(fs_info, "cannot continue dev_replace, tgtdev is missing");
|
||||
btrfs_info(fs_info,
|
||||
"you may cancel the operation after 'mount -o degraded'");
|
||||
"cannot continue dev_replace, tgtdev is missing");
|
||||
btrfs_info(fs_info,
|
||||
"you may cancel the operation after 'mount -o degraded'");
|
||||
btrfs_dev_replace_unlock(dev_replace, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
+4
-3
@@ -472,9 +472,10 @@ int verify_dir_item(struct btrfs_root *root,
|
||||
/* BTRFS_MAX_XATTR_SIZE is the same for all dir items */
|
||||
if ((btrfs_dir_data_len(leaf, dir_item) +
|
||||
btrfs_dir_name_len(leaf, dir_item)) > BTRFS_MAX_XATTR_SIZE(root)) {
|
||||
btrfs_crit(root->fs_info, "invalid dir item name + data len: %u + %u",
|
||||
(unsigned)btrfs_dir_name_len(leaf, dir_item),
|
||||
(unsigned)btrfs_dir_data_len(leaf, dir_item));
|
||||
btrfs_crit(root->fs_info,
|
||||
"invalid dir item name + data len: %u + %u",
|
||||
(unsigned)btrfs_dir_name_len(leaf, dir_item),
|
||||
(unsigned)btrfs_dir_data_len(leaf, dir_item));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
+163
-74
@@ -326,8 +326,7 @@ static int csum_tree_block(struct btrfs_fs_info *fs_info,
|
||||
|
||||
read_extent_buffer(buf, &val, 0, csum_size);
|
||||
btrfs_warn_rl(fs_info,
|
||||
"%s checksum verify failed on %llu wanted %X found %X "
|
||||
"level %d",
|
||||
"%s checksum verify failed on %llu wanted %X found %X level %d",
|
||||
fs_info->sb->s_id, buf->start,
|
||||
val, found, btrfs_header_level(buf));
|
||||
if (result != (char *)&inline_result)
|
||||
@@ -402,7 +401,8 @@ out:
|
||||
* Return 0 if the superblock checksum type matches the checksum value of that
|
||||
* algorithm. Pass the raw disk superblock data.
|
||||
*/
|
||||
static int btrfs_check_super_csum(char *raw_disk_sb)
|
||||
static int btrfs_check_super_csum(struct btrfs_fs_info *fs_info,
|
||||
char *raw_disk_sb)
|
||||
{
|
||||
struct btrfs_super_block *disk_sb =
|
||||
(struct btrfs_super_block *)raw_disk_sb;
|
||||
@@ -428,7 +428,7 @@ static int btrfs_check_super_csum(char *raw_disk_sb)
|
||||
}
|
||||
|
||||
if (csum_type >= ARRAY_SIZE(btrfs_csum_sizes)) {
|
||||
printk(KERN_ERR "BTRFS: unsupported checksum algorithm %u\n",
|
||||
btrfs_err(fs_info, "unsupported checksum algorithm %u",
|
||||
csum_type);
|
||||
ret = 1;
|
||||
}
|
||||
@@ -442,7 +442,7 @@ static int btrfs_check_super_csum(char *raw_disk_sb)
|
||||
*/
|
||||
static int btree_read_extent_buffer_pages(struct btrfs_root *root,
|
||||
struct extent_buffer *eb,
|
||||
u64 start, u64 parent_transid)
|
||||
u64 parent_transid)
|
||||
{
|
||||
struct extent_io_tree *io_tree;
|
||||
int failed = 0;
|
||||
@@ -454,8 +454,7 @@ static int btree_read_extent_buffer_pages(struct btrfs_root *root,
|
||||
clear_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags);
|
||||
io_tree = &BTRFS_I(root->fs_info->btree_inode)->io_tree;
|
||||
while (1) {
|
||||
ret = read_extent_buffer_pages(io_tree, eb, start,
|
||||
WAIT_COMPLETE,
|
||||
ret = read_extent_buffer_pages(io_tree, eb, WAIT_COMPLETE,
|
||||
btree_get_extent, mirror_num);
|
||||
if (!ret) {
|
||||
if (!verify_parent_transid(io_tree, eb,
|
||||
@@ -547,9 +546,10 @@ static int check_tree_block_fsid(struct btrfs_fs_info *fs_info,
|
||||
}
|
||||
|
||||
#define CORRUPT(reason, eb, root, slot) \
|
||||
btrfs_crit(root->fs_info, "corrupt leaf, %s: block=%llu," \
|
||||
"root=%llu, slot=%d", reason, \
|
||||
btrfs_header_bytenr(eb), root->objectid, slot)
|
||||
btrfs_crit(root->fs_info, "corrupt %s, %s: block=%llu," \
|
||||
" root=%llu, slot=%d", \
|
||||
btrfs_header_level(eb) == 0 ? "leaf" : "node",\
|
||||
reason, btrfs_header_bytenr(eb), root->objectid, slot)
|
||||
|
||||
static noinline int check_leaf(struct btrfs_root *root,
|
||||
struct extent_buffer *leaf)
|
||||
@@ -636,6 +636,10 @@ static noinline int check_leaf(struct btrfs_root *root,
|
||||
static int check_node(struct btrfs_root *root, struct extent_buffer *node)
|
||||
{
|
||||
unsigned long nr = btrfs_header_nritems(node);
|
||||
struct btrfs_key key, next_key;
|
||||
int slot;
|
||||
u64 bytenr;
|
||||
int ret = 0;
|
||||
|
||||
if (nr == 0 || nr > BTRFS_NODEPTRS_PER_BLOCK(root)) {
|
||||
btrfs_crit(root->fs_info,
|
||||
@@ -643,7 +647,26 @@ static int check_node(struct btrfs_root *root, struct extent_buffer *node)
|
||||
node->start, root->objectid, nr);
|
||||
return -EIO;
|
||||
}
|
||||
return 0;
|
||||
|
||||
for (slot = 0; slot < nr - 1; slot++) {
|
||||
bytenr = btrfs_node_blockptr(node, slot);
|
||||
btrfs_node_key_to_cpu(node, &key, slot);
|
||||
btrfs_node_key_to_cpu(node, &next_key, slot + 1);
|
||||
|
||||
if (!bytenr) {
|
||||
CORRUPT("invalid item slot", node, root, slot);
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (btrfs_comp_cpu_keys(&key, &next_key) >= 0) {
|
||||
CORRUPT("bad key order", node, root, slot);
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int btree_readpage_end_io_hook(struct btrfs_io_bio *io_bio,
|
||||
@@ -1132,7 +1155,7 @@ void readahead_tree_block(struct btrfs_root *root, u64 bytenr)
|
||||
if (IS_ERR(buf))
|
||||
return;
|
||||
read_extent_buffer_pages(&BTRFS_I(btree_inode)->io_tree,
|
||||
buf, 0, WAIT_NONE, btree_get_extent, 0);
|
||||
buf, WAIT_NONE, btree_get_extent, 0);
|
||||
free_extent_buffer(buf);
|
||||
}
|
||||
|
||||
@@ -1150,7 +1173,7 @@ int reada_tree_block_flagged(struct btrfs_root *root, u64 bytenr,
|
||||
|
||||
set_bit(EXTENT_BUFFER_READAHEAD, &buf->bflags);
|
||||
|
||||
ret = read_extent_buffer_pages(io_tree, buf, 0, WAIT_PAGE_LOCK,
|
||||
ret = read_extent_buffer_pages(io_tree, buf, WAIT_PAGE_LOCK,
|
||||
btree_get_extent, mirror_num);
|
||||
if (ret) {
|
||||
free_extent_buffer(buf);
|
||||
@@ -1206,7 +1229,7 @@ struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr,
|
||||
if (IS_ERR(buf))
|
||||
return buf;
|
||||
|
||||
ret = btree_read_extent_buffer_pages(root, buf, 0, parent_transid);
|
||||
ret = btree_read_extent_buffer_pages(root, buf, parent_transid);
|
||||
if (ret) {
|
||||
free_extent_buffer(buf);
|
||||
return ERR_PTR(ret);
|
||||
@@ -1839,7 +1862,7 @@ static int cleaner_kthread(void *arg)
|
||||
* Do not do anything if we might cause open_ctree() to block
|
||||
* before we have finished mounting the filesystem.
|
||||
*/
|
||||
if (!root->fs_info->open)
|
||||
if (!test_bit(BTRFS_FS_OPEN, &root->fs_info->flags))
|
||||
goto sleep;
|
||||
|
||||
if (!mutex_trylock(&root->fs_info->cleaner_mutex))
|
||||
@@ -2332,8 +2355,6 @@ static void btrfs_init_qgroup(struct btrfs_fs_info *fs_info)
|
||||
fs_info->qgroup_op_tree = RB_ROOT;
|
||||
INIT_LIST_HEAD(&fs_info->dirty_qgroups);
|
||||
fs_info->qgroup_seq = 1;
|
||||
fs_info->quota_enabled = 0;
|
||||
fs_info->pending_quota_state = 0;
|
||||
fs_info->qgroup_ulist = NULL;
|
||||
fs_info->qgroup_rescan_running = false;
|
||||
mutex_init(&fs_info->qgroup_rescan_lock);
|
||||
@@ -2518,8 +2539,7 @@ static int btrfs_read_roots(struct btrfs_fs_info *fs_info,
|
||||
root = btrfs_read_tree_root(tree_root, &location);
|
||||
if (!IS_ERR(root)) {
|
||||
set_bit(BTRFS_ROOT_TRACK_DIRTY, &root->state);
|
||||
fs_info->quota_enabled = 1;
|
||||
fs_info->pending_quota_state = 1;
|
||||
set_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags);
|
||||
fs_info->quota_root = root;
|
||||
}
|
||||
|
||||
@@ -2710,8 +2730,7 @@ int open_ctree(struct super_block *sb,
|
||||
extent_io_tree_init(&fs_info->freed_extents[1],
|
||||
fs_info->btree_inode->i_mapping);
|
||||
fs_info->pinned_extents = &fs_info->freed_extents[0];
|
||||
fs_info->do_barriers = 1;
|
||||
|
||||
set_bit(BTRFS_FS_BARRIER, &fs_info->flags);
|
||||
|
||||
mutex_init(&fs_info->ordered_operations_mutex);
|
||||
mutex_init(&fs_info->tree_log_mutex);
|
||||
@@ -2762,7 +2781,7 @@ int open_ctree(struct super_block *sb,
|
||||
* We want to check superblock checksum, the type is stored inside.
|
||||
* Pass the whole disk block of size BTRFS_SUPER_INFO_SIZE (4k).
|
||||
*/
|
||||
if (btrfs_check_super_csum(bh->b_data)) {
|
||||
if (btrfs_check_super_csum(fs_info, bh->b_data)) {
|
||||
btrfs_err(fs_info, "superblock checksum mismatch");
|
||||
err = -EINVAL;
|
||||
brelse(bh);
|
||||
@@ -3199,10 +3218,9 @@ retry_root_backup:
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
fs_info->update_uuid_tree_gen = 1;
|
||||
set_bit(BTRFS_FS_UPDATE_UUID_TREE_GEN, &fs_info->flags);
|
||||
}
|
||||
|
||||
fs_info->open = 1;
|
||||
set_bit(BTRFS_FS_OPEN, &fs_info->flags);
|
||||
|
||||
/*
|
||||
* backuproot only affect mount behavior, and if open_ctree succeeded,
|
||||
@@ -3607,7 +3625,7 @@ int btrfs_get_num_tolerated_disk_barrier_failures(u64 flags)
|
||||
}
|
||||
|
||||
if (min_tolerated == INT_MAX) {
|
||||
pr_warn("BTRFS: unknown raid flag: %llu\n", flags);
|
||||
pr_warn("BTRFS: unknown raid flag: %llu", flags);
|
||||
min_tolerated = 0;
|
||||
}
|
||||
|
||||
@@ -3893,8 +3911,7 @@ void close_ctree(struct btrfs_root *root)
|
||||
struct btrfs_fs_info *fs_info = root->fs_info;
|
||||
int ret;
|
||||
|
||||
fs_info->closing = 1;
|
||||
smp_mb();
|
||||
set_bit(BTRFS_FS_CLOSING_START, &fs_info->flags);
|
||||
|
||||
/* wait for the qgroup rescan worker to stop */
|
||||
btrfs_qgroup_wait_for_completion(fs_info, false);
|
||||
@@ -3939,8 +3956,7 @@ void close_ctree(struct btrfs_root *root)
|
||||
kthread_stop(fs_info->transaction_kthread);
|
||||
kthread_stop(fs_info->cleaner_kthread);
|
||||
|
||||
fs_info->closing = 2;
|
||||
smp_mb();
|
||||
set_bit(BTRFS_FS_CLOSING_DONE, &fs_info->flags);
|
||||
|
||||
btrfs_free_qgroup_config(fs_info);
|
||||
|
||||
@@ -3965,7 +3981,7 @@ void close_ctree(struct btrfs_root *root)
|
||||
invalidate_inode_pages2(fs_info->btree_inode->i_mapping);
|
||||
btrfs_stop_all_workers(fs_info);
|
||||
|
||||
fs_info->open = 0;
|
||||
clear_bit(BTRFS_FS_OPEN, &fs_info->flags);
|
||||
free_root_pointers(fs_info, 1);
|
||||
|
||||
iput(fs_info->btree_inode);
|
||||
@@ -4036,8 +4052,7 @@ void btrfs_mark_buffer_dirty(struct extent_buffer *buf)
|
||||
root = BTRFS_I(buf->pages[0]->mapping->host)->root;
|
||||
btrfs_assert_tree_locked(buf);
|
||||
if (transid != root->fs_info->generation)
|
||||
WARN(1, KERN_CRIT "btrfs transid mismatch buffer %llu, "
|
||||
"found %llu running %llu\n",
|
||||
WARN(1, KERN_CRIT "btrfs transid mismatch buffer %llu, found %llu running %llu\n",
|
||||
buf->start, transid, root->fs_info->generation);
|
||||
was_dirty = set_extent_buffer_dirty(buf);
|
||||
if (!was_dirty)
|
||||
@@ -4088,7 +4103,7 @@ void btrfs_btree_balance_dirty_nodelay(struct btrfs_root *root)
|
||||
int btrfs_read_buffer(struct extent_buffer *buf, u64 parent_transid)
|
||||
{
|
||||
struct btrfs_root *root = BTRFS_I(buf->pages[0]->mapping->host)->root;
|
||||
return btree_read_extent_buffer_pages(root, buf, 0, parent_transid);
|
||||
return btree_read_extent_buffer_pages(root, buf, parent_transid);
|
||||
}
|
||||
|
||||
static int btrfs_check_super_valid(struct btrfs_fs_info *fs_info,
|
||||
@@ -4100,24 +4115,24 @@ static int btrfs_check_super_valid(struct btrfs_fs_info *fs_info,
|
||||
int ret = 0;
|
||||
|
||||
if (btrfs_super_magic(sb) != BTRFS_MAGIC) {
|
||||
printk(KERN_ERR "BTRFS: no valid FS found\n");
|
||||
btrfs_err(fs_info, "no valid FS found");
|
||||
ret = -EINVAL;
|
||||
}
|
||||
if (btrfs_super_flags(sb) & ~BTRFS_SUPER_FLAG_SUPP)
|
||||
printk(KERN_WARNING "BTRFS: unrecognized super flag: %llu\n",
|
||||
btrfs_warn(fs_info, "unrecognized super flag: %llu",
|
||||
btrfs_super_flags(sb) & ~BTRFS_SUPER_FLAG_SUPP);
|
||||
if (btrfs_super_root_level(sb) >= BTRFS_MAX_LEVEL) {
|
||||
printk(KERN_ERR "BTRFS: tree_root level too big: %d >= %d\n",
|
||||
btrfs_err(fs_info, "tree_root level too big: %d >= %d",
|
||||
btrfs_super_root_level(sb), BTRFS_MAX_LEVEL);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
if (btrfs_super_chunk_root_level(sb) >= BTRFS_MAX_LEVEL) {
|
||||
printk(KERN_ERR "BTRFS: chunk_root level too big: %d >= %d\n",
|
||||
btrfs_err(fs_info, "chunk_root level too big: %d >= %d",
|
||||
btrfs_super_chunk_root_level(sb), BTRFS_MAX_LEVEL);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
if (btrfs_super_log_root_level(sb) >= BTRFS_MAX_LEVEL) {
|
||||
printk(KERN_ERR "BTRFS: log_root level too big: %d >= %d\n",
|
||||
btrfs_err(fs_info, "log_root level too big: %d >= %d",
|
||||
btrfs_super_log_root_level(sb), BTRFS_MAX_LEVEL);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
@@ -4128,47 +4143,48 @@ static int btrfs_check_super_valid(struct btrfs_fs_info *fs_info,
|
||||
*/
|
||||
if (!is_power_of_2(sectorsize) || sectorsize < 4096 ||
|
||||
sectorsize > BTRFS_MAX_METADATA_BLOCKSIZE) {
|
||||
printk(KERN_ERR "BTRFS: invalid sectorsize %llu\n", sectorsize);
|
||||
btrfs_err(fs_info, "invalid sectorsize %llu", sectorsize);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
/* Only PAGE SIZE is supported yet */
|
||||
if (sectorsize != PAGE_SIZE) {
|
||||
printk(KERN_ERR "BTRFS: sectorsize %llu not supported yet, only support %lu\n",
|
||||
sectorsize, PAGE_SIZE);
|
||||
btrfs_err(fs_info,
|
||||
"sectorsize %llu not supported yet, only support %lu",
|
||||
sectorsize, PAGE_SIZE);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
if (!is_power_of_2(nodesize) || nodesize < sectorsize ||
|
||||
nodesize > BTRFS_MAX_METADATA_BLOCKSIZE) {
|
||||
printk(KERN_ERR "BTRFS: invalid nodesize %llu\n", nodesize);
|
||||
btrfs_err(fs_info, "invalid nodesize %llu", nodesize);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
if (nodesize != le32_to_cpu(sb->__unused_leafsize)) {
|
||||
printk(KERN_ERR "BTRFS: invalid leafsize %u, should be %llu\n",
|
||||
le32_to_cpu(sb->__unused_leafsize),
|
||||
nodesize);
|
||||
btrfs_err(fs_info, "invalid leafsize %u, should be %llu",
|
||||
le32_to_cpu(sb->__unused_leafsize), nodesize);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
/* Root alignment check */
|
||||
if (!IS_ALIGNED(btrfs_super_root(sb), sectorsize)) {
|
||||
printk(KERN_WARNING "BTRFS: tree_root block unaligned: %llu\n",
|
||||
btrfs_super_root(sb));
|
||||
btrfs_warn(fs_info, "tree_root block unaligned: %llu",
|
||||
btrfs_super_root(sb));
|
||||
ret = -EINVAL;
|
||||
}
|
||||
if (!IS_ALIGNED(btrfs_super_chunk_root(sb), sectorsize)) {
|
||||
printk(KERN_WARNING "BTRFS: chunk_root block unaligned: %llu\n",
|
||||
btrfs_super_chunk_root(sb));
|
||||
btrfs_warn(fs_info, "chunk_root block unaligned: %llu",
|
||||
btrfs_super_chunk_root(sb));
|
||||
ret = -EINVAL;
|
||||
}
|
||||
if (!IS_ALIGNED(btrfs_super_log_root(sb), sectorsize)) {
|
||||
printk(KERN_WARNING "BTRFS: log_root block unaligned: %llu\n",
|
||||
btrfs_super_log_root(sb));
|
||||
btrfs_warn(fs_info, "log_root block unaligned: %llu",
|
||||
btrfs_super_log_root(sb));
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
if (memcmp(fs_info->fsid, sb->dev_item.fsid, BTRFS_UUID_SIZE) != 0) {
|
||||
printk(KERN_ERR "BTRFS: dev_item UUID does not match fsid: %pU != %pU\n",
|
||||
fs_info->fsid, sb->dev_item.fsid);
|
||||
btrfs_err(fs_info,
|
||||
"dev_item UUID does not match fsid: %pU != %pU",
|
||||
fs_info->fsid, sb->dev_item.fsid);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
@@ -4178,25 +4194,25 @@ static int btrfs_check_super_valid(struct btrfs_fs_info *fs_info,
|
||||
*/
|
||||
if (btrfs_super_bytes_used(sb) < 6 * btrfs_super_nodesize(sb)) {
|
||||
btrfs_err(fs_info, "bytes_used is too small %llu",
|
||||
btrfs_super_bytes_used(sb));
|
||||
btrfs_super_bytes_used(sb));
|
||||
ret = -EINVAL;
|
||||
}
|
||||
if (!is_power_of_2(btrfs_super_stripesize(sb))) {
|
||||
btrfs_err(fs_info, "invalid stripesize %u",
|
||||
btrfs_super_stripesize(sb));
|
||||
btrfs_super_stripesize(sb));
|
||||
ret = -EINVAL;
|
||||
}
|
||||
if (btrfs_super_num_devices(sb) > (1UL << 31))
|
||||
printk(KERN_WARNING "BTRFS: suspicious number of devices: %llu\n",
|
||||
btrfs_super_num_devices(sb));
|
||||
btrfs_warn(fs_info, "suspicious number of devices: %llu",
|
||||
btrfs_super_num_devices(sb));
|
||||
if (btrfs_super_num_devices(sb) == 0) {
|
||||
printk(KERN_ERR "BTRFS: number of devices is 0\n");
|
||||
btrfs_err(fs_info, "number of devices is 0");
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
if (btrfs_super_bytenr(sb) != BTRFS_SUPER_INFO_OFFSET) {
|
||||
printk(KERN_ERR "BTRFS: super offset mismatch %llu != %u\n",
|
||||
btrfs_super_bytenr(sb), BTRFS_SUPER_INFO_OFFSET);
|
||||
btrfs_err(fs_info, "super offset mismatch %llu != %u",
|
||||
btrfs_super_bytenr(sb), BTRFS_SUPER_INFO_OFFSET);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
@@ -4205,17 +4221,17 @@ static int btrfs_check_super_valid(struct btrfs_fs_info *fs_info,
|
||||
* and one chunk
|
||||
*/
|
||||
if (btrfs_super_sys_array_size(sb) > BTRFS_SYSTEM_CHUNK_ARRAY_SIZE) {
|
||||
printk(KERN_ERR "BTRFS: system chunk array too big %u > %u\n",
|
||||
btrfs_super_sys_array_size(sb),
|
||||
BTRFS_SYSTEM_CHUNK_ARRAY_SIZE);
|
||||
btrfs_err(fs_info, "system chunk array too big %u > %u",
|
||||
btrfs_super_sys_array_size(sb),
|
||||
BTRFS_SYSTEM_CHUNK_ARRAY_SIZE);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
if (btrfs_super_sys_array_size(sb) < sizeof(struct btrfs_disk_key)
|
||||
+ sizeof(struct btrfs_chunk)) {
|
||||
printk(KERN_ERR "BTRFS: system chunk array too small %u < %zu\n",
|
||||
btrfs_super_sys_array_size(sb),
|
||||
sizeof(struct btrfs_disk_key)
|
||||
+ sizeof(struct btrfs_chunk));
|
||||
btrfs_err(fs_info, "system chunk array too small %u < %zu",
|
||||
btrfs_super_sys_array_size(sb),
|
||||
sizeof(struct btrfs_disk_key)
|
||||
+ sizeof(struct btrfs_chunk));
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
@@ -4224,14 +4240,16 @@ static int btrfs_check_super_valid(struct btrfs_fs_info *fs_info,
|
||||
* but it's still possible that it's the one that's wrong.
|
||||
*/
|
||||
if (btrfs_super_generation(sb) < btrfs_super_chunk_root_generation(sb))
|
||||
printk(KERN_WARNING
|
||||
"BTRFS: suspicious: generation < chunk_root_generation: %llu < %llu\n",
|
||||
btrfs_super_generation(sb), btrfs_super_chunk_root_generation(sb));
|
||||
btrfs_warn(fs_info,
|
||||
"suspicious: generation < chunk_root_generation: %llu < %llu",
|
||||
btrfs_super_generation(sb),
|
||||
btrfs_super_chunk_root_generation(sb));
|
||||
if (btrfs_super_generation(sb) < btrfs_super_cache_generation(sb)
|
||||
&& btrfs_super_cache_generation(sb) != (u64)-1)
|
||||
printk(KERN_WARNING
|
||||
"BTRFS: suspicious: generation < cache_generation: %llu < %llu\n",
|
||||
btrfs_super_generation(sb), btrfs_super_cache_generation(sb));
|
||||
btrfs_warn(fs_info,
|
||||
"suspicious: generation < cache_generation: %llu < %llu",
|
||||
btrfs_super_generation(sb),
|
||||
btrfs_super_cache_generation(sb));
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -4475,9 +4493,80 @@ again:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void btrfs_cleanup_bg_io(struct btrfs_block_group_cache *cache)
|
||||
{
|
||||
struct inode *inode;
|
||||
|
||||
inode = cache->io_ctl.inode;
|
||||
if (inode) {
|
||||
invalidate_inode_pages2(inode->i_mapping);
|
||||
BTRFS_I(inode)->generation = 0;
|
||||
cache->io_ctl.inode = NULL;
|
||||
iput(inode);
|
||||
}
|
||||
btrfs_put_block_group(cache);
|
||||
}
|
||||
|
||||
void btrfs_cleanup_dirty_bgs(struct btrfs_transaction *cur_trans,
|
||||
struct btrfs_root *root)
|
||||
{
|
||||
struct btrfs_block_group_cache *cache;
|
||||
|
||||
spin_lock(&cur_trans->dirty_bgs_lock);
|
||||
while (!list_empty(&cur_trans->dirty_bgs)) {
|
||||
cache = list_first_entry(&cur_trans->dirty_bgs,
|
||||
struct btrfs_block_group_cache,
|
||||
dirty_list);
|
||||
if (!cache) {
|
||||
btrfs_err(root->fs_info,
|
||||
"orphan block group dirty_bgs list");
|
||||
spin_unlock(&cur_trans->dirty_bgs_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!list_empty(&cache->io_list)) {
|
||||
spin_unlock(&cur_trans->dirty_bgs_lock);
|
||||
list_del_init(&cache->io_list);
|
||||
btrfs_cleanup_bg_io(cache);
|
||||
spin_lock(&cur_trans->dirty_bgs_lock);
|
||||
}
|
||||
|
||||
list_del_init(&cache->dirty_list);
|
||||
spin_lock(&cache->lock);
|
||||
cache->disk_cache_state = BTRFS_DC_ERROR;
|
||||
spin_unlock(&cache->lock);
|
||||
|
||||
spin_unlock(&cur_trans->dirty_bgs_lock);
|
||||
btrfs_put_block_group(cache);
|
||||
spin_lock(&cur_trans->dirty_bgs_lock);
|
||||
}
|
||||
spin_unlock(&cur_trans->dirty_bgs_lock);
|
||||
|
||||
while (!list_empty(&cur_trans->io_bgs)) {
|
||||
cache = list_first_entry(&cur_trans->io_bgs,
|
||||
struct btrfs_block_group_cache,
|
||||
io_list);
|
||||
if (!cache) {
|
||||
btrfs_err(root->fs_info,
|
||||
"orphan block group on io_bgs list");
|
||||
return;
|
||||
}
|
||||
|
||||
list_del_init(&cache->io_list);
|
||||
spin_lock(&cache->lock);
|
||||
cache->disk_cache_state = BTRFS_DC_ERROR;
|
||||
spin_unlock(&cache->lock);
|
||||
btrfs_cleanup_bg_io(cache);
|
||||
}
|
||||
}
|
||||
|
||||
void btrfs_cleanup_one_transaction(struct btrfs_transaction *cur_trans,
|
||||
struct btrfs_root *root)
|
||||
{
|
||||
btrfs_cleanup_dirty_bgs(cur_trans, root);
|
||||
ASSERT(list_empty(&cur_trans->dirty_bgs));
|
||||
ASSERT(list_empty(&cur_trans->io_bgs));
|
||||
|
||||
btrfs_destroy_delayed_refs(cur_trans, root);
|
||||
|
||||
cur_trans->state = TRANS_STATE_COMMIT_START;
|
||||
|
||||
@@ -136,6 +136,8 @@ int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_fs_info *fs_info);
|
||||
int btrfs_add_log_tree(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root);
|
||||
void btrfs_cleanup_dirty_bgs(struct btrfs_transaction *trans,
|
||||
struct btrfs_root *root);
|
||||
void btrfs_cleanup_one_transaction(struct btrfs_transaction *trans,
|
||||
struct btrfs_root *root);
|
||||
struct btrfs_root *btrfs_create_tree(struct btrfs_trans_handle *trans,
|
||||
|
||||
+115
-83
@@ -87,7 +87,8 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans,
|
||||
int force);
|
||||
static int find_next_key(struct btrfs_path *path, int level,
|
||||
struct btrfs_key *key);
|
||||
static void dump_space_info(struct btrfs_space_info *info, u64 bytes,
|
||||
static void dump_space_info(struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_space_info *info, u64 bytes,
|
||||
int dump_block_groups);
|
||||
static int btrfs_add_reserved_bytes(struct btrfs_block_group_cache *cache,
|
||||
u64 ram_bytes, u64 num_bytes, int delalloc);
|
||||
@@ -266,9 +267,8 @@ static int exclude_super_stripes(struct btrfs_root *root,
|
||||
|
||||
for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) {
|
||||
bytenr = btrfs_sb_offset(i);
|
||||
ret = btrfs_rmap_block(&root->fs_info->mapping_tree,
|
||||
cache->key.objectid, bytenr,
|
||||
0, &logical, &nr, &stripe_len);
|
||||
ret = btrfs_rmap_block(root->fs_info, cache->key.objectid,
|
||||
bytenr, 0, &logical, &nr, &stripe_len);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -730,11 +730,7 @@ static int cache_block_group(struct btrfs_block_group_cache *cache,
|
||||
static struct btrfs_block_group_cache *
|
||||
btrfs_lookup_first_block_group(struct btrfs_fs_info *info, u64 bytenr)
|
||||
{
|
||||
struct btrfs_block_group_cache *cache;
|
||||
|
||||
cache = block_group_cache_tree_search(info, bytenr, 0);
|
||||
|
||||
return cache;
|
||||
return block_group_cache_tree_search(info, bytenr, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -744,11 +740,7 @@ struct btrfs_block_group_cache *btrfs_lookup_block_group(
|
||||
struct btrfs_fs_info *info,
|
||||
u64 bytenr)
|
||||
{
|
||||
struct btrfs_block_group_cache *cache;
|
||||
|
||||
cache = block_group_cache_tree_search(info, bytenr, 1);
|
||||
|
||||
return cache;
|
||||
return block_group_cache_tree_search(info, bytenr, 1);
|
||||
}
|
||||
|
||||
static struct btrfs_space_info *__find_space_info(struct btrfs_fs_info *info,
|
||||
@@ -2360,7 +2352,13 @@ static int run_delayed_tree_ref(struct btrfs_trans_handle *trans,
|
||||
ins.type = BTRFS_EXTENT_ITEM_KEY;
|
||||
}
|
||||
|
||||
BUG_ON(node->ref_mod != 1);
|
||||
if (node->ref_mod != 1) {
|
||||
btrfs_err(root->fs_info,
|
||||
"btree block(%llu) has %d references rather than 1: action %d ref_root %llu parent %llu",
|
||||
node->bytenr, node->ref_mod, node->action, ref_root,
|
||||
parent);
|
||||
return -EIO;
|
||||
}
|
||||
if (node->action == BTRFS_ADD_DELAYED_REF && insert_reserved) {
|
||||
BUG_ON(!extent_op || !extent_op->update_flags);
|
||||
ret = alloc_reserved_tree_block(trans, root,
|
||||
@@ -2590,7 +2588,9 @@ static noinline int __btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
|
||||
if (must_insert_reserved)
|
||||
locked_ref->must_insert_reserved = 1;
|
||||
locked_ref->processing = 0;
|
||||
btrfs_debug(fs_info, "run_delayed_extent_op returned %d", ret);
|
||||
btrfs_debug(fs_info,
|
||||
"run_delayed_extent_op returned %d",
|
||||
ret);
|
||||
btrfs_delayed_ref_unlock(locked_ref);
|
||||
return ret;
|
||||
}
|
||||
@@ -2650,7 +2650,8 @@ static noinline int __btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
|
||||
locked_ref->processing = 0;
|
||||
btrfs_delayed_ref_unlock(locked_ref);
|
||||
btrfs_put_delayed_ref(ref);
|
||||
btrfs_debug(fs_info, "run_one_delayed_ref returned %d", ret);
|
||||
btrfs_debug(fs_info, "run_one_delayed_ref returned %d",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -2940,7 +2941,7 @@ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
|
||||
if (trans->aborted)
|
||||
return 0;
|
||||
|
||||
if (root->fs_info->creating_free_space_tree)
|
||||
if (test_bit(BTRFS_FS_CREATING_FREE_SPACE_TREE, &root->fs_info->flags))
|
||||
return 0;
|
||||
|
||||
if (root == root->fs_info->extent_root)
|
||||
@@ -2971,7 +2972,6 @@ again:
|
||||
spin_unlock(&delayed_refs->lock);
|
||||
goto out;
|
||||
}
|
||||
count = (unsigned long)-1;
|
||||
|
||||
while (node) {
|
||||
head = rb_entry(node, struct btrfs_delayed_ref_head,
|
||||
@@ -3694,6 +3694,8 @@ again:
|
||||
goto again;
|
||||
}
|
||||
spin_unlock(&cur_trans->dirty_bgs_lock);
|
||||
} else if (ret < 0) {
|
||||
btrfs_cleanup_dirty_bgs(cur_trans, root);
|
||||
}
|
||||
|
||||
btrfs_free_path(path);
|
||||
@@ -4429,7 +4431,7 @@ void check_system_chunk(struct btrfs_trans_handle *trans,
|
||||
if (left < thresh && btrfs_test_opt(root->fs_info, ENOSPC_DEBUG)) {
|
||||
btrfs_info(root->fs_info, "left=%llu, need=%llu, flags=%llu",
|
||||
left, thresh, type);
|
||||
dump_space_info(info, 0, 0);
|
||||
dump_space_info(root->fs_info, info, 0, 0);
|
||||
}
|
||||
|
||||
if (left < thresh) {
|
||||
@@ -5186,7 +5188,7 @@ static int __reserve_metadata_bytes(struct btrfs_root *root,
|
||||
* which means we won't have fs_info->fs_root set, so don't do
|
||||
* the async reclaim as we will panic.
|
||||
*/
|
||||
if (!root->fs_info->log_root_recovering &&
|
||||
if (!test_bit(BTRFS_FS_LOG_RECOVERING, &root->fs_info->flags) &&
|
||||
need_do_async_reclaim(space_info, root, used) &&
|
||||
!work_busy(&root->fs_info->async_reclaim_work)) {
|
||||
trace_btrfs_trigger_flush(root->fs_info,
|
||||
@@ -5792,7 +5794,7 @@ int btrfs_subvolume_reserve_metadata(struct btrfs_root *root,
|
||||
int ret;
|
||||
struct btrfs_block_rsv *global_rsv = &root->fs_info->global_block_rsv;
|
||||
|
||||
if (root->fs_info->quota_enabled) {
|
||||
if (test_bit(BTRFS_FS_QUOTA_ENABLED, &root->fs_info->flags)) {
|
||||
/* One for parent inode, two for dir entries */
|
||||
num_bytes = 3 * root->nodesize;
|
||||
ret = btrfs_qgroup_reserve_meta(root, num_bytes);
|
||||
@@ -5970,7 +5972,7 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes)
|
||||
csum_bytes = BTRFS_I(inode)->csum_bytes;
|
||||
spin_unlock(&BTRFS_I(inode)->lock);
|
||||
|
||||
if (root->fs_info->quota_enabled) {
|
||||
if (test_bit(BTRFS_FS_QUOTA_ENABLED, &root->fs_info->flags)) {
|
||||
ret = btrfs_qgroup_reserve_meta(root,
|
||||
nr_extents * root->nodesize);
|
||||
if (ret)
|
||||
@@ -6110,8 +6112,6 @@ void btrfs_delalloc_release_metadata(struct inode *inode, u64 num_bytes)
|
||||
* @start: start range we are writing to
|
||||
* @len: how long the range we are writing to
|
||||
*
|
||||
* TODO: This function will finally replace old btrfs_delalloc_reserve_space()
|
||||
*
|
||||
* This will do the following things
|
||||
*
|
||||
* o reserve space in data space info for num bytes
|
||||
@@ -6930,8 +6930,9 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
btrfs_err(info, "umm, got %d back from search, was looking for %llu",
|
||||
ret, bytenr);
|
||||
btrfs_err(info,
|
||||
"umm, got %d back from search, was looking for %llu",
|
||||
ret, bytenr);
|
||||
if (ret > 0)
|
||||
btrfs_print_leaf(extent_root,
|
||||
path->nodes[0]);
|
||||
@@ -6977,7 +6978,8 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
|
||||
ret = btrfs_search_slot(trans, extent_root, &key, path,
|
||||
-1, 1);
|
||||
if (ret) {
|
||||
btrfs_err(info, "umm, got %d back from search, was looking for %llu",
|
||||
btrfs_err(info,
|
||||
"umm, got %d back from search, was looking for %llu",
|
||||
ret, bytenr);
|
||||
btrfs_print_leaf(extent_root, path->nodes[0]);
|
||||
}
|
||||
@@ -7004,8 +7006,9 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
|
||||
|
||||
refs = btrfs_extent_refs(leaf, ei);
|
||||
if (refs < refs_to_drop) {
|
||||
btrfs_err(info, "trying to drop %d refs but we only have %Lu "
|
||||
"for bytenr %Lu", refs_to_drop, refs, bytenr);
|
||||
btrfs_err(info,
|
||||
"trying to drop %d refs but we only have %Lu for bytenr %Lu",
|
||||
refs_to_drop, refs, bytenr);
|
||||
ret = -EINVAL;
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
goto out;
|
||||
@@ -7901,23 +7904,24 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void dump_space_info(struct btrfs_space_info *info, u64 bytes,
|
||||
static void dump_space_info(struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_space_info *info, u64 bytes,
|
||||
int dump_block_groups)
|
||||
{
|
||||
struct btrfs_block_group_cache *cache;
|
||||
int index = 0;
|
||||
|
||||
spin_lock(&info->lock);
|
||||
printk(KERN_INFO "BTRFS: space_info %llu has %llu free, is %sfull\n",
|
||||
info->flags,
|
||||
info->total_bytes - info->bytes_used - info->bytes_pinned -
|
||||
info->bytes_reserved - info->bytes_readonly -
|
||||
info->bytes_may_use, (info->full) ? "" : "not ");
|
||||
printk(KERN_INFO "BTRFS: space_info total=%llu, used=%llu, pinned=%llu, "
|
||||
"reserved=%llu, may_use=%llu, readonly=%llu\n",
|
||||
info->total_bytes, info->bytes_used, info->bytes_pinned,
|
||||
info->bytes_reserved, info->bytes_may_use,
|
||||
info->bytes_readonly);
|
||||
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 ");
|
||||
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,
|
||||
info->bytes_reserved, info->bytes_may_use,
|
||||
info->bytes_readonly);
|
||||
spin_unlock(&info->lock);
|
||||
|
||||
if (!dump_block_groups)
|
||||
@@ -7927,12 +7931,11 @@ static void dump_space_info(struct btrfs_space_info *info, u64 bytes,
|
||||
again:
|
||||
list_for_each_entry(cache, &info->block_groups[index], list) {
|
||||
spin_lock(&cache->lock);
|
||||
printk(KERN_INFO "BTRFS: "
|
||||
"block group %llu has %llu bytes, "
|
||||
"%llu used %llu pinned %llu reserved %s\n",
|
||||
cache->key.objectid, cache->key.offset,
|
||||
btrfs_block_group_used(&cache->item), cache->pinned,
|
||||
cache->reserved, cache->ro ? "[readonly]" : "");
|
||||
btrfs_info(fs_info,
|
||||
"block group %llu has %llu bytes, %llu used %llu pinned %llu reserved %s",
|
||||
cache->key.objectid, cache->key.offset,
|
||||
btrfs_block_group_used(&cache->item), cache->pinned,
|
||||
cache->reserved, cache->ro ? "[readonly]" : "");
|
||||
btrfs_dump_free_space(cache, bytes);
|
||||
spin_unlock(&cache->lock);
|
||||
}
|
||||
@@ -7946,6 +7949,7 @@ int btrfs_reserve_extent(struct btrfs_root *root, u64 ram_bytes,
|
||||
u64 empty_size, u64 hint_byte,
|
||||
struct btrfs_key *ins, int is_data, int delalloc)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = root->fs_info;
|
||||
bool final_tried = num_bytes == min_alloc_size;
|
||||
u64 flags;
|
||||
int ret;
|
||||
@@ -7956,8 +7960,7 @@ again:
|
||||
ret = find_free_extent(root, ram_bytes, num_bytes, empty_size,
|
||||
hint_byte, ins, flags, delalloc);
|
||||
if (!ret && !is_data) {
|
||||
btrfs_dec_block_group_reservations(root->fs_info,
|
||||
ins->objectid);
|
||||
btrfs_dec_block_group_reservations(fs_info, ins->objectid);
|
||||
} else if (ret == -ENOSPC) {
|
||||
if (!final_tried && ins->offset) {
|
||||
num_bytes = min(num_bytes >> 1, ins->offset);
|
||||
@@ -7967,14 +7970,15 @@ again:
|
||||
if (num_bytes == min_alloc_size)
|
||||
final_tried = true;
|
||||
goto again;
|
||||
} else if (btrfs_test_opt(root->fs_info, ENOSPC_DEBUG)) {
|
||||
} else if (btrfs_test_opt(fs_info, ENOSPC_DEBUG)) {
|
||||
struct btrfs_space_info *sinfo;
|
||||
|
||||
sinfo = __find_space_info(root->fs_info, flags);
|
||||
btrfs_err(root->fs_info, "allocation failed flags %llu, wanted %llu",
|
||||
flags, num_bytes);
|
||||
sinfo = __find_space_info(fs_info, flags);
|
||||
btrfs_err(root->fs_info,
|
||||
"allocation failed flags %llu, wanted %llu",
|
||||
flags, num_bytes);
|
||||
if (sinfo)
|
||||
dump_space_info(sinfo, num_bytes, 1);
|
||||
dump_space_info(fs_info, sinfo, num_bytes, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8462,7 +8466,6 @@ static noinline void reada_walk_down(struct btrfs_trans_handle *trans,
|
||||
u64 refs;
|
||||
u64 flags;
|
||||
u32 nritems;
|
||||
u32 blocksize;
|
||||
struct btrfs_key key;
|
||||
struct extent_buffer *eb;
|
||||
int ret;
|
||||
@@ -8480,7 +8483,6 @@ static noinline void reada_walk_down(struct btrfs_trans_handle *trans,
|
||||
|
||||
eb = path->nodes[wc->level];
|
||||
nritems = btrfs_header_nritems(eb);
|
||||
blocksize = root->nodesize;
|
||||
|
||||
for (slot = path->slots[wc->level]; slot < nritems; slot++) {
|
||||
if (nread >= wc->reada_count)
|
||||
@@ -8544,7 +8546,7 @@ static int account_leaf_items(struct btrfs_trans_handle *trans,
|
||||
u64 bytenr, num_bytes;
|
||||
|
||||
/* We can be called directly from walk_up_proc() */
|
||||
if (!root->fs_info->quota_enabled)
|
||||
if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &root->fs_info->flags))
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < nr; i++) {
|
||||
@@ -8653,7 +8655,7 @@ static int account_shared_subtree(struct btrfs_trans_handle *trans,
|
||||
BUG_ON(root_level < 0 || root_level > BTRFS_MAX_LEVEL);
|
||||
BUG_ON(root_eb == NULL);
|
||||
|
||||
if (!root->fs_info->quota_enabled)
|
||||
if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &root->fs_info->flags))
|
||||
return 0;
|
||||
|
||||
if (!extent_buffer_uptodate(root_eb)) {
|
||||
@@ -8884,14 +8886,13 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans,
|
||||
ret = btrfs_lookup_extent_info(trans, root, bytenr, level - 1, 1,
|
||||
&wc->refs[level - 1],
|
||||
&wc->flags[level - 1]);
|
||||
if (ret < 0) {
|
||||
btrfs_tree_unlock(next);
|
||||
return ret;
|
||||
}
|
||||
if (ret < 0)
|
||||
goto out_unlock;
|
||||
|
||||
if (unlikely(wc->refs[level - 1] == 0)) {
|
||||
btrfs_err(root->fs_info, "Missing references.");
|
||||
BUG();
|
||||
ret = -EIO;
|
||||
goto out_unlock;
|
||||
}
|
||||
*lookup_info = 0;
|
||||
|
||||
@@ -8943,7 +8944,12 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans,
|
||||
}
|
||||
|
||||
level--;
|
||||
BUG_ON(level != btrfs_header_level(next));
|
||||
ASSERT(level == btrfs_header_level(next));
|
||||
if (level != btrfs_header_level(next)) {
|
||||
btrfs_err(root->fs_info, "mismatched level");
|
||||
ret = -EIO;
|
||||
goto out_unlock;
|
||||
}
|
||||
path->nodes[level] = next;
|
||||
path->slots[level] = 0;
|
||||
path->locks[level] = BTRFS_WRITE_LOCK_BLOCKING;
|
||||
@@ -8958,8 +8964,15 @@ skip:
|
||||
if (wc->flags[level] & BTRFS_BLOCK_FLAG_FULL_BACKREF) {
|
||||
parent = path->nodes[level]->start;
|
||||
} else {
|
||||
BUG_ON(root->root_key.objectid !=
|
||||
ASSERT(root->root_key.objectid ==
|
||||
btrfs_header_owner(path->nodes[level]));
|
||||
if (root->root_key.objectid !=
|
||||
btrfs_header_owner(path->nodes[level])) {
|
||||
btrfs_err(root->fs_info,
|
||||
"mismatched block owner");
|
||||
ret = -EIO;
|
||||
goto out_unlock;
|
||||
}
|
||||
parent = 0;
|
||||
}
|
||||
|
||||
@@ -8968,20 +8981,24 @@ skip:
|
||||
generation, level - 1);
|
||||
if (ret) {
|
||||
btrfs_err_rl(root->fs_info,
|
||||
"Error "
|
||||
"%d accounting shared subtree. Quota "
|
||||
"is out of sync, rescan required.",
|
||||
ret);
|
||||
"Error %d accounting shared subtree. Quota is out of sync, rescan required.",
|
||||
ret);
|
||||
}
|
||||
}
|
||||
ret = btrfs_free_extent(trans, root, bytenr, blocksize, parent,
|
||||
root->root_key.objectid, level - 1, 0);
|
||||
BUG_ON(ret); /* -ENOMEM */
|
||||
if (ret)
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
*lookup_info = 1;
|
||||
ret = 1;
|
||||
|
||||
out_unlock:
|
||||
btrfs_tree_unlock(next);
|
||||
free_extent_buffer(next);
|
||||
*lookup_info = 1;
|
||||
return 1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -9061,10 +9078,8 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans,
|
||||
ret = account_leaf_items(trans, root, eb);
|
||||
if (ret) {
|
||||
btrfs_err_rl(root->fs_info,
|
||||
"error "
|
||||
"%d accounting leaf items. Quota "
|
||||
"is out of sync, rescan required.",
|
||||
ret);
|
||||
"error %d accounting leaf items. Quota is out of sync, rescan required.",
|
||||
ret);
|
||||
}
|
||||
}
|
||||
/* make block locked assertion in clean_tree_block happy */
|
||||
@@ -9180,9 +9195,10 @@ int btrfs_drop_snapshot(struct btrfs_root *root,
|
||||
struct btrfs_block_rsv *block_rsv, int update_ref,
|
||||
int for_reloc)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = root->fs_info;
|
||||
struct btrfs_path *path;
|
||||
struct btrfs_trans_handle *trans;
|
||||
struct btrfs_root *tree_root = root->fs_info->tree_root;
|
||||
struct btrfs_root *tree_root = fs_info->tree_root;
|
||||
struct btrfs_root_item *root_item = &root->root_item;
|
||||
struct walk_control *wc;
|
||||
struct btrfs_key key;
|
||||
@@ -9191,7 +9207,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root,
|
||||
int level;
|
||||
bool root_dropped = false;
|
||||
|
||||
btrfs_debug(root->fs_info, "Drop subvolume %llu", root->objectid);
|
||||
btrfs_debug(fs_info, "Drop subvolume %llu", root->objectid);
|
||||
|
||||
path = btrfs_alloc_path();
|
||||
if (!path) {
|
||||
@@ -9320,7 +9336,8 @@ int btrfs_drop_snapshot(struct btrfs_root *root,
|
||||
|
||||
btrfs_end_transaction_throttle(trans, tree_root);
|
||||
if (!for_reloc && btrfs_need_cleaner_sleep(root)) {
|
||||
pr_debug("BTRFS: drop snapshot early exit\n");
|
||||
btrfs_debug(fs_info,
|
||||
"drop snapshot early exit");
|
||||
err = -EAGAIN;
|
||||
goto out_free;
|
||||
}
|
||||
@@ -9386,7 +9403,7 @@ out:
|
||||
if (!for_reloc && root_dropped == false)
|
||||
btrfs_add_dead_root(root);
|
||||
if (err && err != -EAGAIN)
|
||||
btrfs_handle_fs_error(root->fs_info, err, NULL);
|
||||
btrfs_handle_fs_error(fs_info, err, NULL);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -10020,7 +10037,7 @@ int btrfs_free_block_groups(struct btrfs_fs_info *info)
|
||||
if (WARN_ON(space_info->bytes_pinned > 0 ||
|
||||
space_info->bytes_reserved > 0 ||
|
||||
space_info->bytes_may_use > 0))
|
||||
dump_space_info(space_info, 0, 0);
|
||||
dump_space_info(info, space_info, 0, 0);
|
||||
list_del(&space_info->list);
|
||||
for (i = 0; i < BTRFS_NR_RAID_TYPES; i++) {
|
||||
struct kobject *kobj;
|
||||
@@ -10069,7 +10086,8 @@ static void __link_block_group(struct btrfs_space_info *space_info,
|
||||
|
||||
return;
|
||||
out_err:
|
||||
pr_warn("BTRFS: failed to add kobject for block cache. ignoring.\n");
|
||||
btrfs_warn(cache->fs_info,
|
||||
"failed to add kobject for block cache, ignoring");
|
||||
}
|
||||
|
||||
static struct btrfs_block_group_cache *
|
||||
@@ -10127,6 +10145,11 @@ int btrfs_read_block_groups(struct btrfs_root *root)
|
||||
struct extent_buffer *leaf;
|
||||
int need_clear = 0;
|
||||
u64 cache_gen;
|
||||
u64 feature;
|
||||
int mixed;
|
||||
|
||||
feature = btrfs_super_incompat_flags(info->super_copy);
|
||||
mixed = !!(feature & BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS);
|
||||
|
||||
root = info->extent_root;
|
||||
key.objectid = 0;
|
||||
@@ -10180,6 +10203,15 @@ int btrfs_read_block_groups(struct btrfs_root *root)
|
||||
btrfs_item_ptr_offset(leaf, path->slots[0]),
|
||||
sizeof(cache->item));
|
||||
cache->flags = btrfs_block_group_flags(&cache->item);
|
||||
if (!mixed &&
|
||||
((cache->flags & BTRFS_BLOCK_GROUP_METADATA) &&
|
||||
(cache->flags & BTRFS_BLOCK_GROUP_DATA))) {
|
||||
btrfs_err(info,
|
||||
"bg %llu is a mixed block group but filesystem hasn't enabled mixed block groups",
|
||||
cache->key.objectid);
|
||||
ret = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
key.objectid = found_key.objectid + found_key.offset;
|
||||
btrfs_release_path(path);
|
||||
@@ -10789,7 +10821,7 @@ void btrfs_delete_unused_bgs(struct btrfs_fs_info *fs_info)
|
||||
struct btrfs_trans_handle *trans;
|
||||
int ret = 0;
|
||||
|
||||
if (!fs_info->open)
|
||||
if (!test_bit(BTRFS_FS_OPEN, &fs_info->flags))
|
||||
return;
|
||||
|
||||
spin_lock(&fs_info->unused_bgs_lock);
|
||||
|
||||
+103
-67
@@ -20,6 +20,7 @@
|
||||
#include "locking.h"
|
||||
#include "rcu-string.h"
|
||||
#include "backref.h"
|
||||
#include "transaction.h"
|
||||
|
||||
static struct kmem_cache *extent_state_cache;
|
||||
static struct kmem_cache *extent_buffer_cache;
|
||||
@@ -74,8 +75,7 @@ void btrfs_leak_debug_check(void)
|
||||
|
||||
while (!list_empty(&buffers)) {
|
||||
eb = list_entry(buffers.next, struct extent_buffer, leak_list);
|
||||
printk(KERN_ERR "BTRFS: buffer leak start %llu len %lu "
|
||||
"refs %d\n",
|
||||
pr_err("BTRFS: buffer leak start %llu len %lu refs %d\n",
|
||||
eb->start, eb->len, atomic_read(&eb->refs));
|
||||
list_del(&eb->leak_list);
|
||||
kmem_cache_free(extent_buffer_cache, eb);
|
||||
@@ -460,8 +460,7 @@ static int insert_state(struct extent_io_tree *tree,
|
||||
if (node) {
|
||||
struct extent_state *found;
|
||||
found = rb_entry(node, struct extent_state, rb_node);
|
||||
printk(KERN_ERR "BTRFS: found node %llu %llu on insert of "
|
||||
"%llu %llu\n",
|
||||
pr_err("BTRFS: found node %llu %llu on insert of %llu %llu\n",
|
||||
found->start, found->end, start, end);
|
||||
return -EEXIST;
|
||||
}
|
||||
@@ -572,9 +571,8 @@ alloc_extent_state_atomic(struct extent_state *prealloc)
|
||||
|
||||
static void extent_io_tree_panic(struct extent_io_tree *tree, int err)
|
||||
{
|
||||
btrfs_panic(tree_fs_info(tree), err, "Locking error: "
|
||||
"Extent tree was modified by another "
|
||||
"thread while locked.");
|
||||
btrfs_panic(tree_fs_info(tree), err,
|
||||
"Locking error: Extent tree was modified by another thread while locked.");
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1729,7 +1727,7 @@ out_failed:
|
||||
}
|
||||
|
||||
void extent_clear_unlock_delalloc(struct inode *inode, u64 start, u64 end,
|
||||
struct page *locked_page,
|
||||
u64 delalloc_end, struct page *locked_page,
|
||||
unsigned clear_bits,
|
||||
unsigned long page_ops)
|
||||
{
|
||||
@@ -2122,8 +2120,9 @@ int clean_io_failure(struct inode *inode, u64 start, struct page *page,
|
||||
|
||||
if (failrec->in_validation) {
|
||||
/* there was no real error, just free the record */
|
||||
pr_debug("clean_io_failure: freeing dummy error at %llu\n",
|
||||
failrec->start);
|
||||
btrfs_debug(fs_info,
|
||||
"clean_io_failure: freeing dummy error at %llu",
|
||||
failrec->start);
|
||||
goto out;
|
||||
}
|
||||
if (fs_info->sb->s_flags & MS_RDONLY)
|
||||
@@ -2189,6 +2188,7 @@ void btrfs_free_io_failure_record(struct inode *inode, u64 start, u64 end)
|
||||
int btrfs_get_io_failure_record(struct inode *inode, u64 start, u64 end,
|
||||
struct io_failure_record **failrec_ret)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
|
||||
struct io_failure_record *failrec;
|
||||
struct extent_map *em;
|
||||
struct extent_io_tree *failure_tree = &BTRFS_I(inode)->io_failure_tree;
|
||||
@@ -2236,8 +2236,9 @@ int btrfs_get_io_failure_record(struct inode *inode, u64 start, u64 end,
|
||||
em->compress_type);
|
||||
}
|
||||
|
||||
pr_debug("Get IO Failure Record: (new) logical=%llu, start=%llu, len=%llu\n",
|
||||
logical, start, failrec->len);
|
||||
btrfs_debug(fs_info,
|
||||
"Get IO Failure Record: (new) logical=%llu, start=%llu, len=%llu",
|
||||
logical, start, failrec->len);
|
||||
|
||||
failrec->logical = logical;
|
||||
free_extent_map(em);
|
||||
@@ -2255,9 +2256,10 @@ int btrfs_get_io_failure_record(struct inode *inode, u64 start, u64 end,
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
pr_debug("Get IO Failure Record: (found) logical=%llu, start=%llu, len=%llu, validation=%d\n",
|
||||
failrec->logical, failrec->start, failrec->len,
|
||||
failrec->in_validation);
|
||||
btrfs_debug(fs_info,
|
||||
"Get IO Failure Record: (found) logical=%llu, start=%llu, len=%llu, validation=%d",
|
||||
failrec->logical, failrec->start, failrec->len,
|
||||
failrec->in_validation);
|
||||
/*
|
||||
* when data can be on disk more than twice, add to failrec here
|
||||
* (e.g. with a list for failed_mirror) to make
|
||||
@@ -2273,18 +2275,19 @@ int btrfs_get_io_failure_record(struct inode *inode, u64 start, u64 end,
|
||||
int btrfs_check_repairable(struct inode *inode, struct bio *failed_bio,
|
||||
struct io_failure_record *failrec, int failed_mirror)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
|
||||
int num_copies;
|
||||
|
||||
num_copies = btrfs_num_copies(BTRFS_I(inode)->root->fs_info,
|
||||
failrec->logical, failrec->len);
|
||||
num_copies = btrfs_num_copies(fs_info, failrec->logical, failrec->len);
|
||||
if (num_copies == 1) {
|
||||
/*
|
||||
* we only have a single copy of the data, so don't bother with
|
||||
* all the retry and error correction code that follows. no
|
||||
* matter what the error is, it is very likely to persist.
|
||||
*/
|
||||
pr_debug("Check Repairable: cannot repair, num_copies=%d, next_mirror %d, failed_mirror %d\n",
|
||||
num_copies, failrec->this_mirror, failed_mirror);
|
||||
btrfs_debug(fs_info,
|
||||
"Check Repairable: cannot repair, num_copies=%d, next_mirror %d, failed_mirror %d",
|
||||
num_copies, failrec->this_mirror, failed_mirror);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2323,8 +2326,9 @@ int btrfs_check_repairable(struct inode *inode, struct bio *failed_bio,
|
||||
}
|
||||
|
||||
if (failrec->this_mirror > num_copies) {
|
||||
pr_debug("Check Repairable: (fail) num_copies=%d, next_mirror %d, failed_mirror %d\n",
|
||||
num_copies, failrec->this_mirror, failed_mirror);
|
||||
btrfs_debug(fs_info,
|
||||
"Check Repairable: (fail) num_copies=%d, next_mirror %d, failed_mirror %d",
|
||||
num_copies, failrec->this_mirror, failed_mirror);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2415,8 +2419,9 @@ static int bio_readpage_error(struct bio *failed_bio, u64 phy_offset,
|
||||
}
|
||||
bio_set_op_attrs(bio, REQ_OP_READ, read_mode);
|
||||
|
||||
pr_debug("Repair Read Error: submitting new read[%#x] to this_mirror=%d, in_validation=%d\n",
|
||||
read_mode, failrec->this_mirror, failrec->in_validation);
|
||||
btrfs_debug(btrfs_sb(inode->i_sb),
|
||||
"Repair Read Error: submitting new read[%#x] to this_mirror=%d, in_validation=%d",
|
||||
read_mode, failrec->this_mirror, failrec->in_validation);
|
||||
|
||||
ret = tree->ops->submit_bio_hook(inode, bio, failrec->this_mirror,
|
||||
failrec->bio_flags, 0);
|
||||
@@ -2484,8 +2489,7 @@ static void end_bio_extent_writepage(struct bio *bio)
|
||||
bvec->bv_offset, bvec->bv_len);
|
||||
else
|
||||
btrfs_info(BTRFS_I(page->mapping->host)->root->fs_info,
|
||||
"incomplete page write in btrfs with offset %u and "
|
||||
"length %u",
|
||||
"incomplete page write in btrfs with offset %u and length %u",
|
||||
bvec->bv_offset, bvec->bv_len);
|
||||
}
|
||||
|
||||
@@ -2541,10 +2545,12 @@ static void end_bio_extent_readpage(struct bio *bio)
|
||||
bio_for_each_segment_all(bvec, bio, i) {
|
||||
struct page *page = bvec->bv_page;
|
||||
struct inode *inode = page->mapping->host;
|
||||
struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
|
||||
|
||||
pr_debug("end_bio_extent_readpage: bi_sector=%llu, err=%d, "
|
||||
"mirror=%u\n", (u64)bio->bi_iter.bi_sector,
|
||||
bio->bi_error, io_bio->mirror_num);
|
||||
btrfs_debug(fs_info,
|
||||
"end_bio_extent_readpage: bi_sector=%llu, err=%d, mirror=%u",
|
||||
(u64)bio->bi_iter.bi_sector, bio->bi_error,
|
||||
io_bio->mirror_num);
|
||||
tree = &BTRFS_I(inode)->io_tree;
|
||||
|
||||
/* We always issue full-page reads, but if some block
|
||||
@@ -2554,13 +2560,12 @@ static void end_bio_extent_readpage(struct bio *bio)
|
||||
* if they don't add up to a full page. */
|
||||
if (bvec->bv_offset || bvec->bv_len != PAGE_SIZE) {
|
||||
if (bvec->bv_offset + bvec->bv_len != PAGE_SIZE)
|
||||
btrfs_err(BTRFS_I(page->mapping->host)->root->fs_info,
|
||||
"partial page read in btrfs with offset %u and length %u",
|
||||
btrfs_err(fs_info,
|
||||
"partial page read in btrfs with offset %u and length %u",
|
||||
bvec->bv_offset, bvec->bv_len);
|
||||
else
|
||||
btrfs_info(BTRFS_I(page->mapping->host)->root->fs_info,
|
||||
"incomplete page read in btrfs with offset %u and "
|
||||
"length %u",
|
||||
btrfs_info(fs_info,
|
||||
"incomplete page read in btrfs with offset %u and length %u",
|
||||
bvec->bv_offset, bvec->bv_len);
|
||||
}
|
||||
|
||||
@@ -3624,7 +3629,6 @@ static void end_extent_buffer_writeback(struct extent_buffer *eb)
|
||||
static void set_btree_ioerr(struct page *page)
|
||||
{
|
||||
struct extent_buffer *eb = (struct extent_buffer *)page->private;
|
||||
struct btrfs_inode *btree_ino = BTRFS_I(eb->fs_info->btree_inode);
|
||||
|
||||
SetPageError(page);
|
||||
if (test_and_set_bit(EXTENT_BUFFER_WRITE_ERR, &eb->bflags))
|
||||
@@ -3670,13 +3674,13 @@ static void set_btree_ioerr(struct page *page)
|
||||
*/
|
||||
switch (eb->log_index) {
|
||||
case -1:
|
||||
set_bit(BTRFS_INODE_BTREE_ERR, &btree_ino->runtime_flags);
|
||||
set_bit(BTRFS_FS_BTREE_ERR, &eb->fs_info->flags);
|
||||
break;
|
||||
case 0:
|
||||
set_bit(BTRFS_INODE_BTREE_LOG1_ERR, &btree_ino->runtime_flags);
|
||||
set_bit(BTRFS_FS_LOG1_ERR, &eb->fs_info->flags);
|
||||
break;
|
||||
case 1:
|
||||
set_bit(BTRFS_INODE_BTREE_LOG2_ERR, &btree_ino->runtime_flags);
|
||||
set_bit(BTRFS_FS_LOG2_ERR, &eb->fs_info->flags);
|
||||
break;
|
||||
default:
|
||||
BUG(); /* unexpected, logic error */
|
||||
@@ -3721,8 +3725,10 @@ static noinline_for_stack int write_one_eb(struct extent_buffer *eb,
|
||||
struct block_device *bdev = fs_info->fs_devices->latest_bdev;
|
||||
struct extent_io_tree *tree = &BTRFS_I(fs_info->btree_inode)->io_tree;
|
||||
u64 offset = eb->start;
|
||||
u32 nritems;
|
||||
unsigned long i, num_pages;
|
||||
unsigned long bio_flags = 0;
|
||||
unsigned long start, end;
|
||||
int write_flags = (epd->sync_io ? WRITE_SYNC : 0) | REQ_META;
|
||||
int ret = 0;
|
||||
|
||||
@@ -3732,6 +3738,23 @@ static noinline_for_stack int write_one_eb(struct extent_buffer *eb,
|
||||
if (btrfs_header_owner(eb) == BTRFS_TREE_LOG_OBJECTID)
|
||||
bio_flags = EXTENT_BIO_TREE_LOG;
|
||||
|
||||
/* set btree blocks beyond nritems with 0 to avoid stale content. */
|
||||
nritems = btrfs_header_nritems(eb);
|
||||
if (btrfs_header_level(eb) > 0) {
|
||||
end = btrfs_node_key_ptr_offset(nritems);
|
||||
|
||||
memset_extent_buffer(eb, 0, end, eb->len - end);
|
||||
} else {
|
||||
/*
|
||||
* leaf:
|
||||
* header 0 1 2 .. N ... data_N .. data_2 data_1 data_0
|
||||
*/
|
||||
start = btrfs_item_nr_offset(nritems);
|
||||
end = btrfs_leaf_data(eb) +
|
||||
leaf_data_end(fs_info->tree_root, eb);
|
||||
memset_extent_buffer(eb, 0, start, end - start);
|
||||
}
|
||||
|
||||
for (i = 0; i < num_pages; i++) {
|
||||
struct page *p = eb->pages[i];
|
||||
|
||||
@@ -4487,11 +4510,24 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
|
||||
flags |= (FIEMAP_EXTENT_DELALLOC |
|
||||
FIEMAP_EXTENT_UNKNOWN);
|
||||
} else if (fieinfo->fi_extents_max) {
|
||||
struct btrfs_trans_handle *trans;
|
||||
|
||||
u64 bytenr = em->block_start -
|
||||
(em->start - em->orig_start);
|
||||
|
||||
disko = em->block_start + offset_in_extent;
|
||||
|
||||
/*
|
||||
* We need a trans handle to get delayed refs
|
||||
*/
|
||||
trans = btrfs_join_transaction(root);
|
||||
/*
|
||||
* It's OK if we can't start a trans we can still check
|
||||
* from commit_root
|
||||
*/
|
||||
if (IS_ERR(trans))
|
||||
trans = NULL;
|
||||
|
||||
/*
|
||||
* As btrfs supports shared space, this information
|
||||
* can be exported to userspace tools via
|
||||
@@ -4499,9 +4535,11 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
|
||||
* then we're just getting a count and we can skip the
|
||||
* lookup stuff.
|
||||
*/
|
||||
ret = btrfs_check_shared(NULL, root->fs_info,
|
||||
ret = btrfs_check_shared(trans, root->fs_info,
|
||||
root->objectid,
|
||||
btrfs_ino(inode), bytenr);
|
||||
if (trans)
|
||||
btrfs_end_transaction(trans, root);
|
||||
if (ret < 0)
|
||||
goto out_free;
|
||||
if (ret)
|
||||
@@ -5173,11 +5211,10 @@ int extent_buffer_uptodate(struct extent_buffer *eb)
|
||||
}
|
||||
|
||||
int read_extent_buffer_pages(struct extent_io_tree *tree,
|
||||
struct extent_buffer *eb, u64 start, int wait,
|
||||
struct extent_buffer *eb, int wait,
|
||||
get_extent_t *get_extent, int mirror_num)
|
||||
{
|
||||
unsigned long i;
|
||||
unsigned long start_i;
|
||||
struct page *page;
|
||||
int err;
|
||||
int ret = 0;
|
||||
@@ -5191,16 +5228,8 @@ int read_extent_buffer_pages(struct extent_io_tree *tree,
|
||||
if (test_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags))
|
||||
return 0;
|
||||
|
||||
if (start) {
|
||||
WARN_ON(start < eb->start);
|
||||
start_i = (start >> PAGE_SHIFT) -
|
||||
(eb->start >> PAGE_SHIFT);
|
||||
} else {
|
||||
start_i = 0;
|
||||
}
|
||||
|
||||
num_pages = num_extent_pages(eb->start, eb->len);
|
||||
for (i = start_i; i < num_pages; i++) {
|
||||
for (i = 0; i < num_pages; i++) {
|
||||
page = eb->pages[i];
|
||||
if (wait == WAIT_NONE) {
|
||||
if (!trylock_page(page))
|
||||
@@ -5209,21 +5238,29 @@ int read_extent_buffer_pages(struct extent_io_tree *tree,
|
||||
lock_page(page);
|
||||
}
|
||||
locked_pages++;
|
||||
}
|
||||
/*
|
||||
* We need to firstly lock all pages to make sure that
|
||||
* the uptodate bit of our pages won't be affected by
|
||||
* clear_extent_buffer_uptodate().
|
||||
*/
|
||||
for (i = 0; i < num_pages; i++) {
|
||||
page = eb->pages[i];
|
||||
if (!PageUptodate(page)) {
|
||||
num_reads++;
|
||||
all_uptodate = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (all_uptodate) {
|
||||
if (start_i == 0)
|
||||
set_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags);
|
||||
set_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags);
|
||||
goto unlock_exit;
|
||||
}
|
||||
|
||||
clear_bit(EXTENT_BUFFER_READ_ERR, &eb->bflags);
|
||||
eb->read_mirror = 0;
|
||||
atomic_set(&eb->io_pages, num_reads);
|
||||
for (i = start_i; i < num_pages; i++) {
|
||||
for (i = 0; i < num_pages; i++) {
|
||||
page = eb->pages[i];
|
||||
|
||||
if (!PageUptodate(page)) {
|
||||
@@ -5264,7 +5301,7 @@ int read_extent_buffer_pages(struct extent_io_tree *tree,
|
||||
if (ret || wait != WAIT_COMPLETE)
|
||||
return ret;
|
||||
|
||||
for (i = start_i; i < num_pages; i++) {
|
||||
for (i = 0; i < num_pages; i++) {
|
||||
page = eb->pages[i];
|
||||
wait_on_page_locked(page);
|
||||
if (!PageUptodate(page))
|
||||
@@ -5274,12 +5311,10 @@ int read_extent_buffer_pages(struct extent_io_tree *tree,
|
||||
return ret;
|
||||
|
||||
unlock_exit:
|
||||
i = start_i;
|
||||
while (locked_pages > 0) {
|
||||
page = eb->pages[i];
|
||||
i++;
|
||||
unlock_page(page);
|
||||
locked_pages--;
|
||||
page = eb->pages[locked_pages];
|
||||
unlock_page(page);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -5382,8 +5417,7 @@ int map_private_extent_buffer(struct extent_buffer *eb, unsigned long start,
|
||||
}
|
||||
|
||||
if (start + min_len > eb->len) {
|
||||
WARN(1, KERN_ERR "btrfs bad mapping eb start %llu len %lu, "
|
||||
"wanted %lu %lu\n",
|
||||
WARN(1, KERN_ERR "btrfs bad mapping eb start %llu len %lu, wanted %lu %lu\n",
|
||||
eb->start, eb->len, start, min_len);
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -5713,14 +5747,14 @@ void memcpy_extent_buffer(struct extent_buffer *dst, unsigned long dst_offset,
|
||||
|
||||
if (src_offset + len > dst->len) {
|
||||
btrfs_err(dst->fs_info,
|
||||
"memmove bogus src_offset %lu move "
|
||||
"len %lu dst len %lu", src_offset, len, dst->len);
|
||||
"memmove bogus src_offset %lu move len %lu dst len %lu",
|
||||
src_offset, len, dst->len);
|
||||
BUG_ON(1);
|
||||
}
|
||||
if (dst_offset + len > dst->len) {
|
||||
btrfs_err(dst->fs_info,
|
||||
"memmove bogus dst_offset %lu move "
|
||||
"len %lu dst len %lu", dst_offset, len, dst->len);
|
||||
"memmove bogus dst_offset %lu move len %lu dst len %lu",
|
||||
dst_offset, len, dst->len);
|
||||
BUG_ON(1);
|
||||
}
|
||||
|
||||
@@ -5760,13 +5794,15 @@ void memmove_extent_buffer(struct extent_buffer *dst, unsigned long dst_offset,
|
||||
unsigned long src_i;
|
||||
|
||||
if (src_offset + len > dst->len) {
|
||||
btrfs_err(dst->fs_info, "memmove bogus src_offset %lu move "
|
||||
"len %lu len %lu", src_offset, len, dst->len);
|
||||
btrfs_err(dst->fs_info,
|
||||
"memmove bogus src_offset %lu move len %lu len %lu",
|
||||
src_offset, len, dst->len);
|
||||
BUG_ON(1);
|
||||
}
|
||||
if (dst_offset + len > dst->len) {
|
||||
btrfs_err(dst->fs_info, "memmove bogus dst_offset %lu move "
|
||||
"len %lu len %lu", dst_offset, len, dst->len);
|
||||
btrfs_err(dst->fs_info,
|
||||
"memmove bogus dst_offset %lu move len %lu len %lu",
|
||||
dst_offset, len, dst->len);
|
||||
BUG_ON(1);
|
||||
}
|
||||
if (dst_offset < src_offset) {
|
||||
|
||||
@@ -359,7 +359,7 @@ void free_extent_buffer_stale(struct extent_buffer *eb);
|
||||
#define WAIT_COMPLETE 1
|
||||
#define WAIT_PAGE_LOCK 2
|
||||
int read_extent_buffer_pages(struct extent_io_tree *tree,
|
||||
struct extent_buffer *eb, u64 start, int wait,
|
||||
struct extent_buffer *eb, int wait,
|
||||
get_extent_t *get_extent, int mirror_num);
|
||||
void wait_on_extent_buffer_writeback(struct extent_buffer *eb);
|
||||
|
||||
@@ -413,7 +413,7 @@ int map_private_extent_buffer(struct extent_buffer *eb, unsigned long offset,
|
||||
void extent_range_clear_dirty_for_io(struct inode *inode, u64 start, u64 end);
|
||||
void extent_range_redirty_for_io(struct inode *inode, u64 start, u64 end);
|
||||
void extent_clear_unlock_delalloc(struct inode *inode, u64 start, u64 end,
|
||||
struct page *locked_page,
|
||||
u64 delalloc_end, struct page *locked_page,
|
||||
unsigned bits_to_clear,
|
||||
unsigned long page_ops);
|
||||
struct bio *
|
||||
|
||||
+34
-9
@@ -503,7 +503,7 @@ int btrfs_dirty_pages(struct btrfs_root *root, struct inode *inode,
|
||||
|
||||
end_of_last_block = start_pos + num_bytes - 1;
|
||||
err = btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block,
|
||||
cached);
|
||||
cached, 0);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -1110,13 +1110,25 @@ again:
|
||||
|
||||
leaf = path->nodes[0];
|
||||
btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
|
||||
BUG_ON(key.objectid != ino || key.type != BTRFS_EXTENT_DATA_KEY);
|
||||
if (key.objectid != ino ||
|
||||
key.type != BTRFS_EXTENT_DATA_KEY) {
|
||||
ret = -EINVAL;
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
goto out;
|
||||
}
|
||||
fi = btrfs_item_ptr(leaf, path->slots[0],
|
||||
struct btrfs_file_extent_item);
|
||||
BUG_ON(btrfs_file_extent_type(leaf, fi) !=
|
||||
BTRFS_FILE_EXTENT_PREALLOC);
|
||||
if (btrfs_file_extent_type(leaf, fi) != BTRFS_FILE_EXTENT_PREALLOC) {
|
||||
ret = -EINVAL;
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
goto out;
|
||||
}
|
||||
extent_end = key.offset + btrfs_file_extent_num_bytes(leaf, fi);
|
||||
BUG_ON(key.offset > start || extent_end < end);
|
||||
if (key.offset > start || extent_end < end) {
|
||||
ret = -EINVAL;
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
bytenr = btrfs_file_extent_disk_bytenr(leaf, fi);
|
||||
num_bytes = btrfs_file_extent_disk_num_bytes(leaf, fi);
|
||||
@@ -1213,12 +1225,19 @@ again:
|
||||
ret = btrfs_inc_extent_ref(trans, root, bytenr, num_bytes, 0,
|
||||
root->root_key.objectid,
|
||||
ino, orig_offset);
|
||||
BUG_ON(ret); /* -ENOMEM */
|
||||
if (ret) {
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (split == start) {
|
||||
key.offset = start;
|
||||
} else {
|
||||
BUG_ON(start != key.offset);
|
||||
if (start != key.offset) {
|
||||
ret = -EINVAL;
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
goto out;
|
||||
}
|
||||
path->slots[0]--;
|
||||
extent_end = end;
|
||||
}
|
||||
@@ -1240,7 +1259,10 @@ again:
|
||||
ret = btrfs_free_extent(trans, root, bytenr, num_bytes,
|
||||
0, root->root_key.objectid,
|
||||
ino, orig_offset);
|
||||
BUG_ON(ret); /* -ENOMEM */
|
||||
if (ret) {
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
other_start = 0;
|
||||
other_end = start;
|
||||
@@ -1257,7 +1279,10 @@ again:
|
||||
ret = btrfs_free_extent(trans, root, bytenr, num_bytes,
|
||||
0, root->root_key.objectid,
|
||||
ino, orig_offset);
|
||||
BUG_ON(ret); /* -ENOMEM */
|
||||
if (ret) {
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
if (del_nr == 0) {
|
||||
fi = btrfs_item_ptr(leaf, path->slots[0],
|
||||
|
||||
@@ -716,8 +716,7 @@ static int __load_free_space_cache(struct btrfs_root *root, struct inode *inode,
|
||||
|
||||
if (BTRFS_I(inode)->generation != generation) {
|
||||
btrfs_err(root->fs_info,
|
||||
"free space inode generation (%llu) "
|
||||
"did not match free space cache generation (%llu)",
|
||||
"free space inode generation (%llu) did not match free space cache generation (%llu)",
|
||||
BTRFS_I(inode)->generation, generation);
|
||||
return 0;
|
||||
}
|
||||
@@ -879,8 +878,9 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info,
|
||||
|
||||
if (!matched) {
|
||||
__btrfs_remove_free_space_cache(ctl);
|
||||
btrfs_warn(fs_info, "block group %llu has wrong amount of free space",
|
||||
block_group->key.objectid);
|
||||
btrfs_warn(fs_info,
|
||||
"block group %llu has wrong amount of free space",
|
||||
block_group->key.objectid);
|
||||
ret = -1;
|
||||
}
|
||||
out:
|
||||
@@ -891,8 +891,9 @@ out:
|
||||
spin_unlock(&block_group->lock);
|
||||
ret = 0;
|
||||
|
||||
btrfs_warn(fs_info, "failed to load free space cache for block group %llu, rebuilding it now",
|
||||
block_group->key.objectid);
|
||||
btrfs_warn(fs_info,
|
||||
"failed to load free space cache for block group %llu, rebuilding it now",
|
||||
block_group->key.objectid);
|
||||
}
|
||||
|
||||
iput(inode);
|
||||
@@ -2298,7 +2299,8 @@ static void steal_from_bitmap(struct btrfs_free_space_ctl *ctl,
|
||||
}
|
||||
}
|
||||
|
||||
int __btrfs_add_free_space(struct btrfs_free_space_ctl *ctl,
|
||||
int __btrfs_add_free_space(struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_free_space_ctl *ctl,
|
||||
u64 offset, u64 bytes)
|
||||
{
|
||||
struct btrfs_free_space *info;
|
||||
@@ -2345,7 +2347,7 @@ out:
|
||||
spin_unlock(&ctl->tree_lock);
|
||||
|
||||
if (ret) {
|
||||
printk(KERN_CRIT "BTRFS: unable to add free space :%d\n", ret);
|
||||
btrfs_crit(fs_info, "unable to add free space :%d", ret);
|
||||
ASSERT(ret != -EEXIST);
|
||||
}
|
||||
|
||||
@@ -2621,7 +2623,8 @@ out:
|
||||
spin_unlock(&ctl->tree_lock);
|
||||
|
||||
if (align_gap_len)
|
||||
__btrfs_add_free_space(ctl, align_gap, align_gap_len);
|
||||
__btrfs_add_free_space(block_group->fs_info, ctl,
|
||||
align_gap, align_gap_len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -89,13 +89,15 @@ int btrfs_write_out_ino_cache(struct btrfs_root *root,
|
||||
struct inode *inode);
|
||||
|
||||
void btrfs_init_free_space_ctl(struct btrfs_block_group_cache *block_group);
|
||||
int __btrfs_add_free_space(struct btrfs_free_space_ctl *ctl,
|
||||
int __btrfs_add_free_space(struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_free_space_ctl *ctl,
|
||||
u64 bytenr, u64 size);
|
||||
static inline int
|
||||
btrfs_add_free_space(struct btrfs_block_group_cache *block_group,
|
||||
u64 bytenr, u64 size)
|
||||
{
|
||||
return __btrfs_add_free_space(block_group->free_space_ctl,
|
||||
return __btrfs_add_free_space(block_group->fs_info,
|
||||
block_group->free_space_ctl,
|
||||
bytenr, size);
|
||||
}
|
||||
int btrfs_remove_free_space(struct btrfs_block_group_cache *block_group,
|
||||
|
||||
@@ -107,7 +107,7 @@ search_free_space_info(struct btrfs_trans_handle *trans,
|
||||
if (ret < 0)
|
||||
return ERR_PTR(ret);
|
||||
if (ret != 0) {
|
||||
btrfs_warn(fs_info, "missing free space info for %llu\n",
|
||||
btrfs_warn(fs_info, "missing free space info for %llu",
|
||||
block_group->key.objectid);
|
||||
ASSERT(0);
|
||||
return ERR_PTR(-ENOENT);
|
||||
@@ -261,7 +261,8 @@ int convert_free_space_to_bitmaps(struct btrfs_trans_handle *trans,
|
||||
btrfs_release_path(path);
|
||||
|
||||
if (extent_count != expected_extent_count) {
|
||||
btrfs_err(fs_info, "incorrect extent count for %llu; counted %u, expected %u",
|
||||
btrfs_err(fs_info,
|
||||
"incorrect extent count for %llu; counted %u, expected %u",
|
||||
block_group->key.objectid, extent_count,
|
||||
expected_extent_count);
|
||||
ASSERT(0);
|
||||
@@ -442,7 +443,8 @@ int convert_free_space_to_extents(struct btrfs_trans_handle *trans,
|
||||
}
|
||||
|
||||
if (extent_count != expected_extent_count) {
|
||||
btrfs_err(fs_info, "incorrect extent count for %llu; counted %u, expected %u",
|
||||
btrfs_err(fs_info,
|
||||
"incorrect extent count for %llu; counted %u, expected %u",
|
||||
block_group->key.objectid, extent_count,
|
||||
expected_extent_count);
|
||||
ASSERT(0);
|
||||
@@ -1163,7 +1165,7 @@ int btrfs_create_free_space_tree(struct btrfs_fs_info *fs_info)
|
||||
if (IS_ERR(trans))
|
||||
return PTR_ERR(trans);
|
||||
|
||||
fs_info->creating_free_space_tree = 1;
|
||||
set_bit(BTRFS_FS_CREATING_FREE_SPACE_TREE, &fs_info->flags);
|
||||
free_space_root = btrfs_create_tree(trans, fs_info,
|
||||
BTRFS_FREE_SPACE_TREE_OBJECTID);
|
||||
if (IS_ERR(free_space_root)) {
|
||||
@@ -1183,7 +1185,7 @@ int btrfs_create_free_space_tree(struct btrfs_fs_info *fs_info)
|
||||
}
|
||||
|
||||
btrfs_set_fs_compat_ro(fs_info, FREE_SPACE_TREE);
|
||||
fs_info->creating_free_space_tree = 0;
|
||||
clear_bit(BTRFS_FS_CREATING_FREE_SPACE_TREE, &fs_info->flags);
|
||||
|
||||
ret = btrfs_commit_transaction(trans, tree_root);
|
||||
if (ret)
|
||||
@@ -1192,7 +1194,7 @@ int btrfs_create_free_space_tree(struct btrfs_fs_info *fs_info)
|
||||
return 0;
|
||||
|
||||
abort:
|
||||
fs_info->creating_free_space_tree = 0;
|
||||
clear_bit(BTRFS_FS_CREATING_FREE_SPACE_TREE, &fs_info->flags);
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
btrfs_end_transaction(trans, tree_root);
|
||||
return ret;
|
||||
@@ -1480,7 +1482,8 @@ static int load_free_space_bitmaps(struct btrfs_caching_control *caching_ctl,
|
||||
}
|
||||
|
||||
if (extent_count != expected_extent_count) {
|
||||
btrfs_err(fs_info, "incorrect extent count for %llu; counted %u, expected %u",
|
||||
btrfs_err(fs_info,
|
||||
"incorrect extent count for %llu; counted %u, expected %u",
|
||||
block_group->key.objectid, extent_count,
|
||||
expected_extent_count);
|
||||
ASSERT(0);
|
||||
@@ -1542,7 +1545,8 @@ static int load_free_space_extents(struct btrfs_caching_control *caching_ctl,
|
||||
}
|
||||
|
||||
if (extent_count != expected_extent_count) {
|
||||
btrfs_err(fs_info, "incorrect extent count for %llu; counted %u, expected %u",
|
||||
btrfs_err(fs_info,
|
||||
"incorrect extent count for %llu; counted %u, expected %u",
|
||||
block_group->key.objectid, extent_count,
|
||||
expected_extent_count);
|
||||
ASSERT(0);
|
||||
|
||||
+17
-14
@@ -104,7 +104,7 @@ again:
|
||||
break;
|
||||
|
||||
if (last != (u64)-1 && last + 1 != key.objectid) {
|
||||
__btrfs_add_free_space(ctl, last + 1,
|
||||
__btrfs_add_free_space(fs_info, ctl, last + 1,
|
||||
key.objectid - last - 1);
|
||||
wake_up(&root->ino_cache_wait);
|
||||
}
|
||||
@@ -115,7 +115,7 @@ next:
|
||||
}
|
||||
|
||||
if (last < root->highest_objectid - 1) {
|
||||
__btrfs_add_free_space(ctl, last + 1,
|
||||
__btrfs_add_free_space(fs_info, ctl, last + 1,
|
||||
root->highest_objectid - last - 1);
|
||||
}
|
||||
|
||||
@@ -136,12 +136,13 @@ out:
|
||||
|
||||
static void start_caching(struct btrfs_root *root)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = root->fs_info;
|
||||
struct btrfs_free_space_ctl *ctl = root->free_ino_ctl;
|
||||
struct task_struct *tsk;
|
||||
int ret;
|
||||
u64 objectid;
|
||||
|
||||
if (!btrfs_test_opt(root->fs_info, INODE_MAP_CACHE))
|
||||
if (!btrfs_test_opt(fs_info, INODE_MAP_CACHE))
|
||||
return;
|
||||
|
||||
spin_lock(&root->ino_cache_lock);
|
||||
@@ -153,7 +154,7 @@ static void start_caching(struct btrfs_root *root)
|
||||
root->ino_cache_state = BTRFS_CACHE_STARTED;
|
||||
spin_unlock(&root->ino_cache_lock);
|
||||
|
||||
ret = load_free_ino_cache(root->fs_info, root);
|
||||
ret = load_free_ino_cache(fs_info, root);
|
||||
if (ret == 1) {
|
||||
spin_lock(&root->ino_cache_lock);
|
||||
root->ino_cache_state = BTRFS_CACHE_FINISHED;
|
||||
@@ -170,15 +171,15 @@ static void start_caching(struct btrfs_root *root)
|
||||
*/
|
||||
ret = btrfs_find_free_objectid(root, &objectid);
|
||||
if (!ret && objectid <= BTRFS_LAST_FREE_OBJECTID) {
|
||||
__btrfs_add_free_space(ctl, objectid,
|
||||
__btrfs_add_free_space(fs_info, ctl, objectid,
|
||||
BTRFS_LAST_FREE_OBJECTID - objectid + 1);
|
||||
}
|
||||
|
||||
tsk = kthread_run(caching_kthread, root, "btrfs-ino-cache-%llu",
|
||||
root->root_key.objectid);
|
||||
if (IS_ERR(tsk)) {
|
||||
btrfs_warn(root->fs_info, "failed to start inode caching task");
|
||||
btrfs_clear_pending_and_info(root->fs_info, INODE_MAP_CACHE,
|
||||
btrfs_warn(fs_info, "failed to start inode caching task");
|
||||
btrfs_clear_pending_and_info(fs_info, INODE_MAP_CACHE,
|
||||
"disabling inode map caching");
|
||||
}
|
||||
}
|
||||
@@ -209,28 +210,29 @@ again:
|
||||
|
||||
void btrfs_return_ino(struct btrfs_root *root, u64 objectid)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = root->fs_info;
|
||||
struct btrfs_free_space_ctl *pinned = root->free_ino_pinned;
|
||||
|
||||
if (!btrfs_test_opt(root->fs_info, INODE_MAP_CACHE))
|
||||
if (!btrfs_test_opt(fs_info, INODE_MAP_CACHE))
|
||||
return;
|
||||
again:
|
||||
if (root->ino_cache_state == BTRFS_CACHE_FINISHED) {
|
||||
__btrfs_add_free_space(pinned, objectid, 1);
|
||||
__btrfs_add_free_space(fs_info, pinned, objectid, 1);
|
||||
} else {
|
||||
down_write(&root->fs_info->commit_root_sem);
|
||||
down_write(&fs_info->commit_root_sem);
|
||||
spin_lock(&root->ino_cache_lock);
|
||||
if (root->ino_cache_state == BTRFS_CACHE_FINISHED) {
|
||||
spin_unlock(&root->ino_cache_lock);
|
||||
up_write(&root->fs_info->commit_root_sem);
|
||||
up_write(&fs_info->commit_root_sem);
|
||||
goto again;
|
||||
}
|
||||
spin_unlock(&root->ino_cache_lock);
|
||||
|
||||
start_caching(root);
|
||||
|
||||
__btrfs_add_free_space(pinned, objectid, 1);
|
||||
__btrfs_add_free_space(fs_info, pinned, objectid, 1);
|
||||
|
||||
up_write(&root->fs_info->commit_root_sem);
|
||||
up_write(&fs_info->commit_root_sem);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -277,7 +279,8 @@ void btrfs_unpin_free_ino(struct btrfs_root *root)
|
||||
rb_erase(&info->offset_index, rbroot);
|
||||
spin_unlock(rbroot_lock);
|
||||
if (add_to_ctl)
|
||||
__btrfs_add_free_space(ctl, info->offset, count);
|
||||
__btrfs_add_free_space(root->fs_info, ctl,
|
||||
info->offset, count);
|
||||
kmem_cache_free(btrfs_free_space_cachep, info);
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user