btrfs: add a BTRFS_FS_ERROR helper
We have a few flags that are inconsistently used to describe the fs in different states of failure. As of5963ffcaf3
("btrfs: always abort the transaction if we abort a trans handle") we will always set BTRFS_FS_STATE_ERROR if we abort, so we don't have to check both ABORTED and ERROR to see if things have gone wrong. Add a helper to check BTRFS_FS_STATE_ERROR and then convert all checkers of FS_STATE_ERROR to use the helper. The TRANS_ABORTED bit check was added inaf72273381
("Btrfs: clean up resources during umount after trans is aborted") but is not actually specific. Reviewed-by: Anand Jain <anand.jain@oracle.com> Reviewed-by: Nikolay Borisov <nborisov@suse.com> Signed-off-by: Josef Bacik <josef@toxicpanda.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
9a35fc9542
commit
8496153945
@ -3607,6 +3607,9 @@ do { \
|
||||
(errno), fmt, ##args); \
|
||||
} while (0)
|
||||
|
||||
#define BTRFS_FS_ERROR(fs_info) (unlikely(test_bit(BTRFS_FS_STATE_ERROR, \
|
||||
&(fs_info)->fs_state)))
|
||||
|
||||
__printf(5, 6)
|
||||
__cold
|
||||
void __btrfs_panic(struct btrfs_fs_info *fs_info, const char *function,
|
||||
|
@ -1954,8 +1954,7 @@ sleep:
|
||||
wake_up_process(fs_info->cleaner_kthread);
|
||||
mutex_unlock(&fs_info->transaction_kthread_mutex);
|
||||
|
||||
if (unlikely(test_bit(BTRFS_FS_STATE_ERROR,
|
||||
&fs_info->fs_state)))
|
||||
if (BTRFS_FS_ERROR(fs_info))
|
||||
btrfs_cleanup_transaction(fs_info);
|
||||
if (!kthread_should_stop() &&
|
||||
(!btrfs_transaction_blocked(fs_info) ||
|
||||
@ -4232,7 +4231,7 @@ void btrfs_drop_and_free_fs_root(struct btrfs_fs_info *fs_info,
|
||||
drop_ref = true;
|
||||
spin_unlock(&fs_info->fs_roots_radix_lock);
|
||||
|
||||
if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state)) {
|
||||
if (BTRFS_FS_ERROR(fs_info)) {
|
||||
ASSERT(root->log_root == NULL);
|
||||
if (root->reloc_root) {
|
||||
btrfs_put_root(root->reloc_root);
|
||||
@ -4383,8 +4382,7 @@ void __cold close_ctree(struct btrfs_fs_info *fs_info)
|
||||
btrfs_err(fs_info, "commit super ret %d", ret);
|
||||
}
|
||||
|
||||
if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state) ||
|
||||
test_bit(BTRFS_FS_STATE_TRANS_ABORTED, &fs_info->fs_state))
|
||||
if (BTRFS_FS_ERROR(fs_info))
|
||||
btrfs_error_commit_super(fs_info);
|
||||
|
||||
kthread_stop(fs_info->transaction_kthread);
|
||||
|
@ -4908,7 +4908,7 @@ retry:
|
||||
* extent io tree. Thus we don't want to submit such wild eb
|
||||
* if the fs already has error.
|
||||
*/
|
||||
if (!test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state)) {
|
||||
if (!BTRFS_FS_ERROR(fs_info)) {
|
||||
ret = flush_write_bio(&epd);
|
||||
} else {
|
||||
ret = -EROFS;
|
||||
|
@ -2018,7 +2018,7 @@ static ssize_t btrfs_file_write_iter(struct kiocb *iocb,
|
||||
* have opened a file as writable, we have to stop this write operation
|
||||
* to ensure consistency.
|
||||
*/
|
||||
if (test_bit(BTRFS_FS_STATE_ERROR, &inode->root->fs_info->fs_state))
|
||||
if (BTRFS_FS_ERROR(inode->root->fs_info))
|
||||
return -EROFS;
|
||||
|
||||
if (!(iocb->ki_flags & IOCB_DIRECT) &&
|
||||
|
@ -4380,7 +4380,7 @@ static void btrfs_prune_dentries(struct btrfs_root *root)
|
||||
struct inode *inode;
|
||||
u64 objectid = 0;
|
||||
|
||||
if (!test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state))
|
||||
if (!BTRFS_FS_ERROR(fs_info))
|
||||
WARN_ON(btrfs_root_refs(&root->root_item) != 0);
|
||||
|
||||
spin_lock(&root->inode_lock);
|
||||
@ -9998,7 +9998,7 @@ int btrfs_start_delalloc_snapshot(struct btrfs_root *root, bool in_reclaim_conte
|
||||
};
|
||||
struct btrfs_fs_info *fs_info = root->fs_info;
|
||||
|
||||
if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state))
|
||||
if (BTRFS_FS_ERROR(fs_info))
|
||||
return -EROFS;
|
||||
|
||||
return start_delalloc_inodes(root, &wbc, true, in_reclaim_context);
|
||||
@ -10017,7 +10017,7 @@ int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, long nr,
|
||||
struct list_head splice;
|
||||
int ret;
|
||||
|
||||
if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state))
|
||||
if (BTRFS_FS_ERROR(fs_info))
|
||||
return -EROFS;
|
||||
|
||||
INIT_LIST_HEAD(&splice);
|
||||
|
@ -3955,7 +3955,7 @@ static noinline_for_stack int scrub_supers(struct scrub_ctx *sctx,
|
||||
int ret;
|
||||
struct btrfs_fs_info *fs_info = sctx->fs_info;
|
||||
|
||||
if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state))
|
||||
if (BTRFS_FS_ERROR(fs_info))
|
||||
return -EROFS;
|
||||
|
||||
/* Seed devices of a new filesystem has their own generation. */
|
||||
|
@ -2006,7 +2006,7 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
|
||||
if (ret)
|
||||
goto restore;
|
||||
} else {
|
||||
if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state)) {
|
||||
if (BTRFS_FS_ERROR(fs_info)) {
|
||||
btrfs_err(fs_info,
|
||||
"Remounting read-write after error is not allowed");
|
||||
ret = -EINVAL;
|
||||
|
@ -283,7 +283,7 @@ static noinline int join_transaction(struct btrfs_fs_info *fs_info,
|
||||
spin_lock(&fs_info->trans_lock);
|
||||
loop:
|
||||
/* The file system has been taken offline. No new transactions. */
|
||||
if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state)) {
|
||||
if (BTRFS_FS_ERROR(fs_info)) {
|
||||
spin_unlock(&fs_info->trans_lock);
|
||||
return -EROFS;
|
||||
}
|
||||
@ -331,7 +331,7 @@ loop:
|
||||
*/
|
||||
kfree(cur_trans);
|
||||
goto loop;
|
||||
} else if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state)) {
|
||||
} else if (BTRFS_FS_ERROR(fs_info)) {
|
||||
spin_unlock(&fs_info->trans_lock);
|
||||
kfree(cur_trans);
|
||||
return -EROFS;
|
||||
@ -579,7 +579,7 @@ start_transaction(struct btrfs_root *root, unsigned int num_items,
|
||||
bool do_chunk_alloc = false;
|
||||
int ret;
|
||||
|
||||
if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state))
|
||||
if (BTRFS_FS_ERROR(fs_info))
|
||||
return ERR_PTR(-EROFS);
|
||||
|
||||
if (current->journal_info) {
|
||||
@ -991,8 +991,7 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
|
||||
if (throttle)
|
||||
btrfs_run_delayed_iputs(info);
|
||||
|
||||
if (TRANS_ABORTED(trans) ||
|
||||
test_bit(BTRFS_FS_STATE_ERROR, &info->fs_state)) {
|
||||
if (TRANS_ABORTED(trans) || BTRFS_FS_ERROR(info)) {
|
||||
wake_up_process(info->transaction_kthread);
|
||||
if (TRANS_ABORTED(trans))
|
||||
err = trans->aborted;
|
||||
@ -2155,7 +2154,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
|
||||
* abort to prevent writing a new superblock that reflects a
|
||||
* corrupt state (pointing to trees with unwritten nodes/leafs).
|
||||
*/
|
||||
if (test_bit(BTRFS_FS_STATE_TRANS_ABORTED, &fs_info->fs_state)) {
|
||||
if (BTRFS_FS_ERROR(fs_info)) {
|
||||
ret = -EROFS;
|
||||
goto cleanup_transaction;
|
||||
}
|
||||
|
@ -3353,7 +3353,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
|
||||
* writing the super here would result in transid mismatches. If there
|
||||
* is an error here just bail.
|
||||
*/
|
||||
if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state)) {
|
||||
if (BTRFS_FS_ERROR(fs_info)) {
|
||||
ret = -EIO;
|
||||
btrfs_set_log_full_commit(trans);
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
|
Loading…
Reference in New Issue
Block a user