Skip to content

Commit

Permalink
Merge tag 'for-6.8-rc3-tag' of git://git.kernel.org/pub/scm/linux/ker…
Browse files Browse the repository at this point in the history
…nel/git/kdave/linux

Pull btrfs fixes from David Sterba:

 - two fixes preventing deletion and manual creation of subvolume qgroup

 - unify error code returned for unknown send flags

 - fix assertion during subvolume creation when anonymous device could
   be allocated by other thread (e.g. due to backref walk)

* tag 'for-6.8-rc3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
  btrfs: do not ASSERT() if the newly created subvolume already got read
  btrfs: forbid deleting live subvol qgroup
  btrfs: forbid creating subvol qgroups
  btrfs: send: return EOPNOTSUPP on unknown flags
  • Loading branch information
Linus Torvalds committed Feb 7, 2024
2 parents 99bd3cb + e03ee2f commit 6d280f4
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 3 deletions.
13 changes: 11 additions & 2 deletions fs/btrfs/disk-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -1336,8 +1336,17 @@ static struct btrfs_root *btrfs_get_root_ref(struct btrfs_fs_info *fs_info,
again:
root = btrfs_lookup_fs_root(fs_info, objectid);
if (root) {
/* Shouldn't get preallocated anon_dev for cached roots */
ASSERT(!anon_dev);
/*
* Some other caller may have read out the newly inserted
* subvolume already (for things like backref walk etc). Not
* that common but still possible. In that case, we just need
* to free the anon_dev.
*/
if (unlikely(anon_dev)) {
free_anon_bdev(anon_dev);
anon_dev = 0;
}

if (check_ref && btrfs_root_refs(&root->root_item) == 0) {
btrfs_put_root(root);
return ERR_PTR(-ENOENT);
Expand Down
5 changes: 5 additions & 0 deletions fs/btrfs/ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -3815,6 +3815,11 @@ static long btrfs_ioctl_qgroup_create(struct file *file, void __user *arg)
goto out;
}

if (sa->create && is_fstree(sa->qgroupid)) {
ret = -EINVAL;
goto out;
}

trans = btrfs_join_transaction(root);
if (IS_ERR(trans)) {
ret = PTR_ERR(trans);
Expand Down
14 changes: 14 additions & 0 deletions fs/btrfs/qgroup.c
Original file line number Diff line number Diff line change
Expand Up @@ -1736,6 +1736,15 @@ int btrfs_create_qgroup(struct btrfs_trans_handle *trans, u64 qgroupid)
return ret;
}

static bool qgroup_has_usage(struct btrfs_qgroup *qgroup)
{
return (qgroup->rfer > 0 || qgroup->rfer_cmpr > 0 ||
qgroup->excl > 0 || qgroup->excl_cmpr > 0 ||
qgroup->rsv.values[BTRFS_QGROUP_RSV_DATA] > 0 ||
qgroup->rsv.values[BTRFS_QGROUP_RSV_META_PREALLOC] > 0 ||
qgroup->rsv.values[BTRFS_QGROUP_RSV_META_PERTRANS] > 0);
}

int btrfs_remove_qgroup(struct btrfs_trans_handle *trans, u64 qgroupid)
{
struct btrfs_fs_info *fs_info = trans->fs_info;
Expand All @@ -1755,6 +1764,11 @@ int btrfs_remove_qgroup(struct btrfs_trans_handle *trans, u64 qgroupid)
goto out;
}

if (is_fstree(qgroupid) && qgroup_has_usage(qgroup)) {
ret = -EBUSY;
goto out;
}

/* Check if there are no children of this qgroup */
if (!list_empty(&qgroup->members)) {
ret = -EBUSY;
Expand Down
2 changes: 1 addition & 1 deletion fs/btrfs/send.c
Original file line number Diff line number Diff line change
Expand Up @@ -8111,7 +8111,7 @@ long btrfs_ioctl_send(struct inode *inode, struct btrfs_ioctl_send_args *arg)
}

if (arg->flags & ~BTRFS_SEND_FLAG_MASK) {
ret = -EINVAL;
ret = -EOPNOTSUPP;
goto out;
}

Expand Down

0 comments on commit 6d280f4

Please sign in to comment.