Skip to content

Fix 'zfs userspace' for received datasets in encrypted root #9596

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 16, 2020

Conversation

loli10K
Copy link
Contributor

@loli10K loli10K commented Nov 17, 2019

Motivation and Context

Fix #9501

Description

For encrypted receives, where user accounting is initially disabled on creation, both 'zfs userspace' and 'zfs groupspace' fails with EOPNOTSUPP: this is because dmu_objset_id_quota_upgrade_cb() forgets to set OBJSET_FLAG_USERACCOUNTING_COMPLETE on the objset flags after a successful dmu_objset_space_upgrade().

Analysis here: #9501 (comment)

I agree with @tcaputi comment here #9501 (comment): while i was debugging the original issue i found some user accounting code confusing, unfortunately i don't have the time nor the knowledge to refactor the existing code right now, i am just pushing the fix so i can cleanup my local workspace.

How Has This Been Tested?

ZFS Test Suite was updated with new test case.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Performance enhancement (non-breaking change which improves efficiency)
  • Code cleanup (non-breaking change which makes code smaller or more readable)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation (a change to man pages or other documentation)

Checklist:

@loli10K loli10K added the Status: Code Review Needed Ready for review and testing label Nov 17, 2019
@codecov
Copy link

codecov bot commented Nov 17, 2019

Codecov Report

Merging #9596 (d45e0db) into master (a724db0) will decrease coverage by 0.34%.
The diff coverage is 95.12%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #9596      +/-   ##
==========================================
- Coverage   79.80%   79.46%   -0.35%     
==========================================
  Files         398      385      -13     
  Lines      125765   121503    -4262     
