1 // SPDX-License-Identifier: CDDL-1.0
2 /*
3 * CDDL HEADER START
4 *
5 * The contents of this file are subject to the terms of the
6 * Common Development and Distribution License (the "License").
7 * You may not use this file except in compliance with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or https://opensource.org/licenses/CDDL-1.0.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22
23 /*
24 * Copyright (C) 2011 Lawrence Livermore National Security, LLC.
25 * Copyright (C) 2015 Jörg Thalheim.
26 * Copyright (c) 2025, Rob Norris <robn@despairlabs.com>
27 */
28
29 #ifndef _ZFS_VFS_H
30 #define _ZFS_VFS_H
31
32 #include <sys/taskq.h>
33 #include <sys/cred.h>
34 #include <linux/backing-dev.h>
35 #include <linux/compat.h>
36
37 /*
38 * 4.14 adds SB_* flag definitions, define them to MS_* equivalents
39 * if not set.
40 */
41 #ifndef SB_RDONLY
42 #define SB_RDONLY MS_RDONLY
43 #endif
44
45 #ifndef SB_SILENT
46 #define SB_SILENT MS_SILENT
47 #endif
48
49 #ifndef SB_ACTIVE
50 #define SB_ACTIVE MS_ACTIVE
51 #endif
52
53 #ifndef SB_POSIXACL
54 #define SB_POSIXACL MS_POSIXACL
55 #endif
56
57 #ifndef SB_MANDLOCK
58 #define SB_MANDLOCK MS_MANDLOCK
59 #endif
60
61 #ifndef SB_NOATIME
62 #define SB_NOATIME MS_NOATIME
63 #endif
64
65 #if defined(SEEK_HOLE) && defined(SEEK_DATA)
66 static inline loff_t
lseek_execute(struct file * filp,struct inode * inode,loff_t offset,loff_t maxsize)67 lseek_execute(
68 struct file *filp,
69 struct inode *inode,
70 loff_t offset,
71 loff_t maxsize)
72 {
73 #ifdef FMODE_UNSIGNED_OFFSET
74 if (offset < 0 && !(filp->f_mode & FMODE_UNSIGNED_OFFSET))
75 #else
76 if (offset < 0 && !(filp->f_op->fop_flags & FOP_UNSIGNED_OFFSET))
77 #endif
78 return (-EINVAL);
79
80 if (offset > maxsize)
81 return (-EINVAL);
82
83 if (offset != filp->f_pos) {
84 spin_lock(&filp->f_lock);
85 filp->f_pos = offset;
86 #ifdef HAVE_FILE_F_VERSION
87 filp->f_version = 0;
88 #endif
89 spin_unlock(&filp->f_lock);
90 }
91
92 return (offset);
93 }
94 #endif /* SEEK_HOLE && SEEK_DATA */
95
96 #if defined(CONFIG_FS_POSIX_ACL)
97 /*
98 * These functions safely approximates the behavior of posix_acl_release()
99 * which cannot be used because it calls the GPL-only symbol kfree_rcu().
100 * The in-kernel version, which can access the RCU, frees the ACLs after
101 * the grace period expires. Because we're unsure how long that grace
102 * period may be this implementation conservatively delays for 60 seconds.
103 * This is several orders of magnitude larger than expected grace period.
104 * At 60 seconds the kernel will also begin issuing RCU stall warnings.
105 */
106
107 #include <linux/posix_acl.h>
108
109 void zpl_posix_acl_release_impl(struct posix_acl *);
110
111 static inline void
zpl_posix_acl_release(struct posix_acl * acl)112 zpl_posix_acl_release(struct posix_acl *acl)
113 {
114 if ((acl == NULL) || (acl == ACL_NOT_CACHED))
115 return;
116 if (refcount_dec_and_test(&acl->a_refcount))
117 zpl_posix_acl_release_impl(acl);
118 }
119 #endif /* CONFIG_FS_POSIX_ACL */
120
zfs_uid_read_impl(struct inode * ip)121 static inline uid_t zfs_uid_read_impl(struct inode *ip)
122 {
123 return (from_kuid(kcred->user_ns, ip->i_uid));
124 }
125
zfs_uid_read(struct inode * ip)126 static inline uid_t zfs_uid_read(struct inode *ip)
127 {
128 return (zfs_uid_read_impl(ip));
129 }
130
zfs_gid_read_impl(struct inode * ip)131 static inline gid_t zfs_gid_read_impl(struct inode *ip)
132 {
133 return (from_kgid(kcred->user_ns, ip->i_gid));
134 }
135
zfs_gid_read(struct inode * ip)136 static inline gid_t zfs_gid_read(struct inode *ip)
137 {
138 return (zfs_gid_read_impl(ip));
139 }
140
zfs_uid_write(struct inode * ip,uid_t uid)141 static inline void zfs_uid_write(struct inode *ip, uid_t uid)
142 {
143 ip->i_uid = make_kuid(kcred->user_ns, uid);
144 }
145
zfs_gid_write(struct inode * ip,gid_t gid)146 static inline void zfs_gid_write(struct inode *ip, gid_t gid)
147 {
148 ip->i_gid = make_kgid(kcred->user_ns, gid);
149 }
150
151 /*
152 * 3.15 API change
153 */
154 #ifndef RENAME_NOREPLACE
155 #define RENAME_NOREPLACE (1 << 0) /* Don't overwrite target */
156 #endif
157 #ifndef RENAME_EXCHANGE
158 #define RENAME_EXCHANGE (1 << 1) /* Exchange source and dest */
159 #endif
160 #ifndef RENAME_WHITEOUT
161 #define RENAME_WHITEOUT (1 << 2) /* Whiteout source */
162 #endif
163
164 /*
165 * 4.9 API change
166 */
167 #if !(defined(HAVE_SETATTR_PREPARE_NO_USERNS) || \
168 defined(HAVE_SETATTR_PREPARE_USERNS) || \
169 defined(HAVE_SETATTR_PREPARE_IDMAP))
170 static inline int
setattr_prepare(struct dentry * dentry,struct iattr * ia)171 setattr_prepare(struct dentry *dentry, struct iattr *ia)
172 {
173 return (inode_change_ok(dentry->d_inode, ia));
174 }
175 #endif
176
177 /*
178 * 4.11 API change
179 * These macros are defined by kernel 4.11. We define them so that the same
180 * code builds under kernels < 4.11 and >= 4.11. The macros are set to 0 so
181 * that it will create obvious failures if they are accidentally used when built
182 * against a kernel >= 4.11.
183 */
184
185 #ifndef STATX_BASIC_STATS
186 #define STATX_BASIC_STATS 0
187 #endif
188
189 #ifndef AT_STATX_SYNC_AS_STAT
190 #define AT_STATX_SYNC_AS_STAT 0
191 #endif
192
193 /*
194 * 4.11 API change
195 * 4.11 takes struct path *, < 4.11 takes vfsmount *
196 */
197
198 #if defined(HAVE_PATH_IOPS_GETATTR)
199 #define ZPL_GETATTR_WRAPPER(func) \
200 static int \
201 func(const struct path *path, struct kstat *stat, u32 request_mask, \
202 unsigned int query_flags) \
203 { \
204 return (func##_impl(path, stat, request_mask, query_flags)); \
205 }
206 #elif defined(HAVE_USERNS_IOPS_GETATTR)
207 #define ZPL_GETATTR_WRAPPER(func) \
208 static int \
209 func(struct user_namespace *user_ns, const struct path *path, \
210 struct kstat *stat, u32 request_mask, unsigned int query_flags) \
211 { \
212 return (func##_impl(user_ns, path, stat, request_mask, \
213 query_flags)); \
214 }
215 #elif defined(HAVE_IDMAP_IOPS_GETATTR)
216 #define ZPL_GETATTR_WRAPPER(func) \
217 static int \
218 func(struct mnt_idmap *user_ns, const struct path *path, \
219 struct kstat *stat, u32 request_mask, unsigned int query_flags) \
220 { \
221 return (func##_impl(user_ns, path, stat, request_mask, \
222 query_flags)); \
223 }
224 #else
225 #error
226 #endif
227
228 /*
229 * Returns true when called in the context of a 32-bit system call.
230 */
231 static inline int
zpl_is_32bit_api(void)232 zpl_is_32bit_api(void)
233 {
234 #ifdef CONFIG_COMPAT
235 return (in_compat_syscall());
236 #else
237 return (BITS_PER_LONG == 32);
238 #endif
239 }
240
241 /*
242 * 5.12 API change
243 * To support id-mapped mounts, generic_fillattr() was modified to
244 * accept a new struct user_namespace* as its first arg.
245 *
246 * 6.3 API change
247 * generic_fillattr() first arg is changed to struct mnt_idmap *
248 *
249 * 6.6 API change
250 * generic_fillattr() gets new second arg request_mask, a u32 type
251 *
252 */
253 #ifdef HAVE_GENERIC_FILLATTR_IDMAP
254 #define zpl_generic_fillattr(idmap, ip, sp) \
255 generic_fillattr(idmap, ip, sp)
256 #elif defined(HAVE_GENERIC_FILLATTR_IDMAP_REQMASK)
257 #define zpl_generic_fillattr(idmap, rqm, ip, sp) \
258 generic_fillattr(idmap, rqm, ip, sp)
259 #elif defined(HAVE_GENERIC_FILLATTR_USERNS)
260 #define zpl_generic_fillattr(user_ns, ip, sp) \
261 generic_fillattr(user_ns, ip, sp)
262 #else
263 #define zpl_generic_fillattr(user_ns, ip, sp) generic_fillattr(ip, sp)
264 #endif
265
266 #ifdef HAVE_INODE_GENERIC_DROP
267 /* 6.18 API change. These were renamed, alias the old names to the new. */
268 #define generic_delete_inode(ip) inode_just_drop(ip)
269 #define generic_drop_inode(ip) inode_generic_drop(ip)
270 #endif
271
272 #endif /* _ZFS_VFS_H */
273