]>
Commit | Line | Data |
---|---|---|
ee154f01 BB |
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 http://www.opensolaris.org/os/licensing. | |
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 | ||
26 | #include <sys/zfs_vfsops.h> | |
27 | #include <sys/zfs_vnops.h> | |
ebe7e575 | 28 | #include <sys/zfs_znode.h> |
ee154f01 BB |
29 | #include <sys/vfs.h> |
30 | #include <sys/zpl.h> | |
31 | ||
32 | ||
33 | static struct dentry * | |
8f195a90 | 34 | #ifdef HAVE_LOOKUP_NAMEIDATA |
ee154f01 | 35 | zpl_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) |
8f195a90 YS |
36 | #else |
37 | zpl_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) | |
38 | #endif | |
ee154f01 | 39 | { |
81e97e21 | 40 | cred_t *cr = CRED(); |
ee154f01 | 41 | struct inode *ip; |
ee154f01 | 42 | int error; |
40d06e3c | 43 | fstrans_cookie_t cookie; |
ee154f01 | 44 | |
9878a89d | 45 | if (dlen(dentry) > ZFS_MAXNAMELEN) |
d1d7e268 | 46 | return (ERR_PTR(-ENAMETOOLONG)); |
9878a89d | 47 | |
81e97e21 | 48 | crhold(cr); |
40d06e3c | 49 | cookie = spl_fstrans_mark(); |
ee154f01 | 50 | error = -zfs_lookup(dir, dname(dentry), &ip, 0, cr, NULL, NULL); |
40d06e3c | 51 | spl_fstrans_unmark(cookie); |
ee154f01 | 52 | ASSERT3S(error, <=, 0); |
81e97e21 | 53 | crfree(cr); |
ee154f01 | 54 | |
7b3e34ba BB |
55 | spin_lock(&dentry->d_lock); |
56 | dentry->d_time = jiffies; | |
ee930353 BB |
57 | #ifndef HAVE_S_D_OP |
58 | d_set_d_op(dentry, &zpl_dentry_operations); | |
59 | #endif /* HAVE_S_D_OP */ | |
7b3e34ba BB |
60 | spin_unlock(&dentry->d_lock); |
61 | ||
ee154f01 BB |
62 | if (error) { |
63 | if (error == -ENOENT) | |
d1d7e268 | 64 | return (d_splice_alias(NULL, dentry)); |
ee154f01 | 65 | else |
d1d7e268 | 66 | return (ERR_PTR(error)); |
ee154f01 BB |
67 | } |
68 | ||
d1d7e268 | 69 | return (d_splice_alias(ip, dentry)); |
ee154f01 BB |
70 | } |
71 | ||
ebe7e575 | 72 | void |
7b3e34ba | 73 | zpl_vap_init(vattr_t *vap, struct inode *dir, zpl_umode_t mode, cred_t *cr) |
9fd91dae BB |
74 | { |
75 | vap->va_mask = ATTR_MODE; | |
76 | vap->va_mode = mode; | |
9fd91dae BB |
77 | vap->va_uid = crgetfsuid(cr); |
78 | ||
79 | if (dir && dir->i_mode & S_ISGID) { | |
570d6edf | 80 | vap->va_gid = KGID_TO_SGID(dir->i_gid); |
9fd91dae BB |
81 | if (S_ISDIR(mode)) |
82 | vap->va_mode |= S_ISGID; | |
83 | } else { | |
84 | vap->va_gid = crgetfsgid(cr); | |
85 | } | |
86 | } | |
87 | ||
ee154f01 | 88 | static int |
558ef6d0 | 89 | #ifdef HAVE_CREATE_NAMEIDATA |
b39d3b9f | 90 | zpl_create(struct inode *dir, struct dentry *dentry, zpl_umode_t mode, |
ee154f01 | 91 | struct nameidata *nd) |
558ef6d0 YS |
92 | #else |
93 | zpl_create(struct inode *dir, struct dentry *dentry, zpl_umode_t mode, | |
94 | bool flag) | |
95 | #endif | |
ee154f01 | 96 | { |
81e97e21 | 97 | cred_t *cr = CRED(); |
ee154f01 BB |
98 | struct inode *ip; |
99 | vattr_t *vap; | |
100 | int error; | |
40d06e3c | 101 | fstrans_cookie_t cookie; |
ee154f01 | 102 | |
81e97e21 | 103 | crhold(cr); |
d1d7e268 | 104 | vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP); |
7b3e34ba | 105 | zpl_vap_init(vap, dir, mode, cr); |
ee154f01 | 106 | |
40d06e3c | 107 | cookie = spl_fstrans_mark(); |
e89260a1 | 108 | error = -zfs_create(dir, dname(dentry), vap, 0, mode, &ip, cr, 0, NULL); |
40d06e3c | 109 | spl_fstrans_unmark(cookie); |
e89260a1 | 110 | if (error == 0) { |
023699cd MM |
111 | VERIFY0(zpl_xattr_security_init(ip, dir, &dentry->d_name)); |
112 | VERIFY0(zpl_init_acl(ip, dir)); | |
7b3e34ba | 113 | d_instantiate(dentry, ip); |
e89260a1 BB |
114 | } |
115 | ||
d1d7e268 | 116 | kmem_free(vap, sizeof (vattr_t)); |
81e97e21 | 117 | crfree(cr); |
ee154f01 BB |
118 | ASSERT3S(error, <=, 0); |
119 | ||
120 | return (error); | |
121 | } | |
122 | ||
123 | static int | |
b39d3b9f BB |
124 | zpl_mknod(struct inode *dir, struct dentry *dentry, zpl_umode_t mode, |
125 | dev_t rdev) | |
ee154f01 | 126 | { |
81e97e21 | 127 | cred_t *cr = CRED(); |
ee154f01 BB |
128 | struct inode *ip; |
129 | vattr_t *vap; | |
130 | int error; | |
40d06e3c | 131 | fstrans_cookie_t cookie; |
ee154f01 | 132 | |
aa6d8c10 NB |
133 | /* |
134 | * We currently expect Linux to supply rdev=0 for all sockets | |
135 | * and fifos, but we want to know if this behavior ever changes. | |
136 | */ | |
137 | if (S_ISSOCK(mode) || S_ISFIFO(mode)) | |
138 | ASSERT(rdev == 0); | |
139 | ||
81e97e21 | 140 | crhold(cr); |
d1d7e268 | 141 | vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP); |
7b3e34ba | 142 | zpl_vap_init(vap, dir, mode, cr); |
ee154f01 | 143 | vap->va_rdev = rdev; |
ee154f01 | 144 | |
40d06e3c | 145 | cookie = spl_fstrans_mark(); |
7b3e34ba | 146 | error = -zfs_create(dir, dname(dentry), vap, 0, mode, &ip, cr, 0, NULL); |
40d06e3c | 147 | spl_fstrans_unmark(cookie); |
023699cd | 148 | if (error == 0) { |
227bc969 | 149 | VERIFY0(zpl_xattr_security_init(ip, dir, &dentry->d_name)); |
023699cd | 150 | VERIFY0(zpl_init_acl(ip, dir)); |
7b3e34ba | 151 | d_instantiate(dentry, ip); |
023699cd | 152 | } |
7b3e34ba | 153 | |
d1d7e268 | 154 | kmem_free(vap, sizeof (vattr_t)); |
81e97e21 | 155 | crfree(cr); |
ee154f01 BB |
156 | ASSERT3S(error, <=, 0); |
157 | ||
34d5a5fd | 158 | return (error); |
ee154f01 BB |
159 | } |
160 | ||
161 | static int | |
162 | zpl_unlink(struct inode *dir, struct dentry *dentry) | |
163 | { | |
81e97e21 | 164 | cred_t *cr = CRED(); |
ee154f01 | 165 | int error; |
40d06e3c | 166 | fstrans_cookie_t cookie; |
ee154f01 | 167 | |
81e97e21 | 168 | crhold(cr); |
40d06e3c | 169 | cookie = spl_fstrans_mark(); |
ee154f01 | 170 | error = -zfs_remove(dir, dname(dentry), cr); |
40d06e3c | 171 | spl_fstrans_unmark(cookie); |
81e97e21 | 172 | crfree(cr); |
ee154f01 BB |
173 | ASSERT3S(error, <=, 0); |
174 | ||
175 | return (error); | |
176 | } | |
177 | ||
178 | static int | |
b39d3b9f | 179 | zpl_mkdir(struct inode *dir, struct dentry *dentry, zpl_umode_t mode) |
ee154f01 | 180 | { |
81e97e21 | 181 | cred_t *cr = CRED(); |
ee154f01 BB |
182 | vattr_t *vap; |
183 | struct inode *ip; | |
184 | int error; | |
40d06e3c | 185 | fstrans_cookie_t cookie; |
ee154f01 | 186 | |
81e97e21 | 187 | crhold(cr); |
d1d7e268 | 188 | vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP); |
7b3e34ba | 189 | zpl_vap_init(vap, dir, mode | S_IFDIR, cr); |
ee154f01 | 190 | |
40d06e3c | 191 | cookie = spl_fstrans_mark(); |
ee154f01 | 192 | error = -zfs_mkdir(dir, dname(dentry), vap, &ip, cr, 0, NULL); |
40d06e3c | 193 | spl_fstrans_unmark(cookie); |
023699cd | 194 | if (error == 0) { |
227bc969 | 195 | VERIFY0(zpl_xattr_security_init(ip, dir, &dentry->d_name)); |
023699cd | 196 | VERIFY0(zpl_init_acl(ip, dir)); |
7b3e34ba | 197 | d_instantiate(dentry, ip); |
023699cd | 198 | } |
7b3e34ba | 199 | |
d1d7e268 | 200 | kmem_free(vap, sizeof (vattr_t)); |
81e97e21 | 201 | crfree(cr); |
ee154f01 BB |
202 | ASSERT3S(error, <=, 0); |
203 | ||
204 | return (error); | |
205 | } | |
206 | ||
207 | static int | |
208 | zpl_rmdir(struct inode * dir, struct dentry *dentry) | |
209 | { | |
81e97e21 | 210 | cred_t *cr = CRED(); |
ee154f01 | 211 | int error; |
40d06e3c | 212 | fstrans_cookie_t cookie; |
ee154f01 | 213 | |
81e97e21 | 214 | crhold(cr); |
40d06e3c | 215 | cookie = spl_fstrans_mark(); |
ee154f01 | 216 | error = -zfs_rmdir(dir, dname(dentry), NULL, cr, 0); |
40d06e3c | 217 | spl_fstrans_unmark(cookie); |
81e97e21 | 218 | crfree(cr); |
ee154f01 BB |
219 | ASSERT3S(error, <=, 0); |
220 | ||
221 | return (error); | |
222 | } | |
223 | ||
224 | static int | |
225 | zpl_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) | |
226 | { | |
ebe7e575 | 227 | boolean_t issnap = ITOZSB(dentry->d_inode)->z_issnap; |
ee154f01 | 228 | int error; |
40d06e3c | 229 | fstrans_cookie_t cookie; |
ee154f01 | 230 | |
ebe7e575 BB |
231 | /* |
232 | * Ensure MNT_SHRINKABLE is set on snapshots to ensure they are | |
233 | * unmounted automatically with the parent file system. This | |
234 | * is done on the first getattr because it's not easy to get the | |
235 | * vfsmount structure at mount time. This call path is explicitly | |
236 | * marked unlikely to avoid any performance impact. FWIW, ext4 | |
237 | * resorts to a similar trick for sysadmin convenience. | |
238 | */ | |
239 | if (unlikely(issnap && !(mnt->mnt_flags & MNT_SHRINKABLE))) | |
240 | mnt->mnt_flags |= MNT_SHRINKABLE; | |
241 | ||
40d06e3c | 242 | cookie = spl_fstrans_mark(); |
057e8eee | 243 | error = -zfs_getattr_fast(dentry->d_inode, stat); |
40d06e3c | 244 | spl_fstrans_unmark(cookie); |
ee154f01 BB |
245 | ASSERT3S(error, <=, 0); |
246 | ||
247 | return (error); | |
248 | } | |
249 | ||
250 | static int | |
5484965a | 251 | zpl_setattr(struct dentry *dentry, struct iattr *ia) |
ee154f01 | 252 | { |
023699cd | 253 | struct inode *ip = dentry->d_inode; |
81e97e21 | 254 | cred_t *cr = CRED(); |
5484965a | 255 | vattr_t *vap; |
ee154f01 | 256 | int error; |
40d06e3c | 257 | fstrans_cookie_t cookie; |
ee154f01 | 258 | |
023699cd | 259 | error = inode_change_ok(ip, ia); |
ee154f01 BB |
260 | if (error) |
261 | return (error); | |
262 | ||
81e97e21 | 263 | crhold(cr); |
d1d7e268 | 264 | vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP); |
5484965a BB |
265 | vap->va_mask = ia->ia_valid & ATTR_IATTR_MASK; |
266 | vap->va_mode = ia->ia_mode; | |
570d6edf RY |
267 | vap->va_uid = KUID_TO_SUID(ia->ia_uid); |
268 | vap->va_gid = KGID_TO_SGID(ia->ia_gid); | |
5484965a BB |
269 | vap->va_size = ia->ia_size; |
270 | vap->va_atime = ia->ia_atime; | |
271 | vap->va_mtime = ia->ia_mtime; | |
272 | vap->va_ctime = ia->ia_ctime; | |
273 | ||
40d06e3c | 274 | cookie = spl_fstrans_mark(); |
023699cd | 275 | error = -zfs_setattr(ip, vap, 0, cr); |
40d06e3c | 276 | spl_fstrans_unmark(cookie); |
023699cd MM |
277 | if (!error && (ia->ia_valid & ATTR_MODE)) |
278 | error = zpl_chmod_acl(ip); | |
5484965a | 279 | |
d1d7e268 | 280 | kmem_free(vap, sizeof (vattr_t)); |
81e97e21 | 281 | crfree(cr); |
ee154f01 BB |
282 | ASSERT3S(error, <=, 0); |
283 | ||
5484965a | 284 | return (error); |
ee154f01 BB |
285 | } |
286 | ||
287 | static int | |
288 | zpl_rename(struct inode *sdip, struct dentry *sdentry, | |
289 | struct inode *tdip, struct dentry *tdentry) | |
290 | { | |
81e97e21 | 291 | cred_t *cr = CRED(); |
ee154f01 | 292 | int error; |
40d06e3c | 293 | fstrans_cookie_t cookie; |
ee154f01 | 294 | |
81e97e21 | 295 | crhold(cr); |
40d06e3c | 296 | cookie = spl_fstrans_mark(); |
ee154f01 | 297 | error = -zfs_rename(sdip, dname(sdentry), tdip, dname(tdentry), cr, 0); |
40d06e3c | 298 | spl_fstrans_unmark(cookie); |
81e97e21 | 299 | crfree(cr); |
ee154f01 BB |
300 | ASSERT3S(error, <=, 0); |
301 | ||
302 | return (error); | |
303 | } | |
304 | ||
305 | static int | |
306 | zpl_symlink(struct inode *dir, struct dentry *dentry, const char *name) | |
307 | { | |
81e97e21 | 308 | cred_t *cr = CRED(); |
ee154f01 BB |
309 | vattr_t *vap; |
310 | struct inode *ip; | |
311 | int error; | |
40d06e3c | 312 | fstrans_cookie_t cookie; |
ee154f01 | 313 | |
81e97e21 | 314 | crhold(cr); |
d1d7e268 | 315 | vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP); |
7b3e34ba | 316 | zpl_vap_init(vap, dir, S_IFLNK | S_IRWXUGO, cr); |
ee154f01 | 317 | |
40d06e3c | 318 | cookie = spl_fstrans_mark(); |
ee154f01 | 319 | error = -zfs_symlink(dir, dname(dentry), vap, (char *)name, &ip, cr, 0); |
40d06e3c | 320 | spl_fstrans_unmark(cookie); |
227bc969 MT |
321 | if (error == 0) { |
322 | VERIFY0(zpl_xattr_security_init(ip, dir, &dentry->d_name)); | |
7b3e34ba | 323 | d_instantiate(dentry, ip); |
227bc969 | 324 | } |
7b3e34ba | 325 | |
d1d7e268 | 326 | kmem_free(vap, sizeof (vattr_t)); |
81e97e21 | 327 | crfree(cr); |
ee154f01 BB |
328 | ASSERT3S(error, <=, 0); |
329 | ||
330 | return (error); | |
331 | } | |
332 | ||
333 | static void * | |
334 | zpl_follow_link(struct dentry *dentry, struct nameidata *nd) | |
335 | { | |
81e97e21 | 336 | cred_t *cr = CRED(); |
8b4f9a2d BB |
337 | struct inode *ip = dentry->d_inode; |
338 | struct iovec iov; | |
339 | uio_t uio; | |
340 | char *link; | |
8b4f9a2d | 341 | int error; |
40d06e3c | 342 | fstrans_cookie_t cookie; |
8b4f9a2d | 343 | |
81e97e21 | 344 | crhold(cr); |
8b4f9a2d BB |
345 | |
346 | iov.iov_len = MAXPATHLEN; | |
347 | iov.iov_base = link = kmem_zalloc(MAXPATHLEN, KM_SLEEP); | |
348 | ||
349 | uio.uio_iov = &iov; | |
350 | uio.uio_iovcnt = 1; | |
351 | uio.uio_resid = (MAXPATHLEN - 1); | |
352 | uio.uio_segflg = UIO_SYSSPACE; | |
353 | ||
40d06e3c | 354 | cookie = spl_fstrans_mark(); |
50950001 | 355 | error = -zfs_readlink(ip, &uio, cr); |
40d06e3c | 356 | spl_fstrans_unmark(cookie); |
8b4f9a2d BB |
357 | if (error) { |
358 | kmem_free(link, MAXPATHLEN); | |
359 | nd_set_link(nd, ERR_PTR(error)); | |
360 | } else { | |
361 | nd_set_link(nd, link); | |
362 | } | |
363 | ||
81e97e21 | 364 | crfree(cr); |
8b4f9a2d | 365 | return (NULL); |
ee154f01 BB |
366 | } |
367 | ||
368 | static void | |
369 | zpl_put_link(struct dentry *dentry, struct nameidata *nd, void *ptr) | |
370 | { | |
0a6b03d3 | 371 | const char *link = nd_get_link(nd); |
ee154f01 | 372 | |
ee154f01 | 373 | if (!IS_ERR(link)) |
8b4f9a2d | 374 | kmem_free(link, MAXPATHLEN); |
ee154f01 BB |
375 | } |
376 | ||
377 | static int | |
378 | zpl_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry) | |
379 | { | |
81e97e21 | 380 | cred_t *cr = CRED(); |
ee154f01 | 381 | struct inode *ip = old_dentry->d_inode; |
ee154f01 | 382 | int error; |
40d06e3c | 383 | fstrans_cookie_t cookie; |
ee154f01 BB |
384 | |
385 | if (ip->i_nlink >= ZFS_LINK_MAX) | |
d1d7e268 | 386 | return (-EMLINK); |
ee154f01 | 387 | |
81e97e21 | 388 | crhold(cr); |
ee154f01 BB |
389 | ip->i_ctime = CURRENT_TIME_SEC; |
390 | igrab(ip); /* Use ihold() if available */ | |
391 | ||
40d06e3c | 392 | cookie = spl_fstrans_mark(); |
ee154f01 | 393 | error = -zfs_link(dir, ip, dname(dentry), cr); |
40d06e3c | 394 | spl_fstrans_unmark(cookie); |
ee154f01 BB |
395 | if (error) { |
396 | iput(ip); | |
397 | goto out; | |
398 | } | |
399 | ||
400 | d_instantiate(dentry, ip); | |
401 | out: | |
81e97e21 | 402 | crfree(cr); |
ee154f01 BB |
403 | ASSERT3S(error, <=, 0); |
404 | ||
405 | return (error); | |
406 | } | |
407 | ||
ea1fdf46 | 408 | #ifdef HAVE_INODE_TRUNCATE_RANGE |
5cb63a57 | 409 | static void |
d1d7e268 | 410 | zpl_truncate_range(struct inode *ip, loff_t start, loff_t end) |
5cb63a57 ED |
411 | { |
412 | cred_t *cr = CRED(); | |
413 | flock64_t bf; | |
40d06e3c | 414 | fstrans_cookie_t cookie; |
5cb63a57 ED |
415 | |
416 | ASSERT3S(start, <=, end); | |
417 | ||
418 | /* | |
419 | * zfs_freesp() will interpret (len == 0) as meaning "truncate until | |
420 | * the end of the file". We don't want that. | |
421 | */ | |
422 | if (start == end) | |
423 | return; | |
424 | ||
425 | crhold(cr); | |
426 | ||
427 | bf.l_type = F_WRLCK; | |
428 | bf.l_whence = 0; | |
429 | bf.l_start = start; | |
430 | bf.l_len = end - start; | |
431 | bf.l_pid = 0; | |
40d06e3c | 432 | cookie = spl_fstrans_mark(); |
5cb63a57 | 433 | zfs_space(ip, F_FREESP, &bf, FWRITE, start, cr); |
40d06e3c | 434 | spl_fstrans_unmark(cookie); |
5cb63a57 ED |
435 | |
436 | crfree(cr); | |
437 | } | |
ea1fdf46 | 438 | #endif /* HAVE_INODE_TRUNCATE_RANGE */ |
5cb63a57 | 439 | |
cb2d1901 ED |
440 | #ifdef HAVE_INODE_FALLOCATE |
441 | static long | |
442 | zpl_fallocate(struct inode *ip, int mode, loff_t offset, loff_t len) | |
443 | { | |
d1d7e268 | 444 | return (zpl_fallocate_common(ip, mode, offset, len)); |
cb2d1901 ED |
445 | } |
446 | #endif /* HAVE_INODE_FALLOCATE */ | |
447 | ||
7b3e34ba BB |
448 | static int |
449 | #ifdef HAVE_D_REVALIDATE_NAMEIDATA | |
450 | zpl_revalidate(struct dentry *dentry, struct nameidata *nd) | |
451 | { | |
09a661e9 | 452 | unsigned int flags = (nd ? nd->flags : 0); |
7b3e34ba BB |
453 | #else |
454 | zpl_revalidate(struct dentry *dentry, unsigned int flags) | |
455 | { | |
456 | #endif /* HAVE_D_REVALIDATE_NAMEIDATA */ | |
457 | zfs_sb_t *zsb = dentry->d_sb->s_fs_info; | |
458 | int error; | |
459 | ||
460 | if (flags & LOOKUP_RCU) | |
461 | return (-ECHILD); | |
462 | ||
463 | /* | |
464 | * After a rollback negative dentries created before the rollback | |
465 | * time must be invalidated. Otherwise they can obscure files which | |
466 | * are only present in the rolled back dataset. | |
467 | */ | |
468 | if (dentry->d_inode == NULL) { | |
469 | spin_lock(&dentry->d_lock); | |
470 | error = time_before(dentry->d_time, zsb->z_rollback_time); | |
471 | spin_unlock(&dentry->d_lock); | |
472 | ||
473 | if (error) | |
474 | return (0); | |
475 | } | |
476 | ||
477 | /* | |
478 | * The dentry may reference a stale inode if a mounted file system | |
479 | * was rolled back to a point in time where the object didn't exist. | |
480 | */ | |
481 | if (dentry->d_inode && ITOZ(dentry->d_inode)->z_is_stale) | |
482 | return (0); | |
483 | ||
484 | return (1); | |
485 | } | |
cb2d1901 | 486 | |
ee154f01 | 487 | const struct inode_operations zpl_inode_operations = { |
ee154f01 BB |
488 | .create = zpl_create, |
489 | .link = zpl_link, | |
490 | .unlink = zpl_unlink, | |
491 | .symlink = zpl_symlink, | |
492 | .mkdir = zpl_mkdir, | |
493 | .rmdir = zpl_rmdir, | |
494 | .mknod = zpl_mknod, | |
495 | .rename = zpl_rename, | |
496 | .setattr = zpl_setattr, | |
497 | .getattr = zpl_getattr, | |
498 | .setxattr = generic_setxattr, | |
499 | .getxattr = generic_getxattr, | |
500 | .removexattr = generic_removexattr, | |
501 | .listxattr = zpl_xattr_list, | |
ea1fdf46 | 502 | #ifdef HAVE_INODE_TRUNCATE_RANGE |
5cb63a57 | 503 | .truncate_range = zpl_truncate_range, |
ea1fdf46 | 504 | #endif /* HAVE_INODE_TRUNCATE_RANGE */ |
cb2d1901 ED |
505 | #ifdef HAVE_INODE_FALLOCATE |
506 | .fallocate = zpl_fallocate, | |
507 | #endif /* HAVE_INODE_FALLOCATE */ | |
b695c34e | 508 | #if defined(CONFIG_FS_POSIX_ACL) |
023699cd MM |
509 | #if defined(HAVE_GET_ACL) |
510 | .get_acl = zpl_get_acl, | |
511 | #elif defined(HAVE_CHECK_ACL) | |
512 | .check_acl = zpl_check_acl, | |
513 | #elif defined(HAVE_PERMISSION) | |
514 | .permission = zpl_permission, | |
515 | #endif /* HAVE_GET_ACL | HAVE_CHECK_ACL | HAVE_PERMISSION */ | |
b695c34e | 516 | #endif /* CONFIG_FS_POSIX_ACL */ |
ee154f01 BB |
517 | }; |
518 | ||
519 | const struct inode_operations zpl_dir_inode_operations = { | |
ee154f01 BB |
520 | .create = zpl_create, |
521 | .lookup = zpl_lookup, | |
522 | .link = zpl_link, | |
523 | .unlink = zpl_unlink, | |
524 | .symlink = zpl_symlink, | |
525 | .mkdir = zpl_mkdir, | |
526 | .rmdir = zpl_rmdir, | |
527 | .mknod = zpl_mknod, | |
528 | .rename = zpl_rename, | |
529 | .setattr = zpl_setattr, | |
a6695d83 BB |
530 | .getattr = zpl_getattr, |
531 | .setxattr = generic_setxattr, | |
532 | .getxattr = generic_getxattr, | |
533 | .removexattr = generic_removexattr, | |
534 | .listxattr = zpl_xattr_list, | |
b695c34e | 535 | #if defined(CONFIG_FS_POSIX_ACL) |
023699cd MM |
536 | #if defined(HAVE_GET_ACL) |
537 | .get_acl = zpl_get_acl, | |
538 | #elif defined(HAVE_CHECK_ACL) | |
539 | .check_acl = zpl_check_acl, | |
540 | #elif defined(HAVE_PERMISSION) | |
541 | .permission = zpl_permission, | |
542 | #endif /* HAVE_GET_ACL | HAVE_CHECK_ACL | HAVE_PERMISSION */ | |
b695c34e | 543 | #endif /* CONFIG_FS_POSIX_ACL */ |
ee154f01 BB |
544 | }; |
545 | ||
546 | const struct inode_operations zpl_symlink_inode_operations = { | |
ee154f01 BB |
547 | .readlink = generic_readlink, |
548 | .follow_link = zpl_follow_link, | |
549 | .put_link = zpl_put_link, | |
6f2255ba BB |
550 | .setattr = zpl_setattr, |
551 | .getattr = zpl_getattr, | |
f31b3ebe BB |
552 | .setxattr = generic_setxattr, |
553 | .getxattr = generic_getxattr, | |
554 | .removexattr = generic_removexattr, | |
555 | .listxattr = zpl_xattr_list, | |
ee154f01 BB |
556 | }; |
557 | ||
558 | const struct inode_operations zpl_special_inode_operations = { | |
a6695d83 BB |
559 | .setattr = zpl_setattr, |
560 | .getattr = zpl_getattr, | |
561 | .setxattr = generic_setxattr, | |
562 | .getxattr = generic_getxattr, | |
563 | .removexattr = generic_removexattr, | |
564 | .listxattr = zpl_xattr_list, | |
b695c34e | 565 | #if defined(CONFIG_FS_POSIX_ACL) |
023699cd MM |
566 | #if defined(HAVE_GET_ACL) |
567 | .get_acl = zpl_get_acl, | |
568 | #elif defined(HAVE_CHECK_ACL) | |
569 | .check_acl = zpl_check_acl, | |
570 | #elif defined(HAVE_PERMISSION) | |
571 | .permission = zpl_permission, | |
572 | #endif /* HAVE_GET_ACL | HAVE_CHECK_ACL | HAVE_PERMISSION */ | |
b695c34e | 573 | #endif /* CONFIG_FS_POSIX_ACL */ |
ee154f01 | 574 | }; |
7b3e34ba BB |
575 | |
576 | dentry_operations_t zpl_dentry_operations = { | |
577 | .d_revalidate = zpl_revalidate, | |
578 | }; |