==========================================
- Hits       100372    96552    -3820     
+ Misses      25393    24951     -442     
Flag Coverage Δ
kernel 79.77% <95.12%> (-0.70%) ⬇️
user 67.09% <29.41%> (+1.21%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
module/zfs/zfs_ioctl.c 86.21% <91.66%> (-0.22%) ⬇️
module/zfs/dmu_objset.c 91.31% <100.00%> (-0.44%) ⬇️
module/os/linux/spl/spl-vmem.c 54.16% <0.00%> (-45.84%) ⬇️
lib/libzpool/util.c 76.04% <0.00%> (-18.90%) ⬇️
module/os/linux/spl/spl-kmem-cache.c 75.31% <0.00%> (-14.78%) ⬇️
include/os/linux/zfs/sys/trace_arc.h 85.71% <0.00%> (-14.29%) ⬇️
module/zfs/zrlock.c 86.15% <0.00%> (-10.57%) ⬇️
module/zfs/zfs_onexit.c 76.19% <0.00%> (-9.86%) ⬇️
lib/libzfs/os/linux/libzfs_mount_os.c 63.71% <0.00%> (-7.04%) ⬇️
module/os/linux/zfs/policy.c 54.16% <0.00%> (-6.65%) ⬇️
... and 280 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update a724db0...a1ce2a2. Read the comment docs.

@tcaputi
Copy link
Contributor

tcaputi commented Nov 18, 2019

The reasoning seems right to me, but I would prefer if someone more familiar with the object accounting code approved the PR.

@loli10K Small nitpick on the commit message: In the code an encrypted receive is any receive that will create an encrypted dataset (even if thats just receiving into an encryption child). A RAW receive will disable the accounting and cause the issue youre fixing here. Just for consistency.

@loli10K
Copy link
Contributor Author

loli10K commented Nov 18, 2019

A RAW receive will disable the accounting and cause the issue youre fixing here

But the issue seems to be affecting un-encrypted datasets received with "normal" zfs send in encrypted hierarchy, not RAW receives:

root@linux:~# POOLNAME='testpool'
root@linux:~# TMPDIR='/var/tmp'
root@linux:~# mountpoint -q $TMPDIR || mount -t tmpfs tmpfs $TMPDIR
root@linux:~# zpool destroy -f $POOLNAME
root@linux:~# rm -f $TMPDIR/zpool.dat
root@linux:~# truncate -s 128m $TMPDIR/zpool.dat
root@linux:~# zpool create -f $POOLNAME $TMPDIR/zpool.dat
root@linux:~# echo 'password' | zfs create -o encryption=on -o keyformat=passphrase -o keylocation=prompt $POOLNAME/encroot
root@linux:~# zfs create $POOLNAME/sendfs
root@linux:~# dd if=/dev/urandom of=/$POOLNAME/sendfs/file.bin bs=1K count=1
1+0 records in
1+0 records out
1024 bytes (1.0 kB, 1.0 KiB) copied, 0.000135247 s, 7.6 MB/s
root@linux:~# zfs snap $POOLNAME/sendfs@snap1
root@linux:~# zfs send $POOLNAME/sendfs@snap1 | zfs recv $POOLNAME/encroot/recvfs
root@linux:~# zfs userspace $POOLNAME/encroot/recvfs
cannot get used/quota for testpool/encroot/recvfs: unsupported version or feature
root@linux:~# 

@tcaputi
Copy link
Contributor

tcaputi commented Nov 18, 2019

Oh, Im sorry. You are right. we did that for regular encrypted sends as well to avoid some interference with raw sending the received datasets. My mistake.

@behlendorf
Copy link
Contributor

I agree with @tcaputi comment here #9501 (comment): while i was debugging the original issue i found some user accounting code confusing

The code is a bit convoluted in places, but I believe I can shed some light on why that's the case. Hopefully it will help guide any refactoring we may have to do here.

Originally ZFS only supported byte level space accounting. This functionality was added in ZPL_VERSION_4 which predates the introduction of feature flags. Subsequently, object and project quota accounting where introduced with their own dedicated feature flags.

Since the object and project quota accounting doesn't technically depend on the original user space accounting the logic was kept separate (zfs_ioc_userspace_upgrade() and zfs_ioc_id_quota_upgrade). This made enabling the new feature a little simpler at the time. Although in practice, if you have either of these feature flags enabled it implies at least a ZPL_VERSION_5 pool.

This code was then subsequently reworked slightly to handle some of the new complications presented by encrypted pools. Specifically the restriction that some accounting information could only be updated when the encryption key was loaded.

In order to solve this efficiently I think we might want to do a little more refactoring. My concern with the proposed fix is that I don't believe it handles the case when neither user object or project quotas features are enabled on the pool. In this case, it looks like the upgrade won't run at all resulting in the same issue.

One minimal solution might be to kick off a dmu_objset_userspace_upgrade() in dmu_objset_own() when neither feature flag is enabled. And to keep the additional logic in this PR with a comment explaining why it's correct to set the OBJSET_FLAG_USERACCOUNTING_COMPLETE flag. i.e. that the existence of these feature flags means user space account must be supported.

@loli10K
Copy link
Contributor Author

loli10K commented Nov 19, 2019

I will not be able to work on the needed refactoring for some time, adding the work in progress tag but feel free to close it.

@loli10K loli10K added Status: Work in Progress Not yet ready for general review and removed Status: Code Review Needed Ready for review and testing labels Nov 19, 2019
@behlendorf
Copy link
Contributor

No problem. To be a little more specific, I believe this untested additional change if included in this PR would be sufficient. Though we'd want to include a test case as well.

diff --git a/module/zfs/dmu_objset.c b/module/zfs/dmu_objset.c
index 2a9464e2a2c..7ebbe533256 100644
--- a/module/zfs/dmu_objset.c
+++ b/module/zfs/dmu_objset.c
@@ -783,11 +783,15 @@ dmu_objset_own(const char *name, dmu_objset_type_t type,
         * speed up pool import times and to keep this txg reserved
         * completely for recovery work.
         */
-       if ((dmu_objset_userobjspace_upgradable(*osp) ||
-           dmu_objset_projectquota_upgradable(*osp)) &&
-           !readonly && !dp->dp_spa->spa_claiming &&
-           (ds->ds_dir->dd_crypto_obj == 0 || decrypt))
-               dmu_objset_id_quota_upgrade(*osp);
+       if (!readonly && !dp->dp_spa->spa_claiming &&
+           (ds->ds_dir->dd_crypto_obj == 0 || decrypt)) {
+               if (dmu_objset_userobjspace_upgradable(*osp) ||
+                   dmu_objset_projectquota_upgradable(*osp)) {
+                       dmu_objset_id_quota_upgrade(*osp);
+               } else if (dmu_objset_userused_enabled(*osp)) {
+                       dmu_objset_userspace_upgrade(*osp);
+               }
+       }
 
        dsl_pool_rele(dp, FTAG);
        return (0);

@loli10K
Copy link
Contributor Author

loli10K commented Dec 28, 2019

My concern with the proposed fix is that I don't believe it handles the case when neither user object or project quotas features are enabled on the pool.

This is indeed correct, pools created with zpool create -d -o feature@encryption=enabled can receive datasets in encrypted hierarchy but running zfs userspace results in "unsupported version or feature":

root@linux:/usr/src/zfs# POOLNAME1='testpool1'
root@linux:/usr/src/zfs# TMPDIR='/var/tmp'
root@linux:/usr/src/zfs# mountpoint -q $TMPDIR || mount -t tmpfs tmpfs $TMPDIR
root@linux:/usr/src/zfs# zpool destroy -f $POOLNAME1
root@linux:/usr/src/zfs# rm -f $TMPDIR/zpool1.dat
root@linux:/usr/src/zfs# truncate -s 128m $TMPDIR/zpool1.dat
root@linux:/usr/src/zfs# echo 'password' | zpool create -f -d -o feature@encryption=enabled -O encryption=on -O keyformat=passphrase $POOLNAME1 $TMPDIR/zpool1.dat
root@linux:/usr/src/zfs# 
root@linux:/usr/src/zfs# POOLNAME2='testpool2'
root@linux:/usr/src/zfs# TMPDIR='/var/tmp'
root@linux:/usr/src/zfs# mountpoint -q $TMPDIR || mount -t tmpfs tmpfs $TMPDIR
root@linux:/usr/src/zfs# zpool destroy -f $POOLNAME2
root@linux:/usr/src/zfs# rm -f $TMPDIR/zpool2.dat
root@linux:/usr/src/zfs# truncate -s 128m $TMPDIR/zpool2.dat
root@linux:/usr/src/zfs# zpool create -f -d $POOLNAME2 $TMPDIR/zpool2.dat
root@linux:/usr/src/zfs# 
root@linux:/usr/src/zfs# zfs create $POOLNAME1/fs
root@linux:/usr/src/zfs# zfs create $POOLNAME2/fs
root@linux:/usr/src/zfs# dd if=/dev/urandom of=/$POOLNAME2/fs/random bs=1M count=1
1+0 records in
1+0 records out
1048576 bytes (1.0 MB, 1.0 MiB) copied, 0.00582125 s, 180 MB/s
root@linux:/usr/src/zfs# zfs snap $POOLNAME2/fs@snap1
root@linux:/usr/src/zfs# zfs send $POOLNAME2/fs@snap1 | zfs recv $POOLNAME1/recv
root@linux:/usr/src/zfs# 
root@linux:/usr/src/zfs# zfs userspace $POOLNAME1/fs
TYPE        NAME   USED  QUOTA  OBJUSED  OBJQUOTA
POSIX User  root  1.50K   none        -         -
root@linux:/usr/src/zfs# zfs userspace $POOLNAME1/recv
cannot get used/quota for testpool1/recv: unsupported version or feature
root@linux:/usr/src/zfs# 

Currently testing the additional dmu_objset_userspace_upgrade() in dmu_objset_own() on a local builder, now i am hitting this:

[ 1760.394775] ((txg_how & TXG_WAIT)) implies (!dsl_pool_config_held(tx->tx_pool))
[ 1760.394807] PANIC at dmu_tx.c:1029:dmu_tx_assign()
[ 1760.394827] Showing stack for process 1518
[ 1760.394829] CPU: 0 PID: 1518 Comm: mount.zfs Tainted: P           O    4.9.0-3-amd64 #1 Debian 4.9.30-2+deb9u5
[ 1760.394829] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
[ 1760.394830]  0000000000000000 ffffffff949285b4 ffffffffc08f78f8 ffffaf6300413c00
[ 1760.394832]  ffffffffc05662d5 ffff9ec86ebfc3f0 ffffffff00000020 ffffaf6300413c10
[ 1760.394834]  ffffaf6300413bb0 6f685f6778742828 5f47585420262077 6920292954494157
[ 1760.394835] Call Trace:
[ 1760.394840]  [<ffffffff949285b4>] ? dump_stack+0x5c/0x78
[ 1760.394848]  [<ffffffffc05662d5>] ? spl_panic+0xc5/0x100 [spl]
[ 1760.394897]  [<ffffffffc06ee184>] ? dbuf_read+0x454/0x600 [zfs]
[ 1760.394899]  [<ffffffff947df0b6>] ? kmem_cache_alloc_node_trace+0x156/0x5a0
[ 1760.394903]  [<ffffffffc0566f88>] ? spl_kmem_zalloc+0xe8/0x150 [spl]
[ 1760.394934]  [<ffffffffc071e366>] ? dnode_hold_impl+0xc76/0x10c0 [zfs]
[ 1760.394938]  [<ffffffffc056f501>] ? tsd_hash_search.isra.0+0x41/0x90 [spl]
[ 1760.394941]  [<ffffffffc056f590>] ? tsd_get+0x40/0x80 [spl]
[ 1760.394978]  [<ffffffffc077b375>] ? rrn_find+0x25/0x40 [zfs]
[ 1760.395008]  [<ffffffffc0718c88>] ? dmu_tx_assign+0x688/0x700 [zfs]
[ 1760.395039]  [<ffffffffc07174ad>] ? dmu_tx_hold_object_impl+0x7d/0xb0 [zfs]
[ 1760.395068]  [<ffffffffc0705055>] ? dmu_objset_space_upgrade+0x175/0x220 [zfs]
[ 1760.395097]  [<ffffffffc070518d>] ? dmu_objset_userspace_upgrade+0x8d/0xd0 [zfs]
[ 1760.395126]  [<ffffffffc0705342>] ? dmu_objset_own+0x172/0x180 [zfs]
[ 1760.395174]  [<ffffffffc08377e6>] ? zfsvfs_create+0x76/0xf0 [zfs]
[ 1760.395214]  [<ffffffffc08378f6>] ? zfs_domount+0x96/0x4e0 [zfs]
[ 1760.395254]  [<ffffffffc08543a4>] ? zpl_mount+0x144/0x200 [zfs]
[ 1760.395256]  [<ffffffff94805f36>] ? mount_fs+0x36/0x150
[ 1760.395258]  [<ffffffff948232a2>] ? vfs_kern_mount+0x62/0x100
[ 1760.395259]  [<ffffffff9482576f>] ? do_mount+0x1cf/0xc80
[ 1760.395260]  [<ffffffff9482654e>] ? SyS_mount+0x7e/0xd0
[ 1760.395263]  [<ffffffff94c0637b>] ? system_call_fast_compare_end+0xc/0x9b

Will debug later this weekend.

EDIT: fixed by running the upgrade in a callback function via dmu_objset_upgrade(). I had to change a lot of zfs_ioc_userspace_many() too.

@loli10K loli10K force-pushed the issue-9501 branch 4 times, most recently from dc9acbe to d45e0db Compare December 30, 2019 06:41
@loli10K loli10K added Status: Code Review Needed Ready for review and testing and removed Status: Work in Progress Not yet ready for general review labels Dec 30, 2019
@scratchings
Copy link

Hi,

Is this likely to merged into a release soon?

@behlendorf
Copy link
Contributor

@scratchings there's still some needed work before this can be merged. @loli10K any chance you might have some time so we can try and get this one wrapped up? It sounds like running dmu_objset_upgrade() in a callback did address my original concern. If that's the case and we can get it rebased then we probably don't need to bother with any refactoring.

@loli10K
Copy link
Contributor Author

loli10K commented Nov 12, 2020

It may take me some time to refresh this, i haven't used my development workspace even since i stopped contributing code. I am going to try something in the upcoming weekend.

Copy link
Contributor

@behlendorf behlendorf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for rebasing this so quickly. The patch itself looks good and passed my local testing. I just have one small concern about the test case.

log_must_retry "unsupported" 3 \
eval "zfs userspace $DATASET_ENCROOT/recvfs > /dev/null"
log_must_retry "unsupported" 3 \
eval "zfs groupspace $DATASET_ENCROOT/recvfs > /dev/null"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was the issue here that it might return unsupported until it completes? I wasn't able to reproduce this locally, and it's not what I'd expect. Unless you're able to reproduce this I'd suggest we simplify this like so:

@@ -65,13 +65,12 @@ for opts in "${POOL_OPTS[@]}"; do
        log_must eval "zfs send $DATASET_SENDFS@snap | zfs recv " \
                "$DATASET_ENCROOT/recvfs"
 
-       # 3. Verify encrypted datasets support 'zfs userspace' and 'zfs groupsp
-       log_must eval "zfs userspace $DATASET_ENCROOT/fs > /dev/null"
-       log_must eval "zfs groupspace $DATASET_ENCROOT/fs > /dev/null"
-       log_must_retry "unsupported" 3 \
-               eval "zfs userspace $DATASET_ENCROOT/recvfs > /dev/null"
-       log_must_retry "unsupported" 3 \
-               eval "zfs groupspace $DATASET_ENCROOT/recvfs > /dev/null"
+       # 3. Verify encrypted datasets support 'zfs userspace' and
+       # 'zfs groupspace'
+       log_must zfs userspace $DATASET_ENCROOT/fs
+       log_must zfs groupspace $DATASET_ENCROOT/fs
+       log_must zfs userspace $DATASET_ENCROOT/recvfs
+       log_must zfs groupspace $DATASET_ENCROOT/recvfs
 
        # Cleanup
        cleanup

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My local builder seems to be a lot slower than those running on build.zfsonlinux.org; i can sometimes triggers failures if i remove log_must_retry()

--- Configuration ---
Runfiles:        /usr/share/zfs/runfiles/zfs-tests.run
STF_TOOLS:       /usr/share/zfs/test-runner
STF_SUITE:       /usr/share/zfs/zfs-tests
STF_PATH:        /var/tmp/constrained_path.QRLQ
FILEDIR:         /var/tmp
FILES:           /var/tmp/file-vdev0 /var/tmp/file-vdev1 /var/tmp/file-vdev2
LOOPBACKS:       /dev/loop0 /dev/loop1 /dev/loop2
DISKS:           loop0 loop1 loop2
NUM_DISKS:       3
FILESIZE:        4G
ITERATIONS:      1
TAGS:            functional
STACK_TRACER:    no
Keep pool(s):    rpool
Missing util(s): mmap_libaio pamtester umask wait

/usr/share/zfs/test-runner/bin/test-runner.py  -c "/usr/share/zfs/runfiles/zfs-tests.run" -T "functional" -i "/usr/share/zfs/zfs-tests" -I "1"
Test: /usr/share/zfs/zfs-tests/tests/functional/userquota/setup (run as root) [00:01] [PASS]
Test: /usr/share/zfs/zfs-tests/tests/functional/userquota/userspace_encrypted (run as root) [00:07] [PASS]
Test: /usr/share/zfs/zfs-tests/tests/functional/userquota/userspace_encrypted (run as root) [00:07] [PASS]
Test: /usr/share/zfs/zfs-tests/tests/functional/userquota/userspace_encrypted (run as root) [00:03] [FAIL]
Test: /usr/share/zfs/zfs-tests/tests/functional/userquota/userspace_encrypted (run as root) [00:07] [PASS]
Test: /usr/share/zfs/zfs-tests/tests/functional/userquota/userspace_encrypted (run as root) [00:06] [PASS]
Test: /usr/share/zfs/zfs-tests/tests/functional/userquota/userspace_encrypted (run as root) [00:03] [FAIL]
Test: /usr/share/zfs/zfs-tests/tests/functional/userquota/cleanup (run as root) [00:01] [PASS]

Results Summary
FAIL	   2
PASS	   6

Running Time:	00:00:38
Percent passed:	75.0%
Log directory:	/var/tmp/test_results/20201113T161214

Tests with results other than PASS that are expected:

Tests with result of PASS that are unexpected:

Tests with results other than PASS that are unexpected:
    FAIL userquota/userspace_encrypted (expected PASS)
Test: /usr/share/zfs/zfs-tests/tests/functional/userquota/userspace_encrypted (run as root) [00:03] [FAIL]
16:12:48.10 ASSERTION: 'zfs user/groupspace' should work on encrypted datasets
16:12:48.20 SUCCESS: zpool create -o feature@encryption=enabled testpool14821 /var/tmp/userspace_encrypted
16:12:48.23 SUCCESS: zfs create testpool14821/sendfs
16:12:49.35 SUCCESS: eval echo 'password' | zfs create -o encryption=on -o keyformat=passphrase -o keylocation=prompt  testpool14821/encroot
16:12:49.45 SUCCESS: zfs create testpool14821/encroot/fs
16:12:49.52 SUCCESS: zfs snap testpool14821/sendfs@snap
16:12:49.65 SUCCESS: eval zfs send testpool14821/sendfs@snap | zfs recv  testpool14821/encroot/recvfs
16:12:49.65 TYPE        NAME   USED  QUOTA  OBJUSED  OBJQUOTA
16:12:49.65 POSIX User  root  1.50K   none        1      none
16:12:49.66 SUCCESS: zfs userspace testpool14821/encroot/fs
16:12:49.67 TYPE         NAME   USED  QUOTA  OBJUSED  OBJQUOTA
16:12:49.67 POSIX Group  root  1.50K   none        1      none
16:12:49.68 SUCCESS: zfs groupspace testpool14821/encroot/fs
16:12:49.69 TYPE        NAME   USED  QUOTA  OBJUSED  OBJQUOTA
16:12:49.69 POSIX User  root  1.50K   none        1      none
16:12:49.69 SUCCESS: zfs userspace testpool14821/encroot/recvfs
16:12:49.70 TYPE         NAME   USED  QUOTA  OBJUSED  OBJQUOTA
16:12:49.70 POSIX Group  root  1.50K   none        1      none
16:12:49.71 SUCCESS: zfs groupspace testpool14821/encroot/recvfs
16:12:49.95 SUCCESS: zpool destroy -f testpool14821
16:12:50.10 SUCCESS: zpool create -d -o feature@encryption=enabled testpool14821 /var/tmp/userspace_encrypted
16:12:50.15 SUCCESS: zfs create testpool14821/sendfs
16:12:51.13 SUCCESS: eval echo 'password' | zfs create -o encryption=on -o keyformat=passphrase -o keylocation=prompt  testpool14821/encroot
16:12:51.19 SUCCESS: zfs create testpool14821/encroot/fs
16:12:51.22 SUCCESS: zfs snap testpool14821/sendfs@snap
16:12:51.32 SUCCESS: eval zfs send testpool14821/sendfs@snap | zfs recv  testpool14821/encroot/recvfs
16:12:51.34 TYPE        NAME   USED  QUOTA  OBJUSED  OBJQUOTA
16:12:51.34 POSIX User  root  1.50K   none        -         -
16:12:51.34 SUCCESS: zfs userspace testpool14821/encroot/fs
16:12:51.35 TYPE         NAME   USED  QUOTA  OBJUSED  OBJQUOTA
16:12:51.35 POSIX Group  root  1.50K   none        -         -
16:12:51.36 SUCCESS: zfs groupspace testpool14821/encroot/fs
16:12:51.38 cannot get used/quota for testpool14821/encroot/recvfs: unsupported version or feature
16:12:51.38 ERROR: zfs userspace testpool14821/encroot/recvfs exited 255

Keeping log_must_retry() should prevent spurious failures.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK. Well in that case we should still add something like (( $? != 0 )) && log_fail after each log_must_retry call. Otherwise it won't fail properly after 3 retries and will incorrectly pass, see the log_must_busy helper function as an example. How about something like this:

function log_must_unsupported
{
        log_must_retry "unsupported" 3 "$@"
        (( $? != 0 )) && log_fail
}

       ....

       # 3. Verify encrypted datasets support 'zfs userspace' and
       # 'zfs groupspace'
       log_must zfs userspace $DATASET_ENCROOT/fs
       log_must zfs groupspace $DATASET_ENCROOT/fs
       log_must_unsupported zfs userspace $DATASET_ENCROOT/recvfs
       log_must_unsupported zfs groupspace $DATASET_ENCROOT/recvfs

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With log_must_unsupported() it is indeed failing if i inject failures with

stap -g -e 'probe module("zfs").function("zfs_ioc_userspace_many").return { $return = 95; }'

so it is safe to assume it will catch real issues: it wasn't doing that with just log_must_retry(), thank you for catching this.

For encrypted receives, where user accounting is initially disabled on
creation, both 'zfs userspace' and 'zfs groupspace' fails with
EOPNOTSUPP: this is because dmu_objset_id_quota_upgrade_cb() forgets to
set OBJSET_FLAG_USERACCOUNTING_COMPLETE on the objset flags after a
successful dmu_objset_space_upgrade().

Signed-off-by: loli10K <[email protected]>
Co-authored-by: Brian Behlendorf <[email protected]>
@behlendorf behlendorf added Status: Accepted Ready to integrate (reviewed, tested) and removed Status: Code Review Needed Ready for review and testing labels Nov 14, 2020
@behlendorf behlendorf merged commit 4072f46 into openzfs:master Nov 16, 2020
behlendorf added a commit that referenced this pull request Nov 17, 2020
For encrypted receives, where user accounting is initially disabled on
creation, both 'zfs userspace' and 'zfs groupspace' fails with
EOPNOTSUPP: this is because dmu_objset_id_quota_upgrade_cb() forgets to
set OBJSET_FLAG_USERACCOUNTING_COMPLETE on the objset flags after a
successful dmu_objset_space_upgrade().

Reviewed-by: Brian Behlendorf <[email protected]>
Co-authored-by: Brian Behlendorf <[email protected]>
Signed-off-by: loli10K <[email protected]>
Closes #9501
Closes #9596
jsai20 pushed a commit to jsai20/zfs that referenced this pull request Mar 30, 2021
For encrypted receives, where user accounting is initially disabled on
creation, both 'zfs userspace' and 'zfs groupspace' fails with
EOPNOTSUPP: this is because dmu_objset_id_quota_upgrade_cb() forgets to
set OBJSET_FLAG_USERACCOUNTING_COMPLETE on the objset flags after a
successful dmu_objset_space_upgrade().

Reviewed-by: Brian Behlendorf <[email protected]>
Co-authored-by: Brian Behlendorf <[email protected]>
Signed-off-by: loli10K <[email protected]>
Closes openzfs#9501 
Closes openzfs#9596
sempervictus pushed a commit to sempervictus/zfs that referenced this pull request May 31, 2021
For encrypted receives, where user accounting is initially disabled on
creation, both 'zfs userspace' and 'zfs groupspace' fails with
EOPNOTSUPP: this is because dmu_objset_id_quota_upgrade_cb() forgets to
set OBJSET_FLAG_USERACCOUNTING_COMPLETE on the objset flags after a
successful dmu_objset_space_upgrade().

Reviewed-by: Brian Behlendorf <[email protected]>
Co-authored-by: Brian Behlendorf <[email protected]>
Signed-off-by: loli10K <[email protected]>
Closes openzfs#9501 
Closes openzfs#9596
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Accepted Ready to integrate (reviewed, tested)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Can't enable userquota on dataset sent to encrypted root
4 participants