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/* 23 * Copyright (C) 2011 Lawrence Livermore National Security, LLC. 24 * Copyright (C) 2015 J��rg Thalheim. 25 */ 26 27#ifndef _ZFS_VFS_H 28#define _ZFS_VFS_H 29 30#include <sys/taskq.h> 31#include <sys/cred.h> 32#include <linux/backing-dev.h> 33#include <linux/compat.h> 34 35/* 36 * 2.6.34 - 3.19, bdi_setup_and_register() takes 3 arguments. 37 * 4.0 - 4.11, bdi_setup_and_register() takes 2 arguments. 38 * 4.12 - x.y, super_setup_bdi_name() new interface. 39 */ 40#if defined(HAVE_SUPER_SETUP_BDI_NAME) 41extern atomic_long_t zfs_bdi_seq; 42 43static inline int 44zpl_bdi_setup(struct super_block *sb, char *name) 45{ 46 return super_setup_bdi_name(sb, "%.28s-%ld", name, 47 atomic_long_inc_return(&zfs_bdi_seq)); 48} 49static inline void 50zpl_bdi_destroy(struct super_block *sb) 51{ 52} 53#elif defined(HAVE_2ARGS_BDI_SETUP_AND_REGISTER) 54static inline int 55zpl_bdi_setup(struct super_block *sb, char *name) 56{ 57 struct backing_dev_info *bdi; 58 int error; 59 60 bdi = kmem_zalloc(sizeof (struct backing_dev_info), KM_SLEEP); 61 error = bdi_setup_and_register(bdi, name); 62 if (error) { 63 kmem_free(bdi, sizeof (struct backing_dev_info)); 64 return (error); 65 } 66 67 sb->s_bdi = bdi; 68 69 return (0); 70} 71static inline void 72zpl_bdi_destroy(struct super_block *sb) 73{ 74 struct backing_dev_info *bdi = sb->s_bdi; 75 76 bdi_destroy(bdi); 77 kmem_free(bdi, sizeof (struct backing_dev_info)); 78 sb->s_bdi = NULL; 79} 80#elif defined(HAVE_3ARGS_BDI_SETUP_AND_REGISTER) 81static inline int 82zpl_bdi_setup(struct super_block *sb, char *name) 83{ 84 struct backing_dev_info *bdi; 85 int error; 86 87 bdi = kmem_zalloc(sizeof (struct backing_dev_info), KM_SLEEP); 88 error = bdi_setup_and_register(bdi, name, BDI_CAP_MAP_COPY); 89 if (error) { 90 kmem_free(sb->s_bdi, sizeof (struct backing_dev_info)); 91 return (error); 92 } 93 94 sb->s_bdi = bdi; 95 96 return (0); 97} 98static inline void 99zpl_bdi_destroy(struct super_block *sb) 100{ 101 struct backing_dev_info *bdi = sb->s_bdi; 102 103 bdi_destroy(bdi); 104 kmem_free(bdi, sizeof (struct backing_dev_info)); 105 sb->s_bdi = NULL; 106} 107#else 108#error "Unsupported kernel" 109#endif 110 111/* 112 * 4.14 adds SB_* flag definitions, define them to MS_* equivalents 113 * if not set. 114 */ 115#ifndef SB_RDONLY 116#define SB_RDONLY MS_RDONLY 117#endif 118 119#ifndef SB_SILENT 120#define SB_SILENT MS_SILENT 121#endif 122 123#ifndef SB_ACTIVE 124#define SB_ACTIVE MS_ACTIVE 125#endif 126 127#ifndef SB_POSIXACL 128#define SB_POSIXACL MS_POSIXACL 129#endif 130 131#ifndef SB_MANDLOCK 132#define SB_MANDLOCK MS_MANDLOCK 133#endif 134 135#ifndef SB_NOATIME 136#define SB_NOATIME MS_NOATIME 137#endif 138 139/* 140 * 3.5 API change, 141 * The clear_inode() function replaces end_writeback() and introduces an 142 * ordering change regarding when the inode_sync_wait() occurs. See the 143 * configure check in config/kernel-clear-inode.m4 for full details. 144 */ 145#if defined(HAVE_EVICT_INODE) && !defined(HAVE_CLEAR_INODE) 146#define clear_inode(ip) end_writeback(ip) 147#endif /* HAVE_EVICT_INODE && !HAVE_CLEAR_INODE */ 148 149#if defined(SEEK_HOLE) && defined(SEEK_DATA) && !defined(HAVE_LSEEK_EXECUTE) 150static inline loff_t 151lseek_execute( 152 struct file *filp, 153 struct inode *inode, 154 loff_t offset, 155 loff_t maxsize) 156{ 157 if (offset < 0 && !(filp->f_mode & FMODE_UNSIGNED_OFFSET)) 158 return (-EINVAL); 159 160 if (offset > maxsize) 161 return (-EINVAL); 162 163 if (offset != filp->f_pos) { 164 spin_lock(&filp->f_lock); 165 filp->f_pos = offset; 166 filp->f_version = 0; 167 spin_unlock(&filp->f_lock); 168 } 169 170 return (offset); 171} 172#endif /* SEEK_HOLE && SEEK_DATA && !HAVE_LSEEK_EXECUTE */ 173 174#if defined(CONFIG_FS_POSIX_ACL) 175/* 176 * These functions safely approximates the behavior of posix_acl_release() 177 * which cannot be used because it calls the GPL-only symbol kfree_rcu(). 178 * The in-kernel version, which can access the RCU, frees the ACLs after 179 * the grace period expires. Because we're unsure how long that grace 180 * period may be this implementation conservatively delays for 60 seconds. 181 * This is several orders of magnitude larger than expected grace period. 182 * At 60 seconds the kernel will also begin issuing RCU stall warnings. 183 */ 184 185#include <linux/posix_acl.h> 186 187#if defined(HAVE_POSIX_ACL_RELEASE) && !defined(HAVE_POSIX_ACL_RELEASE_GPL_ONLY) 188#define zpl_posix_acl_release(arg) posix_acl_release(arg) 189#else 190void zpl_posix_acl_release_impl(struct posix_acl *); 191 192static inline void 193zpl_posix_acl_release(struct posix_acl *acl) 194{ 195 if ((acl == NULL) || (acl == ACL_NOT_CACHED)) 196 return; 197#ifdef HAVE_ACL_REFCOUNT 198 if (refcount_dec_and_test(&acl->a_refcount)) 199 zpl_posix_acl_release_impl(acl); 200#else 201 if (atomic_dec_and_test(&acl->a_refcount)) 202 zpl_posix_acl_release_impl(acl); 203#endif 204} 205#endif /* HAVE_POSIX_ACL_RELEASE */ 206 207#ifdef HAVE_SET_CACHED_ACL_USABLE 208#define zpl_set_cached_acl(ip, ty, n) set_cached_acl(ip, ty, n) 209#define zpl_forget_cached_acl(ip, ty) forget_cached_acl(ip, ty) 210#else 211static inline void 212zpl_set_cached_acl(struct inode *ip, int type, struct posix_acl *newer) 213{ 214 struct posix_acl *older = NULL; 215 216 spin_lock(&ip->i_lock); 217 218 if ((newer != ACL_NOT_CACHED) && (newer != NULL)) 219 posix_acl_dup(newer); 220 221 switch (type) { 222 case ACL_TYPE_ACCESS: 223 older = ip->i_acl; 224 rcu_assign_pointer(ip->i_acl, newer); 225 break; 226 case ACL_TYPE_DEFAULT: 227 older = ip->i_default_acl; 228 rcu_assign_pointer(ip->i_default_acl, newer); 229 break; 230 } 231 232 spin_unlock(&ip->i_lock); 233 234 zpl_posix_acl_release(older); 235} 236 237static inline void 238zpl_forget_cached_acl(struct inode *ip, int type) 239{ 240 zpl_set_cached_acl(ip, type, (struct posix_acl *)ACL_NOT_CACHED); 241} 242#endif /* HAVE_SET_CACHED_ACL_USABLE */ 243 244/* 245 * 3.1 API change, 246 * posix_acl_chmod() was added as the preferred interface. 247 * 248 * 3.14 API change, 249 * posix_acl_chmod() was changed to __posix_acl_chmod() 250 */ 251#ifndef HAVE___POSIX_ACL_CHMOD 252#ifdef HAVE_POSIX_ACL_CHMOD 253#define __posix_acl_chmod(acl, gfp, mode) posix_acl_chmod(acl, gfp, mode) 254#define __posix_acl_create(acl, gfp, mode) posix_acl_create(acl, gfp, mode) 255#else 256#error "Unsupported kernel" 257#endif /* HAVE_POSIX_ACL_CHMOD */ 258#endif /* HAVE___POSIX_ACL_CHMOD */ 259 260/* 261 * 4.8 API change, 262 * posix_acl_valid() now must be passed a namespace, the namespace from 263 * from super block associated with the given inode is used for this purpose. 264 */ 265#ifdef HAVE_POSIX_ACL_VALID_WITH_NS 266#define zpl_posix_acl_valid(ip, acl) posix_acl_valid(ip->i_sb->s_user_ns, acl) 267#else 268#define zpl_posix_acl_valid(ip, acl) posix_acl_valid(acl) 269#endif 270 271#endif /* CONFIG_FS_POSIX_ACL */ 272 273/* 274 * 3.19 API change 275 * struct access f->f_dentry->d_inode was replaced by accessor function 276 * file_inode(f) 277 */ 278#ifndef HAVE_FILE_INODE 279static inline struct inode *file_inode(const struct file *f) 280{ 281 return (f->f_dentry->d_inode); 282} 283#endif /* HAVE_FILE_INODE */ 284 285/* 286 * 4.1 API change 287 * struct access file->f_path.dentry was replaced by accessor function 288 * file_dentry(f) 289 */ 290#ifndef HAVE_FILE_DENTRY 291static inline struct dentry *file_dentry(const struct file *f) 292{ 293 return (f->f_path.dentry); 294} 295#endif /* HAVE_FILE_DENTRY */ 296 297static inline uid_t zfs_uid_read_impl(struct inode *ip) 298{ 299 return (from_kuid(kcred->user_ns, ip->i_uid)); 300} 301 302static inline uid_t zfs_uid_read(struct inode *ip) 303{ 304 return (zfs_uid_read_impl(ip)); 305} 306 307static inline gid_t zfs_gid_read_impl(struct inode *ip) 308{ 309 return (from_kgid(kcred->user_ns, ip->i_gid)); 310} 311 312static inline gid_t zfs_gid_read(struct inode *ip) 313{ 314 return (zfs_gid_read_impl(ip)); 315} 316 317static inline void zfs_uid_write(struct inode *ip, uid_t uid) 318{ 319 ip->i_uid = make_kuid(kcred->user_ns, uid); 320} 321 322static inline void zfs_gid_write(struct inode *ip, gid_t gid) 323{ 324 ip->i_gid = make_kgid(kcred->user_ns, gid); 325} 326 327/* 328 * 3.15 API change 329 */ 330#ifndef RENAME_NOREPLACE 331#define RENAME_NOREPLACE (1 << 0) /* Don't overwrite target */ 332#endif 333#ifndef RENAME_EXCHANGE 334#define RENAME_EXCHANGE (1 << 1) /* Exchange source and dest */ 335#endif 336#ifndef RENAME_WHITEOUT 337#define RENAME_WHITEOUT (1 << 2) /* Whiteout source */ 338#endif 339 340/* 341 * 4.9 API change 342 */ 343#if !(defined(HAVE_SETATTR_PREPARE_NO_USERNS) || \ 344 defined(HAVE_SETATTR_PREPARE_USERNS) || \ 345 defined(HAVE_SETATTR_PREPARE_IDMAP)) 346static inline int 347setattr_prepare(struct dentry *dentry, struct iattr *ia) 348{ 349 return (inode_change_ok(dentry->d_inode, ia)); 350} 351#endif 352 353/* 354 * 4.11 API change 355 * These macros are defined by kernel 4.11. We define them so that the same 356 * code builds under kernels < 4.11 and >= 4.11. The macros are set to 0 so 357 * that it will create obvious failures if they are accidentally used when built 358 * against a kernel >= 4.11. 359 */ 360 361#ifndef STATX_BASIC_STATS 362#define STATX_BASIC_STATS 0 363#endif 364 365#ifndef AT_STATX_SYNC_AS_STAT 366#define AT_STATX_SYNC_AS_STAT 0 367#endif 368 369/* 370 * 4.11 API change 371 * 4.11 takes struct path *, < 4.11 takes vfsmount * 372 */ 373 374#ifdef HAVE_VFSMOUNT_IOPS_GETATTR 375#define ZPL_GETATTR_WRAPPER(func) \ 376static int \ 377func(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) \ 378{ \ 379 struct path path = { .mnt = mnt, .dentry = dentry }; \ 380 return func##_impl(&path, stat, STATX_BASIC_STATS, \ 381 AT_STATX_SYNC_AS_STAT); \ 382} 383#elif defined(HAVE_PATH_IOPS_GETATTR) 384#define ZPL_GETATTR_WRAPPER(func) \ 385static int \ 386func(const struct path *path, struct kstat *stat, u32 request_mask, \ 387 unsigned int query_flags) \ 388{ \ 389 return (func##_impl(path, stat, request_mask, query_flags)); \ 390} 391#elif defined(HAVE_USERNS_IOPS_GETATTR) 392#define ZPL_GETATTR_WRAPPER(func) \ 393static int \ 394func(struct user_namespace *user_ns, const struct path *path, \ 395 struct kstat *stat, u32 request_mask, unsigned int query_flags) \ 396{ \ 397 return (func##_impl(user_ns, path, stat, request_mask, \ 398 query_flags)); \ 399} 400#elif defined(HAVE_IDMAP_IOPS_GETATTR) 401#define ZPL_GETATTR_WRAPPER(func) \ 402static int \ 403func(struct mnt_idmap *user_ns, const struct path *path, \ 404 struct kstat *stat, u32 request_mask, unsigned int query_flags) \ 405{ \ 406 return (func##_impl(user_ns, path, stat, request_mask, \ 407 query_flags)); \ 408} 409#else 410#error 411#endif 412 413/* 414 * 4.9 API change 415 * Preferred interface to get the current FS time. 416 */ 417#if !defined(HAVE_CURRENT_TIME) 418static inline struct timespec 419current_time(struct inode *ip) 420{ 421 return (timespec_trunc(current_kernel_time(), ip->i_sb->s_time_gran)); 422} 423#endif 424 425/* 426 * 4.16 API change 427 * Added iversion interface for managing inode version field. 428 */ 429#ifdef HAVE_INODE_SET_IVERSION 430#include <linux/iversion.h> 431#else 432static inline void 433inode_set_iversion(struct inode *ip, u64 val) 434{ 435 ip->i_version = val; 436} 437#endif 438 439/* 440 * Returns true when called in the context of a 32-bit system call. 441 */ 442static inline int 443zpl_is_32bit_api(void) 444{ 445#ifdef CONFIG_COMPAT 446#ifdef HAVE_IN_COMPAT_SYSCALL 447 return (in_compat_syscall()); 448#else 449 return (is_compat_task()); 450#endif 451#else 452 return (BITS_PER_LONG == 32); 453#endif 454} 455 456/* 457 * 5.12 API change 458 * To support id-mapped mounts, generic_fillattr() was modified to 459 * accept a new struct user_namespace* as its first arg. 460 * 461 * 6.3 API change 462 * generic_fillattr() first arg is changed to struct mnt_idmap * 463 * 464 * 6.6 API change 465 * generic_fillattr() gets new second arg request_mask, a u32 type 466 * 467 */ 468#ifdef HAVE_GENERIC_FILLATTR_IDMAP 469#define zpl_generic_fillattr(idmap, ip, sp) \ 470 generic_fillattr(idmap, ip, sp) 471#elif defined(HAVE_GENERIC_FILLATTR_IDMAP_REQMASK) 472#define zpl_generic_fillattr(idmap, rqm, ip, sp) \ 473 generic_fillattr(idmap, rqm, ip, sp) 474#elif defined(HAVE_GENERIC_FILLATTR_USERNS) 475#define zpl_generic_fillattr(user_ns, ip, sp) \ 476 generic_fillattr(user_ns, ip, sp) 477#else 478#define zpl_generic_fillattr(user_ns, ip, sp) generic_fillattr(ip, sp) 479#endif 480 481#endif /* _ZFS_VFS_H */ 482