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
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 591 additions and 486 deletions

View File

@ -121,29 +121,24 @@ typedef struct zfs_soft_state {
#define zn_rlimit_fsize(zp, uio) \ #define zn_rlimit_fsize(zp, uio) \
vn_rlimit_fsize(ZTOV(zp), GET_UIO_STRUCT(uio), zfs_uio_td(uio)) vn_rlimit_fsize(ZTOV(zp), GET_UIO_STRUCT(uio), zfs_uio_td(uio))
#define ZFS_ENTER_ERROR(zfsvfs, error) do { \
ZFS_TEARDOWN_ENTER_READ((zfsvfs), FTAG); \
if (__predict_false((zfsvfs)->z_unmounted)) { \
ZFS_TEARDOWN_EXIT_READ(zfsvfs, FTAG); \
return (error); \
} \
} while (0)
/* Called on entry to each ZFS vnode and vfs operation */ /* Called on entry to each ZFS vnode and vfs operation */
#define ZFS_ENTER(zfsvfs) ZFS_ENTER_ERROR(zfsvfs, EIO) static inline int
zfs_enter(zfsvfs_t *zfsvfs, const char *tag)
{
ZFS_TEARDOWN_ENTER_READ(zfsvfs, tag);
if (__predict_false((zfsvfs)->z_unmounted)) {
ZFS_TEARDOWN_EXIT_READ(zfsvfs, tag);
return (SET_ERROR(EIO));
}
return (0);
}
/* Must be called before exiting the vop */ /* Must be called before exiting the vop */
#define ZFS_EXIT(zfsvfs) ZFS_TEARDOWN_EXIT_READ(zfsvfs, FTAG) static inline void
zfs_exit(zfsvfs_t *zfsvfs, const char *tag)
#define ZFS_VERIFY_ZP_ERROR(zp, error) do { \ {
if (__predict_false((zp)->z_sa_hdl == NULL)) { \ ZFS_TEARDOWN_EXIT_READ(zfsvfs, tag);
ZFS_EXIT((zp)->z_zfsvfs); \ }
return (error); \
} \
} while (0)
/* Verifies the znode is valid */
#define ZFS_VERIFY_ZP(zp) ZFS_VERIFY_ZP_ERROR(zp, EIO)
/* /*
* Macros for dealing with dmu_buf_hold * Macros for dealing with dmu_buf_hold

View File

@ -84,39 +84,41 @@ extern "C" {
#define zrele(zp) iput(ZTOI((zp))) #define zrele(zp) iput(ZTOI((zp)))
/* Called on entry to each ZFS inode and vfs operation. */ /* Called on entry to each ZFS inode and vfs operation. */
#define ZFS_ENTER_ERROR(zfsvfs, error) \ static inline int
do { \ zfs_enter(zfsvfs_t *zfsvfs, const char *tag)
ZFS_TEARDOWN_ENTER_READ(zfsvfs, FTAG); \ {
if (unlikely((zfsvfs)->z_unmounted)) { \ ZFS_TEARDOWN_ENTER_READ(zfsvfs, tag);
ZFS_TEARDOWN_EXIT_READ(zfsvfs, FTAG); \ if (unlikely(zfsvfs->z_unmounted)) {
return (error); \ ZFS_TEARDOWN_EXIT_READ(zfsvfs, tag);
} \ return (SET_ERROR(EIO));
} while (0) }
#define ZFS_ENTER(zfsvfs) ZFS_ENTER_ERROR(zfsvfs, EIO) return (0);
#define ZPL_ENTER(zfsvfs) ZFS_ENTER_ERROR(zfsvfs, -EIO) }
/* Must be called before exiting the operation. */ /* Must be called before exiting the operation. */
#define ZFS_EXIT(zfsvfs) \ static inline void
do { \ zfs_exit(zfsvfs_t *zfsvfs, const char *tag)
zfs_exit_fs(zfsvfs); \ {
ZFS_TEARDOWN_EXIT_READ(zfsvfs, FTAG); \ zfs_exit_fs(zfsvfs);
} while (0) ZFS_TEARDOWN_EXIT_READ(zfsvfs, tag);
}
#define ZPL_EXIT(zfsvfs) \ static inline int
do { \ zpl_enter(zfsvfs_t *zfsvfs, const char *tag)
rrm_exit(&(zfsvfs)->z_teardown_lock, FTAG); \ {
} while (0) return (-zfs_enter(zfsvfs, tag));
}
/* Verifies the znode is valid. */ static inline void
#define ZFS_VERIFY_ZP_ERROR(zp, error) \ zpl_exit(zfsvfs_t *zfsvfs, const char *tag)
do { \ {
if (unlikely((zp)->z_sa_hdl == NULL)) { \ ZFS_TEARDOWN_EXIT_READ(zfsvfs, tag);
ZFS_EXIT(ZTOZSB(zp)); \ }
return (error); \
} \ /* zfs_verify_zp and zfs_enter_verify_zp are defined in zfs_znode.h */
} while (0) #define zpl_verify_zp(zp) (-zfs_verify_zp(zp))
#define ZFS_VERIFY_ZP(zp) ZFS_VERIFY_ZP_ERROR(zp, EIO) #define zpl_enter_verify_zp(zfsvfs, zp, tag) \
#define ZPL_VERIFY_ZP(zp) ZFS_VERIFY_ZP_ERROR(zp, -EIO) (-zfs_enter_verify_zp(zfsvfs, zp, tag))
/* /*
* Macros for dealing with dmu_buf_hold * Macros for dealing with dmu_buf_hold

View File

@ -218,6 +218,29 @@ typedef struct znode {
ZNODE_OS_FIELDS; ZNODE_OS_FIELDS;
} znode_t; } znode_t;
/* Verifies the znode is valid. */
static inline int
zfs_verify_zp(znode_t *zp)
{
if (unlikely(zp->z_sa_hdl == NULL))
return (SET_ERROR(EIO));
return (0);
}
/* zfs_enter and zfs_verify_zp together */
static inline int
zfs_enter_verify_zp(zfsvfs_t *zfsvfs, znode_t *zp, const char *tag)
{
int error;
if ((error = zfs_enter(zfsvfs, tag)) != 0)
return (error);
if ((error = zfs_verify_zp(zp)) != 0) {
zfs_exit(zfsvfs, tag);
return (error);
}
return (0);
}
typedef struct znode_hold { typedef struct znode_hold {
uint64_t zh_obj; /* object id */ uint64_t zh_obj; /* object id */
kmutex_t zh_lock; /* lock serializing object access */ kmutex_t zh_lock; /* lock serializing object access */

View File

@ -1053,7 +1053,8 @@ zfsctl_snapdir_readdir(struct vop_readdir_args *ap)
return (error); return (error);
} }
ZFS_ENTER(zfsvfs); if ((error = zfs_enter(zfsvfs, FTAG)) != 0)
return (error);
for (;;) { for (;;) {
uint64_t cookie; uint64_t cookie;
uint64_t id; uint64_t id;
@ -1070,7 +1071,7 @@ zfsctl_snapdir_readdir(struct vop_readdir_args *ap)
*eofp = 1; *eofp = 1;
error = 0; error = 0;
} }
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
@ -1083,7 +1084,7 @@ zfsctl_snapdir_readdir(struct vop_readdir_args *ap)
if (error != 0) { if (error != 0) {
if (error == ENAMETOOLONG) if (error == ENAMETOOLONG)
error = 0; error = 0;
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(error)); return (SET_ERROR(error));
} }
zfs_uio_setoffset(&uio, cookie + dots_offset); zfs_uio_setoffset(&uio, cookie + dots_offset);
@ -1101,7 +1102,8 @@ zfsctl_snapdir_getattr(struct vop_getattr_args *ap)
uint64_t snap_count; uint64_t snap_count;
int err; int err;
ZFS_ENTER(zfsvfs); if ((err = zfs_enter(zfsvfs, FTAG)) != 0)
return (err);
ds = dmu_objset_ds(zfsvfs->z_os); ds = dmu_objset_ds(zfsvfs->z_os);
zfsctl_common_getattr(vp, vap); zfsctl_common_getattr(vp, vap);
vap->va_ctime = dmu_objset_snap_cmtime(zfsvfs->z_os); 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, err = zap_count(dmu_objset_pool(ds->ds_objset)->dp_meta_objset,
dsl_dataset_phys(ds)->ds_snapnames_zapobj, &snap_count); dsl_dataset_phys(ds)->ds_snapnames_zapobj, &snap_count);
if (err != 0) { if (err != 0) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (err); return (err);
} }
vap->va_nlink += snap_count; vap->va_nlink += snap_count;
} }
vap->va_size = vap->va_nlink; vap->va_size = vap->va_nlink;
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (0); return (0);
} }

View File

