/* * 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 #include #include #include #include #include #include #include #include #include #include #ifdef __cplusplus extern "C" { #endif #if defined(HAVE_FILEMAP_RANGE_HAS_PAGE) #define ZNODE_OS_FIELDS \ inode_timespec_t z_btime; /* creation/birth time (cached) */ \ struct inode z_inode; #else #define ZNODE_OS_FIELDS \ inode_timespec_t z_btime; /* creation/birth time (cached) */ \ struct inode z_inode; \ boolean_t z_is_mapped; /* we are mmap'ed */ #endif /* * 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) #if defined(HAVE_FILEMAP_RANGE_HAS_PAGE) #define zn_has_cached_data(zp, start, end) \ filemap_range_has_page(ZTOI(zp)->i_mapping, start, end) #else #define zn_has_cached_data(zp, start, end) \ ((zp)->z_is_mapped) #endif #define zn_flush_cached_data(zp, sync) write_inode_now(ZTOI(zp), sync) #define zn_rlimit_fsize(size) (0) #define zn_rlimit_fsize_uio(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 */