Always wait for txg sync when umounting dataset

Currently, when unmounting a filesystem, ZFS will only wait for
a txg sync if the dataset is dirty and not readonly. However, this
can be problematic in cases where a dataset is remounted readonly
immediately before being unmounted, which often happens when the
system is being shut down. Since encrypted datasets require that
all I/O is completed before the dataset is disowned, this issue
causes problems when write I/Os leak into the txgs after the
dataset is disowned, which can happen when sync=disabled.

While looking into fixes for this issue, it was discovered that
dsl_dataset_is_dirty() does not return B_TRUE when the dataset has
been removed from the txg dirty datasets list, but has not actually
been processed yet. Furthermore, the implementation is comletely
different from dmu_objset_is_dirty(), adding to the confusion.
Rather than relying on this function, this patch forces the umount
code path (and the remount readonly code path) to always perform a
txg sync on read-write datasets and removes the function altogether.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Tom Caputi <tcaputi@datto.com>
Closes #7753
Closes #7795
This commit is contained in:
Tom Caputi
2018-08-20 16:42:17 -04:00
committed by Brian Behlendorf
parent 8c4fb36a24
commit 47ab01a18f
5 changed files with 26 additions and 33 deletions
@@ -36,8 +36,10 @@
# 2. Verify we can (re)mount the dataset readonly/read-write
# 3. Verify we can mount the snapshot and it's mounted readonly
# 4. Verify we can't remount it read-write
# 5. Re-import the pool readonly
# 6. Verify we can't remount its filesystem read-write
# 5. Verify we can remount a dataset readonly and unmount it with
# encryption=on and sync=disabled (issue #7753)
# 6. Re-import the pool readonly
# 7. Verify we can't remount its filesystem read-write
#
verify_runnable "both"
@@ -130,11 +132,21 @@ readonlyfs $MNTPSNAP
checkmount $TESTSNAP 'ro'
log_must umount $MNTPSNAP
# 5. Re-import the pool readonly
# 5. Verify we can remount a dataset readonly and unmount it with
# encryption=on and sync=disabled (issue #7753)
log_must eval "echo 'password' | zfs create -o sync=disabled \
-o encryption=on -o keyformat=passphrase $TESTFS/crypt"
CRYPT_MNTPFS="$(get_prop mountpoint $TESTFS/crypt)"
log_must touch $CRYPT_MNTPFS/file.dat
log_must mount -o remount,ro $TESTFS/crypt $CRYPT_MNTPFS
log_must umount -f $CRYPT_MNTPFS
zpool sync $TESTPOOL
# 6. Re-import the pool readonly
log_must zpool export $TESTPOOL
log_must zpool import -o readonly=on $TESTPOOL
# 6. Verify we can't remount its filesystem read-write
# 7. Verify we can't remount its filesystem read-write
readonlyfs $MNTPFS
checkmount $TESTFS 'ro'
log_mustnot mount -o remount,rw $MNTPFS