OSDN Git Service

btrfs: do not write supers if we have an fs error
authorJosef Bacik <josef@toxicpanda.com>
Wed, 19 May 2021 21:15:53 +0000 (17:15 -0400)
committerDavid Sterba <dsterba@suse.com>
Fri, 4 Jun 2021 11:11:38 +0000 (13:11 +0200)
commit165ea85f14831f27fc6fe3b02b35e42e50b9ed94
tree05a344f0b35e05a925e05b565b614f12d8baaaab
parent503d1acb01826b42e5afb496dfcc32751bec9478
btrfs: do not write supers if we have an fs error

Error injection testing uncovered a pretty severe problem where we could
end up committing a super that pointed to the wrong tree roots,
resulting in transid mismatch errors.

The way we commit the transaction is we update the super copy with the
current generations and bytenrs of the important roots, and then copy
that into our super_for_commit.  Then we allow transactions to continue
again, we write out the dirty pages for the transaction, and then we
write the super.  If the write out fails we'll bail and skip writing the
supers.

However since we've allowed a new transaction to start, we can have a
log attempting to sync at this point, which would be blocked on
fs_info->tree_log_mutex.  Once the commit fails we're allowed to do the
log tree commit, which uses super_for_commit, which now points at fs
tree's that were not written out.

Fix this by checking BTRFS_FS_STATE_ERROR once we acquire the
tree_log_mutex.  This way if the transaction commit fails we're sure to
see this bit set and we can skip writing the super out.  This patch
fixes this specific transid mismatch error I was seeing with this
particular error path.

CC: stable@vger.kernel.org # 5.12+
Reviewed-by: Filipe Manana <fdmanana@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>
fs/btrfs/tree-log.c