Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pull request #1

Closed
wants to merge 30 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
96f3136
Btrfs: rename btrfs_sysfs_add_one to btrfs_sysfs_add_mounted
asj Aug 14, 2015
6618a59
Btrfs: rename btrfs_sysfs_remove_one to btrfs_sysfs_remove_mounted
asj Aug 14, 2015
e3bd697
Btrfs: rename btrfs_kobj_add_device to btrfs_sysfs_add_device_link
asj Aug 14, 2015
3257604
Btrfs: rename btrfs_kobj_rm_device to btrfs_sysfs_rm_device_link
asj Aug 14, 2015
c1b7e47
Btrfs: rename super_kobj to fsid_kobj
asj Aug 14, 2015
92fc03f
Btrfs: SB read failure should return EIO for __bread failure
asj Aug 14, 2015
57d816a
Btrfs: __btrfs_std_error() logic should be consistent w/out CONFIG_PR…
asj Aug 14, 2015
a4553fe
Btrfs: consolidate btrfs_error() to btrfs_std_error()
asj Sep 25, 2015
d74a625
Btrfs: use BTRFS_ERROR_DEV_MISSING_NOT_FOUND when missing device is n…
asj Aug 14, 2015
29c36d7
Btrfs: add btrfs_read_dev_one_super() to read one specific SB
asj Aug 14, 2015
12b1c26
Btrfs: enhance btrfs_scratch_superblock to scratch all superblocks
asj Aug 14, 2015
9e271ae
Btrfs: kernel operation should come after user input has been verified
asj Aug 14, 2015
097efc9
Btrfs: don't log error from btrfs_get_bdev_and_sb
asj Aug 14, 2015
f190aa4
Btrfs: add helper for closing one device
asj Aug 14, 2015
73416da
Btrfs: move kobj stuff out of dev_replace lock range
Aug 14, 2015
0aee754
Btrfs: pass the error code to the btrfs_std_error and log ret
asj Oct 2, 2015
8758f87
Btrfs: create a helper function to read the disk super
asj Sep 20, 2015
a964fac
btrfs: maintain consistency in logging to help debugging
asj Sep 21, 2015
defa97a
Btrfs: device path change must be logged
asj May 21, 2015
e6aea8e
Btrfs: add missing brelse when superblock checksum fails
asj Oct 5, 2015
0812a51
Btrfs: optimize check for stale device
asj Oct 5, 2015
bd74b0d
Btrfs: sysfs: support seed devices in the sysfs layout
asj Jun 18, 2015
b0b3990
Btrfs: create a framework to create pool attributes
asj Mar 20, 2015
0efce14
Btrfs: create helper function __check_raid_min_devices()
asj Apr 23, 2015
3f7d4c2
Btrfs: clean up and optimize __check_raid_min_device()
asj Oct 1, 2015
504bed3
Btrfs: create helper btrfs_find_device_by_user_input()
asj Apr 23, 2015
b737e10
Btrfs: make use of btrfs_find_device_by_user_input()
asj Apr 23, 2015
427d077
Btrfs: enhance btrfs_find_device_by_user_input() to check device path
asj May 31, 2015
cef4787
Btrfs: make use of btrfs_scratch_superblocks() in btrfs_rm_device()
asj Apr 24, 2015
497198c
Btrfs: Introduce device delete by devid
asj Apr 13, 2015
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions fs/btrfs/ctree.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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);
Expand Down
13 changes: 3 additions & 10 deletions fs/btrfs/ctree.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -4127,14 +4127,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); \
Expand Down
67 changes: 22 additions & 45 deletions fs/btrfs/dev-replace.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,6 @@ static void btrfs_dev_replace_update_device_in_mapping_tree(
struct btrfs_fs_info *fs_info,
struct btrfs_device *srcdev,
struct btrfs_device *tgtdev);
static int btrfs_dev_replace_find_srcdev(struct btrfs_root *root, u64 srcdevid,
char *srcdev_name,
struct btrfs_device **device);
static u64 __btrfs_dev_replace_cancel(struct btrfs_fs_info *fs_info);
static int btrfs_dev_replace_kthread(void *data);
static int btrfs_dev_replace_continue_on_mount(struct btrfs_fs_info *fs_info);
Expand Down Expand Up @@ -323,26 +320,9 @@ int btrfs_dev_replace_start(struct btrfs_root *root,
return -EINVAL;
}

