Merge branch 'anand/sysfs-updates-v4.3-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux into for-linus-4.4
Signed-off-by: Chris Mason <clm@fb.com>
This commit is contained in:
commit
62fb50ab7c
17 changed files with 198 additions and 177 deletions
|
@ -1011,7 +1011,7 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans,
|
||||||
return ret;
|
return ret;
|
||||||
if (refs == 0) {
|
if (refs == 0) {
|
||||||
ret = -EROFS;
|
ret = -EROFS;
|
||||||
btrfs_std_error(root->fs_info, ret);
|
btrfs_std_error(root->fs_info, ret, NULL);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1927,7 +1927,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
|
||||||
child = read_node_slot(root, mid, 0);
|
child = read_node_slot(root, mid, 0);
|
||||||
if (!child) {
|
if (!child) {
|
||||||
ret = -EROFS;
|
ret = -EROFS;
|
||||||
btrfs_std_error(root->fs_info, ret);
|
btrfs_std_error(root->fs_info, ret, NULL);
|
||||||
goto enospc;
|
goto enospc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2030,7 +2030,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
|
||||||
*/
|
*/
|
||||||
if (!left) {
|
if (!left) {
|
||||||
ret = -EROFS;
|
ret = -EROFS;
|
||||||
btrfs_std_error(root->fs_info, ret);
|
btrfs_std_error(root->fs_info, ret, NULL);
|
||||||
goto enospc;
|
goto enospc;
|
||||||
}
|
}
|
||||||
wret = balance_node_right(trans, root, mid, left);
|
wret = balance_node_right(trans, root, mid, left);
|
||||||
|
|
|
@ -4004,8 +4004,8 @@ int btrfs_defrag_leaves(struct btrfs_trans_handle *trans,
|
||||||
/* sysfs.c */
|
/* sysfs.c */
|
||||||
int btrfs_init_sysfs(void);
|
int btrfs_init_sysfs(void);
|
||||||
void btrfs_exit_sysfs(void);
|
void btrfs_exit_sysfs(void);
|
||||||
int btrfs_sysfs_add_one(struct btrfs_fs_info *fs_info);
|
int btrfs_sysfs_add_mounted(struct btrfs_fs_info *fs_info);
|
||||||
void btrfs_sysfs_remove_one(struct btrfs_fs_info *fs_info);
|
void btrfs_sysfs_remove_mounted(struct btrfs_fs_info *fs_info);
|
||||||
|
|
||||||
/* xattr.c */
|
/* xattr.c */
|
||||||
ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size);
|
ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size);
|
||||||
|
@ -4215,14 +4215,7 @@ do { \
|
||||||
__LINE__, (errno)); \
|
__LINE__, (errno)); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define btrfs_std_error(fs_info, errno) \
|
#define btrfs_std_error(fs_info, errno, fmt, args...) \
|
||||||
do { \
|
|
||||||
if ((errno)) \
|
|
||||||
__btrfs_std_error((fs_info), __func__, \
|
|
||||||
__LINE__, (errno), NULL); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define btrfs_error(fs_info, errno, fmt, args...) \
|
|
||||||
do { \
|
do { \
|
||||||
__btrfs_std_error((fs_info), __func__, __LINE__, \
|
__btrfs_std_error((fs_info), __func__, __LINE__, \
|
||||||
(errno), fmt, ##args); \
|
(errno), fmt, ##args); \
|
||||||
|
|
|
@ -327,19 +327,6 @@ int btrfs_dev_replace_start(struct btrfs_root *root,
|
||||||
args->start.tgtdev_name[0] == '\0')
|
args->start.tgtdev_name[0] == '\0')
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/*
|
|
||||||
* Here we commit the transaction to make sure commit_total_bytes
|
|
||||||
* of all the devices are updated.
|
|
||||||
*/
|
|
||||||
trans = btrfs_attach_transaction(root);
|
|
||||||
if (!IS_ERR(trans)) {
|
|
||||||
ret = btrfs_commit_transaction(trans, root);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
} else if (PTR_ERR(trans) != -ENOENT) {
|
|
||||||
return PTR_ERR(trans);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* the disk copy procedure reuses the scrub code */
|
/* the disk copy procedure reuses the scrub code */
|
||||||
mutex_lock(&fs_info->volume_mutex);
|
mutex_lock(&fs_info->volume_mutex);
|
||||||
ret = btrfs_dev_replace_find_srcdev(root, args->start.srcdevid,
|
ret = btrfs_dev_replace_find_srcdev(root, args->start.srcdevid,
|
||||||
|
@ -356,6 +343,19 @@ int btrfs_dev_replace_start(struct btrfs_root *root,
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Here we commit the transaction to make sure commit_total_bytes
|
||||||
|
* of all the devices are updated.
|
||||||
|
*/
|
||||||
|
trans = btrfs_attach_transaction(root);
|
||||||
|
if (!IS_ERR(trans)) {
|
||||||
|
ret = btrfs_commit_transaction(trans, root);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
} else if (PTR_ERR(trans) != -ENOENT) {
|
||||||
|
return PTR_ERR(trans);
|
||||||
|
}
|
||||||
|
|
||||||
btrfs_dev_replace_lock(dev_replace);
|
btrfs_dev_replace_lock(dev_replace);
|
||||||
switch (dev_replace->replace_state) {
|
switch (dev_replace->replace_state) {
|
||||||
case BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED:
|
case BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED:
|
||||||
|
@ -375,10 +375,6 @@ int btrfs_dev_replace_start(struct btrfs_root *root,
|
||||||
WARN_ON(!tgt_device);
|
WARN_ON(!tgt_device);
|
||||||
dev_replace->tgtdev = tgt_device;
|
dev_replace->tgtdev = tgt_device;
|
||||||
|
|
||||||
ret = btrfs_kobj_add_device(tgt_device->fs_devices, tgt_device);
|
|
||||||
if (ret)
|
|
||||||
btrfs_err(root->fs_info, "kobj add dev failed %d\n", ret);
|
|
||||||
|
|
||||||
btrfs_info_in_rcu(root->fs_info,
|
btrfs_info_in_rcu(root->fs_info,
|
||||||
"dev_replace from %s (devid %llu) to %s started",
|
"dev_replace from %s (devid %llu) to %s started",
|
||||||
src_device->missing ? "<missing disk>" :
|
src_device->missing ? "<missing disk>" :
|
||||||
|
@ -401,6 +397,10 @@ int btrfs_dev_replace_start(struct btrfs_root *root,
|
||||||
args->result = BTRFS_IOCTL_DEV_REPLACE_RESULT_NO_ERROR;
|
args->result = BTRFS_IOCTL_DEV_REPLACE_RESULT_NO_ERROR;
|
||||||
btrfs_dev_replace_unlock(dev_replace);
|
btrfs_dev_replace_unlock(dev_replace);
|
||||||
|
|
||||||
|
ret = btrfs_sysfs_add_device_link(tgt_device->fs_devices, tgt_device);
|
||||||
|
if (ret)
|
||||||
|
btrfs_err(root->fs_info, "kobj add dev failed %d\n", ret);
|
||||||
|
|
||||||
btrfs_wait_ordered_roots(root->fs_info, -1);
|
btrfs_wait_ordered_roots(root->fs_info, -1);
|
||||||
|
|
||||||
/* force writing the updated state information to disk */
|
/* force writing the updated state information to disk */
|
||||||
|
@ -586,7 +586,7 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info,
|
||||||
mutex_unlock(&uuid_mutex);
|
mutex_unlock(&uuid_mutex);
|
||||||
|
|
||||||
/* replace the sysfs entry */
|
/* replace the sysfs entry */
|
||||||
btrfs_kobj_rm_device(fs_info->fs_devices, src_device);
|
btrfs_sysfs_rm_device_link(fs_info->fs_devices, src_device);
|
||||||
btrfs_rm_dev_replace_free_srcdev(fs_info, src_device);
|
btrfs_rm_dev_replace_free_srcdev(fs_info, src_device);
|
||||||
|
|
||||||
/* write back the superblocks */
|
/* write back the superblocks */
|
||||||
|
|
|
@ -2375,7 +2375,7 @@ static int btrfs_replay_log(struct btrfs_fs_info *fs_info,
|
||||||
/* returns with log_tree_root freed on success */
|
/* returns with log_tree_root freed on success */
|
||||||
ret = btrfs_recover_log_trees(log_tree_root);
|
ret = btrfs_recover_log_trees(log_tree_root);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
btrfs_error(tree_root->fs_info, ret,
|
btrfs_std_error(tree_root->fs_info, ret,
|
||||||
"Failed to recover log tree");
|
"Failed to recover log tree");
|
||||||
free_extent_buffer(log_tree_root->node);
|
free_extent_buffer(log_tree_root->node);
|
||||||
kfree(log_tree_root);
|
kfree(log_tree_root);
|
||||||
|
@ -2651,8 +2651,8 @@ int open_ctree(struct super_block *sb,
|
||||||
* Read super block and check the signature bytes only
|
* Read super block and check the signature bytes only
|
||||||
*/
|
*/
|
||||||
bh = btrfs_read_dev_super(fs_devices->latest_bdev);
|
bh = btrfs_read_dev_super(fs_devices->latest_bdev);
|
||||||
if (!bh) {
|
if (IS_ERR(bh)) {
|
||||||
err = -EINVAL;
|
err = PTR_ERR(bh);
|
||||||
goto fail_alloc;
|
goto fail_alloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2935,7 +2935,7 @@ retry_root_backup:
|
||||||
goto fail_fsdev_sysfs;
|
goto fail_fsdev_sysfs;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = btrfs_sysfs_add_one(fs_info);
|
ret = btrfs_sysfs_add_mounted(fs_info);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pr_err("BTRFS: failed to init sysfs interface: %d\n", ret);
|
pr_err("BTRFS: failed to init sysfs interface: %d\n", ret);
|
||||||
goto fail_fsdev_sysfs;
|
goto fail_fsdev_sysfs;
|
||||||
|
@ -3115,7 +3115,7 @@ fail_cleaner:
|
||||||
filemap_write_and_wait(fs_info->btree_inode->i_mapping);
|
filemap_write_and_wait(fs_info->btree_inode->i_mapping);
|
||||||
|
|
||||||
fail_sysfs:
|
fail_sysfs:
|
||||||
btrfs_sysfs_remove_one(fs_info);
|
btrfs_sysfs_remove_mounted(fs_info);
|
||||||
|
|
||||||
fail_fsdev_sysfs:
|
fail_fsdev_sysfs:
|
||||||
btrfs_sysfs_remove_fsid(fs_info->fs_devices);
|
btrfs_sysfs_remove_fsid(fs_info->fs_devices);
|
||||||
|
@ -3190,6 +3190,37 @@ static void btrfs_end_buffer_write_sync(struct buffer_head *bh, int uptodate)
|
||||||
put_bh(bh);
|
put_bh(bh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int btrfs_read_dev_one_super(struct block_device *bdev, int copy_num,
|
||||||
|
struct buffer_head **bh_ret)
|
||||||
|
{
|
||||||
|
struct buffer_head *bh;
|
||||||
|
struct btrfs_super_block *super;
|
||||||
|
u64 bytenr;
|
||||||
|
|
||||||
|
bytenr = btrfs_sb_offset(copy_num);
|
||||||
|
if (bytenr + BTRFS_SUPER_INFO_SIZE >= i_size_read(bdev->bd_inode))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
bh = __bread(bdev, bytenr / 4096, BTRFS_SUPER_INFO_SIZE);
|
||||||
|
/*
|
||||||
|
* If we fail to read from the underlying devices, as of now
|
||||||
|
* the best option we have is to mark it EIO.
|
||||||
|
*/
|
||||||
|
if (!bh)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
super = (struct btrfs_super_block *)bh->b_data;
|
||||||
|
if (btrfs_super_bytenr(super) != bytenr ||
|
||||||
|
btrfs_super_magic(super) != BTRFS_MAGIC) {
|
||||||
|
brelse(bh);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*bh_ret = bh;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct buffer_head *btrfs_read_dev_super(struct block_device *bdev)
|
struct buffer_head *btrfs_read_dev_super(struct block_device *bdev)
|
||||||
{
|
{
|
||||||
struct buffer_head *bh;
|
struct buffer_head *bh;
|
||||||
|
@ -3197,7 +3228,7 @@ struct buffer_head *btrfs_read_dev_super(struct block_device *bdev)
|
||||||
struct btrfs_super_block *super;
|
struct btrfs_super_block *super;
|
||||||
int i;
|
int i;
|
||||||
u64 transid = 0;
|
u64 transid = 0;
|
||||||
u64 bytenr;
|
int ret = -EINVAL;
|
||||||
|
|
||||||
/* we would like to check all the supers, but that would make
|
/* we would like to check all the supers, but that would make
|
||||||
* a btrfs mount succeed after a mkfs from a different FS.
|
* a btrfs mount succeed after a mkfs from a different FS.
|
||||||
|
@ -3205,21 +3236,11 @@ struct buffer_head *btrfs_read_dev_super(struct block_device *bdev)
|
||||||
* later supers, using BTRFS_SUPER_MIRROR_MAX instead
|
* later supers, using BTRFS_SUPER_MIRROR_MAX instead
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < 1; i++) {
|
for (i = 0; i < 1; i++) {
|
||||||
bytenr = btrfs_sb_offset(i);
|
ret = btrfs_read_dev_one_super(bdev, i, &bh);
|
||||||
if (bytenr + BTRFS_SUPER_INFO_SIZE >=
|
if (ret)
|
||||||
i_size_read(bdev->bd_inode))
|
|
||||||
break;
|
|
||||||
bh = __bread(bdev, bytenr / 4096,
|
|
||||||
BTRFS_SUPER_INFO_SIZE);
|
|
||||||
if (!bh)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
super = (struct btrfs_super_block *)bh->b_data;
|
super = (struct btrfs_super_block *)bh->b_data;
|
||||||
if (btrfs_super_bytenr(super) != bytenr ||
|
|
||||||
btrfs_super_magic(super) != BTRFS_MAGIC) {
|
|
||||||
brelse(bh);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!latest || btrfs_super_generation(super) > transid) {
|
if (!latest || btrfs_super_generation(super) > transid) {
|
||||||
brelse(latest);
|
brelse(latest);
|
||||||
|
@ -3229,6 +3250,10 @@ struct buffer_head *btrfs_read_dev_super(struct block_device *bdev)
|
||||||
brelse(bh);
|
brelse(bh);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!latest)
|
||||||
|
return ERR_PTR(ret);
|
||||||
|
|
||||||
return latest;
|
return latest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3547,7 +3572,7 @@ static int write_all_supers(struct btrfs_root *root, int max_mirrors)
|
||||||
if (ret) {
|
if (ret) {
|
||||||
mutex_unlock(
|
mutex_unlock(
|
||||||
&root->fs_info->fs_devices->device_list_mutex);
|
&root->fs_info->fs_devices->device_list_mutex);
|
||||||
btrfs_error(root->fs_info, ret,
|
btrfs_std_error(root->fs_info, ret,
|
||||||
"errors while submitting device barriers.");
|
"errors while submitting device barriers.");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -3587,7 +3612,7 @@ static int write_all_supers(struct btrfs_root *root, int max_mirrors)
|
||||||
mutex_unlock(&root->fs_info->fs_devices->device_list_mutex);
|
mutex_unlock(&root->fs_info->fs_devices->device_list_mutex);
|
||||||
|
|
||||||
/* FUA is masked off if unsupported and can't be the reason */
|
/* FUA is masked off if unsupported and can't be the reason */
|
||||||
btrfs_error(root->fs_info, -EIO,
|
btrfs_std_error(root->fs_info, -EIO,
|
||||||
"%d errors while writing supers", total_errors);
|
"%d errors while writing supers", total_errors);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
@ -3605,7 +3630,7 @@ static int write_all_supers(struct btrfs_root *root, int max_mirrors)
|
||||||
}
|
}
|
||||||
mutex_unlock(&root->fs_info->fs_devices->device_list_mutex);
|
mutex_unlock(&root->fs_info->fs_devices->device_list_mutex);
|
||||||
if (total_errors > max_errors) {
|
if (total_errors > max_errors) {
|
||||||
btrfs_error(root->fs_info, -EIO,
|
btrfs_std_error(root->fs_info, -EIO,
|
||||||
"%d errors while writing supers", total_errors);
|
"%d errors while writing supers", total_errors);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
@ -3791,7 +3816,7 @@ void close_ctree(struct btrfs_root *root)
|
||||||
percpu_counter_sum(&fs_info->delalloc_bytes));
|
percpu_counter_sum(&fs_info->delalloc_bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
btrfs_sysfs_remove_one(fs_info);
|
btrfs_sysfs_remove_mounted(fs_info);
|
||||||
btrfs_sysfs_remove_fsid(fs_info->fs_devices);
|
btrfs_sysfs_remove_fsid(fs_info->fs_devices);
|
||||||
|
|
||||||
btrfs_free_fs_roots(fs_info);
|
btrfs_free_fs_roots(fs_info);
|
||||||
|
|
|
@ -60,6 +60,8 @@ void close_ctree(struct btrfs_root *root);
|
||||||
int write_ctree_super(struct btrfs_trans_handle *trans,
|
int write_ctree_super(struct btrfs_trans_handle *trans,
|
||||||
struct btrfs_root *root, int max_mirrors);
|
struct btrfs_root *root, int max_mirrors);
|
||||||
struct buffer_head *btrfs_read_dev_super(struct block_device *bdev);
|
struct buffer_head *btrfs_read_dev_super(struct block_device *bdev);
|
||||||
|
int btrfs_read_dev_one_super(struct block_device *bdev, int copy_num,
|
||||||
|
struct buffer_head **bh_ret);
|
||||||
int btrfs_commit_super(struct btrfs_root *root);
|
int btrfs_commit_super(struct btrfs_root *root);
|
||||||
struct extent_buffer *btrfs_find_tree_block(struct btrfs_fs_info *fs_info,
|
struct extent_buffer *btrfs_find_tree_block(struct btrfs_fs_info *fs_info,
|
||||||
u64 bytenr);
|
u64 bytenr);
|
||||||
|
|
|
@ -8694,7 +8694,7 @@ out:
|
||||||
if (!for_reloc && root_dropped == false)
|
if (!for_reloc && root_dropped == false)
|
||||||
btrfs_add_dead_root(root);
|
btrfs_add_dead_root(root);
|
||||||
if (err && err != -EAGAIN)
|
if (err && err != -EAGAIN)
|
||||||
btrfs_std_error(root->fs_info, err);
|
btrfs_std_error(root->fs_info, err, NULL);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,
|
if (!btrfs_find_name_in_ext_backref(path, ref_objectid,
|
||||||
name, name_len, &extref)) {
|
name, name_len, &extref)) {
|
||||||
btrfs_std_error(root->fs_info, -ENOENT);
|
btrfs_std_error(root->fs_info, -ENOENT, NULL);
|
||||||
ret = -EROFS;
|
ret = -EROFS;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4806,7 +4806,7 @@ static long btrfs_ioctl_qgroup_assign(struct file *file, void __user *arg)
|
||||||
/* update qgroup status and info */
|
/* update qgroup status and info */
|
||||||
err = btrfs_run_qgroups(trans, root->fs_info);
|
err = btrfs_run_qgroups(trans, root->fs_info);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
btrfs_error(root->fs_info, ret,
|
btrfs_std_error(root->fs_info, ret,
|
||||||
"failed to update qgroup status and info\n");
|
"failed to update qgroup status and info\n");
|
||||||
err = btrfs_end_transaction(trans, root);
|
err = btrfs_end_transaction(trans, root);
|
||||||
if (err && !ret)
|
if (err && !ret)
|
||||||
|
|
|
@ -2418,7 +2418,7 @@ again:
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
if (ret) {
|
if (ret) {
|
||||||
btrfs_std_error(root->fs_info, ret);
|
btrfs_std_error(root->fs_info, ret, NULL);
|
||||||
if (!list_empty(&reloc_roots))
|
if (!list_empty(&reloc_roots))
|
||||||
free_reloc_roots(&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);
|
trans = btrfs_join_transaction(tree_root);
|
||||||
if (IS_ERR(trans)) {
|
if (IS_ERR(trans)) {
|
||||||
err = PTR_ERR(trans);
|
err = PTR_ERR(trans);
|
||||||
btrfs_error(tree_root->fs_info, err,
|
btrfs_std_error(tree_root->fs_info, err,
|
||||||
"Failed to start trans to delete "
|
"Failed to start trans to delete "
|
||||||
"orphan item");
|
"orphan item");
|
||||||
break;
|
break;
|
||||||
|
@ -293,7 +293,7 @@ int btrfs_find_orphan_roots(struct btrfs_root *tree_root)
|
||||||
root_key.objectid);
|
root_key.objectid);
|
||||||
btrfs_end_transaction(trans, tree_root);
|
btrfs_end_transaction(trans, tree_root);
|
||||||
if (err) {
|
if (err) {
|
||||||
btrfs_error(tree_root->fs_info, err,
|
btrfs_std_error(tree_root->fs_info, err,
|
||||||
"Failed to delete root orphan "
|
"Failed to delete root orphan "
|
||||||
"item");
|
"item");
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -130,7 +130,6 @@ static void btrfs_handle_error(struct btrfs_fs_info *fs_info)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PRINTK
|
|
||||||
/*
|
/*
|
||||||
* __btrfs_std_error decodes expected errors from the caller and
|
* __btrfs_std_error decodes expected errors from the caller and
|
||||||
* invokes the approciate error response.
|
* invokes the approciate error response.
|
||||||
|
@ -140,7 +139,9 @@ void __btrfs_std_error(struct btrfs_fs_info *fs_info, const char *function,
|
||||||
unsigned int line, int errno, const char *fmt, ...)
|
unsigned int line, int errno, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
struct super_block *sb = fs_info->sb;
|
struct super_block *sb = fs_info->sb;
|
||||||
|
#ifdef CONFIG_PRINTK
|
||||||
const char *errstr;
|
const char *errstr;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Special case: if the error is EROFS, and we're already
|
* Special case: if the error is EROFS, and we're already
|
||||||
|
@ -149,6 +150,7 @@ void __btrfs_std_error(struct btrfs_fs_info *fs_info, const char *function,
|
||||||
if (errno == -EROFS && (sb->s_flags & MS_RDONLY))
|
if (errno == -EROFS && (sb->s_flags & MS_RDONLY))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
#ifdef CONFIG_PRINTK
|
||||||
errstr = btrfs_decode_error(errno);
|
errstr = btrfs_decode_error(errno);
|
||||||
if (fmt) {
|
if (fmt) {
|
||||||
struct va_format vaf;
|
struct va_format vaf;
|
||||||
|
@ -166,6 +168,7 @@ void __btrfs_std_error(struct btrfs_fs_info *fs_info, const char *function,
|
||||||
printk(KERN_CRIT "BTRFS: error (device %s) in %s:%d: errno=%d %s\n",
|
printk(KERN_CRIT "BTRFS: error (device %s) in %s:%d: errno=%d %s\n",
|
||||||
sb->s_id, function, line, errno, errstr);
|
sb->s_id, function, line, errno, errstr);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Don't go through full error handling during mount */
|
/* Don't go through full error handling during mount */
|
||||||
save_error_info(fs_info);
|
save_error_info(fs_info);
|
||||||
|
@ -173,6 +176,7 @@ void __btrfs_std_error(struct btrfs_fs_info *fs_info, const char *function,
|
||||||
btrfs_handle_error(fs_info);
|
btrfs_handle_error(fs_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_PRINTK
|
||||||
static const char * const logtypes[] = {
|
static const char * const logtypes[] = {
|
||||||
"emergency",
|
"emergency",
|
||||||
"alert",
|
"alert",
|
||||||
|
@ -212,27 +216,6 @@ void btrfs_printk(const struct btrfs_fs_info *fs_info, const char *fmt, ...)
|
||||||
|
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
void __btrfs_std_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;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Special case: if the error is EROFS, and we're already
|
|
||||||
* under MS_RDONLY, then it is safe here.
|
|
||||||
*/
|
|
||||||
if (errno == -EROFS && (sb->s_flags & MS_RDONLY))
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Don't go through full error handling during mount */
|
|
||||||
if (sb->s_flags & MS_BORN) {
|
|
||||||
save_error_info(fs_info);
|
|
||||||
btrfs_handle_error(fs_info);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -437,24 +437,24 @@ static const struct attribute *btrfs_attrs[] = {
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void btrfs_release_super_kobj(struct kobject *kobj)
|
static void btrfs_release_fsid_kobj(struct kobject *kobj)
|
||||||
{
|
{
|
||||||
struct btrfs_fs_devices *fs_devs = to_fs_devs(kobj);
|
struct btrfs_fs_devices *fs_devs = to_fs_devs(kobj);
|
||||||
|
|
||||||
memset(&fs_devs->super_kobj, 0, sizeof(struct kobject));
|
memset(&fs_devs->fsid_kobj, 0, sizeof(struct kobject));
|
||||||
complete(&fs_devs->kobj_unregister);
|
complete(&fs_devs->kobj_unregister);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct kobj_type btrfs_ktype = {
|
static struct kobj_type btrfs_ktype = {
|
||||||
.sysfs_ops = &kobj_sysfs_ops,
|
.sysfs_ops = &kobj_sysfs_ops,
|
||||||
.release = btrfs_release_super_kobj,
|
.release = btrfs_release_fsid_kobj,
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline struct btrfs_fs_devices *to_fs_devs(struct kobject *kobj)
|
static inline struct btrfs_fs_devices *to_fs_devs(struct kobject *kobj)
|
||||||
{
|
{
|
||||||
if (kobj->ktype != &btrfs_ktype)
|
if (kobj->ktype != &btrfs_ktype)
|
||||||
return NULL;
|
return NULL;
|
||||||
return container_of(kobj, struct btrfs_fs_devices, super_kobj);
|
return container_of(kobj, struct btrfs_fs_devices, fsid_kobj);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct btrfs_fs_info *to_fs_info(struct kobject *kobj)
|
static inline struct btrfs_fs_info *to_fs_info(struct kobject *kobj)
|
||||||
|
@ -502,12 +502,12 @@ static int addrm_unknown_feature_attrs(struct btrfs_fs_info *fs_info, bool add)
|
||||||
attrs[0] = &fa->kobj_attr.attr;
|
attrs[0] = &fa->kobj_attr.attr;
|
||||||
if (add) {
|
if (add) {
|
||||||
int ret;
|
int ret;
|
||||||
ret = sysfs_merge_group(&fs_info->fs_devices->super_kobj,
|
ret = sysfs_merge_group(&fs_info->fs_devices->fsid_kobj,
|
||||||
&agroup);
|
&agroup);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
} else
|
} else
|
||||||
sysfs_unmerge_group(&fs_info->fs_devices->super_kobj,
|
sysfs_unmerge_group(&fs_info->fs_devices->fsid_kobj,
|
||||||
&agroup);
|
&agroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -523,9 +523,9 @@ static void __btrfs_sysfs_remove_fsid(struct btrfs_fs_devices *fs_devs)
|
||||||
fs_devs->device_dir_kobj = NULL;
|
fs_devs->device_dir_kobj = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fs_devs->super_kobj.state_initialized) {
|
if (fs_devs->fsid_kobj.state_initialized) {
|
||||||
kobject_del(&fs_devs->super_kobj);
|
kobject_del(&fs_devs->fsid_kobj);
|
||||||
kobject_put(&fs_devs->super_kobj);
|
kobject_put(&fs_devs->fsid_kobj);
|
||||||
wait_for_completion(&fs_devs->kobj_unregister);
|
wait_for_completion(&fs_devs->kobj_unregister);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -545,7 +545,7 @@ void btrfs_sysfs_remove_fsid(struct btrfs_fs_devices *fs_devs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void btrfs_sysfs_remove_one(struct btrfs_fs_info *fs_info)
|
void btrfs_sysfs_remove_mounted(struct btrfs_fs_info *fs_info)
|
||||||
{
|
{
|
||||||
btrfs_reset_fs_info_ptr(fs_info);
|
btrfs_reset_fs_info_ptr(fs_info);
|
||||||
|
|
||||||
|
@ -555,9 +555,9 @@ void btrfs_sysfs_remove_one(struct btrfs_fs_info *fs_info)
|
||||||
kobject_put(fs_info->space_info_kobj);
|
kobject_put(fs_info->space_info_kobj);
|
||||||
}
|
}
|
||||||
addrm_unknown_feature_attrs(fs_info, false);
|
addrm_unknown_feature_attrs(fs_info, false);
|
||||||
sysfs_remove_group(&fs_info->fs_devices->super_kobj, &btrfs_feature_attr_group);
|
sysfs_remove_group(&fs_info->fs_devices->fsid_kobj, &btrfs_feature_attr_group);
|
||||||
sysfs_remove_files(&fs_info->fs_devices->super_kobj, btrfs_attrs);
|
sysfs_remove_files(&fs_info->fs_devices->fsid_kobj, btrfs_attrs);
|
||||||
btrfs_kobj_rm_device(fs_info->fs_devices, NULL);
|
btrfs_sysfs_rm_device_link(fs_info->fs_devices, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char * const btrfs_feature_set_names[3] = {
|
const char * const btrfs_feature_set_names[3] = {
|
||||||
|
@ -637,7 +637,7 @@ static void init_feature_attrs(void)
|
||||||
|
|
||||||
/* when one_device is NULL, it removes all device links */
|
/* when one_device is NULL, it removes all device links */
|
||||||
|
|
||||||
int btrfs_kobj_rm_device(struct btrfs_fs_devices *fs_devices,
|
int btrfs_sysfs_rm_device_link(struct btrfs_fs_devices *fs_devices,
|
||||||
struct btrfs_device *one_device)
|
struct btrfs_device *one_device)
|
||||||
{
|
{
|
||||||
struct hd_struct *disk;
|
struct hd_struct *disk;
|
||||||
|
@ -675,7 +675,7 @@ int btrfs_sysfs_add_device(struct btrfs_fs_devices *fs_devs)
|
||||||
{
|
{
|
||||||
if (!fs_devs->device_dir_kobj)
|
if (!fs_devs->device_dir_kobj)
|
||||||
fs_devs->device_dir_kobj = kobject_create_and_add("devices",
|
fs_devs->device_dir_kobj = kobject_create_and_add("devices",
|
||||||
&fs_devs->super_kobj);
|
&fs_devs->fsid_kobj);
|
||||||
|
|
||||||
if (!fs_devs->device_dir_kobj)
|
if (!fs_devs->device_dir_kobj)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -683,7 +683,7 @@ int btrfs_sysfs_add_device(struct btrfs_fs_devices *fs_devs)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int btrfs_kobj_add_device(struct btrfs_fs_devices *fs_devices,
|
int btrfs_sysfs_add_device_link(struct btrfs_fs_devices *fs_devices,
|
||||||
struct btrfs_device *one_device)
|
struct btrfs_device *one_device)
|
||||||
{
|
{
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
@ -730,31 +730,31 @@ int btrfs_sysfs_add_fsid(struct btrfs_fs_devices *fs_devs,
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
init_completion(&fs_devs->kobj_unregister);
|
init_completion(&fs_devs->kobj_unregister);
|
||||||
fs_devs->super_kobj.kset = btrfs_kset;
|
fs_devs->fsid_kobj.kset = btrfs_kset;
|
||||||
error = kobject_init_and_add(&fs_devs->super_kobj,
|
error = kobject_init_and_add(&fs_devs->fsid_kobj,
|
||||||
&btrfs_ktype, parent, "%pU", fs_devs->fsid);
|
&btrfs_ktype, parent, "%pU", fs_devs->fsid);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
int btrfs_sysfs_add_one(struct btrfs_fs_info *fs_info)
|
int btrfs_sysfs_add_mounted(struct btrfs_fs_info *fs_info)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
struct btrfs_fs_devices *fs_devs = fs_info->fs_devices;
|
struct btrfs_fs_devices *fs_devs = fs_info->fs_devices;
|
||||||
struct kobject *super_kobj = &fs_devs->super_kobj;
|
struct kobject *fsid_kobj = &fs_devs->fsid_kobj;
|
||||||
|
|
||||||
btrfs_set_fs_info_ptr(fs_info);
|
btrfs_set_fs_info_ptr(fs_info);
|
||||||
|
|
||||||
error = btrfs_kobj_add_device(fs_devs, NULL);
|
error = btrfs_sysfs_add_device_link(fs_devs, NULL);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
error = sysfs_create_files(super_kobj, btrfs_attrs);
|
error = sysfs_create_files(fsid_kobj, btrfs_attrs);
|
||||||
if (error) {
|
if (error) {
|
||||||
btrfs_kobj_rm_device(fs_devs, NULL);
|
btrfs_sysfs_rm_device_link(fs_devs, NULL);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = sysfs_create_group(super_kobj,
|
error = sysfs_create_group(fsid_kobj,
|
||||||
&btrfs_feature_attr_group);
|
&btrfs_feature_attr_group);
|
||||||
if (error)
|
if (error)
|
||||||
goto failure;
|
goto failure;
|
||||||
|
@ -764,7 +764,7 @@ int btrfs_sysfs_add_one(struct btrfs_fs_info *fs_info)
|
||||||
goto failure;
|
goto failure;
|
||||||
|
|
||||||
fs_info->space_info_kobj = kobject_create_and_add("allocation",
|
fs_info->space_info_kobj = kobject_create_and_add("allocation",
|
||||||
super_kobj);
|
fsid_kobj);
|
||||||
if (!fs_info->space_info_kobj) {
|
if (!fs_info->space_info_kobj) {
|
||||||
error = -ENOMEM;
|
error = -ENOMEM;
|
||||||
goto failure;
|
goto failure;
|
||||||
|
@ -776,7 +776,7 @@ int btrfs_sysfs_add_one(struct btrfs_fs_info *fs_info)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
failure:
|
failure:
|
||||||
btrfs_sysfs_remove_one(fs_info);
|
btrfs_sysfs_remove_mounted(fs_info);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -82,9 +82,9 @@ char *btrfs_printable_features(enum btrfs_feature_set set, u64 flags);
|
||||||
extern const char * const btrfs_feature_set_names[3];
|
extern const char * const btrfs_feature_set_names[3];
|
||||||
extern struct kobj_type space_info_ktype;
|
extern struct kobj_type space_info_ktype;
|
||||||
extern struct kobj_type btrfs_raid_ktype;
|
extern struct kobj_type btrfs_raid_ktype;
|
||||||
int btrfs_kobj_add_device(struct btrfs_fs_devices *fs_devices,
|
int btrfs_sysfs_add_device_link(struct btrfs_fs_devices *fs_devices,
|
||||||
struct btrfs_device *one_device);
|
struct btrfs_device *one_device);
|
||||||
int btrfs_kobj_rm_device(struct btrfs_fs_devices *fs_devices,
|
int btrfs_sysfs_rm_device_link(struct btrfs_fs_devices *fs_devices,
|
||||||
struct btrfs_device *one_device);
|
struct btrfs_device *one_device);
|
||||||
int btrfs_sysfs_add_fsid(struct btrfs_fs_devices *fs_devs,
|
int btrfs_sysfs_add_fsid(struct btrfs_fs_devices *fs_devs,
|
||||||
struct kobject *parent);
|
struct kobject *parent);
|
||||||
|
|
|
@ -2136,7 +2136,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
|
||||||
|
|
||||||
ret = btrfs_write_and_wait_transaction(trans, root);
|
ret = btrfs_write_and_wait_transaction(trans, root);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
btrfs_error(root->fs_info, ret,
|
btrfs_std_error(root->fs_info, ret,
|
||||||
"Error while writing out transaction");
|
"Error while writing out transaction");
|
||||||
mutex_unlock(&root->fs_info->tree_log_mutex);
|
mutex_unlock(&root->fs_info->tree_log_mutex);
|
||||||
goto scrub_continue;
|
goto scrub_continue;
|
||||||
|
|
|
@ -5314,7 +5314,7 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
|
||||||
|
|
||||||
ret = walk_log_tree(trans, log_root_tree, &wc);
|
ret = walk_log_tree(trans, log_root_tree, &wc);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
btrfs_error(fs_info, ret, "Failed to pin buffers while "
|
btrfs_std_error(fs_info, ret, "Failed to pin buffers while "
|
||||||
"recovering log root tree.");
|
"recovering log root tree.");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
@ -5328,7 +5328,7 @@ again:
|
||||||
ret = btrfs_search_slot(NULL, log_root_tree, &key, path, 0, 0);
|
ret = btrfs_search_slot(NULL, log_root_tree, &key, path, 0, 0);
|
||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
btrfs_error(fs_info, ret,
|
btrfs_std_error(fs_info, ret,
|
||||||
"Couldn't find tree log root.");
|
"Couldn't find tree log root.");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
@ -5346,7 +5346,7 @@ again:
|
||||||
log = btrfs_read_fs_root(log_root_tree, &found_key);
|
log = btrfs_read_fs_root(log_root_tree, &found_key);
|
||||||
if (IS_ERR(log)) {
|
if (IS_ERR(log)) {
|
||||||
ret = PTR_ERR(log);
|
ret = PTR_ERR(log);
|
||||||
btrfs_error(fs_info, ret,
|
btrfs_std_error(fs_info, ret,
|
||||||
"Couldn't read tree log root.");
|
"Couldn't read tree log root.");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
@ -5361,7 +5361,7 @@ again:
|
||||||
free_extent_buffer(log->node);
|
free_extent_buffer(log->node);
|
||||||
free_extent_buffer(log->commit_root);
|
free_extent_buffer(log->commit_root);
|
||||||
kfree(log);
|
kfree(log);
|
||||||
btrfs_error(fs_info, ret, "Couldn't read target root "
|
btrfs_std_error(fs_info, ret, "Couldn't read target root "
|
||||||
"for tree log recovery.");
|
"for tree log recovery.");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
|
@ -198,7 +198,6 @@ btrfs_get_bdev_and_sb(const char *device_path, fmode_t flags, void *holder,
|
||||||
|
|
||||||
if (IS_ERR(*bdev)) {
|
if (IS_ERR(*bdev)) {
|
||||||
ret = PTR_ERR(*bdev);
|
ret = PTR_ERR(*bdev);
|
||||||
printk(KERN_INFO "BTRFS: open %s failed\n", device_path);
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,8 +210,8 @@ btrfs_get_bdev_and_sb(const char *device_path, fmode_t flags, void *holder,
|
||||||
}
|
}
|
||||||
invalidate_bdev(*bdev);
|
invalidate_bdev(*bdev);
|
||||||
*bh = btrfs_read_dev_super(*bdev);
|
*bh = btrfs_read_dev_super(*bdev);
|
||||||
if (!*bh) {
|
if (IS_ERR(*bh)) {
|
||||||
ret = -EINVAL;
|
ret = PTR_ERR(*bh);
|
||||||
blkdev_put(*bdev, flags);
|
blkdev_put(*bdev, flags);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
@ -765,36 +764,7 @@ static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices)
|
||||||
|
|
||||||
mutex_lock(&fs_devices->device_list_mutex);
|
mutex_lock(&fs_devices->device_list_mutex);
|
||||||
list_for_each_entry_safe(device, tmp, &fs_devices->devices, dev_list) {
|
list_for_each_entry_safe(device, tmp, &fs_devices->devices, dev_list) {
|
||||||
struct btrfs_device *new_device;
|
btrfs_close_one_device(device);
|
||||||
struct rcu_string *name;
|
|
||||||
|
|
||||||
if (device->bdev)
|
|
||||||
fs_devices->open_devices--;
|
|
||||||
|
|
||||||
if (device->writeable &&
|
|
||||||
device->devid != BTRFS_DEV_REPLACE_DEVID) {
|
|
||||||
list_del_init(&device->dev_alloc_list);
|
|
||||||
fs_devices->rw_devices--;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (device->missing)
|
|
||||||
fs_devices->missing_devices--;
|
|
||||||
|
|
||||||
new_device = btrfs_alloc_device(NULL, &device->devid,
|
|
||||||
device->uuid);
|
|
||||||
BUG_ON(IS_ERR(new_device)); /* -ENOMEM */
|
|
||||||
|
|
||||||
/* Safe because we are under uuid_mutex */
|
|
||||||
if (device->name) {
|
|
||||||
name = rcu_string_strdup(device->name->str, GFP_NOFS);
|
|
||||||
BUG_ON(!name); /* -ENOMEM */
|
|
||||||
rcu_assign_pointer(new_device->name, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
list_replace_rcu(&device->dev_list, &new_device->dev_list);
|
|
||||||
new_device->fs_devices = device->fs_devices;
|
|
||||||
|
|
||||||
call_rcu(&device->rcu, free_device);
|
|
||||||
}
|
}
|
||||||
mutex_unlock(&fs_devices->device_list_mutex);
|
mutex_unlock(&fs_devices->device_list_mutex);
|
||||||
|
|
||||||
|
@ -1402,7 +1372,7 @@ again:
|
||||||
extent = btrfs_item_ptr(leaf, path->slots[0],
|
extent = btrfs_item_ptr(leaf, path->slots[0],
|
||||||
struct btrfs_dev_extent);
|
struct btrfs_dev_extent);
|
||||||
} else {
|
} else {
|
||||||
btrfs_error(root->fs_info, ret, "Slot search failed");
|
btrfs_std_error(root->fs_info, ret, "Slot search failed");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1410,7 +1380,7 @@ again:
|
||||||
|
|
||||||
ret = btrfs_del_item(trans, root, path);
|
ret = btrfs_del_item(trans, root, path);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
btrfs_error(root->fs_info, ret,
|
btrfs_std_error(root->fs_info, ret,
|
||||||
"Failed to remove dev extent item");
|
"Failed to remove dev extent item");
|
||||||
} else {
|
} else {
|
||||||
trans->transaction->have_free_bgs = 1;
|
trans->transaction->have_free_bgs = 1;
|
||||||
|
@ -1801,7 +1771,7 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
|
||||||
if (device->bdev) {
|
if (device->bdev) {
|
||||||
device->fs_devices->open_devices--;
|
device->fs_devices->open_devices--;
|
||||||
/* remove sysfs entry */
|
/* remove sysfs entry */
|
||||||
btrfs_kobj_rm_device(root->fs_info->fs_devices, device);
|
btrfs_sysfs_rm_device_link(root->fs_info->fs_devices, device);
|
||||||
}
|
}
|
||||||
|
|
||||||
call_rcu(&device->rcu, free_device);
|
call_rcu(&device->rcu, free_device);
|
||||||
|
@ -1924,7 +1894,8 @@ void btrfs_rm_dev_replace_remove_srcdev(struct btrfs_fs_info *fs_info,
|
||||||
if (srcdev->writeable) {
|
if (srcdev->writeable) {
|
||||||
fs_devices->rw_devices--;
|
fs_devices->rw_devices--;
|
||||||
/* zero out the old super if it is writable */
|
/* zero out the old super if it is writable */
|
||||||
btrfs_scratch_superblock(srcdev);
|
btrfs_scratch_superblocks(srcdev->bdev,
|
||||||
|
rcu_str_deref(srcdev->name));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (srcdev->bdev)
|
if (srcdev->bdev)
|
||||||
|
@ -1971,10 +1942,11 @@ void btrfs_destroy_dev_replace_tgtdev(struct btrfs_fs_info *fs_info,
|
||||||
WARN_ON(!tgtdev);
|
WARN_ON(!tgtdev);
|
||||||
mutex_lock(&fs_info->fs_devices->device_list_mutex);
|
mutex_lock(&fs_info->fs_devices->device_list_mutex);
|
||||||
|
|
||||||
btrfs_kobj_rm_device(fs_info->fs_devices, tgtdev);
|
btrfs_sysfs_rm_device_link(fs_info->fs_devices, tgtdev);
|
||||||
|
|
||||||
if (tgtdev->bdev) {
|
if (tgtdev->bdev) {
|
||||||
btrfs_scratch_superblock(tgtdev);
|
btrfs_scratch_superblocks(tgtdev->bdev,
|
||||||
|
rcu_str_deref(tgtdev->name));
|
||||||
fs_info->fs_devices->open_devices--;
|
fs_info->fs_devices->open_devices--;
|
||||||
}
|
}
|
||||||
fs_info->fs_devices->num_devices--;
|
fs_info->fs_devices->num_devices--;
|
||||||
|
@ -2041,10 +2013,8 @@ int btrfs_find_device_missing_or_by_path(struct btrfs_root *root,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!*device) {
|
if (!*device)
|
||||||
btrfs_err(root->fs_info, "no missing device found");
|
return BTRFS_ERROR_DEV_MISSING_NOT_FOUND;
|
||||||
return -ENOENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -2309,7 +2279,7 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path)
|
||||||
tmp + 1);
|
tmp + 1);
|
||||||
|
|
||||||
/* add sysfs device entry */
|
/* add sysfs device entry */
|
||||||
btrfs_kobj_add_device(root->fs_info->fs_devices, device);
|
btrfs_sysfs_add_device_link(root->fs_info->fs_devices, device);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* we've got more storage, clear any full flags on the space
|
* we've got more storage, clear any full flags on the space
|
||||||
|
@ -2350,7 +2320,7 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path)
|
||||||
*/
|
*/
|
||||||
snprintf(fsid_buf, BTRFS_UUID_UNPARSED_SIZE, "%pU",
|
snprintf(fsid_buf, BTRFS_UUID_UNPARSED_SIZE, "%pU",
|
||||||
root->fs_info->fsid);
|
root->fs_info->fsid);
|
||||||
if (kobject_rename(&root->fs_info->fs_devices->super_kobj,
|
if (kobject_rename(&root->fs_info->fs_devices->fsid_kobj,
|
||||||
fsid_buf))
|
fsid_buf))
|
||||||
btrfs_warn(root->fs_info,
|
btrfs_warn(root->fs_info,
|
||||||
"sysfs: failed to create fsid for sprout");
|
"sysfs: failed to create fsid for sprout");
|
||||||
|
@ -2369,7 +2339,7 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path)
|
||||||
|
|
||||||
ret = btrfs_relocate_sys_chunks(root);
|
ret = btrfs_relocate_sys_chunks(root);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
btrfs_error(root->fs_info, ret,
|
btrfs_std_error(root->fs_info, ret,
|
||||||
"Failed to relocate sys chunks after "
|
"Failed to relocate sys chunks after "
|
||||||
"device initialization. This can be fixed "
|
"device initialization. This can be fixed "
|
||||||
"using the \"btrfs balance\" command.");
|
"using the \"btrfs balance\" command.");
|
||||||
|
@ -2389,7 +2359,7 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path)
|
||||||
error_trans:
|
error_trans:
|
||||||
btrfs_end_transaction(trans, root);
|
btrfs_end_transaction(trans, root);
|
||||||
rcu_string_free(device->name);
|
rcu_string_free(device->name);
|
||||||
btrfs_kobj_rm_device(root->fs_info->fs_devices, device);
|
btrfs_sysfs_rm_device_link(root->fs_info->fs_devices, device);
|
||||||
kfree(device);
|
kfree(device);
|
||||||
error:
|
error:
|
||||||
blkdev_put(bdev, FMODE_EXCL);
|
blkdev_put(bdev, FMODE_EXCL);
|
||||||
|
@ -2614,7 +2584,7 @@ static int btrfs_free_chunk(struct btrfs_trans_handle *trans,
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out;
|
goto out;
|
||||||
else if (ret > 0) { /* Logic error or corruption */
|
else if (ret > 0) { /* Logic error or corruption */
|
||||||
btrfs_error(root->fs_info, -ENOENT,
|
btrfs_std_error(root->fs_info, -ENOENT,
|
||||||
"Failed lookup while freeing chunk.");
|
"Failed lookup while freeing chunk.");
|
||||||
ret = -ENOENT;
|
ret = -ENOENT;
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -2622,7 +2592,7 @@ static int btrfs_free_chunk(struct btrfs_trans_handle *trans,
|
||||||
|
|
||||||
ret = btrfs_del_item(trans, root, path);
|
ret = btrfs_del_item(trans, root, path);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
btrfs_error(root->fs_info, ret,
|
btrfs_std_error(root->fs_info, ret,
|
||||||
"Failed to delete chunk item.");
|
"Failed to delete chunk item.");
|
||||||
out:
|
out:
|
||||||
btrfs_free_path(path);
|
btrfs_free_path(path);
|
||||||
|
@ -2807,7 +2777,7 @@ static int btrfs_relocate_chunk(struct btrfs_root *root, u64 chunk_offset)
|
||||||
trans = btrfs_start_transaction(root, 0);
|
trans = btrfs_start_transaction(root, 0);
|
||||||
if (IS_ERR(trans)) {
|
if (IS_ERR(trans)) {
|
||||||
ret = PTR_ERR(trans);
|
ret = PTR_ERR(trans);
|
||||||
btrfs_std_error(root->fs_info, ret);
|
btrfs_std_error(root->fs_info, ret, NULL);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3462,7 +3432,7 @@ static void __cancel_balance(struct btrfs_fs_info *fs_info)
|
||||||
unset_balance_control(fs_info);
|
unset_balance_control(fs_info);
|
||||||
ret = del_balance_item(fs_info->tree_root);
|
ret = del_balance_item(fs_info->tree_root);
|
||||||
if (ret)
|
if (ret)
|
||||||
btrfs_std_error(fs_info, ret);
|
btrfs_std_error(fs_info, ret, NULL);
|
||||||
|
|
||||||
atomic_set(&fs_info->mutually_exclusive_operation_running, 0);
|
atomic_set(&fs_info->mutually_exclusive_operation_running, 0);
|
||||||
}
|
}
|
||||||
|
@ -6741,22 +6711,34 @@ int btrfs_get_dev_stats(struct btrfs_root *root,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int btrfs_scratch_superblock(struct btrfs_device *device)
|
void btrfs_scratch_superblocks(struct block_device *bdev, char *device_path)
|
||||||
{
|
{
|
||||||
struct buffer_head *bh;
|
struct buffer_head *bh;
|
||||||
struct btrfs_super_block *disk_super;
|
struct btrfs_super_block *disk_super;
|
||||||
|
int copy_num;
|
||||||
|
|
||||||
bh = btrfs_read_dev_super(device->bdev);
|
if (!bdev)
|
||||||
if (!bh)
|
return;
|
||||||
return -EINVAL;
|
|
||||||
disk_super = (struct btrfs_super_block *)bh->b_data;
|
|
||||||
|
|
||||||
memset(&disk_super->magic, 0, sizeof(disk_super->magic));
|
for (copy_num = 0; copy_num < BTRFS_SUPER_MIRROR_MAX;
|
||||||
set_buffer_dirty(bh);
|
copy_num++) {
|
||||||
sync_dirty_buffer(bh);
|
|
||||||
brelse(bh);
|
|
||||||
|
|
||||||
return 0;
|
if (btrfs_read_dev_one_super(bdev, copy_num, &bh))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
disk_super = (struct btrfs_super_block *)bh->b_data;
|
||||||
|
|
||||||
|
memset(&disk_super->magic, 0, sizeof(disk_super->magic));
|
||||||
|
set_buffer_dirty(bh);
|
||||||
|
sync_dirty_buffer(bh);
|
||||||
|
brelse(bh);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Notify udev that device has changed */
|
||||||
|
btrfs_kobject_uevent(bdev, KOBJ_CHANGE);
|
||||||
|
|
||||||
|
/* Update ctime/mtime for device path for libblkid */
|
||||||
|
update_dev_time(device_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -6824,3 +6806,38 @@ void btrfs_reset_fs_info_ptr(struct btrfs_fs_info *fs_info)
|
||||||
fs_devices = fs_devices->seed;
|
fs_devices = fs_devices->seed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void btrfs_close_one_device(struct btrfs_device *device)
|
||||||
|
{
|
||||||
|
struct btrfs_fs_devices *fs_devices = device->fs_devices;
|
||||||
|
struct btrfs_device *new_device;
|
||||||
|
struct rcu_string *name;
|
||||||
|
|
||||||
|
if (device->bdev)
|
||||||
|
fs_devices->open_devices--;
|
||||||
|
|
||||||
|
if (device->writeable &&
|
||||||
|
device->devid != BTRFS_DEV_REPLACE_DEVID) {
|
||||||
|
list_del_init(&device->dev_alloc_list);
|
||||||
|
fs_devices->rw_devices--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device->missing)
|
||||||
|
fs_devices->missing_devices--;
|
||||||
|
|
||||||
|
new_device = btrfs_alloc_device(NULL, &device->devid,
|
||||||
|
device->uuid);
|
||||||
|
BUG_ON(IS_ERR(new_device)); /* -ENOMEM */
|
||||||
|
|
||||||
|
/* Safe because we are under uuid_mutex */
|
||||||
|
if (device->name) {
|
||||||
|
name = rcu_string_strdup(device->name->str, GFP_NOFS);
|
||||||
|
BUG_ON(!name); /* -ENOMEM */
|
||||||
|
rcu_assign_pointer(new_device->name, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
list_replace_rcu(&device->dev_list, &new_device->dev_list);
|
||||||
|
new_device->fs_devices = device->fs_devices;
|
||||||
|
|
||||||
|
call_rcu(&device->rcu, free_device);
|
||||||
|
}
|
||||||
|
|
|
@ -256,7 +256,7 @@ struct btrfs_fs_devices {
|
||||||
|
|
||||||
struct btrfs_fs_info *fs_info;
|
struct btrfs_fs_info *fs_info;
|
||||||
/* sysfs kobjects */
|
/* sysfs kobjects */
|
||||||
struct kobject super_kobj;
|
struct kobject fsid_kobj;
|
||||||
struct kobject *device_dir_kobj;
|
struct kobject *device_dir_kobj;
|
||||||
struct completion kobj_unregister;
|
struct completion kobj_unregister;
|
||||||
};
|
};
|
||||||
|
@ -474,7 +474,7 @@ void btrfs_destroy_dev_replace_tgtdev(struct btrfs_fs_info *fs_info,
|
||||||
struct btrfs_device *tgtdev);
|
struct btrfs_device *tgtdev);
|
||||||
void btrfs_init_dev_replace_tgtdev_for_resume(struct btrfs_fs_info *fs_info,
|
void btrfs_init_dev_replace_tgtdev_for_resume(struct btrfs_fs_info *fs_info,
|
||||||
struct btrfs_device *tgtdev);
|
struct btrfs_device *tgtdev);
|
||||||
int btrfs_scratch_superblock(struct btrfs_device *device);
|
void btrfs_scratch_superblocks(struct block_device *bdev, char *device_path);
|
||||||
int btrfs_is_parity_mirror(struct btrfs_mapping_tree *map_tree,
|
int btrfs_is_parity_mirror(struct btrfs_mapping_tree *map_tree,
|
||||||
u64 logical, u64 len, int mirror_num);
|
u64 logical, u64 len, int mirror_num);
|
||||||
unsigned long btrfs_full_stripe_len(struct btrfs_root *root,
|
unsigned long btrfs_full_stripe_len(struct btrfs_root *root,
|
||||||
|
@ -547,5 +547,6 @@ static inline void unlock_chunks(struct btrfs_root *root)
|
||||||
struct list_head *btrfs_get_fs_uuids(void);
|
struct list_head *btrfs_get_fs_uuids(void);
|
||||||
void btrfs_set_fs_info_ptr(struct btrfs_fs_info *fs_info);
|
void btrfs_set_fs_info_ptr(struct btrfs_fs_info *fs_info);
|
||||||
void btrfs_reset_fs_info_ptr(struct btrfs_fs_info *fs_info);
|
void btrfs_reset_fs_info_ptr(struct btrfs_fs_info *fs_info);
|
||||||
|
void btrfs_close_one_device(struct btrfs_device *device);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Reference in a new issue