diff options
author | Chunwei Chen <[email protected]> | 2022-09-16 13:36:47 -0700 |
---|---|---|
committer | GitHub <[email protected]> | 2022-09-16 13:36:47 -0700 |
commit | 768eacedef54922962562e601ca2c3366c4bcc4b (patch) | |
tree | ce625415ee93fd7c03c35526e048daf7c9ddefbc /include | |
parent | b24d1c77f7fc53d26ee915b5203a139f13fd9791 (diff) |
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 <[email protected]>
Reviewed-by: Ryan Moeller <[email protected]>
Signed-off-by: Chunwei Chen <[email protected]>
Closes #13831
Diffstat (limited to 'include')
-rw-r--r-- | include/os/freebsd/zfs/sys/zfs_znode_impl.h | 35 | ||||
-rw-r--r-- | include/os/linux/zfs/sys/zfs_znode_impl.h | 60 | ||||
-rw-r--r-- | include/sys/zfs_znode.h | 23 |
3 files changed, 69 insertions, 49 deletions
diff --git a/include/os/freebsd/zfs/sys/zfs_znode_impl.h b/include/os/freebsd/zfs/sys/zfs_znode_impl.h index f76a84147..41a5bb218 100644 --- a/include/os/freebsd/zfs/sys/zfs_znode_impl.h +++ b/include/os/freebsd/zfs/sys/zfs_znode_impl.h @@ -121,29 +121,24 @@ typedef struct zfs_soft_state { #define zn_rlimit_fsize(zp, 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 */ -#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 */ -#define ZFS_EXIT(zfsvfs) ZFS_TEARDOWN_EXIT_READ(zfsvfs, FTAG) - -#define ZFS_VERIFY_ZP_ERROR(zp, error) do { \ - if (__predict_false((zp)->z_sa_hdl == NULL)) { \ - 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) +static inline void +zfs_exit(zfsvfs_t *zfsvfs, const char *tag) +{ + ZFS_TEARDOWN_EXIT_READ(zfsvfs, tag); +} /* * Macros for dealing with dmu_buf_hold diff --git a/include/os/linux/zfs/sys/zfs_znode_impl.h b/include/os/linux/zfs/sys/zfs_znode_impl.h index a6fa06a3f..525687810 100644 --- a/include/os/linux/zfs/sys/zfs_znode_impl.h +++ b/include/os/linux/zfs/sys/zfs_znode_impl.h @@ -84,39 +84,41 @@ extern "C" { #define zrele(zp) iput(ZTOI((zp))) /* Called on entry to each ZFS inode and vfs operation. */ -#define ZFS_ENTER_ERROR(zfsvfs, error) \ -do { \ - ZFS_TEARDOWN_ENTER_READ(zfsvfs, FTAG); \ - if (unlikely((zfsvfs)->z_unmounted)) { \ - ZFS_TEARDOWN_EXIT_READ(zfsvfs, FTAG); \ - return (error); \ - } \ -} while (0) -#define ZFS_ENTER(zfsvfs) ZFS_ENTER_ERROR(zfsvfs, EIO) -#define ZPL_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 (unlikely(zfsvfs->z_unmounted)) { + ZFS_TEARDOWN_EXIT_READ(zfsvfs, tag); + return (SET_ERROR(EIO)); + } + return (0); +} /* Must be called before exiting the operation. */ -#define ZFS_EXIT(zfsvfs) \ -do { \ - zfs_exit_fs(zfsvfs); \ - ZFS_TEARDOWN_EXIT_READ(zfsvfs, FTAG); \ -} while (0) +static inline void +zfs_exit(zfsvfs_t *zfsvfs, const char *tag) +{ + zfs_exit_fs(zfsvfs); + ZFS_TEARDOWN_EXIT_READ(zfsvfs, tag); +} -#define ZPL_EXIT(zfsvfs) \ -do { \ - rrm_exit(&(zfsvfs)->z_teardown_lock, FTAG); \ -} while (0) +static inline int +zpl_enter(zfsvfs_t *zfsvfs, const char *tag) +{ + return (-zfs_enter(zfsvfs, tag)); +} -/* Verifies the znode is valid. */ -#define ZFS_VERIFY_ZP_ERROR(zp, error) \ -do { \ - if (unlikely((zp)->z_sa_hdl == NULL)) { \ - ZFS_EXIT(ZTOZSB(zp)); \ - return (error); \ - } \ -} while (0) -#define ZFS_VERIFY_ZP(zp) ZFS_VERIFY_ZP_ERROR(zp, EIO) -#define ZPL_VERIFY_ZP(zp) ZFS_VERIFY_ZP_ERROR(zp, -EIO) +static inline void +zpl_exit(zfsvfs_t *zfsvfs, const char *tag) +{ + ZFS_TEARDOWN_EXIT_READ(zfsvfs, tag); +} + +/* zfs_verify_zp and zfs_enter_verify_zp are defined in zfs_znode.h */ +#define zpl_verify_zp(zp) (-zfs_verify_zp(zp)) +#define zpl_enter_verify_zp(zfsvfs, zp, tag) \ + (-zfs_enter_verify_zp(zfsvfs, zp, tag)) /* * Macros for dealing with dmu_buf_hold diff --git a/include/sys/zfs_znode.h b/include/sys/zfs_znode.h index b223c4b3b..7c906050b 100644 --- a/include/sys/zfs_znode.h +++ b/include/sys/zfs_znode.h @@ -218,6 +218,29 @@ typedef struct znode { ZNODE_OS_FIELDS; } 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 { uint64_t zh_obj; /* object id */ kmutex_t zh_lock; /* lock serializing object access */ |