The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/openzfs/module/os/linux/zfs/zpl_ctldir.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 6a47566a41601219cb790afa114f8971


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.