mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-26 05:34:13 +08:00
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
@ -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);
|
||||
btrfs_std_error(root->fs_info, ret, NULL);
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
@ -1927,7 +1927,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);
|
||||
btrfs_std_error(root->fs_info, ret, NULL);
|
||||
goto enospc;
|
||||
}
|
||||
|
||||
@ -2030,7 +2030,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
|
||||
*/
|
||||
if (!left) {
|
||||
ret = -EROFS;
|
||||
btrfs_std_error(root->fs_info, ret);
|
||||
btrfs_std_error(root->fs_info, ret, NULL);
|
||||
goto enospc;
|
||||
}
|
||||
wret = balance_node_right(trans, root, mid, left);
|
||||
|
@ -4004,8 +4004,8 @@ int btrfs_defrag_leaves(struct btrfs_trans_handle *trans,
|
||||
/* sysfs.c */
|
||||
int btrfs_init_sysfs(void);
|
||||
void btrfs_exit_sysfs(void);
|
||||
int btrfs_sysfs_add_one(struct btrfs_fs_info *fs_info);
|
||||
void btrfs_sysfs_remove_one(struct btrfs_fs_info *fs_info);
|
||||
int btrfs_sysfs_add_mounted(struct btrfs_fs_info *fs_info);
|
||||
void btrfs_sysfs_remove_mounted(struct btrfs_fs_info *fs_info);
|
||||
|
||||
/* xattr.c */
|
||||
ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size);
|
||||
@ -4215,14 +4215,7 @@ do { \
|
||||
__LINE__, (errno)); \
|
||||
} while (0)
|
||||
|
||||
#define btrfs_std_error(fs_info, errno) \
|
||||
do { \
|
||||
if ((errno)) \
|
||||
__btrfs_std_error((fs_info), __func__, \
|
||||
__LINE__, (errno), NULL); \
|
||||
} while (0)
|
||||
|
||||
#define btrfs_error(fs_info, errno, fmt, args...) \
|
||||
#define btrfs_std_error(fs_info, errno, fmt, args...) \
|
||||
do { \
|
||||
__btrfs_std_error((fs_info), __func__, __LINE__, \
|
||||
(errno), fmt, ##args); \
|
||||
|
@ -327,19 +327,6 @@ int btrfs_dev_replace_start(struct btrfs_root *root,
|
||||
args->start.tgtdev_name[0] == '\0')
|
||||
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 */
|
||||
mutex_lock(&fs_info->volume_mutex);
|
||||
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)
|
||||
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);
|
||||
switch (dev_replace->replace_state) {
|
||||
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);
|
||||
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,
|
||||
"dev_replace from %s (devid %llu) to %s started",
|
||||
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;
|
||||
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);
|
||||
|
||||
/* 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);
|
||||
|
||||
/* 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);
|
||||
|
||||
/* 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 */
|
||||
ret = btrfs_recover_log_trees(log_tree_root);
|
||||
if (ret) {
|
||||
btrfs_error(tree_root->fs_info, ret,
|
||||
btrfs_std_error(tree_root->fs_info, ret,
|
||||
"Failed to recover log tree");
|
||||
free_extent_buffer(log_tree_root->node);
|
||||
kfree(log_tree_root);
|
||||
@ -2651,8 +2651,8 @@ int open_ctree(struct super_block *sb,
|
||||
* Read super block and check the signature bytes only
|
||||
*/
|
||||
bh = btrfs_read_dev_super(fs_devices->latest_bdev);
|
||||
if (!bh) {
|
||||
err = -EINVAL;
|
||||
if (IS_ERR(bh)) {
|
||||
err = PTR_ERR(bh);
|
||||
goto fail_alloc;
|
||||
}
|
||||
|
||||
@ -2935,7 +2935,7 @@ retry_root_backup:
|
||||
goto fail_fsdev_sysfs;
|
||||
}
|
||||
|
||||
ret = btrfs_sysfs_add_one(fs_info);
|
||||
ret = btrfs_sysfs_add_mounted(fs_info);
|
||||
if (ret) {
|
||||
pr_err("BTRFS: failed to init sysfs interface: %d\n", ret);
|
||||
goto fail_fsdev_sysfs;
|
||||
@ -3115,7 +3115,7 @@ fail_cleaner:
|
||||
filemap_write_and_wait(fs_info->btree_inode->i_mapping);
|
||||
|
||||
fail_sysfs:
|
||||
btrfs_sysfs_remove_one(fs_info);
|
||||
btrfs_sysfs_remove_mounted(fs_info);
|
||||
|
||||
fail_fsdev_sysfs:
|
||||
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);
|
||||
}
|
||||
|
||||
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 *bh;
|
||||
@ -3197,7 +3228,7 @@ struct buffer_head *btrfs_read_dev_super(struct block_device *bdev)
|
||||
struct btrfs_super_block *super;
|
||||
int i;
|
||||
u64 transid = 0;
|
||||
u64 bytenr;
|
||||
int ret = -EINVAL;
|
||||
|
||||
/* we would like to check all the supers, but that would make
|
||||
* 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
|
||||
*/
|
||||
for (i = 0; i < 1; i++) {
|
||||
bytenr = btrfs_sb_offset(i);
|
||||
if (bytenr + BTRFS_SUPER_INFO_SIZE >=
|
||||
i_size_read(bdev->bd_inode))
|
||||
break;
|
||||
bh = __bread(bdev, bytenr / 4096,
|
||||
BTRFS_SUPER_INFO_SIZE);
|
||||
if (!bh)
|
||||
ret = btrfs_read_dev_one_super(bdev, i, &bh);
|
||||
if (ret)
|
||||
continue;
|
||||
|
||||
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) {
|
||||
brelse(latest);
|
||||
@ -3229,6 +3250,10 @@ struct buffer_head *btrfs_read_dev_super(struct block_device *bdev)
|
||||
brelse(bh);
|
||||
}
|
||||
}
|
||||
|
||||
if (!latest)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
return latest;
|
||||
}
|
||||
|
||||
@ -3547,7 +3572,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_error(root->fs_info, ret,
|
||||
btrfs_std_error(root->fs_info, ret,
|
||||
"errors while submitting device barriers.");
|
||||
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);
|
||||
|
||||
/* 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);
|
||||
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);
|
||||
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);
|
||||
return -EIO;
|
||||
}
|
||||
@ -3791,7 +3816,7 @@ void close_ctree(struct btrfs_root *root)
|
||||
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_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,
|
||||
struct btrfs_root *root, int max_mirrors);
|
||||
struct buffer_head *btrfs_read_dev_super(struct block_device *bdev);
|
||||
int btrfs_read_dev_one_super(struct block_device *bdev, int copy_num,
|
||||
struct buffer_head **bh_ret);
|
||||
int btrfs_commit_super(struct btrfs_root *root);
|
||||
struct extent_buffer *btrfs_find_tree_block(struct btrfs_fs_info *fs_info,
|
||||
u64 bytenr);
|
||||
|
@ -8694,7 +8694,7 @@ out:
|
||||
if (!for_reloc && root_dropped == false)
|
||||
btrfs_add_dead_root(root);
|
||||
if (err && err != -EAGAIN)
|
||||
btrfs_std_error(root->fs_info, err);
|
||||
btrfs_std_error(root->fs_info, err, NULL);
|
||||
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,
|
||||
name, name_len, &extref)) {
|
||||
btrfs_std_error(root->fs_info, -ENOENT);
|
||||
btrfs_std_error(root->fs_info, -ENOENT, NULL);
|
||||
ret = -EROFS;
|
||||
goto out;
|
||||
}
|
||||
|
@ -4806,7 +4806,7 @@ 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_error(root->fs_info, ret,
|
||||
btrfs_std_error(root->fs_info, ret,
|
||||
"failed to update qgroup status and info\n");
|
||||
err = btrfs_end_transaction(trans, root);
|
||||
if (err && !ret)
|
||||
|
@ -2418,7 +2418,7 @@ again:
|
||||
}
|
||||
out:
|
||||
if (ret) {
|
||||
btrfs_std_error(root->fs_info, ret);
|
||||
btrfs_std_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_error(tree_root->fs_info, err,
|
||||
btrfs_std_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_error(tree_root->fs_info, err,
|
||||
btrfs_std_error(tree_root->fs_info, err,
|
||||
"Failed to delete root orphan "
|
||||
"item");
|
||||
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
|
||||
* 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, ...)
|
||||
{
|
||||
struct super_block *sb = fs_info->sb;
|
||||
#ifdef CONFIG_PRINTK
|
||||
const char *errstr;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 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))
|
||||
return;
|
||||
|
||||
#ifdef CONFIG_PRINTK
|
||||
errstr = btrfs_decode_error(errno);
|
||||
if (fmt) {
|
||||
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",
|
||||
sb->s_id, function, line, errno, errstr);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Don't go through full error handling during mount */
|
||||
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);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PRINTK
|
||||
static const char * const logtypes[] = {
|
||||
"emergency",
|
||||
"alert",
|
||||
@ -212,27 +216,6 @@ void btrfs_printk(const struct btrfs_fs_info *fs_info, const char *fmt, ...)
|
||||
|
||||
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
|
||||
|
||||
/*
|
||||
|
@ -437,24 +437,24 @@ static const struct attribute *btrfs_attrs[] = {
|
||||
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);
|
||||
|
||||
memset(&fs_devs->super_kobj, 0, sizeof(struct kobject));
|
||||
memset(&fs_devs->fsid_kobj, 0, sizeof(struct kobject));
|
||||
complete(&fs_devs->kobj_unregister);
|
||||
}
|
||||
|
||||
static struct kobj_type btrfs_ktype = {
|
||||
.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)
|
||||
{
|
||||
if (kobj->ktype != &btrfs_ktype)
|
||||
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)
|
||||
@ -502,12 +502,12 @@ static int addrm_unknown_feature_attrs(struct btrfs_fs_info *fs_info, bool add)
|
||||
attrs[0] = &fa->kobj_attr.attr;
|
||||
if (add) {
|
||||
int ret;
|
||||
ret = sysfs_merge_group(&fs_info->fs_devices->super_kobj,
|
||||
ret = sysfs_merge_group(&fs_info->fs_devices->fsid_kobj,
|
||||
&agroup);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else
|
||||
sysfs_unmerge_group(&fs_info->fs_devices->super_kobj,
|
||||
sysfs_unmerge_group(&fs_info->fs_devices->fsid_kobj,
|
||||
&agroup);
|
||||
}
|
||||
|
||||
@ -523,9 +523,9 @@ static void __btrfs_sysfs_remove_fsid(struct btrfs_fs_devices *fs_devs)
|
||||
fs_devs->device_dir_kobj = NULL;
|
||||
}
|
||||
|
||||
if (fs_devs->super_kobj.state_initialized) {
|
||||
kobject_del(&fs_devs->super_kobj);
|
||||
kobject_put(&fs_devs->super_kobj);
|
||||
if (fs_devs->fsid_kobj.state_initialized) {
|
||||
kobject_del(&fs_devs->fsid_kobj);
|
||||
kobject_put(&fs_devs->fsid_kobj);
|
||||
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);
|
||||
|
||||
@ -555,9 +555,9 @@ void btrfs_sysfs_remove_one(struct btrfs_fs_info *fs_info)
|
||||
kobject_put(fs_info->space_info_kobj);
|
||||
}
|
||||
addrm_unknown_feature_attrs(fs_info, false);
|
||||
sysfs_remove_group(&fs_info->fs_devices->super_kobj, &btrfs_feature_attr_group);
|
||||
sysfs_remove_files(&fs_info->fs_devices->super_kobj, btrfs_attrs);
|
||||
btrfs_kobj_rm_device(fs_info->fs_devices, NULL);
|
||||
sysfs_remove_group(&fs_info->fs_devices->fsid_kobj, &btrfs_feature_attr_group);
|
||||
sysfs_remove_files(&fs_info->fs_devices->fsid_kobj, btrfs_attrs);
|
||||
btrfs_sysfs_rm_device_link(fs_info->fs_devices, NULL);
|
||||
}
|
||||
|
||||
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 */
|
||||
|
||||
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 hd_struct *disk;
|
||||
@ -675,7 +675,7 @@ int btrfs_sysfs_add_device(struct btrfs_fs_devices *fs_devs)
|
||||
{
|
||||
if (!fs_devs->device_dir_kobj)
|
||||
fs_devs->device_dir_kobj = kobject_create_and_add("devices",
|
||||
&fs_devs->super_kobj);
|
||||
&fs_devs->fsid_kobj);
|
||||
|
||||
if (!fs_devs->device_dir_kobj)
|
||||
return -ENOMEM;
|
||||
@ -683,7 +683,7 @@ int btrfs_sysfs_add_device(struct btrfs_fs_devices *fs_devs)
|
||||
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)
|
||||
{
|
||||
int error = 0;
|
||||
@ -730,31 +730,31 @@ int btrfs_sysfs_add_fsid(struct btrfs_fs_devices *fs_devs,
|
||||
int error;
|
||||
|
||||
init_completion(&fs_devs->kobj_unregister);
|
||||
fs_devs->super_kobj.kset = btrfs_kset;
|
||||
error = kobject_init_and_add(&fs_devs->super_kobj,
|
||||
fs_devs->fsid_kobj.kset = btrfs_kset;
|
||||
error = kobject_init_and_add(&fs_devs->fsid_kobj,
|
||||
&btrfs_ktype, parent, "%pU", fs_devs->fsid);
|
||||
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;
|
||||
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);
|
||||
|
||||
error = btrfs_kobj_add_device(fs_devs, NULL);
|
||||
error = btrfs_sysfs_add_device_link(fs_devs, NULL);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
error = sysfs_create_files(super_kobj, btrfs_attrs);
|
||||
error = sysfs_create_files(fsid_kobj, btrfs_attrs);
|
||||
if (error) {
|
||||
btrfs_kobj_rm_device(fs_devs, NULL);
|
||||
btrfs_sysfs_rm_device_link(fs_devs, NULL);
|
||||
return error;
|
||||
}
|
||||
|
||||
error = sysfs_create_group(super_kobj,
|
||||
error = sysfs_create_group(fsid_kobj,
|
||||
&btrfs_feature_attr_group);
|
||||
if (error)
|
||||
goto failure;
|
||||
@ -764,7 +764,7 @@ int btrfs_sysfs_add_one(struct btrfs_fs_info *fs_info)
|
||||
goto failure;
|
||||
|
||||
fs_info->space_info_kobj = kobject_create_and_add("allocation",
|
||||
super_kobj);
|
||||
fsid_kobj);
|
||||
if (!fs_info->space_info_kobj) {
|
||||
error = -ENOMEM;
|
||||
goto failure;
|
||||
@ -776,7 +776,7 @@ int btrfs_sysfs_add_one(struct btrfs_fs_info *fs_info)
|
||||
|
||||
return 0;
|
||||
failure:
|
||||
btrfs_sysfs_remove_one(fs_info);
|
||||
btrfs_sysfs_remove_mounted(fs_info);
|
||||
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 struct kobj_type space_info_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);
|
||||
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);
|
||||
int btrfs_sysfs_add_fsid(struct btrfs_fs_devices *fs_devs,
|
||||
struct kobject *parent);
|
||||
|
@ -2136,7 +2136,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
|
||||
|
||||
ret = btrfs_write_and_wait_transaction(trans, root);
|
||||
if (ret) {
|
||||
btrfs_error(root->fs_info, ret,
|
||||
btrfs_std_error(root->fs_info, ret,
|
||||
"Error while writing out transaction");
|
||||
mutex_unlock(&root->fs_info->tree_log_mutex);
|
||||
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);
|
||||
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.");
|
||||
goto error;
|
||||
}
|
||||
@ -5328,7 +5328,7 @@ again:
|
||||
ret = btrfs_search_slot(NULL, log_root_tree, &key, path, 0, 0);
|
||||
|
||||
if (ret < 0) {
|
||||
btrfs_error(fs_info, ret,
|
||||
btrfs_std_error(fs_info, ret,
|
||||
"Couldn't find tree log root.");
|
||||
goto error;
|
||||
}
|
||||
@ -5346,7 +5346,7 @@ again:
|
||||
log = btrfs_read_fs_root(log_root_tree, &found_key);
|
||||
if (IS_ERR(log)) {
|
||||
ret = PTR_ERR(log);
|
||||
btrfs_error(fs_info, ret,
|
||||
btrfs_std_error(fs_info, ret,
|
||||
"Couldn't read tree log root.");
|
||||
goto error;
|
||||
}
|
||||
@ -5361,7 +5361,7 @@ again:
|
||||
free_extent_buffer(log->node);
|
||||
free_extent_buffer(log->commit_root);
|
||||
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.");
|
||||
goto error;
|
||||
}
|
||||
|
@ -198,7 +198,6 @@ btrfs_get_bdev_and_sb(const char *device_path, fmode_t flags, void *holder,
|
||||
|
||||
if (IS_ERR(*bdev)) {
|
||||
ret = PTR_ERR(*bdev);
|
||||
printk(KERN_INFO "BTRFS: open %s failed\n", device_path);
|
||||
goto error;
|
||||
}
|
||||
|
||||
@ -211,8 +210,8 @@ btrfs_get_bdev_and_sb(const char *device_path, fmode_t flags, void *holder,
|
||||
}
|
||||
invalidate_bdev(*bdev);
|
||||
*bh = btrfs_read_dev_super(*bdev);
|
||||
if (!*bh) {
|
||||
ret = -EINVAL;
|
||||
if (IS_ERR(*bh)) {
|
||||
ret = PTR_ERR(*bh);
|
||||
blkdev_put(*bdev, flags);
|
||||
goto error;
|
||||
}
|
||||
@ -765,36 +764,7 @@ static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices)
|
||||
|
||||
mutex_lock(&fs_devices->device_list_mutex);
|
||||
list_for_each_entry_safe(device, tmp, &fs_devices->devices, dev_list) {
|
||||
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);
|
||||
btrfs_close_one_device(device);
|
||||
}
|
||||
mutex_unlock(&fs_devices->device_list_mutex);
|
||||
|
||||
@ -1402,7 +1372,7 @@ again:
|
||||
extent = btrfs_item_ptr(leaf, path->slots[0],
|
||||
struct btrfs_dev_extent);
|
||||
} else {
|
||||
btrfs_error(root->fs_info, ret, "Slot search failed");
|
||||
btrfs_std_error(root->fs_info, ret, "Slot search failed");
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -1410,7 +1380,7 @@ again:
|
||||
|
||||
ret = btrfs_del_item(trans, root, path);
|
||||
if (ret) {
|
||||
btrfs_error(root->fs_info, ret,
|
||||
btrfs_std_error(root->fs_info, ret,
|
||||
"Failed to remove dev extent item");
|
||||
} else {
|
||||
trans->transaction->have_free_bgs = 1;
|
||||
@ -1801,7 +1771,7 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
|
||||
if (device->bdev) {
|
||||
device->fs_devices->open_devices--;
|
||||
/* 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);
|
||||
@ -1924,7 +1894,8 @@ void btrfs_rm_dev_replace_remove_srcdev(struct btrfs_fs_info *fs_info,
|
||||
if (srcdev->writeable) {
|
||||
fs_devices->rw_devices--;
|
||||
/* 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)
|
||||
@ -1971,10 +1942,11 @@ void btrfs_destroy_dev_replace_tgtdev(struct btrfs_fs_info *fs_info,
|
||||
WARN_ON(!tgtdev);
|
||||
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) {
|
||||
btrfs_scratch_superblock(tgtdev);
|
||||
btrfs_scratch_superblocks(tgtdev->bdev,
|
||||
rcu_str_deref(tgtdev->name));
|
||||
fs_info->fs_devices->open_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) {
|
||||
btrfs_err(root->fs_info, "no missing device found");
|
||||
return -ENOENT;
|
||||
}
|
||||
if (!*device)
|
||||
return BTRFS_ERROR_DEV_MISSING_NOT_FOUND;
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
@ -2309,7 +2279,7 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path)
|
||||
tmp + 1);
|
||||
|
||||
/* 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
|
||||
@ -2350,7 +2320,7 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path)
|
||||
*/
|
||||
snprintf(fsid_buf, BTRFS_UUID_UNPARSED_SIZE, "%pU",
|
||||
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))
|
||||
btrfs_warn(root->fs_info,
|
||||
"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);
|
||||
if (ret < 0)
|
||||
btrfs_error(root->fs_info, ret,
|
||||
btrfs_std_error(root->fs_info, ret,
|
||||
"Failed to relocate sys chunks after "
|
||||
"device initialization. This can be fixed "
|
||||
"using the \"btrfs balance\" command.");
|
||||
@ -2389,7 +2359,7 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path)
|
||||
error_trans:
|
||||
btrfs_end_transaction(trans, root);
|
||||
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);
|
||||
error:
|
||||
blkdev_put(bdev, FMODE_EXCL);
|
||||
@ -2614,7 +2584,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_error(root->fs_info, -ENOENT,
|
||||
btrfs_std_error(root->fs_info, -ENOENT,
|
||||
"Failed lookup while freeing chunk.");
|
||||
ret = -ENOENT;
|
||||
goto out;
|
||||
@ -2622,7 +2592,7 @@ static int btrfs_free_chunk(struct btrfs_trans_handle *trans,
|
||||
|
||||
ret = btrfs_del_item(trans, root, path);
|
||||
if (ret < 0)
|
||||
btrfs_error(root->fs_info, ret,
|
||||
btrfs_std_error(root->fs_info, ret,
|
||||
"Failed to delete chunk item.");
|
||||
out:
|
||||
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);
|
||||
if (IS_ERR(trans)) {
|
||||
ret = PTR_ERR(trans);
|
||||
btrfs_std_error(root->fs_info, ret);
|
||||
btrfs_std_error(root->fs_info, ret, NULL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -3462,7 +3432,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);
|
||||
btrfs_std_error(fs_info, ret, NULL);
|
||||
|
||||
atomic_set(&fs_info->mutually_exclusive_operation_running, 0);
|
||||
}
|
||||
@ -6741,22 +6711,34 @@ int btrfs_get_dev_stats(struct btrfs_root *root,
|
||||
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 btrfs_super_block *disk_super;
|
||||
int copy_num;
|
||||
|
||||
bh = btrfs_read_dev_super(device->bdev);
|
||||
if (!bh)
|
||||
return -EINVAL;
|
||||
disk_super = (struct btrfs_super_block *)bh->b_data;
|
||||
if (!bdev)
|
||||
return;
|
||||
|
||||
memset(&disk_super->magic, 0, sizeof(disk_super->magic));
|
||||
set_buffer_dirty(bh);
|
||||
sync_dirty_buffer(bh);
|
||||
brelse(bh);
|
||||
for (copy_num = 0; copy_num < BTRFS_SUPER_MIRROR_MAX;
|
||||
copy_num++) {
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
/* sysfs kobjects */
|
||||
struct kobject super_kobj;
|
||||
struct kobject fsid_kobj;
|
||||
struct kobject *device_dir_kobj;
|
||||
struct completion kobj_unregister;
|
||||
};
|
||||
@ -474,7 +474,7 @@ void btrfs_destroy_dev_replace_tgtdev(struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_device *tgtdev);
|
||||
void btrfs_init_dev_replace_tgtdev_for_resume(struct btrfs_fs_info *fs_info,
|
||||
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,
|
||||
u64 logical, u64 len, int mirror_num);
|
||||
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);
|
||||
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_close_one_device(struct btrfs_device *device);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user