1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or https://opensource.org/licenses/CDDL-1.0. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright (c) 2011, Lawrence Livermore National Security, LLC. 23 */ 24 25 #ifndef _SYS_ZPL_H 26 #define _SYS_ZPL_H 27 28 #include <sys/mntent.h> 29 #include <sys/vfs.h> 30 #include <linux/aio.h> 31 #include <linux/dcache_compat.h> 32 #include <linux/exportfs.h> 33 #include <linux/falloc.h> 34 #include <linux/parser.h> 35 #include <linux/task_io_accounting_ops.h> 36 #include <linux/vfs_compat.h> 37 #include <linux/writeback.h> 38 #include <linux/xattr_compat.h> 39 40 /* zpl_inode.c */ 41 extern void zpl_vap_init(vattr_t *vap, struct inode *dir, 42 umode_t mode, cred_t *cr, zidmap_t *mnt_ns); 43 44 extern const struct inode_operations zpl_inode_operations; 45 #ifdef HAVE_RENAME2_OPERATIONS_WRAPPER 46 extern const struct inode_operations_wrapper zpl_dir_inode_operations; 47 #else 48 extern const struct inode_operations zpl_dir_inode_operations; 49 #endif 50 extern const struct inode_operations zpl_symlink_inode_operations; 51 extern const struct inode_operations zpl_special_inode_operations; 52 53 /* zpl_file.c */ 54 extern const struct address_space_operations zpl_address_space_operations; 55 #ifdef HAVE_VFS_FILE_OPERATIONS_EXTEND 56 extern const struct file_operations_extend zpl_file_operations; 57 #else 58 extern const struct file_operations zpl_file_operations; 59 #endif 60 extern const struct file_operations zpl_dir_file_operations; 61 62 /* zpl_super.c */ 63 extern void zpl_prune_sb(uint64_t nr_to_scan, void *arg); 64 65 extern const struct super_operations zpl_super_operations; 66 extern const struct export_operations zpl_export_operations; 67 extern struct file_system_type zpl_fs_type; 68 69 /* zpl_xattr.c */ 70 extern ssize_t zpl_xattr_list(struct dentry *dentry, char *buf, size_t size); 71 extern int zpl_xattr_security_init(struct inode *ip, struct inode *dip, 72 const struct qstr *qstr); 73 #if defined(CONFIG_FS_POSIX_ACL) 74 #if defined(HAVE_SET_ACL) 75 #if defined(HAVE_SET_ACL_IDMAP_DENTRY) 76 extern int zpl_set_acl(struct mnt_idmap *idmap, struct dentry *dentry, 77 struct posix_acl *acl, int type); 78 #elif defined(HAVE_SET_ACL_USERNS) 79 extern int zpl_set_acl(struct user_namespace *userns, struct inode *ip, 80 struct posix_acl *acl, int type); 81 #elif defined(HAVE_SET_ACL_USERNS_DENTRY_ARG2) 82 extern int zpl_set_acl(struct user_namespace *userns, struct dentry *dentry, 83 struct posix_acl *acl, int type); 84 #else 85 extern int zpl_set_acl(struct inode *ip, struct posix_acl *acl, int type); 86 #endif /* HAVE_SET_ACL_USERNS */ 87 #endif /* HAVE_SET_ACL */ 88 #if defined(HAVE_GET_ACL_RCU) || defined(HAVE_GET_INODE_ACL) 89 extern struct posix_acl *zpl_get_acl(struct inode *ip, int type, bool rcu); 90 #elif defined(HAVE_GET_ACL) 91 extern struct posix_acl *zpl_get_acl(struct inode *ip, int type); 92 #endif 93 extern int zpl_init_acl(struct inode *ip, struct inode *dir); 94 extern int zpl_chmod_acl(struct inode *ip); 95 #else 96 static inline int 97 zpl_init_acl(struct inode *ip, struct inode *dir) 98 { 99 return (0); 100 } 101 102 static inline int 103 zpl_chmod_acl(struct inode *ip) 104 { 105 return (0); 106 } 107 #endif /* CONFIG_FS_POSIX_ACL */ 108 109 extern xattr_handler_t *zpl_xattr_handlers[]; 110 111 /* zpl_ctldir.c */ 112 extern const struct file_operations zpl_fops_root; 113 extern const struct inode_operations zpl_ops_root; 114 115 extern const struct file_operations zpl_fops_snapdir; 116 extern const struct inode_operations zpl_ops_snapdir; 117 118 extern const struct file_operations zpl_fops_shares; 119 extern const struct inode_operations zpl_ops_shares; 120 121 #if defined(HAVE_VFS_ITERATE) || defined(HAVE_VFS_ITERATE_SHARED) 122 123 #define ZPL_DIR_CONTEXT_INIT(_dirent, _actor, _pos) { \ 124 .actor = _actor, \ 125 .pos = _pos, \ 126 } 127 128 typedef struct dir_context zpl_dir_context_t; 129 130 #define zpl_dir_emit dir_emit 131 #define zpl_dir_emit_dot dir_emit_dot 132 #define zpl_dir_emit_dotdot dir_emit_dotdot 133 #define zpl_dir_emit_dots dir_emit_dots 134 135 #else 136 137 typedef struct zpl_dir_context { 138 void *dirent; 139 const filldir_t actor; 140 loff_t pos; 141 } zpl_dir_context_t; 142 143 #define ZPL_DIR_CONTEXT_INIT(_dirent, _actor, _pos) { \ 144 .dirent = _dirent, \ 145 .actor = _actor, \ 146 .pos = _pos, \ 147 } 148 149 static inline bool 150 zpl_dir_emit(zpl_dir_context_t *ctx, const char *name, int namelen, 151 uint64_t ino, unsigned type) 152 { 153 return (!ctx->actor(ctx->dirent, name, namelen, ctx->pos, ino, type)); 154 } 155 156 static inline bool 157 zpl_dir_emit_dot(struct file *file, zpl_dir_context_t *ctx) 158 { 159 return (ctx->actor(ctx->dirent, ".", 1, ctx->pos, 160 file_inode(file)->i_ino, DT_DIR) == 0); 161 } 162 163 static inline bool 164 zpl_dir_emit_dotdot(struct file *file, zpl_dir_context_t *ctx) 165 { 166 return (ctx->actor(ctx->dirent, "..", 2, ctx->pos, 167 parent_ino(file_dentry(file)), DT_DIR) == 0); 168 } 169 170 static inline bool 171 zpl_dir_emit_dots(struct file *file, zpl_dir_context_t *ctx) 172 { 173 if (ctx->pos == 0) { 174 if (!zpl_dir_emit_dot(file, ctx)) 175 return (false); 176 ctx->pos = 1; 177 } 178 if (ctx->pos == 1) { 179 if (!zpl_dir_emit_dotdot(file, ctx)) 180 return (false); 181 ctx->pos = 2; 182 } 183 return (true); 184 } 185 #endif /* HAVE_VFS_ITERATE */ 186 187 188 /* zpl_file_range.c */ 189 190 /* handlers for file_operations of the same name */ 191 extern ssize_t zpl_copy_file_range(struct file *src_file, loff_t src_off, 192 struct file *dst_file, loff_t dst_off, size_t len, unsigned int flags); 193 extern loff_t zpl_remap_file_range(struct file *src_file, loff_t src_off, 194 struct file *dst_file, loff_t dst_off, loff_t len, unsigned int flags); 195 extern int zpl_clone_file_range(struct file *src_file, loff_t src_off, 196 struct file *dst_file, loff_t dst_off, uint64_t len); 197 extern int zpl_dedupe_file_range(struct file *src_file, loff_t src_off, 198 struct file *dst_file, loff_t dst_off, uint64_t len); 199 200 /* compat for FICLONE/FICLONERANGE/FIDEDUPERANGE ioctls */ 201 typedef struct { 202 int64_t fcr_src_fd; 203 uint64_t fcr_src_offset; 204 uint64_t fcr_src_length; 205 uint64_t fcr_dest_offset; 206 } zfs_ioc_compat_file_clone_range_t; 207 208 typedef struct { 209 int64_t fdri_dest_fd; 210 uint64_t fdri_dest_offset; 211 uint64_t fdri_bytes_deduped; 212 int32_t fdri_status; 213 uint32_t fdri_reserved; 214 } zfs_ioc_compat_dedupe_range_info_t; 215 216 typedef struct { 217 uint64_t fdr_src_offset; 218 uint64_t fdr_src_length; 219 uint16_t fdr_dest_count; 220 uint16_t fdr_reserved1; 221 uint32_t fdr_reserved2; 222 zfs_ioc_compat_dedupe_range_info_t fdr_info[]; 223 } zfs_ioc_compat_dedupe_range_t; 224 225 #define ZFS_IOC_COMPAT_FICLONE _IOW(0x94, 9, int) 226 #define ZFS_IOC_COMPAT_FICLONERANGE \ 227 _IOW(0x94, 13, zfs_ioc_compat_file_clone_range_t) 228 #define ZFS_IOC_COMPAT_FIDEDUPERANGE \ 229 _IOWR(0x94, 54, zfs_ioc_compat_dedupe_range_t) 230 231 extern long zpl_ioctl_ficlone(struct file *filp, void *arg); 232 extern long zpl_ioctl_ficlonerange(struct file *filp, void *arg); 233 extern long zpl_ioctl_fideduperange(struct file *filp, void *arg); 234 235 236 #if defined(HAVE_INODE_TIMESTAMP_TRUNCATE) 237 #define zpl_inode_timestamp_truncate(ts, ip) timestamp_truncate(ts, ip) 238 #elif defined(HAVE_INODE_TIMESPEC64_TIMES) 239 #define zpl_inode_timestamp_truncate(ts, ip) \ 240 timespec64_trunc(ts, (ip)->i_sb->s_time_gran) 241 #else 242 #define zpl_inode_timestamp_truncate(ts, ip) \ 243 timespec_trunc(ts, (ip)->i_sb->s_time_gran) 244 #endif 245 246 #if defined(HAVE_INODE_OWNER_OR_CAPABLE) 247 #define zpl_inode_owner_or_capable(ns, ip) inode_owner_or_capable(ip) 248 #elif defined(HAVE_INODE_OWNER_OR_CAPABLE_USERNS) 249 #define zpl_inode_owner_or_capable(ns, ip) inode_owner_or_capable(ns, ip) 250 #elif defined(HAVE_INODE_OWNER_OR_CAPABLE_IDMAP) 251 #define zpl_inode_owner_or_capable(idmap, ip) inode_owner_or_capable(idmap, ip) 252 #else 253 #error "Unsupported kernel" 254 #endif 255 256 #if defined(HAVE_SETATTR_PREPARE_USERNS) || defined(HAVE_SETATTR_PREPARE_IDMAP) 257 #define zpl_setattr_prepare(ns, dentry, ia) setattr_prepare(ns, dentry, ia) 258 #else 259 /* 260 * Use kernel-provided version, or our own from 261 * linux/vfs_compat.h 262 */ 263 #define zpl_setattr_prepare(ns, dentry, ia) setattr_prepare(dentry, ia) 264 #endif 265 266 #ifdef HAVE_INODE_GET_CTIME 267 #define zpl_inode_get_ctime(ip) inode_get_ctime(ip) 268 #else 269 #define zpl_inode_get_ctime(ip) (ip->i_ctime) 270 #endif 271 #ifdef HAVE_INODE_SET_CTIME_TO_TS 272 #define zpl_inode_set_ctime_to_ts(ip, ts) inode_set_ctime_to_ts(ip, ts) 273 #else 274 #define zpl_inode_set_ctime_to_ts(ip, ts) (ip->i_ctime = ts) 275 #endif 276 277 #endif /* _SYS_ZPL_H */ 278