mirror of
https://github.com/opnsense/src.git
synced 2026-04-22 14:49:36 -04:00
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
184 lines
5.1 KiB
C
184 lines
5.1 KiB
C
/*
|
|
* CDDL HEADER START
|
|
*
|
|
* The contents of this file are subject to the terms of the
|
|
* Common Development and Distribution License (the "License").
|
|
* You may not use this file except in compliance with the License.
|
|
*
|
|
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
|
* or https://opensource.org/licenses/CDDL-1.0.
|
|
* See the License for the specific language governing permissions
|
|
* and limitations under the License.
|
|
*
|
|
* When distributing Covered Code, include this CDDL HEADER in each
|
|
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
|
* If applicable, add the following below this CDDL HEADER, with the
|
|
* fields enclosed by brackets "[]" replaced with your own identifying
|
|
* information: Portions Copyright [yyyy] [name of copyright owner]
|
|
*
|
|
* CDDL HEADER END
|
|
*/
|
|
/*
|
|
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
|
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
|
|
* Copyright 2016 Nexenta Systems, Inc. All rights reserved.
|
|
*/
|
|
|
|
#ifndef _SYS_ZFS_ZNODE_IMPL_H
|
|
#define _SYS_ZFS_ZNODE_IMPL_H
|
|
|
|
#ifndef _KERNEL
|
|
#error "no user serviceable parts within"
|
|
#endif
|
|
|
|
#include <sys/isa_defs.h>
|
|
#include <sys/types32.h>
|
|
#include <sys/list.h>
|
|
#include <sys/dmu.h>
|
|
#include <sys/sa.h>
|
|
#include <sys/time.h>
|
|
#include <sys/zfs_vfsops.h>
|
|
#include <sys/rrwlock.h>
|
|
#include <sys/zfs_sa.h>
|
|
#include <sys/zfs_stat.h>
|
|
#include <sys/zfs_rlock.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#define ZNODE_OS_FIELDS \
|
|
inode_timespec_t z_btime; /* creation/birth time (cached) */ \
|
|
struct inode z_inode;
|
|
|
|
/*
|
|
* Convert between znode pointers and inode pointers
|
|
*/
|
|
#define ZTOI(znode) (&((znode)->z_inode))
|
|
#define ITOZ(inode) (container_of((inode), znode_t, z_inode))
|
|
#define ZTOZSB(znode) ((zfsvfs_t *)(ZTOI(znode)->i_sb->s_fs_info))
|
|
#define ITOZSB(inode) ((zfsvfs_t *)((inode)->i_sb->s_fs_info))
|
|
|
|
#define ZTOTYPE(zp) (ZTOI(zp)->i_mode)
|
|
#define ZTOGID(zp) (ZTOI(zp)->i_gid)
|
|
#define ZTOUID(zp) (ZTOI(zp)->i_uid)
|
|
#define ZTONLNK(zp) (ZTOI(zp)->i_nlink)
|
|
|
|
#define Z_ISBLK(type) S_ISBLK(type)
|
|
#define Z_ISCHR(type) S_ISCHR(type)
|
|
#define Z_ISLNK(type) S_ISLNK(type)
|
|
#define Z_ISDEV(type) (S_ISCHR(type) || S_ISBLK(type) || S_ISFIFO(type))
|
|
#define Z_ISDIR(type) S_ISDIR(type)
|
|
|
|
#define zn_has_cached_data(zp) ((zp)->z_is_mapped)
|
|
#define zn_flush_cached_data(zp, sync) write_inode_now(ZTOI(zp), sync)
|
|
#define zn_rlimit_fsize(zp, uio) (0)
|
|
|
|
/*
|
|
* zhold() wraps igrab() on Linux, and igrab() may fail when the
|
|
* inode is in the process of being deleted. As zhold() must only be
|
|
* called when a ref already exists - so the inode cannot be
|
|
* mid-deletion - we VERIFY() this.
|
|
*/
|
|
#define zhold(zp) VERIFY3P(igrab(ZTOI((zp))), !=, NULL)
|
|
#define zrele(zp) iput(ZTOI((zp)))
|
|
|
|
/* Called on entry to each ZFS inode and vfs operation. */
|
|
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. */
|
|
static inline void
|
|
zfs_exit(zfsvfs_t *zfsvfs, const char *tag)
|
|
{
|
|
zfs_exit_fs(zfsvfs);
|
|
ZFS_TEARDOWN_EXIT_READ(zfsvfs, tag);
|
|
}
|
|
|
|
static inline int
|
|
zpl_enter(zfsvfs_t *zfsvfs, const char *tag)
|
|
{
|
|
return (-zfs_enter(zfsvfs, tag));
|
|
}
|
|
|
|
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
|
|
*/
|
|
#define ZFS_OBJ_MTX_SZ 64
|
|
#define ZFS_OBJ_MTX_MAX (1024 * 1024)
|
|
#define ZFS_OBJ_HASH(zfsvfs, obj) ((obj) & ((zfsvfs->z_hold_size) - 1))
|
|
|
|
extern unsigned int zfs_object_mutex_size;
|
|
|
|
/*
|
|
* Encode ZFS stored time values from a struct timespec / struct timespec64.
|
|
*/
|
|
#define ZFS_TIME_ENCODE(tp, stmp) \
|
|
do { \
|
|
(stmp)[0] = (uint64_t)(tp)->tv_sec; \
|
|
(stmp)[1] = (uint64_t)(tp)->tv_nsec; \
|
|
} while (0)
|
|
|
|
#if defined(HAVE_INODE_TIMESPEC64_TIMES)
|
|
/*
|
|
* Decode ZFS stored time values to a struct timespec64
|
|
* 4.18 and newer kernels.
|
|
*/
|
|
#define ZFS_TIME_DECODE(tp, stmp) \
|
|
do { \
|
|
(tp)->tv_sec = (time64_t)(stmp)[0]; \
|
|
(tp)->tv_nsec = (long)(stmp)[1]; \
|
|
} while (0)
|
|
#else
|
|
/*
|
|
* Decode ZFS stored time values to a struct timespec
|
|
* 4.17 and older kernels.
|
|
*/
|
|
#define ZFS_TIME_DECODE(tp, stmp) \
|
|
do { \
|
|
(tp)->tv_sec = (time_t)(stmp)[0]; \
|
|
(tp)->tv_nsec = (long)(stmp)[1]; \
|
|
} while (0)
|
|
#endif /* HAVE_INODE_TIMESPEC64_TIMES */
|
|
|
|
#define ZFS_ACCESSTIME_STAMP(zfsvfs, zp)
|
|
|
|
struct znode;
|
|
|
|
extern int zfs_sync(struct super_block *, int, cred_t *);
|
|
extern int zfs_inode_alloc(struct super_block *, struct inode **ip);
|
|
extern void zfs_inode_destroy(struct inode *);
|
|
extern void zfs_mark_inode_dirty(struct inode *);
|
|
extern boolean_t zfs_relatime_need_update(const struct inode *);
|
|
|
|
#if defined(HAVE_UIO_RW)
|
|
extern caddr_t zfs_map_page(page_t *, enum seg_rw);
|
|
extern void zfs_unmap_page(page_t *, caddr_t);
|
|
#endif /* HAVE_UIO_RW */
|
|
|
|
extern zil_replay_func_t *const zfs_replay_vector[TX_MAX_TYPE];
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* _SYS_ZFS_ZNODE_IMPL_H */
|