FreeBSD: Add zfs_link_create() error handling
Originally Solaris didn't expect errors there, but they may happen if we fail to add entry into ZAP. Linux fixed it in #7421, but it was never fully ported to FreeBSD. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Alexander Motin <mav@FreeBSD.org> Sponsored-By: iXsystems, Inc. Closes #13215 Closes #16138
This commit is contained in:
parent
fec16b93c4
commit
efbef9e6cc
|
@ -543,6 +543,7 @@ zfs_rmnode(znode_t *zp)
|
|||
dataset_kstats_update_nunlinked_kstat(&zfsvfs->z_kstat, 1);
|
||||
|
||||
zfs_znode_delete(zp, tx);
|
||||
zfs_znode_free(zp);
|
||||
|
||||
dmu_tx_commit(tx);
|
||||
|
||||
|
|
|
@ -1175,10 +1175,25 @@ zfs_create(znode_t *dzp, const char *name, vattr_t *vap, int excl, int mode,
|
|||
return (error);
|
||||
}
|
||||
zfs_mknode(dzp, vap, tx, cr, 0, &zp, &acl_ids);
|
||||
|
||||
error = zfs_link_create(dzp, name, zp, tx, ZNEW);
|
||||
if (error != 0) {
|
||||
/*
|
||||
* Since, we failed to add the directory entry for it,
|
||||
* delete the newly created dnode.
|
||||
*/
|
||||
zfs_znode_delete(zp, tx);
|
||||
VOP_UNLOCK1(ZTOV(zp));
|
||||
zrele(zp);
|
||||
zfs_acl_ids_free(&acl_ids);
|
||||
dmu_tx_commit(tx);
|
||||
getnewvnode_drop_reserve();
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (fuid_dirtied)
|
||||
zfs_fuid_sync(zfsvfs, tx);
|
||||
|
||||
(void) zfs_link_create(dzp, name, zp, tx, ZNEW);
|
||||
txtype = zfs_log_create_txtype(Z_FILE, vsecp, vap);
|
||||
zfs_log_create(zilog, tx, txtype, dzp, zp, name,
|
||||
vsecp, acl_ids.z_fuidp, vap);
|
||||
|
@ -1526,13 +1541,19 @@ zfs_mkdir(znode_t *dzp, const char *dirname, vattr_t *vap, znode_t **zpp,
|
|||
*/
|
||||
zfs_mknode(dzp, vap, tx, cr, 0, &zp, &acl_ids);
|
||||
|
||||
if (fuid_dirtied)
|
||||
zfs_fuid_sync(zfsvfs, tx);
|
||||
|
||||
/*
|
||||
* Now put new name in parent dir.
|
||||
*/
|
||||
(void) zfs_link_create(dzp, dirname, zp, tx, ZNEW);
|
||||
error = zfs_link_create(dzp, dirname, zp, tx, ZNEW);
|
||||
if (error != 0) {
|
||||
zfs_znode_delete(zp, tx);
|
||||
VOP_UNLOCK1(ZTOV(zp));
|
||||
zrele(zp);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (fuid_dirtied)
|
||||
zfs_fuid_sync(zfsvfs, tx);
|
||||
|
||||
*zpp = zp;
|
||||
|
||||
|
@ -1540,6 +1561,7 @@ zfs_mkdir(znode_t *dzp, const char *dirname, vattr_t *vap, znode_t **zpp,
|
|||
zfs_log_create(zilog, tx, txtype, dzp, zp, dirname, NULL,
|
||||
acl_ids.z_fuidp, vap);
|
||||
|
||||
out:
|
||||
zfs_acl_ids_free(&acl_ids);
|
||||
|
||||
dmu_tx_commit(tx);
|
||||
|
@ -1550,7 +1572,7 @@ zfs_mkdir(znode_t *dzp, const char *dirname, vattr_t *vap, znode_t **zpp,
|
|||
zil_commit(zilog, 0);
|
||||
|
||||
zfs_exit(zfsvfs, FTAG);
|
||||
return (0);
|
||||
return (error);
|
||||
}
|
||||
|
||||
#if __FreeBSD_version < 1300124
|
||||
|
@ -3586,10 +3608,14 @@ zfs_symlink(znode_t *dzp, const char *name, vattr_t *vap,
|
|||
/*
|
||||
* Insert the new object into the directory.
|
||||
*/
|
||||
(void) zfs_link_create(dzp, name, zp, tx, ZNEW);
|
||||
|
||||
zfs_log_symlink(zilog, tx, txtype, dzp, zp, name, link);
|
||||
*zpp = zp;
|
||||
error = zfs_link_create(dzp, name, zp, tx, ZNEW);
|
||||
if (error != 0) {
|
||||
zfs_znode_delete(zp, tx);
|
||||
VOP_UNLOCK1(ZTOV(zp));
|
||||
zrele(zp);
|
||||
} else {
|
||||
zfs_log_symlink(zilog, tx, txtype, dzp, zp, name, link);
|
||||
}
|
||||
|
||||
zfs_acl_ids_free(&acl_ids);
|
||||
|
||||
|
@ -3597,8 +3623,12 @@ zfs_symlink(znode_t *dzp, const char *name, vattr_t *vap,
|
|||
|
||||
getnewvnode_drop_reserve();
|
||||
|
||||
if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
|
||||
zil_commit(zilog, 0);
|
||||
if (error == 0) {
|
||||
*zpp = zp;
|
||||
|
||||
if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
|
||||
zil_commit(zilog, 0);
|
||||
}
|
||||
|
||||
zfs_exit(zfsvfs, FTAG);
|
||||
return (error);
|
||||
|
|
|
@ -1234,7 +1234,6 @@ zfs_znode_delete(znode_t *zp, dmu_tx_t *tx)
|
|||
VERIFY0(dmu_object_free(os, obj, tx));
|
||||
zfs_znode_dmu_fini(zp);
|
||||
ZFS_OBJ_HOLD_EXIT(zfsvfs, obj);
|
||||
zfs_znode_free(zp);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -182,7 +182,6 @@ if sys.platform.startswith('freebsd'):
|
|||
'cli_root/zfs_unshare/zfs_unshare_008_pos': ['SKIP', na_reason],
|
||||
'cp_files/cp_files_002_pos': ['SKIP', na_reason],
|
||||
'link_count/link_count_001': ['SKIP', na_reason],
|
||||
'casenorm/mixed_create_failure': ['FAIL', 13215],
|
||||
'mmap/mmap_sync_001_pos': ['SKIP', na_reason],
|
||||
'rsend/send_raw_ashift': ['SKIP', 14961],
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue