Print this page
NEX-17003 Autosnapshots should not be managed via .zfs/snapshot
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
6093 zfsctl_shares_lookup should only VN_RELE() on zfs_zget() success
Reviewed by: Gordon Ross <gwr@nexenta.com>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed by: George Wilson <george.wilson@delphix.com>
Approved by: Robert Mustacchi <rm@joyent.com>
5766 Avoid 128K kmem allocations in mzap_upgrade()
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed by: Prakash Surya <prakash.surya@delphix.com>
Reviewed by: George Wilson <george@delphix.com>
Reviewed by: Steven Hartland <killing@multiplay.co.uk>
Approved by: Rich Lowe <richlowe@richlowe.net>
5768 zfsctl_snapshot_inactive() can leak a vnode hold
Reviewed by: George Wilson <george@delphix.com>
Reviewed by: Prakash Surya <prakash.surya@delphix.com>
Reviewed by: Adam Leventhal <adam.leventhal@delphix.com>
Reviewed by: Bayard Bell <buffer.g.overflow@gmail.com>
Approved by: Rich Lowe <richlowe@richlowe.net>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/zfs/zfs_ctldir.c
          +++ new/usr/src/uts/common/fs/zfs/zfs_ctldir.c
↓ open down ↓ 14 lines elided ↑ open up ↑
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  23   23   * Copyright (c) 2012, 2017 by Delphix. All rights reserved.
  24   24   * Copyright 2015, OmniTI Computer Consulting, Inc. All rights reserved.
       25 + * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
  25   26   */
  26   27  
  27   28  /*
  28   29   * ZFS control directory (a.k.a. ".zfs")
  29   30   *
  30   31   * This directory provides a common location for all ZFS meta-objects.
  31   32   * Currently, this is only the 'snapshot' directory, but this may expand in the
  32   33   * future.  The elements are built using the GFS primitives, as the hierarchy
  33   34   * does not actually exist on disk.
  34   35   *
↓ open down ↓ 35 lines elided ↑ open up ↑
  70   71  #include <sys/zfs_ioctl.h>
  71   72  #include <sys/zfs_vfsops.h>
  72   73  #include <sys/vfs_opreg.h>
  73   74  #include <sys/gfs.h>
  74   75  #include <sys/stat.h>
  75   76  #include <sys/dmu.h>
  76   77  #include <sys/dsl_destroy.h>
  77   78  #include <sys/dsl_deleg.h>
  78   79  #include <sys/mount.h>
  79   80  #include <sys/sunddi.h>
       81 +#include <sys/autosnap.h>
  80   82  
  81   83  #include "zfs_namecheck.h"
  82   84  
  83   85  typedef struct zfsctl_node {
  84   86          gfs_dir_t       zc_gfs_private;
  85   87          uint64_t        zc_id;
  86   88          timestruc_t     zc_cmtime;      /* ctime and mtime, always the same */
  87   89  } zfsctl_node_t;
  88   90  
  89   91  typedef struct zfsctl_snapdir {
↓ open down ↓ 644 lines elided ↑ open up ↑
 734  736  static int
 735  737  zfsctl_snapdir_mkdir(vnode_t *dvp, char *dirname, vattr_t *vap, vnode_t  **vpp,
 736  738      cred_t *cr, caller_context_t *cc, int flags, vsecattr_t *vsecp)
 737  739  {
 738  740          zfsvfs_t *zfsvfs = dvp->v_vfsp->vfs_data;
 739  741          char name[ZFS_MAX_DATASET_NAME_LEN];
 740  742          int err;
 741  743          static enum symfollow follow = NO_FOLLOW;
 742  744          static enum uio_seg seg = UIO_SYSSPACE;
 743  745  
 744      -        if (zfs_component_namecheck(dirname, NULL, NULL) != 0)
      746 +        if (zfs_component_namecheck(dirname, NULL, NULL) != 0 ||
      747 +            autosnap_check_name(dirname))
 745  748                  return (SET_ERROR(EILSEQ));
 746  749  
 747  750          dmu_objset_name(zfsvfs->z_os, name);
 748  751  
 749  752          *vpp = NULL;
 750  753  
 751  754          err = zfs_secpolicy_snapshot_perms(name, cr);
 752  755          if (err != 0)
 753  756                  return (err);
 754  757  
↓ open down ↓ 108 lines elided ↑ open up ↑
 863  866          if (err != 0) {
 864  867                  mutex_exit(&sdp->sd_lock);
 865  868                  ZFS_EXIT(zfsvfs);
 866  869                  /*
 867  870                   * handle "ls *" or "?" in a graceful manner,
 868  871                   * forcing EILSEQ to ENOENT.
 869  872                   * Since shell ultimately passes "*" or "?" as name to lookup
 870  873                   */
 871  874                  return (err == EILSEQ ? ENOENT : err);
 872  875          }
      876 +
      877 +        if (autosnap_check_name(strchr(snapname, '@'))) {
      878 +                mutex_exit(&sdp->sd_lock);
      879 +                ZFS_EXIT(zfsvfs);
      880 +                return (SET_ERROR(ENOENT));
      881 +        }
      882 +
 873  883          if (dmu_objset_hold(snapname, FTAG, &snap) != 0) {
 874  884                  mutex_exit(&sdp->sd_lock);
 875  885                  ZFS_EXIT(zfsvfs);
 876  886                  return (SET_ERROR(ENOENT));
 877  887          }
 878  888  
 879  889          sep = kmem_alloc(sizeof (zfs_snapentry_t), KM_SLEEP);
 880  890          sep->se_name = kmem_alloc(strlen(nm) + 1, KM_SLEEP);
 881  891          (void) strcpy(sep->se_name, nm);
 882  892          *vpp = sep->se_root = zfsctl_snapshot_mknode(dvp, dmu_objset_id(snap));
↓ open down ↓ 97 lines elided ↑ open up ↑
 980  990          zfsvfs_t *zfsvfs = vp->v_vfsp->vfs_data;
 981  991          char snapname[ZFS_MAX_DATASET_NAME_LEN];
 982  992          uint64_t id, cookie;
 983  993          boolean_t case_conflict;
 984  994          int error;
 985  995  
 986  996          ZFS_ENTER(zfsvfs);
 987  997  
 988  998          cookie = *offp;
 989  999          dsl_pool_config_enter(dmu_objset_pool(zfsvfs->z_os), FTAG);
 990      -        error = dmu_snapshot_list_next(zfsvfs->z_os,
 991      -            sizeof (snapname), snapname, &id, &cookie, &case_conflict);
     1000 +        do {
     1001 +                error = dmu_snapshot_list_next(zfsvfs->z_os,
     1002 +                    sizeof (snapname), snapname, &id, &cookie, &case_conflict);
     1003 +        } while (error == 0 && autosnap_check_name(snapname));
 992 1004          dsl_pool_config_exit(dmu_objset_pool(zfsvfs->z_os), FTAG);
 993 1005          if (error) {
 994 1006                  ZFS_EXIT(zfsvfs);
 995 1007                  if (error == ENOENT) {
 996 1008                          *eofp = 1;
 997 1009                          return (0);
 998 1010                  }
 999 1011                  return (error);
1000 1012          }
1001 1013  
↓ open down ↓ 360 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX