From 44f712448c965c57605143e2ced5e1980d5f1041 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Wed, 18 Mar 2020 11:47:07 -0700 Subject: [PATCH] Fix zfs_rmnode() unlink / rollback issue If a has rollback has occurred while a file is open and unlinked. Then when the file is closed post rollback it will not exist in the rolled back version of the unlinked object. Therefore, the call to zap_remove_int() may correctly return ENOENT and should be allowed. Signed-off-by: Brian Behlendorf Closes #6812 Closes #9739 --- module/os/linux/zfs/zfs_dir.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/module/os/linux/zfs/zfs_dir.c b/module/os/linux/zfs/zfs_dir.c index 5150209c36f3..7ebf38ddb620 100644 --- a/module/os/linux/zfs/zfs_dir.c +++ b/module/os/linux/zfs/zfs_dir.c @@ -739,9 +739,15 @@ zfs_rmnode(znode_t *zp) zfs_unlinked_add(xzp, tx); } - /* Remove this znode from the unlinked set */ - VERIFY3U(0, ==, - zap_remove_int(zfsvfs->z_os, zfsvfs->z_unlinkedobj, zp->z_id, tx)); + /* + * Remove this znode from the unlinked set. If a has rollback has + * occurred while a file is open and unlinked. Then when the file + * is closed post rollback it will not exist in the rolled back + * version of the unlinked object. + */ + error = zap_remove_int(zfsvfs->z_os, zfsvfs->z_unlinkedobj, + zp->z_id, tx); + VERIFY(error == 0 || error == ENOENT); dataset_kstats_update_nunlinked_kstat(&zfsvfs->z_kstat, 1);