zfs_enter rework

Replace ZFS_ENTER and ZFS_VERIFY_ZP, which have hidden returns, with
functions that return error code. The reason we want to do this is
because hidden returns are not obvious and had caused some missing fail
path unwinding.

This patch changes the common, linux, and freebsd parts. Also fixes
fail path unwinding in zfs_fsync, zpl_fsync, zpl_xattr_{list,get,set}, and
zfs_lookup().

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Ryan Moeller <ryan@iXsystems.com>
Signed-off-by: Chunwei Chen <david.chen@nutanix.com>
Closes #13831
This commit is contained in:
Chunwei Chen
2022-09-16 13:36:47 -07:00
committed by GitHub
parent b24d1c77f7
commit 768eacedef
15 changed files with 591 additions and 486 deletions
+8 -6
View File
@@ -1053,7 +1053,8 @@ zfsctl_snapdir_readdir(struct vop_readdir_args *ap)
return (error);
}
ZFS_ENTER(zfsvfs);
if ((error = zfs_enter(zfsvfs, FTAG)) != 0)
return (error);
for (;;) {
uint64_t cookie;
uint64_t id;
@@ -1070,7 +1071,7 @@ zfsctl_snapdir_readdir(struct vop_readdir_args *ap)
*eofp = 1;
error = 0;
}
ZFS_EXIT(zfsvfs);
zfs_exit(zfsvfs, FTAG);
return (error);
}
@@ -1083,7 +1084,7 @@ zfsctl_snapdir_readdir(struct vop_readdir_args *ap)
if (error != 0) {
if (error == ENAMETOOLONG)
error = 0;
ZFS_EXIT(zfsvfs);
zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(error));
}
zfs_uio_setoffset(&uio, cookie + dots_offset);
@@ -1101,7 +1102,8 @@ zfsctl_snapdir_getattr(struct vop_getattr_args *ap)
uint64_t snap_count;
int err;
ZFS_ENTER(zfsvfs);
if ((err = zfs_enter(zfsvfs, FTAG)) != 0)
return (err);
ds = dmu_objset_ds(zfsvfs->z_os);
zfsctl_common_getattr(vp, vap);
vap->va_ctime = dmu_objset_snap_cmtime(zfsvfs->z_os);
@@ -1111,14 +1113,14 @@ zfsctl_snapdir_getattr(struct vop_getattr_args *ap)
err = zap_count(dmu_objset_pool(ds->ds_objset)->dp_meta_objset,
dsl_dataset_phys(ds)->ds_snapnames_zapobj, &snap_count);
if (err != 0) {
ZFS_EXIT(zfsvfs);
zfs_exit(zfsvfs, FTAG);
return (err);
}
vap->va_nlink += snap_count;
}
vap->va_size = vap->va_nlink;
ZFS_EXIT(zfsvfs);
zfs_exit(zfsvfs, FTAG);
return (0);
}
+28 -20
View File
@@ -286,7 +286,8 @@ zfs_quotactl(vfs_t *vfsp, int cmds, uid_t id, void *arg)
cmd = cmds >> SUBCMDSHIFT;
type = cmds & SUBCMDMASK;
ZFS_ENTER(zfsvfs);
if ((error = zfs_enter(zfsvfs, FTAG)) != 0)
return (error);
if (id == -1) {
switch (type) {
case USRQUOTA:
@@ -385,7 +386,7 @@ zfs_quotactl(vfs_t *vfsp, int cmds, uid_t id, void *arg)
break;
}
done:
ZFS_EXIT(zfsvfs);
zfs_exit(zfsvfs, FTAG);
return (error);
}
@@ -426,7 +427,8 @@ zfs_sync(vfs_t *vfsp, int waitfor)
if (error != 0)
return (error);
ZFS_ENTER(zfsvfs);
if ((error = zfs_enter(zfsvfs, FTAG)) != 0)
return (error);
dp = dmu_objset_pool(zfsvfs->z_os);
/*
@@ -434,14 +436,14 @@ zfs_sync(vfs_t *vfsp, int waitfor)
* filesystems which may exist on a suspended pool.
*/
if (rebooting && spa_suspended(dp->dp_spa)) {
ZFS_EXIT(zfsvfs);
zfs_exit(zfsvfs, FTAG);
return (0);
}
if (zfsvfs->z_log != NULL)
zil_commit(zfsvfs->z_log, 0);
ZFS_EXIT(zfsvfs);
zfs_exit(zfsvfs, FTAG);
} else {
/*
* Sync all ZFS filesystems. This is what happens when you
@@ -1408,10 +1410,12 @@ zfs_statfs(vfs_t *vfsp, struct statfs *statp)
{
zfsvfs_t *zfsvfs = vfsp->vfs_data;
uint64_t refdbytes, availbytes, usedobjs, availobjs;
int error;
statp->f_version = STATFS_VERSION;
ZFS_ENTER(zfsvfs);
if ((error = zfs_enter(zfsvfs, FTAG)) != 0)
return (error);
dmu_objset_space(zfsvfs->z_os,
&refdbytes, &availbytes, &usedobjs, &availobjs);
@@ -1458,7 +1462,7 @@ zfs_statfs(vfs_t *vfsp, struct statfs *statp)
statp->f_namemax = MAXNAMELEN - 1;
ZFS_EXIT(zfsvfs);
zfs_exit(zfsvfs, FTAG);
return (0);
}
@@ -1469,13 +1473,14 @@ zfs_root(vfs_t *vfsp, int flags, vnode_t **vpp)
znode_t *rootzp;
int error;
ZFS_ENTER(zfsvfs);
if ((error = zfs_enter(zfsvfs, FTAG)) != 0)
return (error);
error = zfs_zget(zfsvfs, zfsvfs->z_root, &rootzp);
if (error == 0)
*vpp = ZTOV(rootzp);
ZFS_EXIT(zfsvfs);
zfs_exit(zfsvfs, FTAG);
if (error == 0) {
error = vn_lock(*vpp, flags);
@@ -1712,7 +1717,8 @@ zfs_vget(vfs_t *vfsp, ino_t ino, int flags, vnode_t **vpp)
(zfsvfs->z_shares_dir != 0 && ino == zfsvfs->z_shares_dir))
return (EOPNOTSUPP);
ZFS_ENTER(zfsvfs);
if ((err = zfs_enter(zfsvfs, FTAG)) != 0)
return (err);
err = zfs_zget(zfsvfs, ino, &zp);
if (err == 0 && zp->z_unlinked) {
vrele(ZTOV(zp));
@@ -1720,7 +1726,7 @@ zfs_vget(vfs_t *vfsp, ino_t ino, int flags, vnode_t **vpp)
}
if (err == 0)
*vpp = ZTOV(zp);
ZFS_EXIT(zfsvfs);
zfs_exit(zfsvfs, FTAG);
if (err == 0) {
err = vn_lock(*vpp, flags);
if (err != 0)
@@ -1774,7 +1780,8 @@ zfs_fhtovp(vfs_t *vfsp, fid_t *fidp, int flags, vnode_t **vpp)
*vpp = NULL;
ZFS_ENTER(zfsvfs);
if ((err = zfs_enter(zfsvfs, FTAG)) != 0)
return (err);
/*
* On FreeBSD we can get snapshot's mount point or its parent file
@@ -1790,12 +1797,13 @@ zfs_fhtovp(vfs_t *vfsp, fid_t *fidp, int flags, vnode_t **vpp)
for (i = 0; i < sizeof (zlfid->zf_setgen); i++)
setgen |= ((uint64_t)zlfid->zf_setgen[i]) << (8 * i);
ZFS_EXIT(zfsvfs);
zfs_exit(zfsvfs, FTAG);
err = zfsctl_lookup_objset(vfsp, objsetid, &zfsvfs);
if (err)
return (SET_ERROR(EINVAL));
ZFS_ENTER(zfsvfs);
if ((err = zfs_enter(zfsvfs, FTAG)) != 0)
return (err);
}
if (fidp->fid_len == SHORT_FID_LEN || fidp->fid_len == LONG_FID_LEN) {
@@ -1807,7 +1815,7 @@ zfs_fhtovp(vfs_t *vfsp, fid_t *fidp, int flags, vnode_t **vpp)
for (i = 0; i < sizeof (zfid->zf_gen); i++)
fid_gen |= ((uint64_t)zfid->zf_gen[i]) << (8 * i);
} else {
ZFS_EXIT(zfsvfs);
zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(EINVAL));
}
@@ -1825,7 +1833,7 @@ zfs_fhtovp(vfs_t *vfsp, fid_t *fidp, int flags, vnode_t **vpp)
if ((fid_gen == 0 &&
(object == ZFSCTL_INO_ROOT || object == ZFSCTL_INO_SNAPDIR)) ||
(zfsvfs->z_shares_dir != 0 && object == zfsvfs->z_shares_dir)) {
ZFS_EXIT(zfsvfs);
zfs_exit(zfsvfs, FTAG);
VERIFY0(zfsctl_root(zfsvfs, LK_SHARED, &dvp));
if (object == ZFSCTL_INO_SNAPDIR) {
cn.cn_nameptr = "snapshot";
@@ -1860,7 +1868,7 @@ zfs_fhtovp(vfs_t *vfsp, fid_t *fidp, int flags, vnode_t **vpp)
(u_longlong_t)fid_gen,
(u_longlong_t)gen_mask);
if ((err = zfs_zget(zfsvfs, object, &zp))) {
ZFS_EXIT(zfsvfs);
zfs_exit(zfsvfs, FTAG);
return (err);
}
(void) sa_lookup(zp->z_sa_hdl, SA_ZPL_GEN(zfsvfs), &zp_gen,
@@ -1872,12 +1880,12 @@ zfs_fhtovp(vfs_t *vfsp, fid_t *fidp, int flags, vnode_t **vpp)
dprintf("znode gen (%llu) != fid gen (%llu)\n",
(u_longlong_t)zp_gen, (u_longlong_t)fid_gen);
vrele(ZTOV(zp));
ZFS_EXIT(zfsvfs);
zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(EINVAL));
}
*vpp = ZTOV(zp);
ZFS_EXIT(zfsvfs);
zfs_exit(zfsvfs, FTAG);
err = vn_lock(*vpp, flags);
if (err == 0)
vnode_create_vobject(*vpp, zp->z_size, curthread);
@@ -1945,7 +1953,7 @@ zfs_resume_fs(zfsvfs_t *zfsvfs, dsl_dataset_t *ds)
/*
* Attempt to re-establish all the active znodes with
* their dbufs. If a zfs_rezget() fails, then we'll let
* any potential callers discover that via ZFS_ENTER_VERIFY_VP
* any potential callers discover that via zfs_enter_verify_zp
* when they try to use their znode.
*/
mutex_enter(&zfsvfs->z_znodes_lock);
File diff suppressed because it is too large Load Diff