btrfs: check FS error state bit early during write

fs_info::fs_state is a filesystem bit check as opposed to inode and can
be performed before we begin with write checks. This eliminates inode
lock/unlock in case the error bit is set.

Reviewed-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
Goldwyn Rodrigues 2020-09-24 11:39:14 -05:00 committed by David Sterba
parent 5e8b9ef303
commit c86537a42f
1 changed files with 8 additions and 12 deletions

View File

@ -1907,6 +1907,14 @@ static ssize_t btrfs_file_write_iter(struct kiocb *iocb,
size_t count;
loff_t oldsize;
/*
* If the fs flips readonly due to some impossible error, although we
* have opened a file as writable, we have to stop this write operation
* to ensure consistency.
*/
if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state))
return -EROFS;
if (!(iocb->ki_flags & IOCB_DIRECT) &&
(iocb->ki_flags & IOCB_NOWAIT))
return -EOPNOTSUPP;
@ -1956,18 +1964,6 @@ static ssize_t btrfs_file_write_iter(struct kiocb *iocb,
goto out;
}
/*
* If BTRFS flips readonly due to some impossible error
* (fs_info->fs_state now has BTRFS_SUPER_FLAG_ERROR),
* although we have opened a file as writable, we have
* to stop this write operation to ensure FS consistency.
*/
if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state)) {
inode_unlock(inode);
err = -EROFS;
goto out;
}
/*
* We reserve space for updating the inode when we reserve space for the
* extent we are going to write, so we will enospc out there. We don't