Skip to content

Commit 6d280f4

Browse files
committed
Merge tag 'for-6.8-rc3-tag' of git://git.kernel.org/pub/scm/linux/kernel/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
2 parents 99bd3cb + e03ee2f commit 6d280f4

File tree

4 files changed

+31
-3
lines changed

4 files changed

+31
-3
lines changed

fs/btrfs/disk-io.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1336,8 +1336,17 @@ static struct btrfs_root *btrfs_get_root_ref(struct btrfs_fs_info *fs_info,
13361336
again:
13371337
root = btrfs_lookup_fs_root(fs_info, objectid);
13381338
if (root) {
1339-
/* Shouldn't get preallocated anon_dev for cached roots */
1340-
ASSERT(!anon_dev);
1339+
/*
1340+
* Some other caller may have read out the newly inserted
1341+
* subvolume already (for things like backref walk etc). Not
1342+
* that common but still possible. In that case, we just need
1343+
* to free the anon_dev.
1344+
*/
1345+
if (unlikely(anon_dev)) {
1346+
free_anon_bdev(anon_dev);
1347+
anon_dev = 0;
1348+
}
1349+
13411350
if (check_ref && btrfs_root_refs(&root->root_item) == 0) {
13421351
btrfs_put_root(root);
13431352
return ERR_PTR(-ENOENT);

fs/btrfs/ioctl.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3815,6 +3815,11 @@ static long btrfs_ioctl_qgroup_create(struct file *file, void __user *arg)
38153815
goto out;
38163816
}
38173817

3818+
if (sa->create && is_fstree(sa->qgroupid)) {
3819+
ret = -EINVAL;
3820+
goto out;
3821+
}
3822+
38183823
trans = btrfs_join_transaction(root);
38193824
if (IS_ERR(trans)) {
38203825
ret = PTR_ERR(trans);

fs/btrfs/qgroup.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1736,6 +1736,15 @@ int btrfs_create_qgroup(struct btrfs_trans_handle *trans, u64 qgroupid)
17361736
return ret;
17371737
}
17381738

1739+
static bool qgroup_has_usage(struct btrfs_qgroup *qgroup)
1740+
{
1741+
return (qgroup->rfer > 0 || qgroup->rfer_cmpr > 0 ||
1742+
qgroup->excl > 0 || qgroup->excl_cmpr > 0 ||
1743+
qgroup->rsv.values[BTRFS_QGROUP_RSV_DATA] > 0 ||
1744+
qgroup->rsv.values[BTRFS_QGROUP_RSV_META_PREALLOC] > 0 ||
1745+
qgroup->rsv.values[BTRFS_QGROUP_RSV_META_PERTRANS] > 0);
1746+
}
1747+
17391748
int btrfs_remove_qgroup(struct btrfs_trans_handle *trans, u64 qgroupid)
17401749
{
17411750
struct btrfs_fs_info *fs_info = trans->fs_info;
@@ -1755,6 +1764,11 @@ int btrfs_remove_qgroup(struct btrfs_trans_handle *trans, u64 qgroupid)
17551764
goto out;
17561765
}
17571766

1767+
if (is_fstree(qgroupid) && qgroup_has_usage(qgroup)) {
1768+
ret = -EBUSY;
1769+
goto out;
1770+
}
1771+
17581772
/* Check if there are no children of this qgroup */
17591773
if (!list_empty(&qgroup->members)) {
17601774
ret = -EBUSY;

fs/btrfs/send.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8111,7 +8111,7 @@ long btrfs_ioctl_send(struct inode *inode, struct btrfs_ioctl_send_args *arg)
81118111
}
81128112

81138113
if (arg->flags & ~BTRFS_SEND_FLAG_MASK) {
8114-
ret = -EINVAL;
8114+
ret = -EOPNOTSUPP;
81158115
goto out;
81168116
}
81178117

0 commit comments

Comments
 (0)