aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorChunwei Chen <[email protected]>2022-09-16 13:36:47 -0700
committerGitHub <[email protected]>2022-09-16 13:36:47 -0700
commit768eacedef54922962562e601ca2c3366c4bcc4b (patch)
treece625415ee93fd7c03c35526e048daf7c9ddefbc /include
parentb24d1c77f7fc53d26ee915b5203a139f13fd9791 (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.h35
-rw-r--r--include/os/linux/zfs/sys/zfs_znode_impl.h60
-rw-r--r--include/sys/zfs_znode.h23
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 */