From 768eacedef54922962562e601ca2c3366c4bcc4b Mon Sep 17 00:00:00 2001 From: Chunwei Chen Date: Fri, 16 Sep 2022 13:36:47 -0700 Subject: 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 Reviewed-by: Ryan Moeller Signed-off-by: Chunwei Chen Closes #13831 --- module/os/linux/zfs/zfs_vnops_os.c | 300 +++++++++++++++++++------------------ 1 file changed, 157 insertions(+), 143 deletions(-) (limited to 'module/os/linux/zfs/zfs_vnops_os.c') diff --git a/module/os/linux/zfs/zfs_vnops_os.c b/module/os/linux/zfs/zfs_vnops_os.c index 0b3f7f250..1ff88c121 100644 --- a/module/os/linux/zfs/zfs_vnops_os.c +++ b/module/os/linux/zfs/zfs_vnops_os.c @@ -82,13 +82,13 @@ * 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. - * This is done avoiding races using ZFS_ENTER(zfsvfs). - * A ZFS_EXIT(zfsvfs) is needed before all returns. Any znodes - * must be checked with ZFS_VERIFY_ZP(zp). Both of these macros + * This is done avoiding races using zfs_enter(zfsvfs). + * A zfs_exit(zfsvfs) is needed before all returns. Any znodes + * must be checked with zfs_verify_zp(zp). Both of these macros * can return EIO from the calling function. * * (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 * freed memory. Second, the last reference will call zfs_zinactive(), * 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 * 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 * throughput is constrained by the storage, nearly every transaction * must wait). @@ -142,7 +142,7 @@ * * 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: * zfs_dirent_lock(&dl, ...) // lock directory entry (may igrab()) * rw_enter(...); // grab any other locks you need @@ -160,7 +160,7 @@ * goto top; * } * 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 * } * error = do_real_work(); // do whatever this VOP does @@ -171,7 +171,7 @@ * zfs_dirent_unlock(dl); // unlock directory entry * zrele(...); // release held znodes * zil_commit(zilog, foid); // synchronous when necessary - * ZFS_EXIT(zfsvfs); // finished in zfs + * zfs_exit(zfsvfs); // finished in zfs * return (error); // done, report error */ int @@ -180,14 +180,15 @@ zfs_open(struct inode *ip, int mode, int flag, cred_t *cr) (void) cr; znode_t *zp = ITOZ(ip); zfsvfs_t *zfsvfs = ITOZSB(ip); + int error; - ZFS_ENTER(zfsvfs); - ZFS_VERIFY_ZP(zp); + if ((error = zfs_enter_verify_zp(zfsvfs, zp, FTAG)) != 0) + return (error); /* Honor ZFS_APPENDONLY file attribute */ if ((mode & FMODE_WRITE) && (zp->z_pflags & ZFS_APPENDONLY) && ((flag & O_APPEND) == 0)) { - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (SET_ERROR(EPERM)); } @@ -195,7 +196,7 @@ zfs_open(struct inode *ip, int mode, int flag, cred_t *cr) if (flag & O_SYNC) atomic_inc_32(&zp->z_sync_cnt); - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (0); } @@ -205,15 +206,16 @@ zfs_close(struct inode *ip, int flag, cred_t *cr) (void) cr; znode_t *zp = ITOZ(ip); zfsvfs_t *zfsvfs = ITOZSB(ip); + int error; - ZFS_ENTER(zfsvfs); - ZFS_VERIFY_ZP(zp); + if ((error = zfs_enter_verify_zp(zfsvfs, zp, FTAG)) != 0) + return (error); /* Decrement the synchronous opens in the znode */ if (flag & O_SYNC) atomic_dec_32(&zp->z_sync_cnt); - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (0); } @@ -449,8 +451,8 @@ zfs_lookup(znode_t *zdp, char *nm, znode_t **zpp, int flags, cred_t *cr, } } - ZFS_ENTER(zfsvfs); - ZFS_VERIFY_ZP(zdp); + if ((error = zfs_enter_verify_zp(zfsvfs, zdp, FTAG)) != 0) + return (error); *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. */ if (zdp->z_pflags & ZFS_XATTR) { - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (SET_ERROR(EINVAL)); } if ((error = zfs_get_xattrdir(zdp, zpp, cr, flags))) { - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (error); } @@ -479,12 +481,12 @@ zfs_lookup(znode_t *zdp, char *nm, znode_t **zpp, int flags, cred_t *cr, *zpp = NULL; } - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (error); } if (!S_ISDIR(ZTOI(zdp)->i_mode)) { - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); 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))) { - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (error); } if (zfsvfs->z_utf8 && u8_validate(nm, strlen(nm), NULL, U8_VALIDATE_ENTIRE, &error) < 0) { - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); 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)) zfs_znode_update_vfs(*zpp); - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (error); } @@ -566,21 +568,21 @@ zfs_create(znode_t *dzp, char *name, vattr_t *vap, int excl, if (name == NULL) return (SET_ERROR(EINVAL)); - ZFS_ENTER(zfsvfs); - ZFS_VERIFY_ZP(dzp); + if ((error = zfs_enter_verify_zp(zfsvfs, dzp, FTAG)) != 0) + return (error); os = zfsvfs->z_os; zilog = zfsvfs->z_log; if (zfsvfs->z_utf8 && u8_validate(name, strlen(name), NULL, U8_VALIDATE_ENTIRE, &error) < 0) { - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (SET_ERROR(EILSEQ)); } if (vap->va_mask & ATTR_XVATTR) { if ((error = secpolicy_xvattr((xvattr_t *)vap, crgetuid(cr), cr, vap->va_mode)) != 0) { - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (error); } } @@ -609,7 +611,7 @@ top: zfs_acl_ids_free(&acl_ids); if (strcmp(name, "..") == 0) error = SET_ERROR(EISDIR); - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (error); } } @@ -681,7 +683,7 @@ top: } zfs_acl_ids_free(&acl_ids); dmu_tx_abort(tx); - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (error); } zfs_mknode(dzp, vap, tx, cr, 0, &zp, &acl_ids); @@ -774,7 +776,7 @@ out: if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) zil_commit(zilog, 0); - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (error); } @@ -808,14 +810,14 @@ zfs_tmpfile(struct inode *dip, vattr_t *vap, int excl, (vsecp || IS_EPHEMERAL(uid) || IS_EPHEMERAL(gid))) return (SET_ERROR(EINVAL)); - ZFS_ENTER(zfsvfs); - ZFS_VERIFY_ZP(dzp); + if ((error = zfs_enter_verify_zp(zfsvfs, dzp, FTAG)) != 0) + return (error); os = zfsvfs->z_os; if (vap->va_mask & ATTR_XVATTR) { if ((error = secpolicy_xvattr((xvattr_t *)vap, crgetuid(cr), cr, vap->va_mode)) != 0) { - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (error); } } @@ -870,7 +872,7 @@ top: } zfs_acl_ids_free(&acl_ids); dmu_tx_abort(tx); - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (error); } zfs_mknode(dzp, vap, tx, cr, IS_TMPFILE, &zp, &acl_ids); @@ -894,7 +896,7 @@ out: *ipp = ZTOI(zp); } - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (error); } @@ -941,8 +943,8 @@ zfs_remove(znode_t *dzp, char *name, cred_t *cr, int flags) if (name == NULL) return (SET_ERROR(EINVAL)); - ZFS_ENTER(zfsvfs); - ZFS_VERIFY_ZP(dzp); + if ((error = zfs_enter_verify_zp(zfsvfs, dzp, FTAG)) != 0) + return (error); zilog = zfsvfs->z_log; if (flags & FIGNORECASE) { @@ -961,7 +963,7 @@ top: NULL, realnmp))) { if (realnmp) pn_free(realnmp); - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (error); } @@ -1042,7 +1044,7 @@ top: zrele(zp); if (xzp) zrele(xzp); - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (error); } @@ -1131,7 +1133,7 @@ out: if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) zil_commit(zilog, 0); - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (error); } @@ -1188,18 +1190,18 @@ zfs_mkdir(znode_t *dzp, char *dirname, vattr_t *vap, znode_t **zpp, if (dirname == NULL) return (SET_ERROR(EINVAL)); - ZFS_ENTER(zfsvfs); - ZFS_VERIFY_ZP(dzp); + if ((error = zfs_enter_verify_zp(zfsvfs, dzp, FTAG)) != 0) + return (error); zilog = zfsvfs->z_log; if (dzp->z_pflags & ZFS_XATTR) { - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (SET_ERROR(EINVAL)); } if (zfsvfs->z_utf8 && u8_validate(dirname, strlen(dirname), NULL, U8_VALIDATE_ENTIRE, &error) < 0) { - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (SET_ERROR(EILSEQ)); } 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 ((error = secpolicy_xvattr((xvattr_t *)vap, crgetuid(cr), cr, vap->va_mode)) != 0) { - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (error); } } if ((error = zfs_acl_ids_create(dzp, 0, vap, cr, vsecp, &acl_ids)) != 0) { - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (error); } /* @@ -1231,21 +1233,21 @@ top: if ((error = zfs_dirent_lock(&dl, dzp, dirname, &zp, zf, NULL, NULL))) { zfs_acl_ids_free(&acl_ids); - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (error); } if ((error = zfs_zaccess(dzp, ACE_ADD_SUBDIRECTORY, 0, B_FALSE, cr))) { zfs_acl_ids_free(&acl_ids); zfs_dirent_unlock(dl); - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (error); } if (zfs_acl_ids_overquota(zfsvfs, &acl_ids, zfs_inherit_projid(dzp))) { zfs_acl_ids_free(&acl_ids); zfs_dirent_unlock(dl); - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (SET_ERROR(EDQUOT)); } @@ -1277,7 +1279,7 @@ top: } zfs_acl_ids_free(&acl_ids); dmu_tx_abort(tx); - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (error); } @@ -1323,7 +1325,7 @@ out: zfs_znode_update_vfs(dzp); zfs_znode_update_vfs(zp); } - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (error); } @@ -1359,8 +1361,8 @@ zfs_rmdir(znode_t *dzp, char *name, znode_t *cwd, cred_t *cr, if (name == NULL) return (SET_ERROR(EINVAL)); - ZFS_ENTER(zfsvfs); - ZFS_VERIFY_ZP(dzp); + if ((error = zfs_enter_verify_zp(zfsvfs, dzp, FTAG)) != 0) + return (error); zilog = zfsvfs->z_log; if (flags & FIGNORECASE) @@ -1373,7 +1375,7 @@ top: */ if ((error = zfs_dirent_lock(&dl, dzp, name, &zp, zflg, NULL, NULL))) { - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (error); } @@ -1424,7 +1426,7 @@ top: } dmu_tx_abort(tx); zrele(zp); - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (error); } @@ -1452,7 +1454,7 @@ out: if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) zil_commit(zilog, 0); - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (error); } @@ -1491,8 +1493,8 @@ zfs_readdir(struct inode *ip, zpl_dir_context_t *ctx, cred_t *cr) uint64_t parent; uint64_t offset; /* must be unsigned; checks for < 1 */ - ZFS_ENTER(zfsvfs); - ZFS_VERIFY_ZP(zp); + if ((error = zfs_enter_verify_zp(zfsvfs, zp, FTAG)) != 0) + return (error); if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_PARENT(zfsvfs), &parent, sizeof (parent))) != 0) @@ -1611,7 +1613,7 @@ update: if (error == ENOENT) error = 0; out: - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (error); } @@ -1636,9 +1638,10 @@ zfs_getattr_fast(struct user_namespace *user_ns, struct inode *ip, zfsvfs_t *zfsvfs = ITOZSB(ip); uint32_t blksize; u_longlong_t nblocks; + int error; - ZFS_ENTER(zfsvfs); - ZFS_VERIFY_ZP(zp); + if ((error = zfs_enter_verify_zp(zfsvfs, zp, FTAG)) != 0) + return (error); 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); } - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (0); } @@ -1849,8 +1852,8 @@ zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr) if (mask == 0) return (0); - ZFS_ENTER(zfsvfs); - ZFS_VERIFY_ZP(zp); + if ((err = zfs_enter_verify_zp(zfsvfs, zp, FTAG)) != 0) + return (err); 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 (!dmu_objset_projectquota_enabled(os) || (!S_ISREG(ip->i_mode) && !S_ISDIR(ip->i_mode))) { - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (SET_ERROR(ENOTSUP)); } projid = xoap->xoa_projid; if (unlikely(projid == ZFS_INVALID_PROJID)) { - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); 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)) && (!dmu_objset_projectquota_enabled(os) || (!S_ISREG(ip->i_mode) && !S_ISDIR(ip->i_mode)))) { - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); 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_GID) && IS_EPHEMERAL(vap->va_gid)) || (mask & ATTR_XVATTR))) { - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (SET_ERROR(EINVAL)); } if (mask & ATTR_SIZE && S_ISDIR(ip->i_mode)) { - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (SET_ERROR(EISDIR)); } 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)); } @@ -2526,7 +2529,7 @@ out3: kmem_free(xattr_bulk, sizeof (sa_bulk_attr_t) * bulks); kmem_free(bulk, sizeof (sa_bulk_attr_t) * bulks); kmem_free(tmpxvattr, sizeof (xvattr_t)); - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (err); } @@ -2661,11 +2664,14 @@ zfs_rename(znode_t *sdzp, char *snm, znode_t *tdzp, char *tnm, if (snm == NULL || tnm == NULL) return (SET_ERROR(EINVAL)); - ZFS_ENTER(zfsvfs); - ZFS_VERIFY_ZP(sdzp); + if ((error = zfs_enter_verify_zp(zfsvfs, sdzp, FTAG)) != 0) + return (error); 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 @@ -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 || zfsctl_is_node(ZTOI(tdzp))) { - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (SET_ERROR(EXDEV)); } if (zfsvfs->z_utf8 && u8_validate(tnm, strlen(tnm), NULL, U8_VALIDATE_ENTIRE, &error) < 0) { - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (SET_ERROR(EILSEQ)); } @@ -2697,7 +2703,7 @@ top: * See the comment in zfs_link() for why this is considered bad. */ if ((tdzp->z_pflags & ZFS_XATTR) != (sdzp->z_pflags & ZFS_XATTR)) { - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (SET_ERROR(EINVAL)); } @@ -2727,7 +2733,7 @@ top: * the rename() function shall return successfully * and perform no other action." */ - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (0); } /* @@ -2799,7 +2805,7 @@ top: if (strcmp(snm, "..") == 0) serr = EINVAL; - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (serr); } if (terr) { @@ -2811,7 +2817,7 @@ top: if (strcmp(tnm, "..") == 0) terr = EINVAL; - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (terr); } @@ -2915,7 +2921,7 @@ top: zrele(szp); if (tzp) zrele(tzp); - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (error); } @@ -2989,7 +2995,7 @@ out: if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) zil_commit(zilog, 0); - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (error); } @@ -3032,26 +3038,26 @@ zfs_symlink(znode_t *dzp, char *name, vattr_t *vap, char *link, if (name == NULL) return (SET_ERROR(EINVAL)); - ZFS_ENTER(zfsvfs); - ZFS_VERIFY_ZP(dzp); + if ((error = zfs_enter_verify_zp(zfsvfs, dzp, FTAG)) != 0) + return (error); zilog = zfsvfs->z_log; if (zfsvfs->z_utf8 && u8_validate(name, strlen(name), NULL, U8_VALIDATE_ENTIRE, &error) < 0) { - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (SET_ERROR(EILSEQ)); } if (flags & FIGNORECASE) zflg |= ZCILOOK; if (len > MAXPATHLEN) { - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (SET_ERROR(ENAMETOOLONG)); } if ((error = zfs_acl_ids_create(dzp, 0, vap, cr, NULL, &acl_ids)) != 0) { - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (error); } top: @@ -3063,21 +3069,21 @@ top: error = zfs_dirent_lock(&dl, dzp, name, &zp, zflg, NULL, NULL); if (error) { zfs_acl_ids_free(&acl_ids); - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (error); } if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr))) { zfs_acl_ids_free(&acl_ids); zfs_dirent_unlock(dl); - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (error); } if (zfs_acl_ids_overquota(zfsvfs, &acl_ids, ZFS_DEFAULT_PROJID)) { zfs_acl_ids_free(&acl_ids); zfs_dirent_unlock(dl); - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (SET_ERROR(EDQUOT)); } tx = dmu_tx_create(zfsvfs->z_os); @@ -3104,7 +3110,7 @@ top: } zfs_acl_ids_free(&acl_ids); dmu_tx_abort(tx); - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (error); } @@ -3159,7 +3165,7 @@ top: zrele(zp); } - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (error); } @@ -3185,8 +3191,8 @@ zfs_readlink(struct inode *ip, zfs_uio_t *uio, cred_t *cr) zfsvfs_t *zfsvfs = ITOZSB(ip); int error; - ZFS_ENTER(zfsvfs); - ZFS_VERIFY_ZP(zp); + if ((error = zfs_enter_verify_zp(zfsvfs, zp, FTAG)) != 0) + return (error); mutex_enter(&zp->z_lock); 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); mutex_exit(&zp->z_lock); - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (error); } @@ -3241,8 +3247,8 @@ zfs_link(znode_t *tdzp, znode_t *szp, char *name, cred_t *cr, if (name == NULL) return (SET_ERROR(EINVAL)); - ZFS_ENTER(zfsvfs); - ZFS_VERIFY_ZP(tdzp); + if ((error = zfs_enter_verify_zp(zfsvfs, tdzp, FTAG)) != 0) + return (error); 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. */ if (S_ISDIR(sip->i_mode)) { - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); 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 @@ -3265,7 +3274,7 @@ zfs_link(znode_t *tdzp, znode_t *szp, char *name, cred_t *cr, */ if (tdzp->z_pflags & ZFS_PROJINHERIT && tdzp->z_projid != szp->z_projid) { - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (SET_ERROR(EXDEV)); } @@ -3274,7 +3283,7 @@ zfs_link(znode_t *tdzp, znode_t *szp, char *name, cred_t *cr, * super blocks. */ if (sip->i_sb != ZTOI(tdzp)->i_sb || zfsctl_is_node(sip)) { - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); 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), &parent, sizeof (uint64_t))) != 0) { - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (error); } if (parent == zfsvfs->z_shares_dir) { - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (SET_ERROR(EPERM)); } if (zfsvfs->z_utf8 && u8_validate(name, strlen(name), NULL, U8_VALIDATE_ENTIRE, &error) < 0) { - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (SET_ERROR(EILSEQ)); } if (flags & FIGNORECASE) @@ -3305,19 +3314,19 @@ zfs_link(znode_t *tdzp, znode_t *szp, char *name, cred_t *cr, * imposed in attribute space. */ if ((szp->z_pflags & ZFS_XATTR) != (tdzp->z_pflags & ZFS_XATTR)) { - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (SET_ERROR(EINVAL)); } owner = zfs_fuid_map_id(zfsvfs, KUID_TO_SUID(sip->i_uid), cr, ZFS_OWNER); if (owner != crgetuid(cr) && secpolicy_basic_link(cr) != 0) { - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (SET_ERROR(EPERM)); } if ((error = zfs_zaccess(tdzp, ACE_ADD_FILE, 0, B_FALSE, cr))) { - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (error); } @@ -3327,7 +3336,7 @@ top: */ error = zfs_dirent_lock(&dl, tdzp, name, &tzp, zf, NULL, NULL); if (error) { - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (error); } @@ -3349,7 +3358,7 @@ top: goto top; } dmu_tx_abort(tx); - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (error); } /* unmark z_unlinked so zfs_link_create will not reject */ @@ -3391,7 +3400,7 @@ top: zfs_znode_update_vfs(tdzp); zfs_znode_update_vfs(szp); - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (error); } @@ -3448,8 +3457,8 @@ zfs_putpage(struct inode *ip, struct page *pp, struct writeback_control *wbc, int cnt = 0; struct address_space *mapping; - ZFS_ENTER(zfsvfs); - ZFS_VERIFY_ZP(zp); + if ((err = zfs_enter_verify_zp(zfsvfs, zp, FTAG)) != 0) + return (err); 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 */ if (pgoff >= offset) { unlock_page(pp); - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); 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))) { unlock_page(pp); zfs_rangelock_exit(lr); - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (0); } @@ -3549,7 +3558,7 @@ zfs_putpage(struct inode *ip, struct page *pp, struct writeback_control *wbc, #endif } - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); 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)) { unlock_page(pp); zfs_rangelock_exit(lr); - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (0); } @@ -3592,7 +3601,7 @@ zfs_putpage(struct inode *ip, struct page *pp, struct writeback_control *wbc, if (!for_sync) atomic_dec_32(&zp->z_async_writes_cnt); zfs_rangelock_exit(lr); - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); 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); - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); 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)) return (0); - ZFS_ENTER(zfsvfs); - ZFS_VERIFY_ZP(zp); + if ((error = zfs_enter_verify_zp(zfsvfs, zp, FTAG)) != 0) + return (error); #ifdef I_DIRTY_TIME /* @@ -3714,7 +3723,7 @@ zfs_dirty_inode(struct inode *ip, int flags) dmu_tx_commit(tx); out: - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (error); } @@ -3831,14 +3840,14 @@ zfs_getpage(struct inode *ip, struct page *pl[], int nr_pages) if (pl == NULL) return (0); - ZFS_ENTER(zfsvfs); - ZFS_VERIFY_ZP(zp); + if ((err = zfs_enter_verify_zp(zfsvfs, zp, FTAG)) != 0) + return (err); err = zfs_fillpage(ip, pl, nr_pages); dataset_kstats_update_read_kstats(&zfsvfs->z_kstat, nr_pages*PAGESIZE); - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (err); } @@ -3861,28 +3870,29 @@ zfs_map(struct inode *ip, offset_t off, caddr_t *addrp, size_t len, (void) addrp; znode_t *zp = ITOZ(ip); zfsvfs_t *zfsvfs = ITOZSB(ip); + int error; - ZFS_ENTER(zfsvfs); - ZFS_VERIFY_ZP(zp); + if ((error = zfs_enter_verify_zp(zfsvfs, zp, FTAG)) != 0) + return (error); if ((vm_flags & VM_WRITE) && (zp->z_pflags & (ZFS_IMMUTABLE | ZFS_READONLY | ZFS_APPENDONLY))) { - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (SET_ERROR(EPERM)); } if ((vm_flags & (VM_READ | VM_EXEC)) && (zp->z_pflags & ZFS_AV_QUARANTINED)) { - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (SET_ERROR(EACCES)); } if (off < 0 || len > MAXOFFSET_T - off) { - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (SET_ERROR(ENXIO)); } - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (0); } @@ -3913,11 +3923,11 @@ zfs_space(znode_t *zp, int cmd, flock64_t *bfp, int flag, uint64_t off, len; int error; - ZFS_ENTER(zfsvfs); - ZFS_VERIFY_ZP(zp); + if ((error = zfs_enter_verify_zp(zfsvfs, zp, FTAG)) != 0) + return (error); if (cmd != F_FREESP) { - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); 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. */ if (zfs_is_readonly(zfsvfs)) { - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (SET_ERROR(EROFS)); } if (bfp->l_len < 0) { - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); 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. */ if ((error = zfs_zaccess(zp, ACE_WRITE_DATA, 0, B_FALSE, cr))) { - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); 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); - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (error); } @@ -3966,19 +3976,23 @@ zfs_fid(struct inode *ip, fid_t *fidp) zfid_short_t *zfid; int size, i, error; - ZFS_ENTER(zfsvfs); + if ((error = zfs_enter(zfsvfs, FTAG)) != 0) + return (error); if (fidp->fid_len < SHORT_FID_LEN) { fidp->fid_len = SHORT_FID_LEN; - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); 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), &gen64, sizeof (uint64_t))) != 0) { - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (error); } @@ -3999,7 +4013,7 @@ zfs_fid(struct inode *ip, fid_t *fidp) for (i = 0; i < sizeof (zfid->zf_gen); i++) zfid->zf_gen[i] = (uint8_t)(gen >> (8 * i)); - ZFS_EXIT(zfsvfs); + zfs_exit(zfsvfs, FTAG); return (0); } -- cgit v1.2.3