@ -286,7 +286,8 @@ zfs_quotactl(vfs_t *vfsp, int cmds, uid_t id, void *arg)
cmd = cmds >> SUBCMDSHIFT; cmd = cmds >> SUBCMDSHIFT;
type = cmds & SUBCMDMASK; type = cmds & SUBCMDMASK;
ZFS_ENTER(zfsvfs); if ((error = zfs_enter(zfsvfs, FTAG)) != 0)
return (error);
if (id == -1) { if (id == -1) {
switch (type) { switch (type) {
case USRQUOTA: case USRQUOTA:
@ -385,7 +386,7 @@ zfs_quotactl(vfs_t *vfsp, int cmds, uid_t id, void *arg)
break; break;
} }
done: done:
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
@ -426,7 +427,8 @@ zfs_sync(vfs_t *vfsp, int waitfor)
if (error != 0) if (error != 0)
return (error); return (error);
ZFS_ENTER(zfsvfs); if ((error = zfs_enter(zfsvfs, FTAG)) != 0)
return (error);
dp = dmu_objset_pool(zfsvfs->z_os); 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. * filesystems which may exist on a suspended pool.
*/ */
if (rebooting && spa_suspended(dp->dp_spa)) { if (rebooting && spa_suspended(dp->dp_spa)) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (0); return (0);
} }
if (zfsvfs->z_log != NULL) if (zfsvfs->z_log != NULL)
zil_commit(zfsvfs->z_log, 0); zil_commit(zfsvfs->z_log, 0);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
} else { } else {
/* /*
* Sync all ZFS filesystems. This is what happens when you * 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; zfsvfs_t *zfsvfs = vfsp->vfs_data;
uint64_t refdbytes, availbytes, usedobjs, availobjs; uint64_t refdbytes, availbytes, usedobjs, availobjs;
int error;
statp->f_version = STATFS_VERSION; statp->f_version = STATFS_VERSION;
ZFS_ENTER(zfsvfs); if ((error = zfs_enter(zfsvfs, FTAG)) != 0)
return (error);
dmu_objset_space(zfsvfs->z_os, dmu_objset_space(zfsvfs->z_os,
&refdbytes, &availbytes, &usedobjs, &availobjs); &refdbytes, &availbytes, &usedobjs, &availobjs);
@ -1458,7 +1462,7 @@ zfs_statfs(vfs_t *vfsp, struct statfs *statp)
statp->f_namemax = MAXNAMELEN - 1; statp->f_namemax = MAXNAMELEN - 1;
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (0); return (0);
} }
@ -1469,13 +1473,14 @@ zfs_root(vfs_t *vfsp, int flags, vnode_t **vpp)
znode_t *rootzp; znode_t *rootzp;
int error; int error;
ZFS_ENTER(zfsvfs); if ((error = zfs_enter(zfsvfs, FTAG)) != 0)
return (error);
error = zfs_zget(zfsvfs, zfsvfs->z_root, &rootzp); error = zfs_zget(zfsvfs, zfsvfs->z_root, &rootzp);
if (error == 0) if (error == 0)
*vpp = ZTOV(rootzp); *vpp = ZTOV(rootzp);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
if (error == 0) { if (error == 0) {
error = vn_lock(*vpp, flags); 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)) (zfsvfs->z_shares_dir != 0 && ino == zfsvfs->z_shares_dir))
return (EOPNOTSUPP); return (EOPNOTSUPP);
ZFS_ENTER(zfsvfs); if ((err = zfs_enter(zfsvfs, FTAG)) != 0)
return (err);
err = zfs_zget(zfsvfs, ino, &zp); err = zfs_zget(zfsvfs, ino, &zp);
if (err == 0 && zp->z_unlinked) { if (err == 0 && zp->z_unlinked) {
vrele(ZTOV(zp)); vrele(ZTOV(zp));
@ -1720,7 +1726,7 @@ zfs_vget(vfs_t *vfsp, ino_t ino, int flags, vnode_t **vpp)
} }
if (err == 0) if (err == 0)
*vpp = ZTOV(zp); *vpp = ZTOV(zp);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
if (err == 0) { if (err == 0) {
err = vn_lock(*vpp, flags); err = vn_lock(*vpp, flags);
if (err != 0) if (err != 0)
@ -1774,7 +1780,8 @@ zfs_fhtovp(vfs_t *vfsp, fid_t *fidp, int flags, vnode_t **vpp)
*vpp = NULL; *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 * 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++) for (i = 0; i < sizeof (zlfid->zf_setgen); i++)
setgen |= ((uint64_t)zlfid->zf_setgen[i]) << (8 * i); setgen |= ((uint64_t)zlfid->zf_setgen[i]) << (8 * i);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
err = zfsctl_lookup_objset(vfsp, objsetid, &zfsvfs); err = zfsctl_lookup_objset(vfsp, objsetid, &zfsvfs);
if (err) if (err)
return (SET_ERROR(EINVAL)); 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) { 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++) for (i = 0; i < sizeof (zfid->zf_gen); i++)
fid_gen |= ((uint64_t)zfid->zf_gen[i]) << (8 * i); fid_gen |= ((uint64_t)zfid->zf_gen[i]) << (8 * i);
} else { } else {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(EINVAL)); 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 && if ((fid_gen == 0 &&
(object == ZFSCTL_INO_ROOT || object == ZFSCTL_INO_SNAPDIR)) || (object == ZFSCTL_INO_ROOT || object == ZFSCTL_INO_SNAPDIR)) ||
(zfsvfs->z_shares_dir != 0 && object == zfsvfs->z_shares_dir)) { (zfsvfs->z_shares_dir != 0 && object == zfsvfs->z_shares_dir)) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
VERIFY0(zfsctl_root(zfsvfs, LK_SHARED, &dvp)); VERIFY0(zfsctl_root(zfsvfs, LK_SHARED, &dvp));
if (object == ZFSCTL_INO_SNAPDIR) { if (object == ZFSCTL_INO_SNAPDIR) {
cn.cn_nameptr = "snapshot"; 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)fid_gen,
(u_longlong_t)gen_mask); (u_longlong_t)gen_mask);
if ((err = zfs_zget(zfsvfs, object, &zp))) { if ((err = zfs_zget(zfsvfs, object, &zp))) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (err); return (err);
} }
(void) sa_lookup(zp->z_sa_hdl, SA_ZPL_GEN(zfsvfs), &zp_gen, (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", dprintf("znode gen (%llu) != fid gen (%llu)\n",
(u_longlong_t)zp_gen, (u_longlong_t)fid_gen); (u_longlong_t)zp_gen, (u_longlong_t)fid_gen);
vrele(ZTOV(zp)); vrele(ZTOV(zp));
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(EINVAL)); return (SET_ERROR(EINVAL));
} }
*vpp = ZTOV(zp); *vpp = ZTOV(zp);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
err = vn_lock(*vpp, flags); err = vn_lock(*vpp, flags);
if (err == 0) if (err == 0)
vnode_create_vobject(*vpp, zp->z_size, curthread); 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 * Attempt to re-establish all the active znodes with
* their dbufs. If a zfs_rezget() fails, then we'll let * 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. * when they try to use their znode.
*/ */
mutex_enter(&zfsvfs->z_znodes_lock); mutex_enter(&zfsvfs->z_znodes_lock);

File diff suppressed because it is too large Load Diff

View File

@ -2596,9 +2596,10 @@ zfs_fastaccesschk_execute(znode_t *zdp, cred_t *cr)
slow: slow:
DTRACE_PROBE(zfs__fastpath__execute__access__miss); DTRACE_PROBE(zfs__fastpath__execute__access__miss);
ZFS_ENTER(ZTOZSB(zdp)); if ((error = zfs_enter(ZTOZSB(zdp), FTAG)) != 0)
return (error);
error = zfs_zaccess(zdp, ACE_EXECUTE, 0, B_FALSE, cr); error = zfs_zaccess(zdp, ACE_EXECUTE, 0, B_FALSE, cr);
ZFS_EXIT(ZTOZSB(zdp)); zfs_exit(ZTOZSB(zdp), FTAG);
return (error); return (error);
} }

View File

@ -673,17 +673,19 @@ zfsctl_fid(struct inode *ip, fid_t *fidp)
uint64_t object = zp->z_id; uint64_t object = zp->z_id;
zfid_short_t *zfid; zfid_short_t *zfid;
int i; int i;
int error;
ZFS_ENTER(zfsvfs); if ((error = zfs_enter(zfsvfs, FTAG)) != 0)
return (error);
if (zfsctl_is_snapdir(ip)) { if (zfsctl_is_snapdir(ip)) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (zfsctl_snapdir_fid(ip, fidp)); return (zfsctl_snapdir_fid(ip, fidp));
} }
if (fidp->fid_len < SHORT_FID_LEN) { if (fidp->fid_len < SHORT_FID_LEN) {
fidp->fid_len = SHORT_FID_LEN; fidp->fid_len = SHORT_FID_LEN;
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(ENOSPC)); return (SET_ERROR(ENOSPC));
} }
@ -698,7 +700,7 @@ zfsctl_fid(struct inode *ip, fid_t *fidp)
for (i = 0; i < sizeof (zfid->zf_gen); i++) for (i = 0; i < sizeof (zfid->zf_gen); i++)
zfid->zf_gen[i] = 0; zfid->zf_gen[i] = 0;
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (0); return (0);
} }
@ -776,7 +778,8 @@ zfsctl_root_lookup(struct inode *dip, const char *name, struct inode **ipp,
zfsvfs_t *zfsvfs = ITOZSB(dip); zfsvfs_t *zfsvfs = ITOZSB(dip);
int error = 0; int error = 0;
ZFS_ENTER(zfsvfs); if ((error = zfs_enter(zfsvfs, FTAG)) != 0)
return (error);
if (strcmp(name, "..") == 0) { if (strcmp(name, "..") == 0) {
*ipp = dip->i_sb->s_root->d_inode; *ipp = dip->i_sb->s_root->d_inode;
@ -793,7 +796,7 @@ zfsctl_root_lookup(struct inode *dip, const char *name, struct inode **ipp,
if (*ipp == NULL) if (*ipp == NULL)
error = SET_ERROR(ENOENT); error = SET_ERROR(ENOENT);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
@ -810,11 +813,12 @@ zfsctl_snapdir_lookup(struct inode *dip, const char *name, struct inode **ipp,
uint64_t id; uint64_t id;
int error; int error;
ZFS_ENTER(zfsvfs); if ((error = zfs_enter(zfsvfs, FTAG)) != 0)
return (error);
error = dmu_snapshot_lookup(zfsvfs->z_os, name, &id); error = dmu_snapshot_lookup(zfsvfs->z_os, name, &id);
if (error) { if (error) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
@ -823,7 +827,7 @@ zfsctl_snapdir_lookup(struct inode *dip, const char *name, struct inode **ipp,
if (*ipp == NULL) if (*ipp == NULL)
error = SET_ERROR(ENOENT); error = SET_ERROR(ENOENT);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
@ -844,7 +848,8 @@ zfsctl_snapdir_rename(struct inode *sdip, const char *snm,
if (!zfs_admin_snapshot) if (!zfs_admin_snapshot)
return (SET_ERROR(EACCES)); return (SET_ERROR(EACCES));
ZFS_ENTER(zfsvfs); if ((error = zfs_enter(zfsvfs, FTAG)) != 0)
return (error);
to = kmem_alloc(ZFS_MAX_DATASET_NAME_LEN, KM_SLEEP); to = kmem_alloc(ZFS_MAX_DATASET_NAME_LEN, KM_SLEEP);
from = kmem_alloc(ZFS_MAX_DATASET_NAME_LEN, KM_SLEEP); from = kmem_alloc(ZFS_MAX_DATASET_NAME_LEN, KM_SLEEP);
@ -902,7 +907,7 @@ out:
kmem_free(real, ZFS_MAX_DATASET_NAME_LEN); kmem_free(real, ZFS_MAX_DATASET_NAME_LEN);
kmem_free(fsname, ZFS_MAX_DATASET_NAME_LEN); kmem_free(fsname, ZFS_MAX_DATASET_NAME_LEN);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
@ -922,7 +927,8 @@ zfsctl_snapdir_remove(struct inode *dip, const char *name, cred_t *cr,
if (!zfs_admin_snapshot) if (!zfs_admin_snapshot)
return (SET_ERROR(EACCES)); return (SET_ERROR(EACCES));
ZFS_ENTER(zfsvfs); if ((error = zfs_enter(zfsvfs, FTAG)) != 0)
return (error);
snapname = kmem_alloc(ZFS_MAX_DATASET_NAME_LEN, KM_SLEEP); snapname = kmem_alloc(ZFS_MAX_DATASET_NAME_LEN, KM_SLEEP);
real = kmem_alloc(ZFS_MAX_DATASET_NAME_LEN, KM_SLEEP); real = kmem_alloc(ZFS_MAX_DATASET_NAME_LEN, KM_SLEEP);
@ -951,7 +957,7 @@ out:
kmem_free(snapname, ZFS_MAX_DATASET_NAME_LEN); kmem_free(snapname, ZFS_MAX_DATASET_NAME_LEN);
kmem_free(real, ZFS_MAX_DATASET_NAME_LEN); kmem_free(real, ZFS_MAX_DATASET_NAME_LEN);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
@ -1076,7 +1082,8 @@ zfsctl_snapshot_mount(struct path *path, int flags)
return (SET_ERROR(EISDIR)); return (SET_ERROR(EISDIR));
zfsvfs = ITOZSB(ip); zfsvfs = ITOZSB(ip);
ZFS_ENTER(zfsvfs); if ((error = zfs_enter(zfsvfs, FTAG)) != 0)
return (error);
full_name = kmem_zalloc(ZFS_MAX_DATASET_NAME_LEN, KM_SLEEP); full_name = kmem_zalloc(ZFS_MAX_DATASET_NAME_LEN, KM_SLEEP);
full_path = kmem_zalloc(MAXPATHLEN, KM_SLEEP); full_path = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
@ -1164,7 +1171,7 @@ error:
kmem_free(full_name, ZFS_MAX_DATASET_NAME_LEN); kmem_free(full_name, ZFS_MAX_DATASET_NAME_LEN);
kmem_free(full_path, MAXPATHLEN); kmem_free(full_path, MAXPATHLEN);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
@ -1228,10 +1235,11 @@ zfsctl_shares_lookup(struct inode *dip, char *name, struct inode **ipp,
znode_t *dzp; znode_t *dzp;
int error; int error;
ZFS_ENTER(zfsvfs); if ((error = zfs_enter(zfsvfs, FTAG)) != 0)
return (error);
if (zfsvfs->z_shares_dir == 0) { if (zfsvfs->z_shares_dir == 0) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(ENOTSUP)); return (SET_ERROR(ENOTSUP));
} }
@ -1240,7 +1248,7 @@ zfsctl_shares_lookup(struct inode *dip, char *name, struct inode **ipp,
zrele(dzp); zrele(dzp);
} }
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }

View File

@ -273,8 +273,10 @@ zfs_sync(struct super_block *sb, int wait, cred_t *cr)
* Sync a specific filesystem. * Sync a specific filesystem.
*/ */
dsl_pool_t *dp; dsl_pool_t *dp;
int error;
ZFS_ENTER(zfsvfs); if ((error = zfs_enter(zfsvfs, FTAG)) != 0)
return (error);
dp = dmu_objset_pool(zfsvfs->z_os); dp = dmu_objset_pool(zfsvfs->z_os);
/* /*
@ -282,14 +284,14 @@ zfs_sync(struct super_block *sb, int wait, cred_t *cr)
* filesystems which may exist on a suspended pool. * filesystems which may exist on a suspended pool.
*/ */
if (spa_suspended(dp->dp_spa)) { if (spa_suspended(dp->dp_spa)) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (0); return (0);
} }
if (zfsvfs->z_log != NULL) if (zfsvfs->z_log != NULL)
zil_commit(zfsvfs->z_log, 0); zil_commit(zfsvfs->z_log, 0);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
} else { } else {
/* /*
* Sync all ZFS filesystems. This is what happens when you * Sync all ZFS filesystems. This is what happens when you
@ -1092,7 +1094,8 @@ zfs_statvfs(struct inode *ip, struct kstatfs *statp)
uint64_t refdbytes, availbytes, usedobjs, availobjs; uint64_t refdbytes, availbytes, usedobjs, availobjs;
int err = 0; int err = 0;
ZFS_ENTER(zfsvfs); if ((err = zfs_enter(zfsvfs, FTAG)) != 0)
return (err);
dmu_objset_space(zfsvfs->z_os, dmu_objset_space(zfsvfs->z_os,
&refdbytes, &availbytes, &usedobjs, &availobjs); &refdbytes, &availbytes, &usedobjs, &availobjs);
@ -1153,7 +1156,7 @@ zfs_statvfs(struct inode *ip, struct kstatfs *statp)
err = zfs_statfs_project(zfsvfs, zp, statp, bshift); err = zfs_statfs_project(zfsvfs, zp, statp, bshift);
} }
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (err); return (err);
} }
@ -1163,13 +1166,14 @@ zfs_root(zfsvfs_t *zfsvfs, struct inode **ipp)
znode_t *rootzp; znode_t *rootzp;
int error; int error;
ZFS_ENTER(zfsvfs); if ((error = zfs_enter(zfsvfs, FTAG)) != 0)
return (error);
error = zfs_zget(zfsvfs, zfsvfs->z_root, &rootzp); error = zfs_zget(zfsvfs, zfsvfs->z_root, &rootzp);
if (error == 0) if (error == 0)
*ipp = ZTOI(rootzp); *ipp = ZTOI(rootzp);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
@ -1247,7 +1251,8 @@ zfs_prune(struct super_block *sb, unsigned long nr_to_scan, int *objects)
.gfp_mask = GFP_KERNEL, .gfp_mask = GFP_KERNEL,
}; };
ZFS_ENTER(zfsvfs); if ((error = zfs_enter(zfsvfs, FTAG)) != 0)
return (error);
#if defined(HAVE_SPLIT_SHRINKER_CALLBACK) && \ #if defined(HAVE_SPLIT_SHRINKER_CALLBACK) && \
defined(SHRINK_CONTROL_HAS_NID) && \ defined(SHRINK_CONTROL_HAS_NID) && \
@ -1288,7 +1293,7 @@ zfs_prune(struct super_block *sb, unsigned long nr_to_scan, int *objects)
*objects = zfs_prune_aliases(zfsvfs, nr_to_scan); *objects = zfs_prune_aliases(zfsvfs, nr_to_scan);
#endif #endif
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
dprintf_ds(zfsvfs->z_os->os_dsl_dataset, dprintf_ds(zfsvfs->z_os->os_dsl_dataset,
"pruning, nr_to_scan=%lu objects=%d error=%d\n", "pruning, nr_to_scan=%lu objects=%d error=%d\n",
@ -1745,7 +1750,8 @@ zfs_vget(struct super_block *sb, struct inode **ipp, fid_t *fidp)
return (zfsctl_snapdir_vget(sb, objsetid, fid_gen, ipp)); return (zfsctl_snapdir_vget(sb, objsetid, fid_gen, ipp));
} }
ZFS_ENTER(zfsvfs); if ((err = zfs_enter(zfsvfs, FTAG)) != 0)
return (err);
/* A zero fid_gen means we are in the .zfs control directories */ /* A zero fid_gen means we are in the .zfs control directories */
if (fid_gen == 0 && if (fid_gen == 0 &&
(object == ZFSCTL_INO_ROOT || object == ZFSCTL_INO_SNAPDIR)) { (object == ZFSCTL_INO_ROOT || object == ZFSCTL_INO_SNAPDIR)) {
@ -1761,7 +1767,7 @@ zfs_vget(struct super_block *sb, struct inode **ipp, fid_t *fidp)
*/ */
VERIFY3P(igrab(*ipp), !=, NULL); VERIFY3P(igrab(*ipp), !=, NULL);
} }
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (0); return (0);
} }
@ -1769,14 +1775,14 @@ zfs_vget(struct super_block *sb, struct inode **ipp, fid_t *fidp)
dprintf("getting %llu [%llu mask %llx]\n", object, fid_gen, gen_mask); dprintf("getting %llu [%llu mask %llx]\n", object, fid_gen, gen_mask);
if ((err = zfs_zget(zfsvfs, object, &zp))) { if ((err = zfs_zget(zfsvfs, object, &zp))) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (err); return (err);
} }
/* Don't export xattr stuff */ /* Don't export xattr stuff */
if (zp->z_pflags & ZFS_XATTR) { if (zp->z_pflags & ZFS_XATTR) {
zrele(zp); zrele(zp);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(ENOENT)); return (SET_ERROR(ENOENT));
} }
@ -1791,7 +1797,7 @@ zfs_vget(struct super_block *sb, struct inode **ipp, fid_t *fidp)
dprintf("znode gen (%llu) != fid gen (%llu)\n", zp_gen, dprintf("znode gen (%llu) != fid gen (%llu)\n", zp_gen,
fid_gen); fid_gen);
zrele(zp); zrele(zp);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(ENOENT)); return (SET_ERROR(ENOENT));
} }
@ -1799,7 +1805,7 @@ zfs_vget(struct super_block *sb, struct inode **ipp, fid_t *fidp)
if (*ipp) if (*ipp)
zfs_znode_update_vfs(ITOZ(*ipp)); zfs_znode_update_vfs(ITOZ(*ipp));
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (0); return (0);
} }

View File

@ -82,13 +82,13 @@
* to freed memory. The example below illustrates the following Big Rules: * to freed memory. The example below illustrates the following Big Rules:
* *
* (1) A check must be made in each zfs thread for a mounted file system. * (1) A check must be made in each zfs thread for a mounted file system.
* This is done avoiding races using ZFS_ENTER(zfsvfs). * This is done avoiding races using zfs_enter(zfsvfs).
* A ZFS_EXIT(zfsvfs) is needed before all returns. Any znodes * A zfs_exit(zfsvfs) is needed before all returns. Any znodes
* must be checked with ZFS_VERIFY_ZP(zp). Both of these macros * must be checked with zfs_verify_zp(zp). Both of these macros
* can return EIO from the calling function. * can return EIO from the calling function.
* *
* (2) zrele() should always be the last thing except for zil_commit() (if * (2) zrele() should always be the last thing except for zil_commit() (if
* necessary) and ZFS_EXIT(). This is for 3 reasons: First, if it's the * necessary) and zfs_exit(). This is for 3 reasons: First, if it's the
* last reference, the vnode/znode can be freed, so the zp may point to * last reference, the vnode/znode can be freed, so the zp may point to
* freed memory. Second, the last reference will call zfs_zinactive(), * freed memory. Second, the last reference will call zfs_zinactive(),
* which may induce a lot of work -- pushing cached pages (which acquires * which may induce a lot of work -- pushing cached pages (which acquires
@ -107,7 +107,7 @@
* dmu_tx_assign(). This is critical because we don't want to block * dmu_tx_assign(). This is critical because we don't want to block
* while holding locks. * while holding locks.
* *
* If no ZPL locks are held (aside from ZFS_ENTER()), use TXG_WAIT. This * If no ZPL locks are held (aside from zfs_enter()), use TXG_WAIT. This
* reduces lock contention and CPU usage when we must wait (note that if * reduces lock contention and CPU usage when we must wait (note that if
* throughput is constrained by the storage, nearly every transaction * throughput is constrained by the storage, nearly every transaction
* must wait). * must wait).
@ -142,7 +142,7 @@
* *
* In general, this is how things should be ordered in each vnode op: * In general, this is how things should be ordered in each vnode op:
* *
* ZFS_ENTER(zfsvfs); // exit if unmounted * zfs_enter(zfsvfs); // exit if unmounted
* top: * top:
* zfs_dirent_lock(&dl, ...) // lock directory entry (may igrab()) * zfs_dirent_lock(&dl, ...) // lock directory entry (may igrab())
* rw_enter(...); // grab any other locks you need * rw_enter(...); // grab any other locks you need
@ -160,7 +160,7 @@
* goto top; * goto top;
* } * }
* dmu_tx_abort(tx); // abort DMU tx * dmu_tx_abort(tx); // abort DMU tx
* ZFS_EXIT(zfsvfs); // finished in zfs * zfs_exit(zfsvfs); // finished in zfs
* return (error); // really out of space * return (error); // really out of space
* } * }
* error = do_real_work(); // do whatever this VOP does * error = do_real_work(); // do whatever this VOP does
@ -171,7 +171,7 @@
* zfs_dirent_unlock(dl); // unlock directory entry * zfs_dirent_unlock(dl); // unlock directory entry
* zrele(...); // release held znodes * zrele(...); // release held znodes
* zil_commit(zilog, foid); // synchronous when necessary * zil_commit(zilog, foid); // synchronous when necessary
* ZFS_EXIT(zfsvfs); // finished in zfs * zfs_exit(zfsvfs); // finished in zfs
* return (error); // done, report error * return (error); // done, report error
*/ */
int int
@ -180,14 +180,15 @@ zfs_open(struct inode *ip, int mode, int flag, cred_t *cr)
(void) cr; (void) cr;
znode_t *zp = ITOZ(ip); znode_t *zp = ITOZ(ip);
zfsvfs_t *zfsvfs = ITOZSB(ip); zfsvfs_t *zfsvfs = ITOZSB(ip);
int error;
ZFS_ENTER(zfsvfs); if ((error = zfs_enter_verify_zp(zfsvfs, zp, FTAG)) != 0)
ZFS_VERIFY_ZP(zp); return (error);
/* Honor ZFS_APPENDONLY file attribute */ /* Honor ZFS_APPENDONLY file attribute */
if ((mode & FMODE_WRITE) && (zp->z_pflags & ZFS_APPENDONLY) && if ((mode & FMODE_WRITE) && (zp->z_pflags & ZFS_APPENDONLY) &&
((flag & O_APPEND) == 0)) { ((flag & O_APPEND) == 0)) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(EPERM)); return (SET_ERROR(EPERM));
} }
@ -195,7 +196,7 @@ zfs_open(struct inode *ip, int mode, int flag, cred_t *cr)
if (flag & O_SYNC) if (flag & O_SYNC)
atomic_inc_32(&zp->z_sync_cnt); atomic_inc_32(&zp->z_sync_cnt);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (0); return (0);
} }
@ -205,15 +206,16 @@ zfs_close(struct inode *ip, int flag, cred_t *cr)
(void) cr; (void) cr;
znode_t *zp = ITOZ(ip); znode_t *zp = ITOZ(ip);
zfsvfs_t *zfsvfs = ITOZSB(ip); zfsvfs_t *zfsvfs = ITOZSB(ip);
int error;
ZFS_ENTER(zfsvfs); if ((error = zfs_enter_verify_zp(zfsvfs, zp, FTAG)) != 0)
ZFS_VERIFY_ZP(zp); return (error);
/* Decrement the synchronous opens in the znode */ /* Decrement the synchronous opens in the znode */
if (flag & O_SYNC) if (flag & O_SYNC)
atomic_dec_32(&zp->z_sync_cnt); atomic_dec_32(&zp->z_sync_cnt);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (0); return (0);
} }
@ -449,8 +451,8 @@ zfs_lookup(znode_t *zdp, char *nm, znode_t **zpp, int flags, cred_t *cr,
} }
} }
ZFS_ENTER(zfsvfs); if ((error = zfs_enter_verify_zp(zfsvfs, zdp, FTAG)) != 0)
ZFS_VERIFY_ZP(zdp); return (error);
*zpp = NULL; *zpp = NULL;
@ -460,12 +462,12 @@ zfs_lookup(znode_t *zdp, char *nm, znode_t **zpp, int flags, cred_t *cr,
* Maybe someday we will. * Maybe someday we will.
*/ */
if (zdp->z_pflags & ZFS_XATTR) { if (zdp->z_pflags & ZFS_XATTR) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(EINVAL)); return (SET_ERROR(EINVAL));
} }
if ((error = zfs_get_xattrdir(zdp, zpp, cr, flags))) { if ((error = zfs_get_xattrdir(zdp, zpp, cr, flags))) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
@ -479,12 +481,12 @@ zfs_lookup(znode_t *zdp, char *nm, znode_t **zpp, int flags, cred_t *cr,
*zpp = NULL; *zpp = NULL;
} }
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
if (!S_ISDIR(ZTOI(zdp)->i_mode)) { if (!S_ISDIR(ZTOI(zdp)->i_mode)) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(ENOTDIR)); return (SET_ERROR(ENOTDIR));
} }
@ -493,13 +495,13 @@ zfs_lookup(znode_t *zdp, char *nm, znode_t **zpp, int flags, cred_t *cr,
*/ */
if ((error = zfs_zaccess(zdp, ACE_EXECUTE, 0, B_FALSE, cr))) { if ((error = zfs_zaccess(zdp, ACE_EXECUTE, 0, B_FALSE, cr))) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
if (zfsvfs->z_utf8 && u8_validate(nm, strlen(nm), if (zfsvfs->z_utf8 && u8_validate(nm, strlen(nm),
NULL, U8_VALIDATE_ENTIRE, &error) < 0) { NULL, U8_VALIDATE_ENTIRE, &error) < 0) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(EILSEQ)); return (SET_ERROR(EILSEQ));
} }
@ -507,7 +509,7 @@ zfs_lookup(znode_t *zdp, char *nm, znode_t **zpp, int flags, cred_t *cr,
if ((error == 0) && (*zpp)) if ((error == 0) && (*zpp))
zfs_znode_update_vfs(*zpp); zfs_znode_update_vfs(*zpp);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
@ -566,21 +568,21 @@ zfs_create(znode_t *dzp, char *name, vattr_t *vap, int excl,
if (name == NULL) if (name == NULL)
return (SET_ERROR(EINVAL)); return (SET_ERROR(EINVAL));
ZFS_ENTER(zfsvfs); if ((error = zfs_enter_verify_zp(zfsvfs, dzp, FTAG)) != 0)
ZFS_VERIFY_ZP(dzp); return (error);
os = zfsvfs->z_os; os = zfsvfs->z_os;
zilog = zfsvfs->z_log; zilog = zfsvfs->z_log;
if (zfsvfs->z_utf8 && u8_validate(name, strlen(name), if (zfsvfs->z_utf8 && u8_validate(name, strlen(name),
NULL, U8_VALIDATE_ENTIRE, &error) < 0) { NULL, U8_VALIDATE_ENTIRE, &error) < 0) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(EILSEQ)); return (SET_ERROR(EILSEQ));
} }
if (vap->va_mask & ATTR_XVATTR) { if (vap->va_mask & ATTR_XVATTR) {
if ((error = secpolicy_xvattr((xvattr_t *)vap, if ((error = secpolicy_xvattr((xvattr_t *)vap,
crgetuid(cr), cr, vap->va_mode)) != 0) { crgetuid(cr), cr, vap->va_mode)) != 0) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
} }
@ -609,7 +611,7 @@ top:
zfs_acl_ids_free(&acl_ids); zfs_acl_ids_free(&acl_ids);
if (strcmp(name, "..") == 0) if (strcmp(name, "..") == 0)
error = SET_ERROR(EISDIR); error = SET_ERROR(EISDIR);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
} }
@ -681,7 +683,7 @@ top:
} }
zfs_acl_ids_free(&acl_ids); zfs_acl_ids_free(&acl_ids);
dmu_tx_abort(tx); dmu_tx_abort(tx);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
zfs_mknode(dzp, vap, tx, cr, 0, &zp, &acl_ids); zfs_mknode(dzp, vap, tx, cr, 0, &zp, &acl_ids);
@ -774,7 +776,7 @@ out:
if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
zil_commit(zilog, 0); zil_commit(zilog, 0);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
@ -808,14 +810,14 @@ zfs_tmpfile(struct inode *dip, vattr_t *vap, int excl,
(vsecp || IS_EPHEMERAL(uid) || IS_EPHEMERAL(gid))) (vsecp || IS_EPHEMERAL(uid) || IS_EPHEMERAL(gid)))
return (SET_ERROR(EINVAL)); return (SET_ERROR(EINVAL));
ZFS_ENTER(zfsvfs); if ((error = zfs_enter_verify_zp(zfsvfs, dzp, FTAG)) != 0)
ZFS_VERIFY_ZP(dzp); return (error);
os = zfsvfs->z_os; os = zfsvfs->z_os;
if (vap->va_mask & ATTR_XVATTR) { if (vap->va_mask & ATTR_XVATTR) {
if ((error = secpolicy_xvattr((xvattr_t *)vap, if ((error = secpolicy_xvattr((xvattr_t *)vap,
crgetuid(cr), cr, vap->va_mode)) != 0) { crgetuid(cr), cr, vap->va_mode)) != 0) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
} }
@ -870,7 +872,7 @@ top:
} }
zfs_acl_ids_free(&acl_ids); zfs_acl_ids_free(&acl_ids);
dmu_tx_abort(tx); dmu_tx_abort(tx);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
zfs_mknode(dzp, vap, tx, cr, IS_TMPFILE, &zp, &acl_ids); zfs_mknode(dzp, vap, tx, cr, IS_TMPFILE, &zp, &acl_ids);
@ -894,7 +896,7 @@ out:
*ipp = ZTOI(zp); *ipp = ZTOI(zp);
} }
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
@ -941,8 +943,8 @@ zfs_remove(znode_t *dzp, char *name, cred_t *cr, int flags)
if (name == NULL) if (name == NULL)
return (SET_ERROR(EINVAL)); return (SET_ERROR(EINVAL));
ZFS_ENTER(zfsvfs); if ((error = zfs_enter_verify_zp(zfsvfs, dzp, FTAG)) != 0)
ZFS_VERIFY_ZP(dzp); return (error);
zilog = zfsvfs->z_log; zilog = zfsvfs->z_log;
if (flags & FIGNORECASE) { if (flags & FIGNORECASE) {
@ -961,7 +963,7 @@ top:
NULL, realnmp))) { NULL, realnmp))) {
if (realnmp) if (realnmp)
pn_free(realnmp); pn_free(realnmp);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
@ -1042,7 +1044,7 @@ top:
zrele(zp); zrele(zp);
if (xzp) if (xzp)
zrele(xzp); zrele(xzp);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
@ -1131,7 +1133,7 @@ out:
if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
zil_commit(zilog, 0); zil_commit(zilog, 0);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
@ -1188,18 +1190,18 @@ zfs_mkdir(znode_t *dzp, char *dirname, vattr_t *vap, znode_t **zpp,
if (dirname == NULL) if (dirname == NULL)
return (SET_ERROR(EINVAL)); return (SET_ERROR(EINVAL));
ZFS_ENTER(zfsvfs); if ((error = zfs_enter_verify_zp(zfsvfs, dzp, FTAG)) != 0)
ZFS_VERIFY_ZP(dzp); return (error);
zilog = zfsvfs->z_log; zilog = zfsvfs->z_log;
if (dzp->z_pflags & ZFS_XATTR) { if (dzp->z_pflags & ZFS_XATTR) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(EINVAL)); return (SET_ERROR(EINVAL));
} }
if (zfsvfs->z_utf8 && u8_validate(dirname, if (zfsvfs->z_utf8 && u8_validate(dirname,
strlen(dirname), NULL, U8_VALIDATE_ENTIRE, &error) < 0) { strlen(dirname), NULL, U8_VALIDATE_ENTIRE, &error) < 0) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(EILSEQ)); return (SET_ERROR(EILSEQ));
} }
if (flags & FIGNORECASE) if (flags & FIGNORECASE)
@ -1208,14 +1210,14 @@ zfs_mkdir(znode_t *dzp, char *dirname, vattr_t *vap, znode_t **zpp,
if (vap->va_mask & ATTR_XVATTR) { if (vap->va_mask & ATTR_XVATTR) {
if ((error = secpolicy_xvattr((xvattr_t *)vap, if ((error = secpolicy_xvattr((xvattr_t *)vap,
crgetuid(cr), cr, vap->va_mode)) != 0) { crgetuid(cr), cr, vap->va_mode)) != 0) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
} }
if ((error = zfs_acl_ids_create(dzp, 0, vap, cr, if ((error = zfs_acl_ids_create(dzp, 0, vap, cr,
vsecp, &acl_ids)) != 0) { vsecp, &acl_ids)) != 0) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
/* /*
@ -1231,21 +1233,21 @@ top:
if ((error = zfs_dirent_lock(&dl, dzp, dirname, &zp, zf, if ((error = zfs_dirent_lock(&dl, dzp, dirname, &zp, zf,
NULL, NULL))) { NULL, NULL))) {
zfs_acl_ids_free(&acl_ids); zfs_acl_ids_free(&acl_ids);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
if ((error = zfs_zaccess(dzp, ACE_ADD_SUBDIRECTORY, 0, B_FALSE, cr))) { if ((error = zfs_zaccess(dzp, ACE_ADD_SUBDIRECTORY, 0, B_FALSE, cr))) {
zfs_acl_ids_free(&acl_ids); zfs_acl_ids_free(&acl_ids);
zfs_dirent_unlock(dl); zfs_dirent_unlock(dl);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
if (zfs_acl_ids_overquota(zfsvfs, &acl_ids, zfs_inherit_projid(dzp))) { if (zfs_acl_ids_overquota(zfsvfs, &acl_ids, zfs_inherit_projid(dzp))) {
zfs_acl_ids_free(&acl_ids); zfs_acl_ids_free(&acl_ids);
zfs_dirent_unlock(dl); zfs_dirent_unlock(dl);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(EDQUOT)); return (SET_ERROR(EDQUOT));
} }
@ -1277,7 +1279,7 @@ top:
} }
zfs_acl_ids_free(&acl_ids); zfs_acl_ids_free(&acl_ids);
dmu_tx_abort(tx); dmu_tx_abort(tx);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
@ -1323,7 +1325,7 @@ out:
zfs_znode_update_vfs(dzp); zfs_znode_update_vfs(dzp);
zfs_znode_update_vfs(zp); zfs_znode_update_vfs(zp);
} }
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
@ -1359,8 +1361,8 @@ zfs_rmdir(znode_t *dzp, char *name, znode_t *cwd, cred_t *cr,
if (name == NULL) if (name == NULL)
return (SET_ERROR(EINVAL)); return (SET_ERROR(EINVAL));
ZFS_ENTER(zfsvfs); if ((error = zfs_enter_verify_zp(zfsvfs, dzp, FTAG)) != 0)
ZFS_VERIFY_ZP(dzp); return (error);
zilog = zfsvfs->z_log; zilog = zfsvfs->z_log;
if (flags & FIGNORECASE) if (flags & FIGNORECASE)
@ -1373,7 +1375,7 @@ top:
*/ */
if ((error = zfs_dirent_lock(&dl, dzp, name, &zp, zflg, if ((error = zfs_dirent_lock(&dl, dzp, name, &zp, zflg,
NULL, NULL))) { NULL, NULL))) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
@ -1424,7 +1426,7 @@ top:
} }
dmu_tx_abort(tx); dmu_tx_abort(tx);
zrele(zp); zrele(zp);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
@ -1452,7 +1454,7 @@ out:
if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
zil_commit(zilog, 0); zil_commit(zilog, 0);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
@ -1491,8 +1493,8 @@ zfs_readdir(struct inode *ip, zpl_dir_context_t *ctx, cred_t *cr)
uint64_t parent; uint64_t parent;
uint64_t offset; /* must be unsigned; checks for < 1 */ uint64_t offset; /* must be unsigned; checks for < 1 */
ZFS_ENTER(zfsvfs); if ((error = zfs_enter_verify_zp(zfsvfs, zp, FTAG)) != 0)
ZFS_VERIFY_ZP(zp); return (error);
if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_PARENT(zfsvfs), if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_PARENT(zfsvfs),
&parent, sizeof (parent))) != 0) &parent, sizeof (parent))) != 0)
@ -1611,7 +1613,7 @@ update:
if (error == ENOENT) if (error == ENOENT)
error = 0; error = 0;
out: out:
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
@ -1636,9 +1638,10 @@ zfs_getattr_fast(struct user_namespace *user_ns, struct inode *ip,
zfsvfs_t *zfsvfs = ITOZSB(ip); zfsvfs_t *zfsvfs = ITOZSB(ip);
uint32_t blksize; uint32_t blksize;
u_longlong_t nblocks; u_longlong_t nblocks;
int error;
ZFS_ENTER(zfsvfs); if ((error = zfs_enter_verify_zp(zfsvfs, zp, FTAG)) != 0)
ZFS_VERIFY_ZP(zp); return (error);
mutex_enter(&zp->z_lock); mutex_enter(&zp->z_lock);
@ -1673,7 +1676,7 @@ zfs_getattr_fast(struct user_namespace *user_ns, struct inode *ip,
dmu_objset_id(zfsvfs->z_os); dmu_objset_id(zfsvfs->z_os);
} }
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (0); return (0);
} }
@ -1849,8 +1852,8 @@ zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr)
if (mask == 0) if (mask == 0)
return (0); return (0);
ZFS_ENTER(zfsvfs); if ((err = zfs_enter_verify_zp(zfsvfs, zp, FTAG)) != 0)
ZFS_VERIFY_ZP(zp); return (err);
ip = ZTOI(zp); ip = ZTOI(zp);
/* /*
@ -1862,13 +1865,13 @@ zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr)
if (XVA_ISSET_REQ(xvap, XAT_PROJID)) { if (XVA_ISSET_REQ(xvap, XAT_PROJID)) {
if (!dmu_objset_projectquota_enabled(os) || if (!dmu_objset_projectquota_enabled(os) ||
(!S_ISREG(ip->i_mode) && !S_ISDIR(ip->i_mode))) { (!S_ISREG(ip->i_mode) && !S_ISDIR(ip->i_mode))) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(ENOTSUP)); return (SET_ERROR(ENOTSUP));
} }
projid = xoap->xoa_projid; projid = xoap->xoa_projid;
if (unlikely(projid == ZFS_INVALID_PROJID)) { if (unlikely(projid == ZFS_INVALID_PROJID)) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(EINVAL)); return (SET_ERROR(EINVAL));
} }
@ -1883,7 +1886,7 @@ zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr)
((zp->z_pflags & ZFS_PROJINHERIT) != 0)) && ((zp->z_pflags & ZFS_PROJINHERIT) != 0)) &&
(!dmu_objset_projectquota_enabled(os) || (!dmu_objset_projectquota_enabled(os) ||
(!S_ISREG(ip->i_mode) && !S_ISDIR(ip->i_mode)))) { (!S_ISREG(ip->i_mode) && !S_ISDIR(ip->i_mode)))) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(ENOTSUP)); return (SET_ERROR(ENOTSUP));
} }
} }
@ -1899,17 +1902,17 @@ zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr)
(((mask & ATTR_UID) && IS_EPHEMERAL(vap->va_uid)) || (((mask & ATTR_UID) && IS_EPHEMERAL(vap->va_uid)) ||
((mask & ATTR_GID) && IS_EPHEMERAL(vap->va_gid)) || ((mask & ATTR_GID) && IS_EPHEMERAL(vap->va_gid)) ||
(mask & ATTR_XVATTR))) { (mask & ATTR_XVATTR))) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(EINVAL)); return (SET_ERROR(EINVAL));
} }
if (mask & ATTR_SIZE && S_ISDIR(ip->i_mode)) { if (mask & ATTR_SIZE && S_ISDIR(ip->i_mode)) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(EISDIR)); return (SET_ERROR(EISDIR));
} }
if (mask & ATTR_SIZE && !S_ISREG(ip->i_mode) && !S_ISFIFO(ip->i_mode)) { if (mask & ATTR_SIZE && !S_ISREG(ip->i_mode) && !S_ISFIFO(ip->i_mode)) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(EINVAL)); return (SET_ERROR(EINVAL));
} }
@ -2526,7 +2529,7 @@ out3:
kmem_free(xattr_bulk, sizeof (sa_bulk_attr_t) * bulks); kmem_free(xattr_bulk, sizeof (sa_bulk_attr_t) * bulks);
kmem_free(bulk, sizeof (sa_bulk_attr_t) * bulks); kmem_free(bulk, sizeof (sa_bulk_attr_t) * bulks);
kmem_free(tmpxvattr, sizeof (xvattr_t)); kmem_free(tmpxvattr, sizeof (xvattr_t));
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (err); return (err);
} }
@ -2661,11 +2664,14 @@ zfs_rename(znode_t *sdzp, char *snm, znode_t *tdzp, char *tnm,
if (snm == NULL || tnm == NULL) if (snm == NULL || tnm == NULL)
return (SET_ERROR(EINVAL)); return (SET_ERROR(EINVAL));
ZFS_ENTER(zfsvfs); if ((error = zfs_enter_verify_zp(zfsvfs, sdzp, FTAG)) != 0)
ZFS_VERIFY_ZP(sdzp); return (error);
zilog = zfsvfs->z_log; zilog = zfsvfs->z_log;
ZFS_VERIFY_ZP(tdzp); if ((error = zfs_verify_zp(tdzp)) != 0) {
zfs_exit(zfsvfs, FTAG);
return (error);
}
/* /*
* We check i_sb because snapshots and the ctldir must have different * We check i_sb because snapshots and the ctldir must have different
@ -2673,13 +2679,13 @@ zfs_rename(znode_t *sdzp, char *snm, znode_t *tdzp, char *tnm,
*/ */
if (ZTOI(tdzp)->i_sb != ZTOI(sdzp)->i_sb || if (ZTOI(tdzp)->i_sb != ZTOI(sdzp)->i_sb ||
zfsctl_is_node(ZTOI(tdzp))) { zfsctl_is_node(ZTOI(tdzp))) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(EXDEV)); return (SET_ERROR(EXDEV));
} }
if (zfsvfs->z_utf8 && u8_validate(tnm, if (zfsvfs->z_utf8 && u8_validate(tnm,
strlen(tnm), NULL, U8_VALIDATE_ENTIRE, &error) < 0) { strlen(tnm), NULL, U8_VALIDATE_ENTIRE, &error) < 0) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(EILSEQ)); return (SET_ERROR(EILSEQ));
} }
@ -2697,7 +2703,7 @@ top:
* See the comment in zfs_link() for why this is considered bad. * See the comment in zfs_link() for why this is considered bad.
*/ */
if ((tdzp->z_pflags & ZFS_XATTR) != (sdzp->z_pflags & ZFS_XATTR)) { if ((tdzp->z_pflags & ZFS_XATTR) != (sdzp->z_pflags & ZFS_XATTR)) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(EINVAL)); return (SET_ERROR(EINVAL));
} }
@ -2727,7 +2733,7 @@ top:
* the rename() function shall return successfully * the rename() function shall return successfully
* and perform no other action." * and perform no other action."
*/ */
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (0); return (0);
} }
/* /*
@ -2799,7 +2805,7 @@ top:
if (strcmp(snm, "..") == 0) if (strcmp(snm, "..") == 0)
serr = EINVAL; serr = EINVAL;
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (serr); return (serr);
} }
if (terr) { if (terr) {
@ -2811,7 +2817,7 @@ top:
if (strcmp(tnm, "..") == 0) if (strcmp(tnm, "..") == 0)
terr = EINVAL; terr = EINVAL;
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (terr); return (terr);
} }
@ -2915,7 +2921,7 @@ top:
zrele(szp); zrele(szp);
if (tzp) if (tzp)
zrele(tzp); zrele(tzp);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
@ -2989,7 +2995,7 @@ out:
if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
zil_commit(zilog, 0); zil_commit(zilog, 0);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
@ -3032,26 +3038,26 @@ zfs_symlink(znode_t *dzp, char *name, vattr_t *vap, char *link,
if (name == NULL) if (name == NULL)
return (SET_ERROR(EINVAL)); return (SET_ERROR(EINVAL));
ZFS_ENTER(zfsvfs); if ((error = zfs_enter_verify_zp(zfsvfs, dzp, FTAG)) != 0)
ZFS_VERIFY_ZP(dzp); return (error);
zilog = zfsvfs->z_log; zilog = zfsvfs->z_log;
if (zfsvfs->z_utf8 && u8_validate(name, strlen(name), if (zfsvfs->z_utf8 && u8_validate(name, strlen(name),
NULL, U8_VALIDATE_ENTIRE, &error) < 0) { NULL, U8_VALIDATE_ENTIRE, &error) < 0) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(EILSEQ)); return (SET_ERROR(EILSEQ));
} }
if (flags & FIGNORECASE) if (flags & FIGNORECASE)
zflg |= ZCILOOK; zflg |= ZCILOOK;
if (len > MAXPATHLEN) { if (len > MAXPATHLEN) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(ENAMETOOLONG)); return (SET_ERROR(ENAMETOOLONG));
} }
if ((error = zfs_acl_ids_create(dzp, 0, if ((error = zfs_acl_ids_create(dzp, 0,
vap, cr, NULL, &acl_ids)) != 0) { vap, cr, NULL, &acl_ids)) != 0) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
top: top:
@ -3063,21 +3069,21 @@ top:
error = zfs_dirent_lock(&dl, dzp, name, &zp, zflg, NULL, NULL); error = zfs_dirent_lock(&dl, dzp, name, &zp, zflg, NULL, NULL);
if (error) { if (error) {
zfs_acl_ids_free(&acl_ids); zfs_acl_ids_free(&acl_ids);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr))) { if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr))) {
zfs_acl_ids_free(&acl_ids); zfs_acl_ids_free(&acl_ids);
zfs_dirent_unlock(dl); zfs_dirent_unlock(dl);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
if (zfs_acl_ids_overquota(zfsvfs, &acl_ids, ZFS_DEFAULT_PROJID)) { if (zfs_acl_ids_overquota(zfsvfs, &acl_ids, ZFS_DEFAULT_PROJID)) {
zfs_acl_ids_free(&acl_ids); zfs_acl_ids_free(&acl_ids);
zfs_dirent_unlock(dl); zfs_dirent_unlock(dl);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(EDQUOT)); return (SET_ERROR(EDQUOT));
} }
tx = dmu_tx_create(zfsvfs->z_os); tx = dmu_tx_create(zfsvfs->z_os);
@ -3104,7 +3110,7 @@ top:
} }
zfs_acl_ids_free(&acl_ids); zfs_acl_ids_free(&acl_ids);
dmu_tx_abort(tx); dmu_tx_abort(tx);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
@ -3159,7 +3165,7 @@ top:
zrele(zp); zrele(zp);
} }
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
@ -3185,8 +3191,8 @@ zfs_readlink(struct inode *ip, zfs_uio_t *uio, cred_t *cr)
zfsvfs_t *zfsvfs = ITOZSB(ip); zfsvfs_t *zfsvfs = ITOZSB(ip);
int error; int error;
ZFS_ENTER(zfsvfs); if ((error = zfs_enter_verify_zp(zfsvfs, zp, FTAG)) != 0)
ZFS_VERIFY_ZP(zp); return (error);
mutex_enter(&zp->z_lock); mutex_enter(&zp->z_lock);
if (zp->z_is_sa) if (zp->z_is_sa)
@ -3196,7 +3202,7 @@ zfs_readlink(struct inode *ip, zfs_uio_t *uio, cred_t *cr)
error = zfs_sa_readlink(zp, uio); error = zfs_sa_readlink(zp, uio);
mutex_exit(&zp->z_lock); mutex_exit(&zp->z_lock);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
@ -3241,8 +3247,8 @@ zfs_link(znode_t *tdzp, znode_t *szp, char *name, cred_t *cr,
if (name == NULL) if (name == NULL)
return (SET_ERROR(EINVAL)); return (SET_ERROR(EINVAL));
ZFS_ENTER(zfsvfs); if ((error = zfs_enter_verify_zp(zfsvfs, tdzp, FTAG)) != 0)
ZFS_VERIFY_ZP(tdzp); return (error);
zilog = zfsvfs->z_log; zilog = zfsvfs->z_log;
/* /*
@ -3250,11 +3256,14 @@ zfs_link(znode_t *tdzp, znode_t *szp, char *name, cred_t *cr,
* Better choices include ENOTSUP or EISDIR. * Better choices include ENOTSUP or EISDIR.
*/ */
if (S_ISDIR(sip->i_mode)) { if (S_ISDIR(sip->i_mode)) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(EPERM)); return (SET_ERROR(EPERM));
} }
ZFS_VERIFY_ZP(szp); if ((error = zfs_verify_zp(szp)) != 0) {
zfs_exit(zfsvfs, FTAG);
return (error);
}
/* /*
* If we are using project inheritance, means if the directory has * If we are using project inheritance, means if the directory has
@ -3265,7 +3274,7 @@ zfs_link(znode_t *tdzp, znode_t *szp, char *name, cred_t *cr,
*/ */
if (tdzp->z_pflags & ZFS_PROJINHERIT && if (tdzp->z_pflags & ZFS_PROJINHERIT &&
tdzp->z_projid != szp->z_projid) { tdzp->z_projid != szp->z_projid) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(EXDEV)); return (SET_ERROR(EXDEV));
} }
@ -3274,7 +3283,7 @@ zfs_link(znode_t *tdzp, znode_t *szp, char *name, cred_t *cr,
* super blocks. * super blocks.
*/ */
if (sip->i_sb != ZTOI(tdzp)->i_sb || zfsctl_is_node(sip)) { if (sip->i_sb != ZTOI(tdzp)->i_sb || zfsctl_is_node(sip)) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(EXDEV)); return (SET_ERROR(EXDEV));
} }
@ -3282,17 +3291,17 @@ zfs_link(znode_t *tdzp, znode_t *szp, char *name, cred_t *cr,
if ((error = sa_lookup(szp->z_sa_hdl, SA_ZPL_PARENT(zfsvfs), if ((error = sa_lookup(szp->z_sa_hdl, SA_ZPL_PARENT(zfsvfs),
&parent, sizeof (uint64_t))) != 0) { &parent, sizeof (uint64_t))) != 0) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
if (parent == zfsvfs->z_shares_dir) { if (parent == zfsvfs->z_shares_dir) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(EPERM)); return (SET_ERROR(EPERM));
} }
if (zfsvfs->z_utf8 && u8_validate(name, if (zfsvfs->z_utf8 && u8_validate(name,
strlen(name), NULL, U8_VALIDATE_ENTIRE, &error) < 0) { strlen(name), NULL, U8_VALIDATE_ENTIRE, &error) < 0) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(EILSEQ)); return (SET_ERROR(EILSEQ));
} }
if (flags & FIGNORECASE) if (flags & FIGNORECASE)
@ -3305,19 +3314,19 @@ zfs_link(znode_t *tdzp, znode_t *szp, char *name, cred_t *cr,
* imposed in attribute space. * imposed in attribute space.
*/ */
if ((szp->z_pflags & ZFS_XATTR) != (tdzp->z_pflags & ZFS_XATTR)) { if ((szp->z_pflags & ZFS_XATTR) != (tdzp->z_pflags & ZFS_XATTR)) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(EINVAL)); return (SET_ERROR(EINVAL));
} }
owner = zfs_fuid_map_id(zfsvfs, KUID_TO_SUID(sip->i_uid), owner = zfs_fuid_map_id(zfsvfs, KUID_TO_SUID(sip->i_uid),
cr, ZFS_OWNER); cr, ZFS_OWNER);
if (owner != crgetuid(cr) && secpolicy_basic_link(cr) != 0) { if (owner != crgetuid(cr) && secpolicy_basic_link(cr) != 0) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(EPERM)); return (SET_ERROR(EPERM));
} }
if ((error = zfs_zaccess(tdzp, ACE_ADD_FILE, 0, B_FALSE, cr))) { if ((error = zfs_zaccess(tdzp, ACE_ADD_FILE, 0, B_FALSE, cr))) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
@ -3327,7 +3336,7 @@ top:
*/ */
error = zfs_dirent_lock(&dl, tdzp, name, &tzp, zf, NULL, NULL); error = zfs_dirent_lock(&dl, tdzp, name, &tzp, zf, NULL, NULL);
if (error) { if (error) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
@ -3349,7 +3358,7 @@ top:
goto top; goto top;
} }
dmu_tx_abort(tx); dmu_tx_abort(tx);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
/* unmark z_unlinked so zfs_link_create will not reject */ /* unmark z_unlinked so zfs_link_create will not reject */
@ -3391,7 +3400,7 @@ top:
zfs_znode_update_vfs(tdzp); zfs_znode_update_vfs(tdzp);
zfs_znode_update_vfs(szp); zfs_znode_update_vfs(szp);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
@ -3448,8 +3457,8 @@ zfs_putpage(struct inode *ip, struct page *pp, struct writeback_control *wbc,
int cnt = 0; int cnt = 0;
struct address_space *mapping; struct address_space *mapping;
ZFS_ENTER(zfsvfs); if ((err = zfs_enter_verify_zp(zfsvfs, zp, FTAG)) != 0)
ZFS_VERIFY_ZP(zp); return (err);
ASSERT(PageLocked(pp)); ASSERT(PageLocked(pp));
@ -3461,7 +3470,7 @@ zfs_putpage(struct inode *ip, struct page *pp, struct writeback_control *wbc,
/* Page is beyond end of file */ /* Page is beyond end of file */
if (pgoff >= offset) { if (pgoff >= offset) {
unlock_page(pp); unlock_page(pp);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (0); return (0);
} }
@ -3521,7 +3530,7 @@ zfs_putpage(struct inode *ip, struct page *pp, struct writeback_control *wbc,
if (unlikely((mapping != pp->mapping) || !PageDirty(pp))) { if (unlikely((mapping != pp->mapping) || !PageDirty(pp))) {
unlock_page(pp); unlock_page(pp);
zfs_rangelock_exit(lr); zfs_rangelock_exit(lr);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (0); return (0);
} }
@ -3549,7 +3558,7 @@ zfs_putpage(struct inode *ip, struct page *pp, struct writeback_control *wbc,
#endif #endif
} }
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (0); return (0);
} }
@ -3557,7 +3566,7 @@ zfs_putpage(struct inode *ip, struct page *pp, struct writeback_control *wbc,
if (!clear_page_dirty_for_io(pp)) { if (!clear_page_dirty_for_io(pp)) {
unlock_page(pp); unlock_page(pp);
zfs_rangelock_exit(lr); zfs_rangelock_exit(lr);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (0); return (0);
} }
@ -3592,7 +3601,7 @@ zfs_putpage(struct inode *ip, struct page *pp, struct writeback_control *wbc,
if (!for_sync) if (!for_sync)
atomic_dec_32(&zp->z_async_writes_cnt); atomic_dec_32(&zp->z_async_writes_cnt);
zfs_rangelock_exit(lr); zfs_rangelock_exit(lr);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (err); return (err);
} }
@ -3643,7 +3652,7 @@ zfs_putpage(struct inode *ip, struct page *pp, struct writeback_control *wbc,
dataset_kstats_update_write_kstats(&zfsvfs->z_kstat, pglen); dataset_kstats_update_write_kstats(&zfsvfs->z_kstat, pglen);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (err); return (err);
} }
@ -3665,8 +3674,8 @@ zfs_dirty_inode(struct inode *ip, int flags)
if (zfs_is_readonly(zfsvfs) || dmu_objset_is_snapshot(zfsvfs->z_os)) if (zfs_is_readonly(zfsvfs) || dmu_objset_is_snapshot(zfsvfs->z_os))
return (0); return (0);
ZFS_ENTER(zfsvfs); if ((error = zfs_enter_verify_zp(zfsvfs, zp, FTAG)) != 0)
ZFS_VERIFY_ZP(zp); return (error);
#ifdef I_DIRTY_TIME #ifdef I_DIRTY_TIME
/* /*
@ -3714,7 +3723,7 @@ zfs_dirty_inode(struct inode *ip, int flags)
dmu_tx_commit(tx); dmu_tx_commit(tx);
out: out:
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
@ -3831,14 +3840,14 @@ zfs_getpage(struct inode *ip, struct page *pl[], int nr_pages)
if (pl == NULL) if (pl == NULL)
return (0); return (0);
ZFS_ENTER(zfsvfs); if ((err = zfs_enter_verify_zp(zfsvfs, zp, FTAG)) != 0)
ZFS_VERIFY_ZP(zp); return (err);
err = zfs_fillpage(ip, pl, nr_pages); err = zfs_fillpage(ip, pl, nr_pages);
dataset_kstats_update_read_kstats(&zfsvfs->z_kstat, nr_pages*PAGESIZE); dataset_kstats_update_read_kstats(&zfsvfs->z_kstat, nr_pages*PAGESIZE);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (err); return (err);
} }
@ -3861,28 +3870,29 @@ zfs_map(struct inode *ip, offset_t off, caddr_t *addrp, size_t len,
(void) addrp; (void) addrp;
znode_t *zp = ITOZ(ip); znode_t *zp = ITOZ(ip);
zfsvfs_t *zfsvfs = ITOZSB(ip); zfsvfs_t *zfsvfs = ITOZSB(ip);
int error;
ZFS_ENTER(zfsvfs); if ((error = zfs_enter_verify_zp(zfsvfs, zp, FTAG)) != 0)
ZFS_VERIFY_ZP(zp); return (error);
if ((vm_flags & VM_WRITE) && (zp->z_pflags & if ((vm_flags & VM_WRITE) && (zp->z_pflags &
(ZFS_IMMUTABLE | ZFS_READONLY | ZFS_APPENDONLY))) { (ZFS_IMMUTABLE | ZFS_READONLY | ZFS_APPENDONLY))) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(EPERM)); return (SET_ERROR(EPERM));
} }
if ((vm_flags & (VM_READ | VM_EXEC)) && if ((vm_flags & (VM_READ | VM_EXEC)) &&
(zp->z_pflags & ZFS_AV_QUARANTINED)) { (zp->z_pflags & ZFS_AV_QUARANTINED)) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(EACCES)); return (SET_ERROR(EACCES));
} }
if (off < 0 || len > MAXOFFSET_T - off) { if (off < 0 || len > MAXOFFSET_T - off) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(ENXIO)); return (SET_ERROR(ENXIO));
} }
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (0); return (0);
} }
@ -3913,11 +3923,11 @@ zfs_space(znode_t *zp, int cmd, flock64_t *bfp, int flag,
uint64_t off, len; uint64_t off, len;
int error; int error;
ZFS_ENTER(zfsvfs); if ((error = zfs_enter_verify_zp(zfsvfs, zp, FTAG)) != 0)
ZFS_VERIFY_ZP(zp); return (error);
if (cmd != F_FREESP) { if (cmd != F_FREESP) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(EINVAL)); return (SET_ERROR(EINVAL));
} }
@ -3926,12 +3936,12 @@ zfs_space(znode_t *zp, int cmd, flock64_t *bfp, int flag,
* so check it explicitly here. * so check it explicitly here.
*/ */
if (zfs_is_readonly(zfsvfs)) { if (zfs_is_readonly(zfsvfs)) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(EROFS)); return (SET_ERROR(EROFS));
} }
if (bfp->l_len < 0) { if (bfp->l_len < 0) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(EINVAL)); return (SET_ERROR(EINVAL));
} }
@ -3942,7 +3952,7 @@ zfs_space(znode_t *zp, int cmd, flock64_t *bfp, int flag,
* operates directly on inodes, so we need to check access rights. * operates directly on inodes, so we need to check access rights.
*/ */
if ((error = zfs_zaccess(zp, ACE_WRITE_DATA, 0, B_FALSE, cr))) { if ((error = zfs_zaccess(zp, ACE_WRITE_DATA, 0, B_FALSE, cr))) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
@ -3951,7 +3961,7 @@ zfs_space(znode_t *zp, int cmd, flock64_t *bfp, int flag,
error = zfs_freesp(zp, off, len, flag, TRUE); error = zfs_freesp(zp, off, len, flag, TRUE);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
@ -3966,19 +3976,23 @@ zfs_fid(struct inode *ip, fid_t *fidp)
zfid_short_t *zfid; zfid_short_t *zfid;
int size, i, error; int size, i, error;
ZFS_ENTER(zfsvfs); if ((error = zfs_enter(zfsvfs, FTAG)) != 0)
return (error);
if (fidp->fid_len < SHORT_FID_LEN) { if (fidp->fid_len < SHORT_FID_LEN) {
fidp->fid_len = SHORT_FID_LEN; fidp->fid_len = SHORT_FID_LEN;
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(ENOSPC)); return (SET_ERROR(ENOSPC));
} }
ZFS_VERIFY_ZP(zp); if ((error = zfs_verify_zp(zp)) != 0) {
zfs_exit(zfsvfs, FTAG);
return (error);
}
if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_GEN(zfsvfs), if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_GEN(zfsvfs),
&gen64, sizeof (uint64_t))) != 0) { &gen64, sizeof (uint64_t))) != 0) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
@ -3999,7 +4013,7 @@ zfs_fid(struct inode *ip, fid_t *fidp)
for (i = 0; i < sizeof (zfid->zf_gen); i++) for (i = 0; i < sizeof (zfid->zf_gen); i++)
zfid->zf_gen[i] = (uint8_t)(gen >> (8 * i)); zfid->zf_gen[i] = (uint8_t)(gen >> (8 * i));
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (0); return (0);
} }

View File

@ -57,7 +57,8 @@ zpl_root_iterate(struct file *filp, zpl_dir_context_t *ctx)
zfsvfs_t *zfsvfs = ITOZSB(file_inode(filp)); zfsvfs_t *zfsvfs = ITOZSB(file_inode(filp));
int error = 0; int error = 0;
ZPL_ENTER(zfsvfs); if ((error = zpl_enter(zfsvfs, FTAG)) != 0)
return (error);
if (!zpl_dir_emit_dots(filp, ctx)) if (!zpl_dir_emit_dots(filp, ctx))
goto out; goto out;
@ -78,7 +79,7 @@ zpl_root_iterate(struct file *filp, zpl_dir_context_t *ctx)
ctx->pos++; ctx->pos++;
} }
out: out:
ZPL_EXIT(zfsvfs); zpl_exit(zfsvfs, FTAG);
return (error); return (error);
} }
@ -258,7 +259,8 @@ zpl_snapdir_iterate(struct file *filp, zpl_dir_context_t *ctx)
uint64_t id, pos; uint64_t id, pos;
int error = 0; int error = 0;
ZPL_ENTER(zfsvfs); if ((error = zpl_enter(zfsvfs, FTAG)) != 0)
return (error);
cookie = spl_fstrans_mark(); cookie = spl_fstrans_mark();
if (!zpl_dir_emit_dots(filp, ctx)) if (!zpl_dir_emit_dots(filp, ctx))
@ -282,7 +284,7 @@ zpl_snapdir_iterate(struct file *filp, zpl_dir_context_t *ctx)
} }
out: out:
spl_fstrans_unmark(cookie); spl_fstrans_unmark(cookie);
ZPL_EXIT(zfsvfs); zpl_exit(zfsvfs, FTAG);
if (error == -ENOENT) if (error == -ENOENT)
return (0); return (0);
@ -401,8 +403,10 @@ zpl_snapdir_getattr_impl(const struct path *path, struct kstat *stat,
(void) request_mask, (void) query_flags; (void) request_mask, (void) query_flags;
struct inode *ip = path->dentry->d_inode; struct inode *ip = path->dentry->d_inode;
zfsvfs_t *zfsvfs = ITOZSB(ip); zfsvfs_t *zfsvfs = ITOZSB(ip);
int error;
ZPL_ENTER(zfsvfs); if ((error = zpl_enter(zfsvfs, FTAG)) != 0)
return (error);
#ifdef HAVE_USERNS_IOPS_GETATTR #ifdef HAVE_USERNS_IOPS_GETATTR
#ifdef HAVE_GENERIC_FILLATTR_USERNS #ifdef HAVE_GENERIC_FILLATTR_USERNS
generic_fillattr(user_ns, ip, stat); generic_fillattr(user_ns, ip, stat);
@ -422,7 +426,7 @@ zpl_snapdir_getattr_impl(const struct path *path, struct kstat *stat,
dmu_objset_pool(ds->ds_objset)->dp_meta_objset, dmu_objset_pool(ds->ds_objset)->dp_meta_objset,
dsl_dataset_phys(ds)->ds_snapnames_zapobj, &snap_count); dsl_dataset_phys(ds)->ds_snapnames_zapobj, &snap_count);
if (err != 0) { if (err != 0) {
ZPL_EXIT(zfsvfs); zpl_exit(zfsvfs, FTAG);
return (-err); return (-err);
} }
stat->nlink += snap_count; stat->nlink += snap_count;
@ -430,7 +434,7 @@ zpl_snapdir_getattr_impl(const struct path *path, struct kstat *stat,
stat->ctime = stat->mtime = dmu_objset_snap_cmtime(zfsvfs->z_os); stat->ctime = stat->mtime = dmu_objset_snap_cmtime(zfsvfs->z_os);
stat->atime = current_time(ip); stat->atime = current_time(ip);
ZPL_EXIT(zfsvfs); zpl_exit(zfsvfs, FTAG);
return (0); return (0);
} }
@ -508,7 +512,8 @@ zpl_shares_iterate(struct file *filp, zpl_dir_context_t *ctx)
znode_t *dzp; znode_t *dzp;
int error = 0; int error = 0;
ZPL_ENTER(zfsvfs); if ((error = zpl_enter(zfsvfs, FTAG)) != 0)
return (error);
cookie = spl_fstrans_mark(); cookie = spl_fstrans_mark();
if (zfsvfs->z_shares_dir == 0) { if (zfsvfs->z_shares_dir == 0) {
@ -527,7 +532,7 @@ zpl_shares_iterate(struct file *filp, zpl_dir_context_t *ctx)
iput(ZTOI(dzp)); iput(ZTOI(dzp));
out: out:
spl_fstrans_unmark(cookie); spl_fstrans_unmark(cookie);
ZPL_EXIT(zfsvfs); zpl_exit(zfsvfs, FTAG);
ASSERT3S(error, <=, 0); ASSERT3S(error, <=, 0);
return (error); return (error);
@ -564,7 +569,8 @@ zpl_shares_getattr_impl(const struct path *path, struct kstat *stat,
znode_t *dzp; znode_t *dzp;
int error; int error;
ZPL_ENTER(zfsvfs); if ((error = zpl_enter(zfsvfs, FTAG)) != 0)
return (error);
if (zfsvfs->z_shares_dir == 0) { if (zfsvfs->z_shares_dir == 0) {
#ifdef HAVE_USERNS_IOPS_GETATTR #ifdef HAVE_USERNS_IOPS_GETATTR
@ -578,7 +584,7 @@ zpl_shares_getattr_impl(const struct path *path, struct kstat *stat,
#endif #endif
stat->nlink = stat->size = 2; stat->nlink = stat->size = 2;
stat->atime = current_time(ip); stat->atime = current_time(ip);
ZPL_EXIT(zfsvfs); zpl_exit(zfsvfs, FTAG);
return (0); return (0);
} }
@ -596,7 +602,7 @@ zpl_shares_getattr_impl(const struct path *path, struct kstat *stat,
iput(ZTOI(dzp)); iput(ZTOI(dzp));
} }
ZPL_EXIT(zfsvfs); zpl_exit(zfsvfs, FTAG);
ASSERT3S(error, <=, 0); ASSERT3S(error, <=, 0);
return (error); return (error);

View File

@ -195,9 +195,12 @@ zpl_fsync(struct file *filp, loff_t start, loff_t end, int datasync)
* zfs_putpage() respectively. * zfs_putpage() respectively.
*/ */
if (atomic_load_32(&zp->z_async_writes_cnt) > 0) { if (atomic_load_32(&zp->z_async_writes_cnt) > 0) {
ZPL_ENTER(zfsvfs); if ((error = zpl_enter(zfsvfs, FTAG)) != 0) {
atomic_dec_32(&zp->z_sync_writes_cnt);
return (error);
}
zil_commit(zfsvfs->z_log, zp->z_id); zil_commit(zfsvfs->z_log, zp->z_id);
ZPL_EXIT(zfsvfs); zpl_exit(zfsvfs, FTAG);
} }
error = filemap_write_and_wait_range(inode->i_mapping, start, end); error = filemap_write_and_wait_range(inode->i_mapping, start, end);
@ -752,10 +755,11 @@ zpl_writepages(struct address_space *mapping, struct writeback_control *wbc)
enum writeback_sync_modes sync_mode; enum writeback_sync_modes sync_mode;
int result; int result;
ZPL_ENTER(zfsvfs); if ((result = zpl_enter(zfsvfs, FTAG)) != 0)
return (result);
if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
wbc->sync_mode = WB_SYNC_ALL; wbc->sync_mode = WB_SYNC_ALL;
ZPL_EXIT(zfsvfs); zpl_exit(zfsvfs, FTAG);
sync_mode = wbc->sync_mode; sync_mode = wbc->sync_mode;
/* /*
@ -769,11 +773,11 @@ zpl_writepages(struct address_space *mapping, struct writeback_control *wbc)
wbc->sync_mode = WB_SYNC_NONE; wbc->sync_mode = WB_SYNC_NONE;
result = write_cache_pages(mapping, wbc, zpl_putpage, &for_sync); result = write_cache_pages(mapping, wbc, zpl_putpage, &for_sync);
if (sync_mode != wbc->sync_mode) { if (sync_mode != wbc->sync_mode) {
ZPL_ENTER(zfsvfs); if ((result = zpl_enter_verify_zp(zfsvfs, zp, FTAG)) != 0)
ZPL_VERIFY_ZP(zp); return (result);
if (zfsvfs->z_log != NULL) if (zfsvfs->z_log != NULL)
zil_commit(zfsvfs->z_log, zp->z_id); zil_commit(zfsvfs->z_log, zp->z_id);
ZPL_EXIT(zfsvfs); zpl_exit(zfsvfs, FTAG);
/* /*
* We need to call write_cache_pages() again (we can't just * We need to call write_cache_pages() again (we can't just

View File

@ -185,7 +185,9 @@ zpl_remount_fs(struct super_block *sb, int *flags, char *data)
static int static int
__zpl_show_devname(struct seq_file *seq, zfsvfs_t *zfsvfs) __zpl_show_devname(struct seq_file *seq, zfsvfs_t *zfsvfs)
{ {
ZPL_ENTER(zfsvfs); int error;
if ((error = zpl_enter(zfsvfs, FTAG)) != 0)
return (error);
char *fsname = kmem_alloc(ZFS_MAX_DATASET_NAME_LEN, KM_SLEEP); char *fsname = kmem_alloc(ZFS_MAX_DATASET_NAME_LEN, KM_SLEEP);
dmu_objset_name(zfsvfs->z_os, fsname); dmu_objset_name(zfsvfs->z_os, fsname);
@ -205,7 +207,7 @@ __zpl_show_devname(struct seq_file *seq, zfsvfs_t *zfsvfs)
kmem_free(fsname, ZFS_MAX_DATASET_NAME_LEN); kmem_free(fsname, ZFS_MAX_DATASET_NAME_LEN);
ZPL_EXIT(zfsvfs); zpl_exit(zfsvfs, FTAG);
return (0); return (0);
} }

View File

@ -246,8 +246,8 @@ zpl_xattr_list(struct dentry *dentry, char *buffer, size_t buffer_size)
crhold(cr); crhold(cr);
cookie = spl_fstrans_mark(); cookie = spl_fstrans_mark();
ZPL_ENTER(zfsvfs); if ((error = zpl_enter_verify_zp(zfsvfs, zp, FTAG)) != 0)
ZPL_VERIFY_ZP(zp); goto out1;
rw_enter(&zp->z_xattr_lock, RW_READER); rw_enter(&zp->z_xattr_lock, RW_READER);
if (zfsvfs->z_use_sa && zp->z_is_sa) { if (zfsvfs->z_use_sa && zp->z_is_sa) {
@ -264,7 +264,8 @@ zpl_xattr_list(struct dentry *dentry, char *buffer, size_t buffer_size)
out: out:
rw_exit(&zp->z_xattr_lock); rw_exit(&zp->z_xattr_lock);
ZPL_EXIT(zfsvfs); zpl_exit(zfsvfs, FTAG);
out1:
spl_fstrans_unmark(cookie); spl_fstrans_unmark(cookie);
crfree(cr); crfree(cr);
@ -435,12 +436,13 @@ zpl_xattr_get(struct inode *ip, const char *name, void *value, size_t size)
crhold(cr); crhold(cr);
cookie = spl_fstrans_mark(); cookie = spl_fstrans_mark();
ZPL_ENTER(zfsvfs); if ((error = zpl_enter_verify_zp(zfsvfs, zp, FTAG)) != 0)
ZPL_VERIFY_ZP(zp); goto out;
rw_enter(&zp->z_xattr_lock, RW_READER); rw_enter(&zp->z_xattr_lock, RW_READER);
error = __zpl_xattr_get(ip, name, value, size, cr); error = __zpl_xattr_get(ip, name, value, size, cr);
rw_exit(&zp->z_xattr_lock); rw_exit(&zp->z_xattr_lock);
ZPL_EXIT(zfsvfs); zpl_exit(zfsvfs, FTAG);
out:
spl_fstrans_unmark(cookie); spl_fstrans_unmark(cookie);
crfree(cr); crfree(cr);
@ -604,8 +606,8 @@ zpl_xattr_set(struct inode *ip, const char *name, const void *value,
crhold(cr); crhold(cr);
cookie = spl_fstrans_mark(); cookie = spl_fstrans_mark();
ZPL_ENTER(zfsvfs); if ((error = zpl_enter_verify_zp(zfsvfs, zp, FTAG)) != 0)
ZPL_VERIFY_ZP(zp); goto out1;
rw_enter(&zp->z_xattr_lock, RW_WRITER); rw_enter(&zp->z_xattr_lock, RW_WRITER);
/* /*
@ -658,7 +660,8 @@ zpl_xattr_set(struct inode *ip, const char *name, const void *value,
zpl_xattr_set_sa(ip, name, NULL, 0, 0, cr); zpl_xattr_set_sa(ip, name, NULL, 0, 0, cr);
out: out:
rw_exit(&zp->z_xattr_lock); rw_exit(&zp->z_xattr_lock);
ZPL_EXIT(zfsvfs); zpl_exit(zfsvfs, FTAG);
out1:
spl_fstrans_unmark(cookie); spl_fstrans_unmark(cookie);
crfree(cr); crfree(cr);
ASSERT3S(error, <=, 0); ASSERT3S(error, <=, 0);

View File

@ -61,21 +61,23 @@ static ulong_t zfs_fsync_sync_cnt = 4;
int int
zfs_fsync(znode_t *zp, int syncflag, cred_t *cr) zfs_fsync(znode_t *zp, int syncflag, cred_t *cr)
{ {
int error = 0;
zfsvfs_t *zfsvfs = ZTOZSB(zp); zfsvfs_t *zfsvfs = ZTOZSB(zp);
(void) tsd_set(zfs_fsyncer_key, (void *)zfs_fsync_sync_cnt); (void) tsd_set(zfs_fsyncer_key, (void *)zfs_fsync_sync_cnt);
if (zfsvfs->z_os->os_sync != ZFS_SYNC_DISABLED) { if (zfsvfs->z_os->os_sync != ZFS_SYNC_DISABLED) {
ZFS_ENTER(zfsvfs); if ((error = zfs_enter_verify_zp(zfsvfs, zp, FTAG)) != 0)
ZFS_VERIFY_ZP(zp); goto out;
atomic_inc_32(&zp->z_sync_writes_cnt); atomic_inc_32(&zp->z_sync_writes_cnt);
zil_commit(zfsvfs->z_log, zp->z_id); zil_commit(zfsvfs->z_log, zp->z_id);
atomic_dec_32(&zp->z_sync_writes_cnt); atomic_dec_32(&zp->z_sync_writes_cnt);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
} }
out:
tsd_set(zfs_fsyncer_key, NULL); tsd_set(zfs_fsyncer_key, NULL);
return (0); return (error);
} }
@ -146,12 +148,12 @@ zfs_holey(znode_t *zp, ulong_t cmd, loff_t *off)
zfsvfs_t *zfsvfs = ZTOZSB(zp); zfsvfs_t *zfsvfs = ZTOZSB(zp);
int error; int error;
ZFS_ENTER(zfsvfs); if ((error = zfs_enter_verify_zp(zfsvfs, zp, FTAG)) != 0)
ZFS_VERIFY_ZP(zp); return (error);
error = zfs_holey_common(zp, cmd, off); error = zfs_holey_common(zp, cmd, off);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
#endif /* SEEK_HOLE && SEEK_DATA */ #endif /* SEEK_HOLE && SEEK_DATA */
@ -162,15 +164,15 @@ zfs_access(znode_t *zp, int mode, int flag, cred_t *cr)
zfsvfs_t *zfsvfs = ZTOZSB(zp); zfsvfs_t *zfsvfs = ZTOZSB(zp);
int error; int error;
ZFS_ENTER(zfsvfs); if ((error = zfs_enter_verify_zp(zfsvfs, zp, FTAG)) != 0)
ZFS_VERIFY_ZP(zp); return (error);
if (flag & V_ACE_MASK) if (flag & V_ACE_MASK)
error = zfs_zaccess(zp, mode, flag, B_FALSE, cr); error = zfs_zaccess(zp, mode, flag, B_FALSE, cr);
else else
error = zfs_zaccess_rwx(zp, mode, flag, cr); error = zfs_zaccess_rwx(zp, mode, flag, cr);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
@ -201,17 +203,17 @@ zfs_read(struct znode *zp, zfs_uio_t *uio, int ioflag, cred_t *cr)
boolean_t frsync = B_FALSE; boolean_t frsync = B_FALSE;
zfsvfs_t *zfsvfs = ZTOZSB(zp); zfsvfs_t *zfsvfs = ZTOZSB(zp);
ZFS_ENTER(zfsvfs); if ((error = zfs_enter_verify_zp(zfsvfs, zp, FTAG)) != 0)
ZFS_VERIFY_ZP(zp); return (error);
if (zp->z_pflags & ZFS_AV_QUARANTINED) { if (zp->z_pflags & ZFS_AV_QUARANTINED) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(EACCES)); return (SET_ERROR(EACCES));
} }
/* We don't copy out anything useful for directories. */ /* We don't copy out anything useful for directories. */
if (Z_ISDIR(ZTOTYPE(zp))) { if (Z_ISDIR(ZTOTYPE(zp))) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(EISDIR)); return (SET_ERROR(EISDIR));
} }
@ -219,7 +221,7 @@ zfs_read(struct znode *zp, zfs_uio_t *uio, int ioflag, cred_t *cr)
* Validate file offset * Validate file offset
*/ */
if (zfs_uio_offset(uio) < (offset_t)0) { if (zfs_uio_offset(uio) < (offset_t)0) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(EINVAL)); return (SET_ERROR(EINVAL));
} }
@ -227,7 +229,7 @@ zfs_read(struct znode *zp, zfs_uio_t *uio, int ioflag, cred_t *cr)
* Fasttrack empty reads * Fasttrack empty reads
*/ */
if (zfs_uio_resid(uio) == 0) { if (zfs_uio_resid(uio) == 0) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (0); return (0);
} }
@ -312,7 +314,7 @@ out:
zfs_rangelock_exit(lr); zfs_rangelock_exit(lr);
ZFS_ACCESSTIME_STAMP(zfsvfs, zp); ZFS_ACCESSTIME_STAMP(zfsvfs, zp);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
@ -404,8 +406,8 @@ zfs_write(znode_t *zp, zfs_uio_t *uio, int ioflag, cred_t *cr)
return (0); return (0);
zfsvfs_t *zfsvfs = ZTOZSB(zp); zfsvfs_t *zfsvfs = ZTOZSB(zp);
ZFS_ENTER(zfsvfs); if ((error = zfs_enter_verify_zp(zfsvfs, zp, FTAG)) != 0)
ZFS_VERIFY_ZP(zp); return (error);
sa_bulk_attr_t bulk[4]; sa_bulk_attr_t bulk[4];
int count = 0; int count = 0;
@ -422,7 +424,7 @@ zfs_write(znode_t *zp, zfs_uio_t *uio, int ioflag, cred_t *cr)
* so check it explicitly here. * so check it explicitly here.
*/ */
if (zfs_is_readonly(zfsvfs)) { if (zfs_is_readonly(zfsvfs)) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(EROFS)); return (SET_ERROR(EROFS));
} }
@ -434,7 +436,7 @@ zfs_write(znode_t *zp, zfs_uio_t *uio, int ioflag, cred_t *cr)
if ((zp->z_pflags & ZFS_IMMUTABLE) || if ((zp->z_pflags & ZFS_IMMUTABLE) ||
((zp->z_pflags & ZFS_APPENDONLY) && !(ioflag & O_APPEND) && ((zp->z_pflags & ZFS_APPENDONLY) && !(ioflag & O_APPEND) &&
(zfs_uio_offset(uio) < zp->z_size))) { (zfs_uio_offset(uio) < zp->z_size))) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(EPERM)); return (SET_ERROR(EPERM));
} }
@ -443,7 +445,7 @@ zfs_write(znode_t *zp, zfs_uio_t *uio, int ioflag, cred_t *cr)
*/ */
offset_t woff = ioflag & O_APPEND ? zp->z_size : zfs_uio_offset(uio); offset_t woff = ioflag & O_APPEND ? zp->z_size : zfs_uio_offset(uio);
if (woff < 0) { if (woff < 0) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(EINVAL)); return (SET_ERROR(EINVAL));
} }
@ -455,7 +457,7 @@ zfs_write(znode_t *zp, zfs_uio_t *uio, int ioflag, cred_t *cr)
* Skip this if uio contains loaned arc_buf. * Skip this if uio contains loaned arc_buf.
*/ */
if (zfs_uio_prefaultpages(MIN(n, max_blksz), uio)) { if (zfs_uio_prefaultpages(MIN(n, max_blksz), uio)) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(EFAULT)); return (SET_ERROR(EFAULT));
} }
@ -490,7 +492,7 @@ zfs_write(znode_t *zp, zfs_uio_t *uio, int ioflag, cred_t *cr)
if (zn_rlimit_fsize(zp, uio)) { if (zn_rlimit_fsize(zp, uio)) {
zfs_rangelock_exit(lr); zfs_rangelock_exit(lr);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(EFBIG)); return (SET_ERROR(EFBIG));
} }
@ -498,7 +500,7 @@ zfs_write(znode_t *zp, zfs_uio_t *uio, int ioflag, cred_t *cr)
if (woff >= limit) { if (woff >= limit) {
zfs_rangelock_exit(lr); zfs_rangelock_exit(lr);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(EFBIG)); return (SET_ERROR(EFBIG));
} }
@ -761,7 +763,7 @@ zfs_write(znode_t *zp, zfs_uio_t *uio, int ioflag, cred_t *cr)
*/ */
if (zfsvfs->z_replay || zfs_uio_resid(uio) == start_resid || if (zfsvfs->z_replay || zfs_uio_resid(uio) == start_resid ||
error == EFAULT) { error == EFAULT) {
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
@ -773,7 +775,7 @@ zfs_write(znode_t *zp, zfs_uio_t *uio, int ioflag, cred_t *cr)
dataset_kstats_update_write_kstats(&zfsvfs->z_kstat, nwritten); dataset_kstats_update_write_kstats(&zfsvfs->z_kstat, nwritten);
task_io_account_write(nwritten); task_io_account_write(nwritten);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (0); return (0);
} }
@ -784,10 +786,10 @@ zfs_getsecattr(znode_t *zp, vsecattr_t *vsecp, int flag, cred_t *cr)
int error; int error;
boolean_t skipaclchk = (flag & ATTR_NOACLCHECK) ? B_TRUE : B_FALSE; boolean_t skipaclchk = (flag & ATTR_NOACLCHECK) ? B_TRUE : B_FALSE;
ZFS_ENTER(zfsvfs); if ((error = zfs_enter_verify_zp(zfsvfs, zp, FTAG)) != 0)
ZFS_VERIFY_ZP(zp); return (error);
error = zfs_getacl(zp, vsecp, skipaclchk, cr); error = zfs_getacl(zp, vsecp, skipaclchk, cr);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }
@ -800,15 +802,15 @@ zfs_setsecattr(znode_t *zp, vsecattr_t *vsecp, int flag, cred_t *cr)
boolean_t skipaclchk = (flag & ATTR_NOACLCHECK) ? B_TRUE : B_FALSE; boolean_t skipaclchk = (flag & ATTR_NOACLCHECK) ? B_TRUE : B_FALSE;
zilog_t *zilog = zfsvfs->z_log; zilog_t *zilog = zfsvfs->z_log;
ZFS_ENTER(zfsvfs); if ((error = zfs_enter_verify_zp(zfsvfs, zp, FTAG)) != 0)
ZFS_VERIFY_ZP(zp); return (error);
error = zfs_setacl(zp, vsecp, skipaclchk, cr); error = zfs_setacl(zp, vsecp, skipaclchk, cr);
if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
zil_commit(zilog, 0); zil_commit(zilog, 0);
ZFS_EXIT(zfsvfs); zfs_exit(zfsvfs, FTAG);
return (error); return (error);
} }