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
fa4b1a404e
commit
4c0fbd8d6d
|
@ -543,6 +543,7 @@ zfs_rmnode(znode_t *zp)
|
||||||
dataset_kstats_update_nunlinked_kstat(&zfsvfs->z_kstat, 1);
|
dataset_kstats_update_nunlinked_kstat(&zfsvfs->z_kstat, 1);
|
||||||
|
|
||||||
zfs_znode_delete(zp, tx);
|
zfs_znode_delete(zp, tx);
|
||||||
|
zfs_znode_free(zp);
|
||||||
|
|
||||||
dmu_tx_commit(tx);
|
dmu_tx_commit(tx);
|
||||||
|
|
||||||
|
|
|
@ -1169,10 +1169,25 @@ zfs_create(znode_t *dzp, const char *name, vattr_t *vap, int excl, int mode,
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
zfs_mknode(dzp, vap, tx, cr, 0, &zp, &acl_ids);
|
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)
|
if (fuid_dirtied)
|
||||||
zfs_fuid_sync(zfsvfs, tx);
|
zfs_fuid_sync(zfsvfs, tx);
|
||||||
|
|
||||||
(void) zfs_link_create(dzp, name, zp, tx, ZNEW);
|
|
||||||
txtype = zfs_log_create_txtype(Z_FILE, vsecp, vap);
|
txtype = zfs_log_create_txtype(Z_FILE, vsecp, vap);
|
||||||
zfs_log_create(zilog, tx, txtype, dzp, zp, name,
|
zfs_log_create(zilog, tx, txtype, dzp, zp, name,
|
||||||
vsecp, acl_ids.z_fuidp, vap);
|
vsecp, acl_ids.z_fuidp, vap);
|
||||||
|
@ -1520,13 +1535,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);
|
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.
|
* 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;
|
*zpp = zp;
|
||||||
|
|
||||||
|
@ -1534,6 +1555,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,
|
zfs_log_create(zilog, tx, txtype, dzp, zp, dirname, NULL,
|
||||||
acl_ids.z_fuidp, vap);
|
acl_ids.z_fuidp, vap);
|
||||||
|
|
||||||
|
out:
|
||||||
zfs_acl_ids_free(&acl_ids);
|
zfs_acl_ids_free(&acl_ids);
|
||||||
|
|
||||||
dmu_tx_commit(tx);
|
dmu_tx_commit(tx);
|
||||||
|
@ -1544,7 +1566,7 @@ zfs_mkdir(znode_t *dzp, const char *dirname, vattr_t *vap, znode_t **zpp,
|
||||||
zil_commit(zilog, 0);
|
zil_commit(zilog, 0);
|
||||||
|
|
||||||
zfs_exit(zfsvfs, FTAG);
|
zfs_exit(zfsvfs, FTAG);
|
||||||
return (0);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if __FreeBSD_version < 1300124
|
#if __FreeBSD_version < 1300124
|
||||||
|
@ -3578,10 +3600,14 @@ zfs_symlink(znode_t *dzp, const char *name, vattr_t *vap,
|
||||||
/*
|
/*
|
||||||
* Insert the new object into the directory.
|
* Insert the new object into the directory.
|
||||||
*/
|
*/
|
||||||
(void) zfs_link_create(dzp, name, zp, tx, ZNEW);
|
error = zfs_link_create(dzp, name, zp, tx, ZNEW);
|
||||||
|
if (error != 0) {
|
||||||
zfs_log_symlink(zilog, tx, txtype, dzp, zp, name, link);
|
zfs_znode_delete(zp, tx);
|
||||||
*zpp = zp;
|
VOP_UNLOCK1(ZTOV(zp));
|
||||||
|
zrele(zp);
|
||||||
|
} else {
|
||||||
|
zfs_log_symlink(zilog, tx, txtype, dzp, zp, name, link);
|
||||||
|
}
|
||||||
|
|
||||||
zfs_acl_ids_free(&acl_ids);
|
zfs_acl_ids_free(&acl_ids);
|
||||||
|
|
||||||
|
@ -3589,8 +3615,12 @@ zfs_symlink(znode_t *dzp, const char *name, vattr_t *vap,
|
||||||
|
|
||||||
getnewvnode_drop_reserve();
|
getnewvnode_drop_reserve();
|
||||||
|
|
||||||
if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
|
if (error == 0) {
|
||||||
zil_commit(zilog, 0);
|
*zpp = zp;
|
||||||
|
|
||||||
|
if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
|
||||||
|
zil_commit(zilog, 0);
|
||||||
|
}
|
||||||
|
|
||||||
zfs_exit(zfsvfs, FTAG);
|
zfs_exit(zfsvfs, FTAG);
|
||||||
return (error);
|
return (error);
|
||||||
|
|
|
@ -1234,7 +1234,6 @@ zfs_znode_delete(znode_t *zp, dmu_tx_t *tx)
|
||||||
VERIFY0(dmu_object_free(os, obj, tx));
|
VERIFY0(dmu_object_free(os, obj, tx));
|
||||||
zfs_znode_dmu_fini(zp);
|
zfs_znode_dmu_fini(zp);
|
||||||
ZFS_OBJ_HOLD_EXIT(zfsvfs, obj);
|
ZFS_OBJ_HOLD_EXIT(zfsvfs, obj);
|
||||||
zfs_znode_free(zp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -182,7 +182,6 @@ if sys.platform.startswith('freebsd'):
|
||||||
'cli_root/zfs_unshare/zfs_unshare_008_pos': ['SKIP', na_reason],
|
'cli_root/zfs_unshare/zfs_unshare_008_pos': ['SKIP', na_reason],
|
||||||
'cp_files/cp_files_002_pos': ['SKIP', na_reason],
|
'cp_files/cp_files_002_pos': ['SKIP', na_reason],
|
||||||
'link_count/link_count_001': ['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],
|
'mmap/mmap_sync_001_pos': ['SKIP', na_reason],
|
||||||
'rsend/send_raw_ashift': ['SKIP', 14961],
|
'rsend/send_raw_ashift': ['SKIP', 14961],
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue