Merge branch 'cleanups-4.7' into for-chris-4.7-20160516
This commit is contained in:
Коммит
5ef64a3e75
|
@ -1011,7 +1011,7 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans,
|
|||
return ret;
|
||||
if (refs == 0) {
|
||||
ret = -EROFS;
|
||||
btrfs_std_error(root->fs_info, ret, NULL);
|
||||
btrfs_handle_fs_error(root->fs_info, ret, NULL);
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
|
@ -1928,7 +1928,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
|
|||
child = read_node_slot(root, mid, 0);
|
||||
if (!child) {
|
||||
ret = -EROFS;
|
||||
btrfs_std_error(root->fs_info, ret, NULL);
|
||||
btrfs_handle_fs_error(root->fs_info, ret, NULL);
|
||||
goto enospc;
|
||||
}
|
||||
|
||||
|
@ -2031,7 +2031,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
|
|||
*/
|
||||
if (!left) {
|
||||
ret = -EROFS;
|
||||
btrfs_std_error(root->fs_info, ret, NULL);
|
||||
btrfs_handle_fs_error(root->fs_info, ret, NULL);
|
||||
goto enospc;
|
||||
}
|
||||
wret = balance_node_right(trans, root, mid, left);
|
||||
|
|
|
@ -4327,10 +4327,9 @@ static inline void assfail(char *expr, char *file, int line)
|
|||
#define ASSERT(expr) ((void)0)
|
||||
#endif
|
||||
|
||||
#define btrfs_assert()
|
||||
__printf(5, 6)
|
||||
__cold
|
||||
void __btrfs_std_error(struct btrfs_fs_info *fs_info, const char *function,
|
||||
void __btrfs_handle_fs_error(struct btrfs_fs_info *fs_info, const char *function,
|
||||
unsigned int line, int errno, const char *fmt, ...);
|
||||
|
||||
const char *btrfs_decode_error(int errno);
|
||||
|
@ -4340,6 +4339,46 @@ void __btrfs_abort_transaction(struct btrfs_trans_handle *trans,
|
|||
struct btrfs_root *root, const char *function,
|
||||
unsigned int line, int errno);
|
||||
|
||||
/*
|
||||
* Call btrfs_abort_transaction as early as possible when an error condition is
|
||||
* detected, that way the exact line number is reported.
|
||||
*/
|
||||
#define btrfs_abort_transaction(trans, root, errno) \
|
||||
do { \
|
||||
/* Report first abort since mount */ \
|
||||
if (!test_and_set_bit(BTRFS_FS_STATE_TRANS_ABORTED, \
|
||||
&((root)->fs_info->fs_state))) { \
|
||||
WARN(1, KERN_DEBUG \
|
||||
"BTRFS: Transaction aborted (error %d)\n", \
|
||||
(errno)); \
|
||||
} \
|
||||
__btrfs_abort_transaction((trans), (root), __func__, \
|
||||
__LINE__, (errno)); \
|
||||
} while (0)
|
||||
|
||||
#define btrfs_handle_fs_error(fs_info, errno, fmt, args...) \
|
||||
do { \
|
||||
__btrfs_handle_fs_error((fs_info), __func__, __LINE__, \
|
||||
(errno), fmt, ##args); \
|
||||
} while (0)
|
||||
|
||||
__printf(5, 6)
|
||||
__cold
|
||||
void __btrfs_panic(struct btrfs_fs_info *fs_info, const char *function,
|
||||
unsigned int line, int errno, const char *fmt, ...);
|
||||
/*
|
||||
* If BTRFS_MOUNT_PANIC_ON_FATAL_ERROR is in mount_opt, __btrfs_panic
|
||||
* will panic(). Otherwise we BUG() here.
|
||||
*/
|
||||
#define btrfs_panic(fs_info, errno, fmt, args...) \
|
||||
do { \
|
||||
__btrfs_panic(fs_info, __func__, __LINE__, errno, fmt, ##args); \
|
||||
BUG(); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* compatibility and incompatibility defines */
|
||||
|
||||
#define btrfs_set_fs_incompat(__fs_info, opt) \
|
||||
__btrfs_set_fs_incompat((__fs_info), BTRFS_FEATURE_INCOMPAT_##opt)
|
||||
|
||||
|
@ -4456,44 +4495,6 @@ static inline int __btrfs_fs_compat_ro(struct btrfs_fs_info *fs_info, u64 flag)
|
|||
return !!(btrfs_super_compat_ro_flags(disk_super) & flag);
|
||||
}
|
||||
|
||||
/*
|
||||
* Call btrfs_abort_transaction as early as possible when an error condition is
|
||||
* detected, that way the exact line number is reported.
|
||||
*/
|
||||
#define btrfs_abort_transaction(trans, root, errno) \
|
||||
do { \
|
||||
/* Report first abort since mount */ \
|
||||
if (!test_and_set_bit(BTRFS_FS_STATE_TRANS_ABORTED, \
|
||||
&((root)->fs_info->fs_state))) { \
|
||||
WARN(1, KERN_DEBUG \
|
||||
"BTRFS: Transaction aborted (error %d)\n", \
|
||||
(errno)); \
|
||||
} \
|
||||
__btrfs_abort_transaction((trans), (root), __func__, \
|
||||
__LINE__, (errno)); \
|
||||
} while (0)
|
||||
|
||||
#define btrfs_std_error(fs_info, errno, fmt, args...) \
|
||||
do { \
|
||||
__btrfs_std_error((fs_info), __func__, __LINE__, \
|
||||
(errno), fmt, ##args); \
|
||||
} while (0)
|
||||
|
||||
__printf(5, 6)
|
||||
__cold
|
||||
void __btrfs_panic(struct btrfs_fs_info *fs_info, const char *function,
|
||||
unsigned int line, int errno, const char *fmt, ...);
|
||||
|
||||
/*
|
||||
* If BTRFS_MOUNT_PANIC_ON_FATAL_ERROR is in mount_opt, __btrfs_panic
|
||||
* will panic(). Otherwise we BUG() here.
|
||||
*/
|
||||
#define btrfs_panic(fs_info, errno, fmt, args...) \
|
||||
do { \
|
||||
__btrfs_panic(fs_info, __func__, __LINE__, errno, fmt, ##args); \
|
||||
BUG(); \
|
||||
} while (0)
|
||||
|
||||
/* acl.c */
|
||||
#ifdef CONFIG_BTRFS_FS_POSIX_ACL
|
||||
struct posix_acl *btrfs_get_acl(struct inode *inode, int type);
|
||||
|
|
|
@ -134,7 +134,7 @@ again:
|
|||
/* cached in the btrfs inode and can be accessed */
|
||||
atomic_add(2, &node->refs);
|
||||
|
||||
ret = radix_tree_preload(GFP_NOFS & ~__GFP_HIGHMEM);
|
||||
ret = radix_tree_preload(GFP_NOFS);
|
||||
if (ret) {
|
||||
kmem_cache_free(delayed_node_cache, node);
|
||||
return ERR_PTR(ret);
|
||||
|
|
|
@ -1640,7 +1640,7 @@ int btrfs_insert_fs_root(struct btrfs_fs_info *fs_info,
|
|||
{
|
||||
int ret;
|
||||
|
||||
ret = radix_tree_preload(GFP_NOFS & ~__GFP_HIGHMEM);
|
||||
ret = radix_tree_preload(GFP_NOFS);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -2417,7 +2417,7 @@ static int btrfs_replay_log(struct btrfs_fs_info *fs_info,
|
|||
/* returns with log_tree_root freed on success */
|
||||
ret = btrfs_recover_log_trees(log_tree_root);
|
||||
if (ret) {
|
||||
btrfs_std_error(tree_root->fs_info, ret,
|
||||
btrfs_handle_fs_error(tree_root->fs_info, ret,
|
||||
"Failed to recover log tree");
|
||||
free_extent_buffer(log_tree_root->node);
|
||||
kfree(log_tree_root);
|
||||
|
@ -2714,7 +2714,7 @@ int open_ctree(struct super_block *sb,
|
|||
* Pass the whole disk block of size BTRFS_SUPER_INFO_SIZE (4k).
|
||||
*/
|
||||
if (btrfs_check_super_csum(bh->b_data)) {
|
||||
printk(KERN_ERR "BTRFS: superblock checksum mismatch\n");
|
||||
btrfs_err(fs_info, "superblock checksum mismatch");
|
||||
err = -EINVAL;
|
||||
brelse(bh);
|
||||
goto fail_alloc;
|
||||
|
@ -2734,7 +2734,7 @@ int open_ctree(struct super_block *sb,
|
|||
|
||||
ret = btrfs_check_super_valid(fs_info, sb->s_flags & MS_RDONLY);
|
||||
if (ret) {
|
||||
printk(KERN_ERR "BTRFS: superblock contains fatal errors\n");
|
||||
btrfs_err(fs_info, "superblock contains fatal errors");
|
||||
err = -EINVAL;
|
||||
goto fail_alloc;
|
||||
}
|
||||
|
@ -2769,9 +2769,9 @@ int open_ctree(struct super_block *sb,
|
|||
features = btrfs_super_incompat_flags(disk_super) &
|
||||
~BTRFS_FEATURE_INCOMPAT_SUPP;
|
||||
if (features) {
|
||||
printk(KERN_ERR "BTRFS: couldn't mount because of "
|
||||
"unsupported optional features (%Lx).\n",
|
||||
features);
|
||||
btrfs_err(fs_info,
|
||||
"cannot mount because of unsupported optional features (%llx)",
|
||||
features);
|
||||
err = -EINVAL;
|
||||
goto fail_alloc;
|
||||
}
|
||||
|
@ -2782,7 +2782,7 @@ int open_ctree(struct super_block *sb,
|
|||
features |= BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO;
|
||||
|
||||
if (features & BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA)
|
||||
printk(KERN_INFO "BTRFS: has skinny extents\n");
|
||||
btrfs_info(fs_info, "has skinny extents");
|
||||
|
||||
/*
|
||||
* flag our filesystem as having big metadata blocks if
|
||||
|
@ -2790,7 +2790,8 @@ int open_ctree(struct super_block *sb,
|
|||
*/
|
||||
if (btrfs_super_nodesize(disk_super) > PAGE_SIZE) {
|
||||
if (!(features & BTRFS_FEATURE_INCOMPAT_BIG_METADATA))
|
||||
printk(KERN_INFO "BTRFS: flagging fs with big metadata feature\n");
|
||||
btrfs_info(fs_info,
|
||||
"flagging fs with big metadata feature");
|
||||
features |= BTRFS_FEATURE_INCOMPAT_BIG_METADATA;
|
||||
}
|
||||
|
||||
|
@ -2806,9 +2807,9 @@ int open_ctree(struct super_block *sb,
|
|||
*/
|
||||
if ((features & BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS) &&
|
||||
(sectorsize != nodesize)) {
|
||||
printk(KERN_ERR "BTRFS: unequal leaf/node/sector sizes "
|
||||
"are not allowed for mixed block groups on %s\n",
|
||||
sb->s_id);
|
||||
btrfs_err(fs_info,
|
||||
"unequal nodesize/sectorsize (%u != %u) are not allowed for mixed block groups",
|
||||
nodesize, sectorsize);
|
||||
goto fail_alloc;
|
||||
}
|
||||
|
||||
|
@ -2821,8 +2822,8 @@ int open_ctree(struct super_block *sb,
|
|||
features = btrfs_super_compat_ro_flags(disk_super) &
|
||||
~BTRFS_FEATURE_COMPAT_RO_SUPP;
|
||||
if (!(sb->s_flags & MS_RDONLY) && features) {
|
||||
printk(KERN_ERR "BTRFS: couldn't mount RDWR because of "
|
||||
"unsupported option features (%Lx).\n",
|
||||
btrfs_err(fs_info,
|
||||
"cannot mount read-write because of unsupported optional features (%llx)",
|
||||
features);
|
||||
err = -EINVAL;
|
||||
goto fail_alloc;
|
||||
|
@ -2851,8 +2852,7 @@ int open_ctree(struct super_block *sb,
|
|||
ret = btrfs_read_sys_array(tree_root);
|
||||
mutex_unlock(&fs_info->chunk_mutex);
|
||||
if (ret) {
|
||||
printk(KERN_ERR "BTRFS: failed to read the system "
|
||||
"array on %s\n", sb->s_id);
|
||||
btrfs_err(fs_info, "failed to read the system array: %d", ret);
|
||||
goto fail_sb_buffer;
|
||||
}
|
||||
|
||||
|
@ -2866,8 +2866,7 @@ int open_ctree(struct super_block *sb,
|
|||
generation);
|
||||
if (IS_ERR(chunk_root->node) ||
|
||||
!extent_buffer_uptodate(chunk_root->node)) {
|
||||
printk(KERN_ERR "BTRFS: failed to read chunk root on %s\n",
|
||||
sb->s_id);
|
||||
btrfs_err(fs_info, "failed to read chunk root");
|
||||
if (!IS_ERR(chunk_root->node))
|
||||
free_extent_buffer(chunk_root->node);
|
||||
chunk_root->node = NULL;
|
||||
|
@ -2881,8 +2880,7 @@ int open_ctree(struct super_block *sb,
|
|||
|
||||
ret = btrfs_read_chunk_tree(chunk_root);
|
||||
if (ret) {
|
||||
printk(KERN_ERR "BTRFS: failed to read chunk tree on %s\n",
|
||||
sb->s_id);
|
||||
btrfs_err(fs_info, "failed to read chunk tree: %d", ret);
|
||||
goto fail_tree_roots;
|
||||
}
|
||||
|
||||
|
@ -2893,8 +2891,7 @@ int open_ctree(struct super_block *sb,
|
|||
btrfs_close_extra_devices(fs_devices, 0);
|
||||
|
||||
if (!fs_devices->latest_bdev) {
|
||||
printk(KERN_ERR "BTRFS: failed to read devices on %s\n",
|
||||
sb->s_id);
|
||||
btrfs_err(fs_info, "failed to read devices");
|
||||
goto fail_tree_roots;
|
||||
}
|
||||
|
||||
|
@ -2906,8 +2903,7 @@ retry_root_backup:
|
|||
generation);
|
||||
if (IS_ERR(tree_root->node) ||
|
||||
!extent_buffer_uptodate(tree_root->node)) {
|
||||
printk(KERN_WARNING "BTRFS: failed to read tree root on %s\n",
|
||||
sb->s_id);
|
||||
btrfs_warn(fs_info, "failed to read tree root");
|
||||
if (!IS_ERR(tree_root->node))
|
||||
free_extent_buffer(tree_root->node);
|
||||
tree_root->node = NULL;
|
||||
|
@ -2939,20 +2935,19 @@ retry_root_backup:
|
|||
|
||||
ret = btrfs_recover_balance(fs_info);
|
||||
if (ret) {
|
||||
printk(KERN_ERR "BTRFS: failed to recover balance\n");
|
||||
btrfs_err(fs_info, "failed to recover balance: %d", ret);
|
||||
goto fail_block_groups;
|
||||
}
|
||||
|
||||
ret = btrfs_init_dev_stats(fs_info);
|
||||
if (ret) {
|
||||
printk(KERN_ERR "BTRFS: failed to init dev_stats: %d\n",
|
||||
ret);
|
||||
btrfs_err(fs_info, "failed to init dev_stats: %d", ret);
|
||||
goto fail_block_groups;
|
||||
}
|
||||
|
||||
ret = btrfs_init_dev_replace(fs_info);
|
||||
if (ret) {
|
||||
pr_err("BTRFS: failed to init dev_replace: %d\n", ret);
|
||||
btrfs_err(fs_info, "failed to init dev_replace: %d", ret);
|
||||
goto fail_block_groups;
|
||||
}
|
||||
|
||||
|
@ -2960,31 +2955,33 @@ retry_root_backup:
|
|||
|
||||
ret = btrfs_sysfs_add_fsid(fs_devices, NULL);
|
||||
if (ret) {
|
||||
pr_err("BTRFS: failed to init sysfs fsid interface: %d\n", ret);
|
||||
btrfs_err(fs_info, "failed to init sysfs fsid interface: %d",
|
||||
ret);
|
||||
goto fail_block_groups;
|
||||
}
|
||||
|
||||
ret = btrfs_sysfs_add_device(fs_devices);
|
||||
if (ret) {
|
||||
pr_err("BTRFS: failed to init sysfs device interface: %d\n", ret);
|
||||
btrfs_err(fs_info, "failed to init sysfs device interface: %d",
|
||||
ret);
|
||||
goto fail_fsdev_sysfs;
|
||||
}
|
||||
|
||||
ret = btrfs_sysfs_add_mounted(fs_info);
|
||||
if (ret) {
|
||||
pr_err("BTRFS: failed to init sysfs interface: %d\n", ret);
|
||||
btrfs_err(fs_info, "failed to init sysfs interface: %d", ret);
|
||||
goto fail_fsdev_sysfs;
|
||||
}
|
||||
|
||||
ret = btrfs_init_space_info(fs_info);
|
||||
if (ret) {
|
||||
printk(KERN_ERR "BTRFS: Failed to initial space info: %d\n", ret);
|
||||
btrfs_err(fs_info, "failed to initialize space info: %d", ret);
|
||||
goto fail_sysfs;
|
||||
}
|
||||
|
||||
ret = btrfs_read_block_groups(fs_info->extent_root);
|
||||
if (ret) {
|
||||
printk(KERN_ERR "BTRFS: Failed to read block groups: %d\n", ret);
|
||||
btrfs_err(fs_info, "failed to read block groups: %d", ret);
|
||||
goto fail_sysfs;
|
||||
}
|
||||
fs_info->num_tolerated_disk_barrier_failures =
|
||||
|
@ -2992,7 +2989,8 @@ retry_root_backup:
|
|||
if (fs_info->fs_devices->missing_devices >
|
||||
fs_info->num_tolerated_disk_barrier_failures &&
|
||||
!(sb->s_flags & MS_RDONLY)) {
|
||||
pr_warn("BTRFS: missing devices(%llu) exceeds the limit(%d), writeable mount is not allowed\n",
|
||||
btrfs_warn(fs_info,
|
||||
"missing devices (%llu) exceeds the limit (%d), writeable mount is not allowed",
|
||||
fs_info->fs_devices->missing_devices,
|
||||
fs_info->num_tolerated_disk_barrier_failures);
|
||||
goto fail_sysfs;
|
||||
|
@ -3019,8 +3017,7 @@ retry_root_backup:
|
|||
if (!btrfs_test_opt(tree_root, SSD) &&
|
||||
!btrfs_test_opt(tree_root, NOSSD) &&
|
||||
!fs_info->fs_devices->rotating) {
|
||||
printk(KERN_INFO "BTRFS: detected SSD devices, enabling SSD "
|
||||
"mode\n");
|
||||
btrfs_info(fs_info, "detected SSD devices, enabling SSD mode");
|
||||
btrfs_set_opt(fs_info->mount_opt, SSD);
|
||||
}
|
||||
|
||||
|
@ -3038,8 +3035,9 @@ retry_root_backup:
|
|||
1 : 0,
|
||||
fs_info->check_integrity_print_mask);
|
||||
if (ret)
|
||||
printk(KERN_WARNING "BTRFS: failed to initialize"
|
||||
" integrity check module %s\n", sb->s_id);
|
||||
btrfs_warn(fs_info,
|
||||
"failed to initialize integrity check module: %d",
|
||||
ret);
|
||||
}
|
||||
#endif
|
||||
ret = btrfs_read_qgroup_config(fs_info);
|
||||
|
@ -3067,8 +3065,8 @@ retry_root_backup:
|
|||
/* We locked cleaner_mutex before creating cleaner_kthread. */
|
||||
ret = btrfs_recover_relocation(tree_root);
|
||||
if (ret < 0) {
|
||||
printk(KERN_WARNING
|
||||
"BTRFS: failed to recover relocation\n");
|
||||
btrfs_warn(fs_info, "failed to recover relocation: %d",
|
||||
ret);
|
||||
err = -EINVAL;
|
||||
goto fail_qgroup;
|
||||
}
|
||||
|
@ -3091,11 +3089,11 @@ retry_root_backup:
|
|||
|
||||
if (btrfs_test_opt(tree_root, FREE_SPACE_TREE) &&
|
||||
!btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE)) {
|
||||
pr_info("BTRFS: creating free space tree\n");
|
||||
btrfs_info(fs_info, "creating free space tree");
|
||||
ret = btrfs_create_free_space_tree(fs_info);
|
||||
if (ret) {
|
||||
pr_warn("BTRFS: failed to create free space tree %d\n",
|
||||
ret);
|
||||
btrfs_warn(fs_info,
|
||||
"failed to create free space tree: %d", ret);
|
||||
close_ctree(tree_root);
|
||||
return ret;
|
||||
}
|
||||
|
@ -3112,14 +3110,14 @@ retry_root_backup:
|
|||
|
||||
ret = btrfs_resume_balance_async(fs_info);
|
||||
if (ret) {
|
||||
printk(KERN_WARNING "BTRFS: failed to resume balance\n");
|
||||
btrfs_warn(fs_info, "failed to resume balance: %d", ret);
|
||||
close_ctree(tree_root);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = btrfs_resume_dev_replace_async(fs_info);
|
||||
if (ret) {
|
||||
pr_warn("BTRFS: failed to resume dev_replace\n");
|
||||
btrfs_warn(fs_info, "failed to resume device replace: %d", ret);
|
||||
close_ctree(tree_root);
|
||||
return ret;
|
||||
}
|
||||
|
@ -3128,33 +3126,33 @@ retry_root_backup:
|
|||
|
||||
if (btrfs_test_opt(tree_root, CLEAR_CACHE) &&
|
||||
btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE)) {
|
||||
pr_info("BTRFS: clearing free space tree\n");
|
||||
btrfs_info(fs_info, "clearing free space tree");
|
||||
ret = btrfs_clear_free_space_tree(fs_info);
|
||||
if (ret) {
|
||||
pr_warn("BTRFS: failed to clear free space tree %d\n",
|
||||
ret);
|
||||
btrfs_warn(fs_info,
|
||||
"failed to clear free space tree: %d", ret);
|
||||
close_ctree(tree_root);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (!fs_info->uuid_root) {
|
||||
pr_info("BTRFS: creating UUID tree\n");
|
||||
btrfs_info(fs_info, "creating UUID tree");
|
||||
ret = btrfs_create_uuid_tree(fs_info);
|
||||
if (ret) {
|
||||
pr_warn("BTRFS: failed to create the UUID tree %d\n",
|
||||
ret);
|
||||
btrfs_warn(fs_info,
|
||||
"failed to create the UUID tree: %d", ret);
|
||||
close_ctree(tree_root);
|
||||
return ret;
|
||||
}
|
||||
} else if (btrfs_test_opt(tree_root, RESCAN_UUID_TREE) ||
|
||||
fs_info->generation !=
|
||||
btrfs_super_uuid_tree_generation(disk_super)) {
|
||||
pr_info("BTRFS: checking UUID tree\n");
|
||||
btrfs_info(fs_info, "checking UUID tree");
|
||||
ret = btrfs_check_uuid_tree(fs_info);
|
||||
if (ret) {
|
||||
pr_warn("BTRFS: failed to check the UUID tree %d\n",
|
||||
ret);
|
||||
btrfs_warn(fs_info,
|
||||
"failed to check the UUID tree: %d", ret);
|
||||
close_ctree(tree_root);
|
||||
return ret;
|
||||
}
|
||||
|
@ -3658,7 +3656,7 @@ static int write_all_supers(struct btrfs_root *root, int max_mirrors)
|
|||
if (ret) {
|
||||
mutex_unlock(
|
||||
&root->fs_info->fs_devices->device_list_mutex);
|
||||
btrfs_std_error(root->fs_info, ret,
|
||||
btrfs_handle_fs_error(root->fs_info, ret,
|
||||
"errors while submitting device barriers.");
|
||||
return ret;
|
||||
}
|
||||
|
@ -3698,7 +3696,7 @@ static int write_all_supers(struct btrfs_root *root, int max_mirrors)
|
|||
mutex_unlock(&root->fs_info->fs_devices->device_list_mutex);
|
||||
|
||||
/* FUA is masked off if unsupported and can't be the reason */
|
||||
btrfs_std_error(root->fs_info, -EIO,
|
||||
btrfs_handle_fs_error(root->fs_info, -EIO,
|
||||
"%d errors while writing supers", total_errors);
|
||||
return -EIO;
|
||||
}
|
||||
|
@ -3716,7 +3714,7 @@ static int write_all_supers(struct btrfs_root *root, int max_mirrors)
|
|||
}
|
||||
mutex_unlock(&root->fs_info->fs_devices->device_list_mutex);
|
||||
if (total_errors > max_errors) {
|
||||
btrfs_std_error(root->fs_info, -EIO,
|
||||
btrfs_handle_fs_error(root->fs_info, -EIO,
|
||||
"%d errors while writing supers", total_errors);
|
||||
return -EIO;
|
||||
}
|
||||
|
|
|
@ -7025,36 +7025,35 @@ btrfs_lock_cluster(struct btrfs_block_group_cache *block_group,
|
|||
int delalloc)
|
||||
{
|
||||
struct btrfs_block_group_cache *used_bg = NULL;
|
||||
bool locked = false;
|
||||
again:
|
||||
|
||||
spin_lock(&cluster->refill_lock);
|
||||
if (locked) {
|
||||
while (1) {
|
||||
used_bg = cluster->block_group;
|
||||
if (!used_bg)
|
||||
return NULL;
|
||||
|
||||
if (used_bg == block_group)
|
||||
return used_bg;
|
||||
|
||||
btrfs_get_block_group(used_bg);
|
||||
|
||||
if (!delalloc)
|
||||
return used_bg;
|
||||
|
||||
if (down_read_trylock(&used_bg->data_rwsem))
|
||||
return used_bg;
|
||||
|
||||
spin_unlock(&cluster->refill_lock);
|
||||
|
||||
down_read(&used_bg->data_rwsem);
|
||||
|
||||
spin_lock(&cluster->refill_lock);
|
||||
if (used_bg == cluster->block_group)
|
||||
return used_bg;
|
||||
|
||||
up_read(&used_bg->data_rwsem);
|
||||
btrfs_put_block_group(used_bg);
|
||||
}
|
||||
|
||||
used_bg = cluster->block_group;
|
||||
if (!used_bg)
|
||||
return NULL;
|
||||
|
||||
if (used_bg == block_group)
|
||||
return used_bg;
|
||||
|
||||
btrfs_get_block_group(used_bg);
|
||||
|
||||
if (!delalloc)
|
||||
return used_bg;
|
||||
|
||||
if (down_read_trylock(&used_bg->data_rwsem))
|
||||
return used_bg;
|
||||
|
||||
spin_unlock(&cluster->refill_lock);
|
||||
down_read(&used_bg->data_rwsem);
|
||||
locked = true;
|
||||
goto again;
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
@ -9058,7 +9057,7 @@ out:
|
|||
if (!for_reloc && root_dropped == false)
|
||||
btrfs_add_dead_root(root);
|
||||
if (err && err != -EAGAIN)
|
||||
btrfs_std_error(root->fs_info, err, NULL);
|
||||
btrfs_handle_fs_error(root->fs_info, err, NULL);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
|
@ -3364,6 +3364,8 @@ static noinline_for_stack int __extent_writepage_io(struct inode *inode,
|
|||
|
||||
while (cur <= end) {
|
||||
u64 em_end;
|
||||
unsigned long max_nr;
|
||||
|
||||
if (cur >= i_size) {
|
||||
if (tree->ops && tree->ops->writepage_end_io_hook)
|
||||
tree->ops->writepage_end_io_hook(page, cur,
|
||||
|
@ -3419,32 +3421,23 @@ static noinline_for_stack int __extent_writepage_io(struct inode *inode,
|
|||
continue;
|
||||
}
|
||||
|
||||
if (tree->ops && tree->ops->writepage_io_hook) {
|
||||
ret = tree->ops->writepage_io_hook(page, cur,
|
||||
cur + iosize - 1);
|
||||
} else {
|
||||
ret = 0;
|
||||
max_nr = (i_size >> PAGE_SHIFT) + 1;
|
||||
|
||||
set_range_writeback(tree, cur, cur + iosize - 1);
|
||||
if (!PageWriteback(page)) {
|
||||
btrfs_err(BTRFS_I(inode)->root->fs_info,
|
||||
"page %lu not writeback, cur %llu end %llu",
|
||||
page->index, cur, end);
|
||||
}
|
||||
if (ret) {
|
||||
|
||||
ret = submit_extent_page(write_flags, tree, wbc, page,
|
||||
sector, iosize, pg_offset,
|
||||
bdev, &epd->bio, max_nr,
|
||||
end_bio_extent_writepage,
|
||||
0, 0, 0, false);
|
||||
if (ret)
|
||||
SetPageError(page);
|
||||
} else {
|
||||
unsigned long max_nr = (i_size >> PAGE_SHIFT) + 1;
|
||||
|
||||
set_range_writeback(tree, cur, cur + iosize - 1);
|
||||
if (!PageWriteback(page)) {
|
||||
btrfs_err(BTRFS_I(inode)->root->fs_info,
|
||||
"page %lu not writeback, cur %llu end %llu",
|
||||
page->index, cur, end);
|
||||
}
|
||||
|
||||
ret = submit_extent_page(write_flags, tree, wbc, page,
|
||||
sector, iosize, pg_offset,
|
||||
bdev, &epd->bio, max_nr,
|
||||
end_bio_extent_writepage,
|
||||
0, 0, 0, false);
|
||||
if (ret)
|
||||
SetPageError(page);
|
||||
}
|
||||
cur = cur + iosize;
|
||||
pg_offset += iosize;
|
||||
nr++;
|
||||
|
@ -4839,7 +4832,7 @@ struct extent_buffer *alloc_test_extent_buffer(struct btrfs_fs_info *fs_info,
|
|||
return NULL;
|
||||
eb->fs_info = fs_info;
|
||||
again:
|
||||
ret = radix_tree_preload(GFP_NOFS & ~__GFP_HIGHMEM);
|
||||
ret = radix_tree_preload(GFP_NOFS);
|
||||
if (ret)
|
||||
goto free_eb;
|
||||
spin_lock(&fs_info->buffer_lock);
|
||||
|
@ -4940,7 +4933,7 @@ struct extent_buffer *alloc_extent_buffer(struct btrfs_fs_info *fs_info,
|
|||
if (uptodate)
|
||||
set_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags);
|
||||
again:
|
||||
ret = radix_tree_preload(GFP_NOFS & ~__GFP_HIGHMEM);
|
||||
ret = radix_tree_preload(GFP_NOFS);
|
||||
if (ret)
|
||||
goto free_eb;
|
||||
|
||||
|
|
|
@ -71,7 +71,6 @@ struct extent_io_ops {
|
|||
u64 start, u64 end, int *page_started,
|
||||
unsigned long *nr_written);
|
||||
int (*writepage_start_hook)(struct page *page, u64 start, u64 end);
|
||||
int (*writepage_io_hook)(struct page *page, u64 start, u64 end);
|
||||
extent_submit_bio_hook_t *submit_bio_hook;
|
||||
int (*merge_bio_hook)(int rw, struct page *page, unsigned long offset,
|
||||
size_t size, struct bio *bio,
|
||||
|
|
|
@ -157,7 +157,7 @@ static int btrfs_del_inode_extref(struct btrfs_trans_handle *trans,
|
|||
*/
|
||||
if (!btrfs_find_name_in_ext_backref(path, ref_objectid,
|
||||
name, name_len, &extref)) {
|
||||
btrfs_std_error(root->fs_info, -ENOENT, NULL);
|
||||
btrfs_handle_fs_error(root->fs_info, -ENOENT, NULL);
|
||||
ret = -EROFS;
|
||||
goto out;
|
||||
}
|
||||
|
|
|
@ -125,10 +125,10 @@ static unsigned int btrfs_flags_to_ioctl(unsigned int flags)
|
|||
if (flags & BTRFS_INODE_NODATACOW)
|
||||
iflags |= FS_NOCOW_FL;
|
||||
|
||||
if ((flags & BTRFS_INODE_COMPRESS) && !(flags & BTRFS_INODE_NOCOMPRESS))
|
||||
iflags |= FS_COMPR_FL;
|
||||
else if (flags & BTRFS_INODE_NOCOMPRESS)
|
||||
if (flags & BTRFS_INODE_NOCOMPRESS)
|
||||
iflags |= FS_NOCOMP_FL;
|
||||
else if (flags & BTRFS_INODE_COMPRESS)
|
||||
iflags |= FS_COMPR_FL;
|
||||
|
||||
return iflags;
|
||||
}
|
||||
|
@ -4858,8 +4858,8 @@ static long btrfs_ioctl_qgroup_assign(struct file *file, void __user *arg)
|
|||
/* update qgroup status and info */
|
||||
err = btrfs_run_qgroups(trans, root->fs_info);
|
||||
if (err < 0)
|
||||
btrfs_std_error(root->fs_info, ret,
|
||||
"failed to update qgroup status and info\n");
|
||||
btrfs_handle_fs_error(root->fs_info, err,
|
||||
"failed to update qgroup status and info");
|
||||
err = btrfs_end_transaction(trans, root);
|
||||
if (err && !ret)
|
||||
ret = err;
|
||||
|
|
|
@ -2418,7 +2418,7 @@ again:
|
|||
}
|
||||
out:
|
||||
if (ret) {
|
||||
btrfs_std_error(root->fs_info, ret, NULL);
|
||||
btrfs_handle_fs_error(root->fs_info, ret, NULL);
|
||||
if (!list_empty(&reloc_roots))
|
||||
free_reloc_roots(&reloc_roots);
|
||||
|
||||
|
|
|
@ -284,7 +284,7 @@ int btrfs_find_orphan_roots(struct btrfs_root *tree_root)
|
|||
trans = btrfs_join_transaction(tree_root);
|
||||
if (IS_ERR(trans)) {
|
||||
err = PTR_ERR(trans);
|
||||
btrfs_std_error(tree_root->fs_info, err,
|
||||
btrfs_handle_fs_error(tree_root->fs_info, err,
|
||||
"Failed to start trans to delete "
|
||||
"orphan item");
|
||||
break;
|
||||
|
@ -293,7 +293,7 @@ int btrfs_find_orphan_roots(struct btrfs_root *tree_root)
|
|||
root_key.objectid);
|
||||
btrfs_end_transaction(trans, tree_root);
|
||||
if (err) {
|
||||
btrfs_std_error(tree_root->fs_info, err,
|
||||
btrfs_handle_fs_error(tree_root->fs_info, err,
|
||||
"Failed to delete root orphan "
|
||||
"item");
|
||||
break;
|
||||
|
|
|
@ -97,15 +97,6 @@ const char *btrfs_decode_error(int errno)
|
|||
return errstr;
|
||||
}
|
||||
|
||||
static void save_error_info(struct btrfs_fs_info *fs_info)
|
||||
{
|
||||
/*
|
||||
* today we only save the error info into ram. Long term we'll
|
||||
* also send it down to the disk
|
||||
*/
|
||||
set_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state);
|
||||
}
|
||||
|
||||
/* btrfs handle error by forcing the filesystem readonly */
|
||||
static void btrfs_handle_error(struct btrfs_fs_info *fs_info)
|
||||
{
|
||||
|
@ -131,11 +122,11 @@ static void btrfs_handle_error(struct btrfs_fs_info *fs_info)
|
|||
}
|
||||
|
||||
/*
|
||||
* __btrfs_std_error decodes expected errors from the caller and
|
||||
* __btrfs_handle_fs_error decodes expected errors from the caller and
|
||||
* invokes the approciate error response.
|
||||
*/
|
||||
__cold
|
||||
void __btrfs_std_error(struct btrfs_fs_info *fs_info, const char *function,
|
||||
void __btrfs_handle_fs_error(struct btrfs_fs_info *fs_info, const char *function,
|
||||
unsigned int line, int errno, const char *fmt, ...)
|
||||
{
|
||||
struct super_block *sb = fs_info->sb;
|
||||
|
@ -170,8 +161,13 @@ void __btrfs_std_error(struct btrfs_fs_info *fs_info, const char *function,
|
|||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Today we only save the error info to memory. Long term we'll
|
||||
* also send it down to the disk
|
||||
*/
|
||||
set_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state);
|
||||
|
||||
/* Don't go through full error handling during mount */
|
||||
save_error_info(fs_info);
|
||||
if (sb->s_flags & MS_BORN)
|
||||
btrfs_handle_error(fs_info);
|
||||
}
|
||||
|
@ -252,7 +248,7 @@ void __btrfs_abort_transaction(struct btrfs_trans_handle *trans,
|
|||
/* Wake up anybody who may be waiting on this transaction */
|
||||
wake_up(&root->fs_info->transaction_wait);
|
||||
wake_up(&root->fs_info->transaction_blocked_wait);
|
||||
__btrfs_std_error(root->fs_info, function, line, errno, NULL);
|
||||
__btrfs_handle_fs_error(root->fs_info, function, line, errno, NULL);
|
||||
}
|
||||
/*
|
||||
* __btrfs_panic decodes unexpected, fatal errors from the caller,
|
||||
|
@ -1488,10 +1484,10 @@ static int setup_security_options(struct btrfs_fs_info *fs_info,
|
|||
memcpy(&fs_info->security_opts, sec_opts, sizeof(*sec_opts));
|
||||
} else {
|
||||
/*
|
||||
* Since SELinux(the only one supports security_mnt_opts) does
|
||||
* NOT support changing context during remount/mount same sb,
|
||||
* This must be the same or part of the same security options,
|
||||
* just free it.
|
||||
* Since SELinux (the only one supporting security_mnt_opts)
|
||||
* does NOT support changing context during remount/mount of
|
||||
* the same sb, this must be the same or part of the same
|
||||
* security options, just free it.
|
||||
*/
|
||||
security_free_mnt_opts(sec_opts);
|
||||
}
|
||||
|
@ -1669,8 +1665,8 @@ static inline void btrfs_remount_cleanup(struct btrfs_fs_info *fs_info,
|
|||
unsigned long old_opts)
|
||||
{
|
||||
/*
|
||||
* We need cleanup all defragable inodes if the autodefragment is
|
||||
* close or the fs is R/O.
|
||||
* We need to cleanup all defragable inodes if the autodefragment is
|
||||
* close or the filesystem is read only.
|
||||
*/
|
||||
if (btrfs_raw_test_opt(old_opts, AUTO_DEFRAG) &&
|
||||
(!btrfs_raw_test_opt(fs_info->mount_opt, AUTO_DEFRAG) ||
|
||||
|
@ -2054,7 +2050,7 @@ static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf)
|
|||
int mixed = 0;
|
||||
|
||||
/*
|
||||
* holding chunk_muext to avoid allocating new chunks, holding
|
||||
* holding chunk_mutex to avoid allocating new chunks, holding
|
||||
* device_list_mutex to avoid the device being removed
|
||||
*/
|
||||
rcu_read_lock();
|
||||
|
|
|
@ -2231,7 +2231,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
|
|||
|
||||
ret = btrfs_write_and_wait_transaction(trans, root);
|
||||
if (ret) {
|
||||
btrfs_std_error(root->fs_info, ret,
|
||||
btrfs_handle_fs_error(root->fs_info, ret,
|
||||
"Error while writing out transaction");
|
||||
mutex_unlock(&root->fs_info->tree_log_mutex);
|
||||
goto scrub_continue;
|
||||
|
|
|
@ -5519,7 +5519,7 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
|
|||
|
||||
ret = walk_log_tree(trans, log_root_tree, &wc);
|
||||
if (ret) {
|
||||
btrfs_std_error(fs_info, ret, "Failed to pin buffers while "
|
||||
btrfs_handle_fs_error(fs_info, ret, "Failed to pin buffers while "
|
||||
"recovering log root tree.");
|
||||
goto error;
|
||||
}
|
||||
|
@ -5533,7 +5533,7 @@ again:
|
|||
ret = btrfs_search_slot(NULL, log_root_tree, &key, path, 0, 0);
|
||||
|
||||
if (ret < 0) {
|
||||
btrfs_std_error(fs_info, ret,
|
||||
btrfs_handle_fs_error(fs_info, ret,
|
||||
"Couldn't find tree log root.");
|
||||
goto error;
|
||||
}
|
||||
|
@ -5551,7 +5551,7 @@ again:
|
|||
log = btrfs_read_fs_root(log_root_tree, &found_key);
|
||||
if (IS_ERR(log)) {
|
||||
ret = PTR_ERR(log);
|
||||
btrfs_std_error(fs_info, ret,
|
||||
btrfs_handle_fs_error(fs_info, ret,
|
||||
"Couldn't read tree log root.");
|
||||
goto error;
|
||||
}
|
||||
|
@ -5566,7 +5566,7 @@ again:
|
|||
free_extent_buffer(log->node);
|
||||
free_extent_buffer(log->commit_root);
|
||||
kfree(log);
|
||||
btrfs_std_error(fs_info, ret, "Couldn't read target root "
|
||||
btrfs_handle_fs_error(fs_info, ret, "Couldn't read target root "
|
||||
"for tree log recovery.");
|
||||
goto error;
|
||||
}
|
||||
|
|
|
@ -1454,7 +1454,7 @@ again:
|
|||
extent = btrfs_item_ptr(leaf, path->slots[0],
|
||||
struct btrfs_dev_extent);
|
||||
} else {
|
||||
btrfs_std_error(root->fs_info, ret, "Slot search failed");
|
||||
btrfs_handle_fs_error(root->fs_info, ret, "Slot search failed");
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -1462,7 +1462,7 @@ again:
|
|||
|
||||
ret = btrfs_del_item(trans, root, path);
|
||||
if (ret) {
|
||||
btrfs_std_error(root->fs_info, ret,
|
||||
btrfs_handle_fs_error(root->fs_info, ret,
|
||||
"Failed to remove dev extent item");
|
||||
} else {
|
||||
set_bit(BTRFS_TRANS_HAVE_FREE_BGS, &trans->transaction->flags);
|
||||
|
@ -2426,7 +2426,7 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path)
|
|||
|
||||
ret = btrfs_relocate_sys_chunks(root);
|
||||
if (ret < 0)
|
||||
btrfs_std_error(root->fs_info, ret,
|
||||
btrfs_handle_fs_error(root->fs_info, ret,
|
||||
"Failed to relocate sys chunks after "
|
||||
"device initialization. This can be fixed "
|
||||
"using the \"btrfs balance\" command.");
|
||||
|
@ -2671,7 +2671,7 @@ static int btrfs_free_chunk(struct btrfs_trans_handle *trans,
|
|||
if (ret < 0)
|
||||
goto out;
|
||||
else if (ret > 0) { /* Logic error or corruption */
|
||||
btrfs_std_error(root->fs_info, -ENOENT,
|
||||
btrfs_handle_fs_error(root->fs_info, -ENOENT,
|
||||
"Failed lookup while freeing chunk.");
|
||||
ret = -ENOENT;
|
||||
goto out;
|
||||
|
@ -2679,7 +2679,7 @@ static int btrfs_free_chunk(struct btrfs_trans_handle *trans,
|
|||
|
||||
ret = btrfs_del_item(trans, root, path);
|
||||
if (ret < 0)
|
||||
btrfs_std_error(root->fs_info, ret,
|
||||
btrfs_handle_fs_error(root->fs_info, ret,
|
||||
"Failed to delete chunk item.");
|
||||
out:
|
||||
btrfs_free_path(path);
|
||||
|
@ -2865,7 +2865,7 @@ static int btrfs_relocate_chunk(struct btrfs_root *root, u64 chunk_offset)
|
|||
chunk_offset);
|
||||
if (IS_ERR(trans)) {
|
||||
ret = PTR_ERR(trans);
|
||||
btrfs_std_error(root->fs_info, ret, NULL);
|
||||
btrfs_handle_fs_error(root->fs_info, ret, NULL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -3647,7 +3647,7 @@ static void __cancel_balance(struct btrfs_fs_info *fs_info)
|
|||
unset_balance_control(fs_info);
|
||||
ret = del_balance_item(fs_info->tree_root);
|
||||
if (ret)
|
||||
btrfs_std_error(fs_info, ret, NULL);
|
||||
btrfs_handle_fs_error(fs_info, ret, NULL);
|
||||
|
||||
atomic_set(&fs_info->mutually_exclusive_operation_running, 0);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче