Skip to content

Commit d621aa5

Browse files
tuxokonedbass
authored andcommitted
Make xattr dir truncate and remove in one tx
We need truncate and remove be in the same tx when doing zfs_rmnode on xattr dir. Otherwise, if we truncate and crash, we'll end up with inconsistent zap object on the delete queue. We do this by skipping dmu_free_long_range and let zfs_znode_delete to do the work. Signed-off-by: Chunwei Chen <david.chen@osnexus.com> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Issue #4114 Issue #4052 Issue #4006 Issue #3018 Issue #2861
1 parent 19d991a commit d621aa5

1 file changed

Lines changed: 15 additions & 8 deletions

File tree

module/zfs/zfs_dir.c

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -632,15 +632,22 @@ zfs_rmnode(znode_t *zp)
632632
}
633633

634634
/*
635-
* Free up all the data in the file.
635+
* Free up all the data in the file. We don't do this for directories
636+
* because we need truncate and remove to be in the same tx, like in
637+
* zfs_znode_delete(). Otherwise, if we crash here we'll end up with
638+
* an inconsistent truncated zap object in the delete queue. Note a
639+
* truncated file is harmless since it only contains user data.
636640
*/
637-
error = dmu_free_long_range(os, zp->z_id, 0, DMU_OBJECT_END);
638-
if (error) {
639-
/*
640-
* Not enough space. Leave the file in the unlinked set.
641-
*/
642-
zfs_znode_dmu_fini(zp);
643-
return;
641+
if (S_ISREG(ZTOI(zp)->i_mode)) {
642+
error = dmu_free_long_range(os, zp->z_id, 0, DMU_OBJECT_END);
643+
if (error) {
644+
/*
645+
* Not enough space. Leave the file in the unlinked
646+
* set.
647+
*/
648+
zfs_znode_dmu_fini(zp);
649+
return;
650+
}
644651
}
645652

646653
/*

0 commit comments

Comments
 (0)