mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-22 02:17:36 -04:00
btrfs: validate properties before setting them
We set the xattr and then attempt to apply the property. If the apply fails we then attempt to delete the xattr to avoid an inconsistency. However we don't verify if the deletion succeed, so if it fails we leave an inconsistency between the state in the btree and the in-memory inode. Address this by validating first if we can apply the property, then set the xattr, then apply the property, and this last step should not fail since the validation succeeded before - assert that it does not fail but leave code to attempt to delete the xattr if it happens, and then abort the transaction only if the xattr delete failed. Reviewed-by: Qu Wenruo <wqu@suse.com> Signed-off-by: Filipe Manana <fdmanana@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
committed by
David Sterba
parent
ae2eb64bfd
commit
cf1afec09e
@@ -127,14 +127,24 @@ int btrfs_set_prop(struct btrfs_trans_handle *trans, struct btrfs_inode *inode,
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = handler->validate(inode, value, value_len);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = btrfs_setxattr(trans, &inode->vfs_inode, handler->xattr_name, value,
|
||||
value_len, flags);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = handler->apply(inode, value, value_len);
|
||||
if (ret) {
|
||||
btrfs_setxattr(trans, &inode->vfs_inode, handler->xattr_name, NULL,
|
||||
0, flags);
|
||||
/* We validated before, so it should not fail here. */
|
||||
ASSERT(ret == 0);
|
||||
if (unlikely(ret)) {
|
||||
int ret2;
|
||||
|
||||
/* Try to delete xattr, if not possible abort transaction. */
|
||||
ret2 = btrfs_setxattr(trans, &inode->vfs_inode, handler->xattr_name,
|
||||
NULL, 0, flags);
|
||||
if (unlikely(ret2))
|
||||
btrfs_abort_transaction(trans, ret2);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user