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 * Copyright (C) 2011 Lawrence Livermore National Security, LLC. 24 * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). 25 * LLNL-CODE-403049. 26 * Rewritten for Linux by: 27 * Rohan Puri <rohan.puri15@gmail.com> 28 * Brian Behlendorf <behlendorf1@llnl.gov> 29 */ 30 31 #include <sys/zfs_znode.h> 32 #include <sys/zfs_vfsops.h> 33 #include <sys/zfs_vnops.h> 34 #include <sys/zfs_ctldir.h> 35 #include <sys/zpl.h> 36 #include <sys/dmu.h> 37 #include <sys/dsl_dataset.h> 38 #include <sys/zap.h> 39 40 /* 41 * Common open routine. Disallow any write access. 42 */ 43 static int 44 zpl_common_open(struct inode *ip, struct file *filp) 45 { 46 if (blk_mode_is_open_write(filp->f_mode)) 47 return (-EACCES); 48 49 return (generic_file_open(ip, filp)); 50 } 51 52 /* 53 * Get root directory contents. 54 */ 55 static int 56 zpl_root_iterate(struct file *filp, struct dir_context *ctx) 57 { 58 zfsvfs_t *zfsvfs = ITOZSB(file_inode(filp)); 59 int error = 0; 60 61 if (zfsvfs->z_show_ctldir == ZFS_SNAPDIR_DISABLED) { 62 return (SET_ERROR(ENOENT)); 63 } 64 65 if ((error = zpl_enter(zfsvfs, FTAG)) != 0) 66 return (error); 67 68 if (!dir_emit_dots(filp, ctx)) 69 goto out; 70 71 if (ctx->pos == 2) { 72 if (!dir_emit(ctx, ZFS_SNAPDIR_NAME, 73 strlen(ZFS_SNAPDIR_NAME), ZFSCTL_INO_SNAPDIR, DT_DIR)) 74 goto out; 75 76 ctx->pos++; 77 } 78 79 if (ctx->pos == 3) { 80 if (!dir_emit(ctx, ZFS_SHAREDIR_NAME, 81 strlen(ZFS_SHAREDIR_NAME), ZFSCTL_INO_SHARES, DT_DIR)) 82 goto out; 83 84 ctx->pos++; 85 } 86 out: 87 zpl_exit(zfsvfs, FTAG); 88 89 return (error); 90 } 91 92 /* 93 * Get root directory attributes. 94 */ 95 static int 96 #ifdef HAVE_IDMAP_IOPS_GETATTR 97 zpl_root_getattr_impl(struct mnt_idmap *user_ns, 98 const struct path *path, struct kstat *stat, u32 request_mask, 99 unsigned int query_flags) 100 #elif defined(HAVE_USERNS_IOPS_GETATTR) 101 zpl_root_getattr_impl(struct user_namespace *user_ns, 102 const struct path *path, struct kstat *stat, u32 request_mask, 103 unsigned int query_flags) 104 #else 105 zpl_root_getattr_impl(const struct path *path, struct kstat *stat, 106 u32 request_mask, unsigned int query_flags) 107 #endif 108 { 109 (void) request_mask, (void) query_flags; 110 struct inode *ip = path->dentry->d_inode; 111 112 #if (defined(HAVE_USERNS_IOPS_GETATTR) || defined(HAVE_IDMAP_IOPS_GETATTR)) 113 #ifdef HAVE_GENERIC_FILLATTR_USERNS 114 generic_fillattr(user_ns, ip, stat); 115 #elif defined(HAVE_GENERIC_FILLATTR_IDMAP) 116 generic_fillattr(user_ns, ip, stat); 117 #elif defined(HAVE_GENERIC_FILLATTR_IDMAP_REQMASK) 118 generic_fillattr(user_ns, request_mask, ip, stat); 119 #else 120 (void) user_ns; 121 #endif 122 #else 123 generic_fillattr(ip, stat); 124 #endif 125 stat->atime = current_time(ip); 126 127 return (0); 128 } 129 ZPL_GETATTR_WRAPPER(zpl_root_getattr); 130 131 static struct dentry * 132 zpl_root_lookup(struct inode *dip, struct dentry *dentry, unsigned int flags) 133 { 134 cred_t *cr = CRED(); 135 struct inode *ip; 136 int error; 137 138 crhold(cr); 139 error = -zfsctl_root_lookup(dip, dname(dentry), &ip, 0, cr, NULL, NULL); 140 ASSERT3S(error, <=, 0); 141 crfree(cr); 142 143 if (error) { 144 if (error == -ENOENT) 145 return (d_splice_alias(NULL, dentry)); 146 else 147 return (ERR_PTR(error)); 148 } 149 150 return (d_splice_alias(ip, dentry)); 151 } 152 153 /* 154 * The '.zfs' control directory file and inode operations. 155 */ 156 const struct file_operations zpl_fops_root = { 157 .open = zpl_common_open, 158 .llseek = generic_file_llseek, 159 .read = generic_read_dir, 160 .iterate_shared = zpl_root_iterate, 161 }; 162 163 const struct inode_operations zpl_ops_root = { 164 .lookup = zpl_root_lookup, 165 .getattr = zpl_root_getattr, 166 }; 167 168 static struct vfsmount * 169 zpl_snapdir_automount(struct path *path) 170 { 171 int error; 172 173 error = -zfsctl_snapshot_mount(path, 0); 174 if (error) 175 return (ERR_PTR(error)); 176 177 /* 178 * Rather than returning the new vfsmount for the snapshot we must 179 * return NULL to indicate a mount collision. This is done because 180 * the user space mount calls do_add_mount() which adds the vfsmount 181 * to the name space. If we returned the new mount here it would be 182 * added again to the vfsmount list resulting in list corruption. 183 */ 184 return (NULL); 185 } 186 187 /* 188 * Negative dentries must always be revalidated so newly created snapshots 189 * can be detected and automounted. Normal dentries should be kept because 190 * as of the 3.18 kernel revaliding the mountpoint dentry will result in 191 * the snapshot being immediately unmounted. 192 */ 193 #ifdef HAVE_D_REVALIDATE_4ARGS 194 static int 195 zpl_snapdir_revalidate(struct inode *dir, const struct qstr *name, 196 struct dentry *dentry, unsigned int flags) 197 #else 198 static int 199 zpl_snapdir_revalidate(struct dentry *dentry, unsigned int flags) 200 #endif 201 { 202 return (!!dentry->d_inode); 203 } 204 205 static const struct dentry_operations zpl_dops_snapdirs = { 206 /* 207 * Auto mounting of snapshots is only supported for 2.6.37 and 208 * newer kernels. Prior to this kernel the ops->follow_link() 209 * callback was used as a hack to trigger the mount. The 210 * resulting vfsmount was then explicitly grafted in to the 211 * name space. While it might be possible to add compatibility 212 * code to accomplish this it would require considerable care. 213 */ 214 .d_automount = zpl_snapdir_automount, 215 .d_revalidate = zpl_snapdir_revalidate, 216 }; 217 218 /* 219 * For the .zfs control directory to work properly we must be able to override 220 * the default operations table and register custom .d_automount and 221 * .d_revalidate callbacks. 222 */ 223 static void 224 set_snapdir_dentry_ops(struct dentry *dentry, unsigned int extraflags) { 225 static const unsigned int op_flags = 226 DCACHE_OP_HASH | DCACHE_OP_COMPARE | 227 DCACHE_OP_REVALIDATE | DCACHE_OP_DELETE | 228 DCACHE_OP_PRUNE | DCACHE_OP_WEAK_REVALIDATE | DCACHE_OP_REAL; 229 230 #ifdef HAVE_D_SET_D_OP 231 /* 232 * d_set_d_op() will set the DCACHE_OP_ flags according to what it 233 * finds in the passed dentry_operations, so we don't have to. 234 * 235 * We clear the flags and the old op table before calling d_set_d_op() 236 * because issues a warning when the dentry operations table is already 237 * set. 238 */ 239 dentry->d_op = NULL; 240 dentry->d_flags &= ~op_flags; 241 d_set_d_op(dentry, &zpl_dops_snapdirs); 242 dentry->d_flags |= extraflags; 243 #else 244 /* 245 * Since 6.17 there's no exported way to modify dentry ops, so we have 246 * to reach in and do it ourselves. This should be safe for our very 247 * narrow use case, which is to create or splice in an entry to give 248 * access to a snapshot. 249 * 250 * We need to set the op flags directly. We hardcode 251 * DCACHE_OP_REVALIDATE because that's the only operation we have; if 252 * we ever extend zpl_dops_snapdirs we will need to update the op flags 253 * to match. 254 */ 255 spin_lock(&dentry->d_lock); 256 dentry->d_op = &zpl_dops_snapdirs; 257 dentry->d_flags &= ~op_flags; 258 dentry->d_flags |= DCACHE_OP_REVALIDATE | extraflags; 259 spin_unlock(&dentry->d_lock); 260 #endif 261 } 262 263 static struct dentry * 264 zpl_snapdir_lookup(struct inode *dip, struct dentry *dentry, 265 unsigned int flags) 266 { 267 fstrans_cookie_t cookie; 268 cred_t *cr = CRED(); 269 struct inode *ip = NULL; 270 int error; 271 272 crhold(cr); 273 cookie = spl_fstrans_mark(); 274 error = -zfsctl_snapdir_lookup(dip, dname(dentry), &ip, 275 0, cr, NULL, NULL); 276 ASSERT3S(error, <=, 0); 277 spl_fstrans_unmark(cookie); 278 crfree(cr); 279 280 if (error && error != -ENOENT) 281 return (ERR_PTR(error)); 282 283 ASSERT(error == 0 || ip == NULL); 284 set_snapdir_dentry_ops(dentry, DCACHE_NEED_AUTOMOUNT); 285 return (d_splice_alias(ip, dentry)); 286 } 287 288 static int 289 zpl_snapdir_iterate(struct file *filp, struct dir_context *ctx) 290 { 291 zfsvfs_t *zfsvfs = ITOZSB(file_inode(filp)); 292 fstrans_cookie_t cookie; 293 char snapname[MAXNAMELEN]; 294 boolean_t case_conflict; 295 uint64_t id, pos; 296 int error = 0; 297 298 if ((error = zpl_enter(zfsvfs, FTAG)) != 0) 299 return (error); 300 cookie = spl_fstrans_mark(); 301 302 if (!dir_emit_dots(filp, ctx)) 303 goto out; 304 305 /* Start the position at 0 if it already emitted . and .. */ 306 pos = (ctx->pos == 2 ? 0 : ctx->pos); 307 while (error == 0) { 308 dsl_pool_config_enter(dmu_objset_pool(zfsvfs->z_os), FTAG); 309 error = -dmu_snapshot_list_next(zfsvfs->z_os, MAXNAMELEN, 310 snapname, &id, &pos, &case_conflict); 311 dsl_pool_config_exit(dmu_objset_pool(zfsvfs->z_os), FTAG); 312 if (error) 313 goto out; 314 315 if (!dir_emit(ctx, snapname, strlen(snapname), 316 ZFSCTL_INO_SHARES - id, DT_DIR)) 317 goto out; 318 319 ctx->pos = pos; 320 } 321 out: 322 spl_fstrans_unmark(cookie); 323 zpl_exit(zfsvfs, FTAG); 324 325 if (error == -ENOENT) 326 return (0); 327 328 return (error); 329 } 330 331 static int 332 #ifdef HAVE_IOPS_RENAME_USERNS 333 zpl_snapdir_rename2(struct user_namespace *user_ns, struct inode *sdip, 334 struct dentry *sdentry, struct inode *tdip, struct dentry *tdentry, 335 unsigned int flags) 336 #elif defined(HAVE_IOPS_RENAME_IDMAP) 337 zpl_snapdir_rename2(struct mnt_idmap *user_ns, struct inode *sdip, 338 struct dentry *sdentry, struct inode *tdip, struct dentry *tdentry, 339 unsigned int flags) 340 #else 341 zpl_snapdir_rename2(struct inode *sdip, struct dentry *sdentry, 342 struct inode *tdip, struct dentry *tdentry, unsigned int flags) 343 #endif 344 { 345 cred_t *cr = CRED(); 346 int error; 347 348 /* We probably don't want to support renameat2(2) in ctldir */ 349 if (flags) 350 return (-EINVAL); 351 352 crhold(cr); 353 error = -zfsctl_snapdir_rename(sdip, dname(sdentry), 354 tdip, dname(tdentry), cr, 0); 355 ASSERT3S(error, <=, 0); 356 crfree(cr); 357 358 return (error); 359 } 360 361 #if (!defined(HAVE_RENAME_WANTS_FLAGS) && \ 362 !defined(HAVE_IOPS_RENAME_USERNS) && \ 363 !defined(HAVE_IOPS_RENAME_IDMAP)) 364 static int 365 zpl_snapdir_rename(struct inode *sdip, struct dentry *sdentry, 366 struct inode *tdip, struct dentry *tdentry) 367 { 368 return (zpl_snapdir_rename2(sdip, sdentry, tdip, tdentry, 0)); 369 } 370 #endif 371 372 static int 373 zpl_snapdir_rmdir(struct inode *dip, struct dentry *dentry) 374 { 375 cred_t *cr = CRED(); 376 int error; 377 378 crhold(cr); 379 error = -zfsctl_snapdir_remove(dip, dname(dentry), cr, 0); 380 ASSERT3S(error, <=, 0); 381 crfree(cr); 382 383 return (error); 384 } 385 386 #if defined(HAVE_IOPS_MKDIR_USERNS) 387 static int 388 zpl_snapdir_mkdir(struct user_namespace *user_ns, struct inode *dip, 389 struct dentry *dentry, umode_t mode) 390 #elif defined(HAVE_IOPS_MKDIR_IDMAP) 391 static int 392 zpl_snapdir_mkdir(struct mnt_idmap *user_ns, struct inode *dip, 393 struct dentry *dentry, umode_t mode) 394 #elif defined(HAVE_IOPS_MKDIR_DENTRY) 395 static struct dentry * 396 zpl_snapdir_mkdir(struct mnt_idmap *user_ns, struct inode *dip, 397 struct dentry *dentry, umode_t mode) 398 #else 399 static int 400 zpl_snapdir_mkdir(struct inode *dip, struct dentry *dentry, umode_t mode) 401 #endif 402 { 403 cred_t *cr = CRED(); 404 vattr_t *vap; 405 struct inode *ip; 406 int error; 407 408 crhold(cr); 409 vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP); 410 #if (defined(HAVE_IOPS_MKDIR_USERNS) || defined(HAVE_IOPS_MKDIR_IDMAP)) 411 zpl_vap_init(vap, dip, mode | S_IFDIR, cr, user_ns); 412 #else 413 zpl_vap_init(vap, dip, mode | S_IFDIR, cr, zfs_init_idmap); 414 #endif 415 416 error = -zfsctl_snapdir_mkdir(dip, dname(dentry), vap, &ip, cr, 0); 417 if (error == 0) { 418 set_snapdir_dentry_ops(dentry, 0); 419 d_instantiate(dentry, ip); 420 } 421 422 kmem_free(vap, sizeof (vattr_t)); 423 ASSERT3S(error, <=, 0); 424 crfree(cr); 425 426 #if defined(HAVE_IOPS_MKDIR_DENTRY) 427 return (ERR_PTR(error)); 428 #else 429 return (error); 430 #endif 431 } 432 433 /* 434 * Get snapshot directory attributes. 435 */ 436 static int 437 #ifdef HAVE_IDMAP_IOPS_GETATTR 438 zpl_snapdir_getattr_impl(struct mnt_idmap *user_ns, 439 const struct path *path, struct kstat *stat, u32 request_mask, 440 unsigned int query_flags) 441 #elif defined(HAVE_USERNS_IOPS_GETATTR) 442 zpl_snapdir_getattr_impl(struct user_namespace *user_ns, 443 const struct path *path, struct kstat *stat, u32 request_mask, 444 unsigned int query_flags) 445 #else 446 zpl_snapdir_getattr_impl(const struct path *path, struct kstat *stat, 447 u32 request_mask, unsigned int query_flags) 448 #endif 449 { 450 (void) request_mask, (void) query_flags; 451 struct inode *ip = path->dentry->d_inode; 452 zfsvfs_t *zfsvfs = ITOZSB(ip); 453 int error; 454 455 if ((error = zpl_enter(zfsvfs, FTAG)) != 0) 456 return (error); 457 #if (defined(HAVE_USERNS_IOPS_GETATTR) || defined(HAVE_IDMAP_IOPS_GETATTR)) 458 #ifdef HAVE_GENERIC_FILLATTR_USERNS 459 generic_fillattr(user_ns, ip, stat); 460 #elif defined(HAVE_GENERIC_FILLATTR_IDMAP) 461 generic_fillattr(user_ns, ip, stat); 462 #elif defined(HAVE_GENERIC_FILLATTR_IDMAP_REQMASK) 463 generic_fillattr(user_ns, request_mask, ip, stat); 464 #else 465 (void) user_ns; 466 #endif 467 #else 468 generic_fillattr(ip, stat); 469 #endif 470 471 stat->nlink = stat->size = 2; 472 473 dsl_dataset_t *ds = dmu_objset_ds(zfsvfs->z_os); 474 if (dsl_dataset_phys(ds)->ds_snapnames_zapobj != 0) { 475 uint64_t snap_count; 476 int err = zap_count( 477 dmu_objset_pool(ds->ds_objset)->dp_meta_objset, 478 dsl_dataset_phys(ds)->ds_snapnames_zapobj, &snap_count); 479 if (err != 0) { 480 zpl_exit(zfsvfs, FTAG); 481 return (-err); 482 } 483 stat->nlink += snap_count; 484 } 485 486 stat->ctime = stat->mtime = dmu_objset_snap_cmtime(zfsvfs->z_os); 487 stat->atime = current_time(ip); 488 zpl_exit(zfsvfs, FTAG); 489 490 return (0); 491 } 492 ZPL_GETATTR_WRAPPER(zpl_snapdir_getattr); 493 494 /* 495 * The '.zfs/snapshot' directory file operations. These mainly control 496 * generating the list of available snapshots when doing an 'ls' in the 497 * directory. See zpl_snapdir_readdir(). 498 */ 499 const struct file_operations zpl_fops_snapdir = { 500 .open = zpl_common_open, 501 .llseek = generic_file_llseek, 502 .read = generic_read_dir, 503 .iterate_shared = zpl_snapdir_iterate, 504 505 }; 506 507 /* 508 * The '.zfs/snapshot' directory inode operations. These mainly control 509 * creating an inode for a snapshot directory and initializing the needed 510 * infrastructure to automount the snapshot. See zpl_snapdir_lookup(). 511 */ 512 const struct inode_operations zpl_ops_snapdir = { 513 .lookup = zpl_snapdir_lookup, 514 .getattr = zpl_snapdir_getattr, 515 #if (defined(HAVE_RENAME_WANTS_FLAGS) || \ 516 defined(HAVE_IOPS_RENAME_USERNS) || \ 517 defined(HAVE_IOPS_RENAME_IDMAP)) 518 .rename = zpl_snapdir_rename2, 519 #else 520 .rename = zpl_snapdir_rename, 521 #endif 522 .rmdir = zpl_snapdir_rmdir, 523 .mkdir = zpl_snapdir_mkdir, 524 }; 525 526 static struct dentry * 527 zpl_shares_lookup(struct inode *dip, struct dentry *dentry, 528 unsigned int flags) 529 { 530 fstrans_cookie_t cookie; 531 cred_t *cr = CRED(); 532 struct inode *ip = NULL; 533 int error; 534 535 crhold(cr); 536 cookie = spl_fstrans_mark(); 537 error = -zfsctl_shares_lookup(dip, dname(dentry), &ip, 538 0, cr, NULL, NULL); 539 ASSERT3S(error, <=, 0); 540 spl_fstrans_unmark(cookie); 541 crfree(cr); 542 543 if (error) { 544 if (error == -ENOENT) 545 return (d_splice_alias(NULL, dentry)); 546 else 547 return (ERR_PTR(error)); 548 } 549 550 return (d_splice_alias(ip, dentry)); 551 } 552 553 static int 554 zpl_shares_iterate(struct file *filp, struct dir_context *ctx) 555 { 556 fstrans_cookie_t cookie; 557 cred_t *cr = CRED(); 558 zfsvfs_t *zfsvfs = ITOZSB(file_inode(filp)); 559 znode_t *dzp; 560 int error = 0; 561 562 if ((error = zpl_enter(zfsvfs, FTAG)) != 0) 563 return (error); 564 cookie = spl_fstrans_mark(); 565 566 if (zfsvfs->z_shares_dir == 0) { 567 dir_emit_dots(filp, ctx); 568 goto out; 569 } 570 571 error = -zfs_zget(zfsvfs, zfsvfs->z_shares_dir, &dzp); 572 if (error) 573 goto out; 574 575 crhold(cr); 576 error = -zfs_readdir(ZTOI(dzp), ctx, cr); 577 crfree(cr); 578 579 iput(ZTOI(dzp)); 580 out: 581 spl_fstrans_unmark(cookie); 582 zpl_exit(zfsvfs, FTAG); 583 ASSERT3S(error, <=, 0); 584 585 return (error); 586 } 587 588 static int 589 #ifdef HAVE_USERNS_IOPS_GETATTR 590 zpl_shares_getattr_impl(struct user_namespace *user_ns, 591 const struct path *path, struct kstat *stat, u32 request_mask, 592 unsigned int query_flags) 593 #elif defined(HAVE_IDMAP_IOPS_GETATTR) 594 zpl_shares_getattr_impl(struct mnt_idmap *user_ns, 595 const struct path *path, struct kstat *stat, u32 request_mask, 596 unsigned int query_flags) 597 #else 598 zpl_shares_getattr_impl(const struct path *path, struct kstat *stat, 599 u32 request_mask, unsigned int query_flags) 600 #endif 601 { 602 (void) request_mask, (void) query_flags; 603 struct inode *ip = path->dentry->d_inode; 604 zfsvfs_t *zfsvfs = ITOZSB(ip); 605 znode_t *dzp; 606 int error; 607 608 if ((error = zpl_enter(zfsvfs, FTAG)) != 0) 609 return (error); 610 611 if (zfsvfs->z_shares_dir == 0) { 612 #if (defined(HAVE_USERNS_IOPS_GETATTR) || defined(HAVE_IDMAP_IOPS_GETATTR)) 613 #ifdef HAVE_GENERIC_FILLATTR_USERNS 614 generic_fillattr(user_ns, path->dentry->d_inode, stat); 615 #elif defined(HAVE_GENERIC_FILLATTR_IDMAP) 616 generic_fillattr(user_ns, path->dentry->d_inode, stat); 617 #elif defined(HAVE_GENERIC_FILLATTR_IDMAP_REQMASK) 618 generic_fillattr(user_ns, request_mask, ip, stat); 619 #else 620 (void) user_ns; 621 #endif 622 #else 623 generic_fillattr(path->dentry->d_inode, stat); 624 #endif 625 stat->nlink = stat->size = 2; 626 stat->atime = current_time(ip); 627 zpl_exit(zfsvfs, FTAG); 628 return (0); 629 } 630 631 error = -zfs_zget(zfsvfs, zfsvfs->z_shares_dir, &dzp); 632 if (error == 0) { 633 #ifdef HAVE_GENERIC_FILLATTR_IDMAP_REQMASK 634 error = -zfs_getattr_fast(user_ns, request_mask, ZTOI(dzp), 635 stat); 636 #elif (defined(HAVE_USERNS_IOPS_GETATTR) || defined(HAVE_IDMAP_IOPS_GETATTR)) 637 error = -zfs_getattr_fast(user_ns, ZTOI(dzp), stat); 638 #else 639 error = -zfs_getattr_fast(kcred->user_ns, ZTOI(dzp), stat); 640 #endif 641 iput(ZTOI(dzp)); 642 } 643 644 zpl_exit(zfsvfs, FTAG); 645 ASSERT3S(error, <=, 0); 646 647 return (error); 648 } 649 ZPL_GETATTR_WRAPPER(zpl_shares_getattr); 650 651 /* 652 * The '.zfs/shares' directory file operations. 653 */ 654 const struct file_operations zpl_fops_shares = { 655 .open = zpl_common_open, 656 .llseek = generic_file_llseek, 657 .read = generic_read_dir, 658 .iterate_shared = zpl_shares_iterate, 659 }; 660 661 /* 662 * The '.zfs/shares' directory inode operations. 663 */ 664 const struct inode_operations zpl_ops_shares = { 665 .lookup = zpl_shares_lookup, 666 .getattr = zpl_shares_getattr, 667 }; 668