if ((args->start.srcdevid == 0 && args->start.srcdev_name[0] == '\0') ||
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,
ret = btrfs_find_device_by_user_input(root, args->start.srcdevid,
args->start.srcdev_name,
&src_device);
if (ret) {
Expand All @@ -356,6 +336,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:
Expand All @@ -375,10 +368,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);

printk_in_rcu(KERN_INFO
"BTRFS: dev_replace from %s (devid %llu) to %s started\n",
src_device->missing ? "<missing disk>" :
Expand All @@ -401,6 +390,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, 0);
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 */
Expand Down Expand Up @@ -586,7 +579,10 @@ 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, 0);
if (src_device->fs_devices->seeding &&
!src_device->fs_devices->num_devices)
btrfs_sysfs_remove_fsid(src_device->fs_devices);
btrfs_rm_dev_replace_free_srcdev(fs_info, src_device);

/* write back the superblocks */
Expand Down Expand Up @@ -625,25 +621,6 @@ static void btrfs_dev_replace_update_device_in_mapping_tree(
write_unlock(&em_tree->lock);
}

static int btrfs_dev_replace_find_srcdev(struct btrfs_root *root, u64 srcdevid,
char *srcdev_name,
struct btrfs_device **device)
{
int ret;

if (srcdevid) {
ret = 0;
*device = btrfs_find_device(root->fs_info, srcdevid, NULL,
NULL);
if (!*device)
ret = -ENOENT;
} else {
ret = btrfs_find_device_missing_or_by_path(root, srcdev_name,
device);
}
return ret;
}

void btrfs_dev_replace_status(struct btrfs_fs_info *fs_info,
struct btrfs_ioctl_dev_replace_args *args)
{
Expand Down
86 changes: 56 additions & 30 deletions fs/btrfs/disk-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -2377,7 +2377,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);
Expand Down Expand Up @@ -2653,8 +2653,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;
}

Expand All @@ -2665,6 +2665,7 @@ int open_ctree(struct super_block *sb,
if (btrfs_check_super_csum(bh->b_data)) {
printk(KERN_ERR "BTRFS: superblock checksum mismatch\n");
err = -EINVAL;
brelse(bh);
goto fail_alloc;
}

Expand Down Expand Up @@ -2921,22 +2922,22 @@ int open_ctree(struct super_block *sb,

btrfs_close_extra_devices(fs_devices, 1);

ret = btrfs_sysfs_add_fsid(fs_devices, NULL);
if (ret) {
ret = btrfs_sysfs_add_fsid(fs_devices, NULL, 1);
if (ret && ret != -EEXIST) {
pr_err("BTRFS: failed to init sysfs fsid interface: %d\n", ret);
goto fail_block_groups;
}

ret = btrfs_sysfs_add_device(fs_devices);
ret = btrfs_sysfs_add_device(fs_devices, 1);
if (ret) {
pr_err("BTRFS: failed to init sysfs device interface: %d\n", ret);
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;
goto fail_block_groups;
}

ret = btrfs_init_space_info(fs_info);
Expand Down Expand Up @@ -3113,10 +3114,7 @@ int open_ctree(struct super_block *sb,
filemap_write_and_wait(fs_info->btree_inode->i_mapping);

fail_sysfs:
btrfs_sysfs_remove_one(fs_info);

fail_fsdev_sysfs:
btrfs_sysfs_remove_fsid(fs_info->fs_devices);
btrfs_sysfs_remove_mounted(fs_info);

fail_block_groups:
btrfs_put_block_group_cache(fs_info);
Expand Down Expand Up @@ -3188,36 +3186,57 @@ 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;
struct buffer_head *latest = NULL;
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.
* So, we need to add a special mount option to scan for
* 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);
Expand All @@ -3227,6 +3246,10 @@ struct buffer_head *btrfs_read_dev_super(struct block_device *bdev)
brelse(bh);
}
}

if (!latest)
return ERR_PTR(ret);

return latest;
}

Expand Down Expand Up @@ -3544,7 +3567,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;
}
Expand Down Expand Up @@ -3584,7 +3607,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;
}
Expand All @@ -3602,7 +3625,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;
}
Expand Down Expand Up @@ -3788,8 +3811,11 @@ void close_ctree(struct btrfs_root *root)
percpu_counter_sum(&fs_info->delalloc_bytes));
}

btrfs_sysfs_remove_one(fs_info);
btrfs_sysfs_remove_fsid(fs_info->fs_devices);
btrfs_sysfs_remove_mounted(fs_info);
if (fs_info->fs_devices->seed) {
btrfs_sysfs_remove_fsid(fs_info->fs_devices->seed);
btrfs_sysfs_rm_seed_dir(fs_info->fs_devices);
}

btrfs_free_fs_roots(fs_info);

Expand Down
2 changes: 2 additions & 0 deletions fs/btrfs/disk-io.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion fs/btrfs/extent-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -8688,7 +8688,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root,
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;
}

Expand Down
2 changes: 1 addition & 1 deletion fs/btrfs/inode-item.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
Loading