Print this page
NEX-19394 backport 9337 zfs get all is slow due to uncached metadata
Reviewed by: Joyce McIntosh <joyce.mcintosh@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Prakash Surya <prakash.surya@delphix.com>
Reviewed by: George Wilson <george.wilson@delphix.com>
Reviewed by: Thomas Caputi <tcaputi@datto.com>
Approved by: Richard Lowe <richlowe@richlowe.net>
 Conflicts:
  usr/src/uts/common/fs/zfs/dbuf.c
  usr/src/uts/common/fs/zfs/dmu.c
  usr/src/uts/common/fs/zfs/sys/dmu_objset.h
NEX-9200 Improve the scalability of attribute locking in zfs_zget
Reviewed by: Joyce McIntosh <joyce.mcintosh@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
NEX-9436 Rate limiting controls (was QoS) per ZFS dataset, updates from demo
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
NEX-8972 Async-delete side-effect that may cause unmount EBUSY
Reviewed by: Alek Pinchuk <alek@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
NEX-8852 Quality-of-Service (QoS) controls per NFS share
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
NEX-5085 implement async delete for large files
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
NEX-3762 Appliance crashes with a NULL pointer dereference during a zpool export when a zfs_vn_rele_taskq thread attempts to check a bogus rwlock from rw_write_held
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
6160 /usr/lib/fs/zfs/bootinstall should use bootadm
Reviewed by: Igor Kozhukhov <ikozhukhov@gmail.com>
Reviewed by: Adam Števko <adam.stevko@gmail.com>
Reviewed by: Josef Sipek <jeffpc@josefsipek.net>
Approved by: Richard Lowe <richlowe@richlowe.net>
4185 add new cryptographic checksums to ZFS: SHA-512, Skein, Edon-R (NULL is not an int)
6171 dsl_prop_unregister() slows down dataset eviction.
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed by: Prakash Surya <prakash.surya@delphix.com>
Approved by: Dan McDonald <danmcd@omniti.com>
NEX-4582 update wrc test cases for allow to use write back cache per tree of datasets
Reviewed by: Steve Peng <steve.peng@nexenta.com>
Reviewed by: Alex Aizman <alex.aizman@nexenta.com>
5960 zfs recv should prefetch indirect blocks
5925 zfs receive -o origin=
Reviewed by: Prakash Surya <prakash.surya@delphix.com>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
NEX-3485 Deferred deletes causing loss of service for NFS clients on cluster failover
Reviewed by: Marcel Telka <marcel.telka@nexenta.com>
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
NEX-2965 4.0.3-FP2: deferred deletes causing RSF import failure during fail-over of service
Reviewed by: Josef Sipek <josef.sipek@nexenta.com>
Reviewed by: Alek Pinchuk <alek.pinchuk@nexenta.com>
re #13253 rb4328 ssh: openssl version checking needs updating
re #11441 rb4292 panic in apic_record_rdt_entry on VMware hardware version 9
re #12619, rb4287 Deadlocked zfs txg processing in dsl_sync_task_group_sync()
re #13204 rb4280 zfs receive/rollback deadlock
re #6815 rb1758 need WORM in nza-kernel (4.0)

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/zfs/zfs_vfsops.c
          +++ new/usr/src/uts/common/fs/zfs/zfs_vfsops.c
↓ open down ↓ 37 lines elided ↑ open up ↑
  38   38  #include <sys/vfs_opreg.h>
  39   39  #include <sys/mntent.h>
  40   40  #include <sys/mount.h>
  41   41  #include <sys/cmn_err.h>
  42   42  #include "fs/fs_subr.h"
  43   43  #include <sys/zfs_znode.h>
  44   44  #include <sys/zfs_dir.h>
  45   45  #include <sys/zil.h>
  46   46  #include <sys/fs/zfs.h>
  47   47  #include <sys/dmu.h>
       48 +#include <sys/dsl_dir.h>
  48   49  #include <sys/dsl_prop.h>
  49   50  #include <sys/dsl_dataset.h>
  50   51  #include <sys/dsl_deleg.h>
  51   52  #include <sys/spa.h>
  52   53  #include <sys/zap.h>
  53   54  #include <sys/sa.h>
  54   55  #include <sys/sa_impl.h>
  55   56  #include <sys/varargs.h>
  56   57  #include <sys/policy.h>
  57   58  #include <sys/atomic.h>
↓ open down ↓ 331 lines elided ↑ open up ↑
 389  390  }
 390  391  
 391  392  static void
 392  393  acl_inherit_changed_cb(void *arg, uint64_t newval)
 393  394  {
 394  395          zfsvfs_t *zfsvfs = arg;
 395  396  
 396  397          zfsvfs->z_acl_inherit = newval;
 397  398  }
 398  399  
      400 +static void
      401 +rate_changed_cb(void *arg, uint64_t newval)
      402 +{
      403 +        zfsvfs_t *zfsvfs = arg;
      404 +
      405 +        if (newval == UINT64_MAX)
      406 +                newval = 0;
      407 +        zfsvfs->z_rate.rate_cap = newval;
      408 +}
      409 +
 399  410  static int
 400  411  zfs_register_callbacks(vfs_t *vfsp)
 401  412  {
 402  413          struct dsl_dataset *ds = NULL;
 403  414          objset_t *os = NULL;
 404  415          zfsvfs_t *zfsvfs = NULL;
 405  416          uint64_t nbmand;
 406  417          boolean_t readonly = B_FALSE;
 407  418          boolean_t do_readonly = B_FALSE;
 408  419          boolean_t setuid = B_FALSE;
↓ open down ↓ 117 lines elided ↑ open up ↑
 526  537              zfs_prop_to_name(ZFS_PROP_EXEC), exec_changed_cb, zfsvfs);
 527  538          error = error ? error : dsl_prop_register(ds,
 528  539              zfs_prop_to_name(ZFS_PROP_SNAPDIR), snapdir_changed_cb, zfsvfs);
 529  540          error = error ? error : dsl_prop_register(ds,
 530  541              zfs_prop_to_name(ZFS_PROP_ACLMODE), acl_mode_changed_cb, zfsvfs);
 531  542          error = error ? error : dsl_prop_register(ds,
 532  543              zfs_prop_to_name(ZFS_PROP_ACLINHERIT), acl_inherit_changed_cb,
 533  544              zfsvfs);
 534  545          error = error ? error : dsl_prop_register(ds,
 535  546              zfs_prop_to_name(ZFS_PROP_VSCAN), vscan_changed_cb, zfsvfs);
      547 +        error = error ? error : dsl_prop_register(ds,
      548 +            zfs_prop_to_name(ZFS_PROP_RATE_LIMIT), rate_changed_cb, zfsvfs);
      549 +
 536  550          dsl_pool_config_exit(dmu_objset_pool(os), FTAG);
 537  551          if (error)
 538  552                  goto unregister;
 539  553  
 540  554          /*
 541  555           * Invoke our callbacks to restore temporary mount options.
 542  556           */
 543  557          if (do_readonly)
 544  558                  readonly_changed_cb(zfsvfs, readonly);
 545  559          if (do_setuid)
↓ open down ↓ 440 lines elided ↑ open up ↑
 986 1000                  dmu_objset_disown(os, zfsvfs);
 987 1001          }
 988 1002          return (error);
 989 1003  }
 990 1004  
 991 1005  
 992 1006  int
 993 1007  zfsvfs_create_impl(zfsvfs_t **zfvp, zfsvfs_t *zfsvfs, objset_t *os)
 994 1008  {
 995 1009          int error;
     1010 +        int size = spa_get_obj_mtx_sz(dmu_objset_spa(os));
 996 1011  
 997 1012          zfsvfs->z_vfs = NULL;
 998 1013          zfsvfs->z_parent = zfsvfs;
 999 1014  
1000 1015          mutex_init(&zfsvfs->z_znodes_lock, NULL, MUTEX_DEFAULT, NULL);
1001 1016          mutex_init(&zfsvfs->z_lock, NULL, MUTEX_DEFAULT, NULL);
1002 1017          list_create(&zfsvfs->z_all_znodes, sizeof (znode_t),
1003 1018              offsetof(znode_t, z_link_node));
1004 1019          rrm_init(&zfsvfs->z_teardown_lock, B_FALSE);
1005 1020          rw_init(&zfsvfs->z_teardown_inactive_lock, NULL, RW_DEFAULT, NULL);
1006 1021          rw_init(&zfsvfs->z_fuid_lock, NULL, RW_DEFAULT, NULL);
1007      -        for (int i = 0; i != ZFS_OBJ_MTX_SZ; i++)
     1022 +        zfsvfs->z_hold_mtx_sz = size;
     1023 +        zfsvfs->z_hold_mtx = kmem_zalloc(sizeof (kmutex_t) * size, KM_SLEEP);
     1024 +        for (int i = 0; i != size; i++)
1008 1025                  mutex_init(&zfsvfs->z_hold_mtx[i], NULL, MUTEX_DEFAULT, NULL);
     1026 +        mutex_init(&zfsvfs->z_drain_lock, NULL, MUTEX_DEFAULT, NULL);
     1027 +        cv_init(&zfsvfs->z_drain_cv, NULL, CV_DEFAULT, NULL);
1009 1028  
1010 1029          error = zfsvfs_init(zfsvfs, os);
1011 1030          if (error != 0) {
1012 1031                  *zfvp = NULL;
     1032 +                kmem_free(zfsvfs->z_hold_mtx, sizeof (kmutex_t) * size);
1013 1033                  kmem_free(zfsvfs, sizeof (zfsvfs_t));
1014 1034                  return (error);
1015 1035          }
1016 1036  
1017 1037          *zfvp = zfsvfs;
1018 1038          return (0);
1019 1039  }
1020 1040  
1021 1041  static int
1022 1042  zfsvfs_setup(zfsvfs_t *zfsvfs, boolean_t mounting)
↓ open down ↓ 12 lines elided ↑ open up ↑
1035 1055           * operations out since we closed the ZIL.
1036 1056           */
1037 1057          if (mounting) {
1038 1058                  boolean_t readonly;
1039 1059  
1040 1060                  /*
1041 1061                   * During replay we remove the read only flag to
1042 1062                   * allow replays to succeed.
1043 1063                   */
1044 1064                  readonly = zfsvfs->z_vfs->vfs_flag & VFS_RDONLY;
1045      -                if (readonly != 0)
     1065 +                if (readonly)
1046 1066                          zfsvfs->z_vfs->vfs_flag &= ~VFS_RDONLY;
1047      -                else
     1067 +                else {
1048 1068                          zfs_unlinked_drain(zfsvfs);
     1069 +                }
1049 1070  
1050 1071                  /*
1051 1072                   * Parse and replay the intent log.
1052 1073                   *
1053 1074                   * Because of ziltest, this must be done after
1054 1075                   * zfs_unlinked_drain().  (Further note: ziltest
1055 1076                   * doesn't use readonly mounts, where
1056 1077                   * zfs_unlinked_drain() isn't called.)  This is because
1057 1078                   * ziltest causes spa_sync() to think it's committed,
1058 1079                   * but actually it is not, so the intent log contains
↓ open down ↓ 18 lines elided ↑ open up ↑
1077 1098                  if (spa_writeable(dmu_objset_spa(zfsvfs->z_os))) {
1078 1099                          if (zil_replay_disable) {
1079 1100                                  zil_destroy(zfsvfs->z_log, B_FALSE);
1080 1101                          } else {
1081 1102                                  zfsvfs->z_replay = B_TRUE;
1082 1103                                  zil_replay(zfsvfs->z_os, zfsvfs,
1083 1104                                      zfs_replay_vector);
1084 1105                                  zfsvfs->z_replay = B_FALSE;
1085 1106                          }
1086 1107                  }
1087      -                zfsvfs->z_vfs->vfs_flag |= readonly; /* restore readonly bit */
     1108 +
     1109 +                /* restore readonly bit */
     1110 +                if (readonly)
     1111 +                        zfsvfs->z_vfs->vfs_flag |= VFS_RDONLY;
1088 1112          }
1089 1113  
1090 1114          /*
1091 1115           * Set the objset user_ptr to track its zfsvfs.
1092 1116           */
1093 1117          mutex_enter(&zfsvfs->z_os->os_user_ptr_lock);
1094 1118          dmu_objset_set_user(zfsvfs->z_os, zfsvfs);
1095 1119          mutex_exit(&zfsvfs->z_os->os_user_ptr_lock);
1096 1120  
1097 1121          return (0);
↓ open down ↓ 7 lines elided ↑ open up ↑
1105 1129  
1106 1130          /*
1107 1131           * This is a barrier to prevent the filesystem from going away in
1108 1132           * zfs_znode_move() until we can safely ensure that the filesystem is
1109 1133           * not unmounted. We consider the filesystem valid before the barrier
1110 1134           * and invalid after the barrier.
1111 1135           */
1112 1136          rw_enter(&zfsvfs_lock, RW_READER);
1113 1137          rw_exit(&zfsvfs_lock);
1114 1138  
     1139 +        VERIFY0(zfsvfs->z_znodes_freeing_cnt);
     1140 +
1115 1141          zfs_fuid_destroy(zfsvfs);
1116 1142  
     1143 +        cv_destroy(&zfsvfs->z_drain_cv);
     1144 +        mutex_destroy(&zfsvfs->z_drain_lock);
1117 1145          mutex_destroy(&zfsvfs->z_znodes_lock);
1118 1146          mutex_destroy(&zfsvfs->z_lock);
1119 1147          list_destroy(&zfsvfs->z_all_znodes);
1120 1148          rrm_destroy(&zfsvfs->z_teardown_lock);
1121 1149          rw_destroy(&zfsvfs->z_teardown_inactive_lock);
1122 1150          rw_destroy(&zfsvfs->z_fuid_lock);
1123      -        for (i = 0; i != ZFS_OBJ_MTX_SZ; i++)
     1151 +        for (i = 0; i != zfsvfs->z_hold_mtx_sz; i++)
1124 1152                  mutex_destroy(&zfsvfs->z_hold_mtx[i]);
     1153 +
     1154 +        kmem_free(zfsvfs->z_hold_mtx,
     1155 +            sizeof (kmutex_t) * zfsvfs->z_hold_mtx_sz);
1125 1156          kmem_free(zfsvfs, sizeof (zfsvfs_t));
1126 1157  }
1127 1158  
1128 1159  static void
1129 1160  zfs_set_fuid_feature(zfsvfs_t *zfsvfs)
1130 1161  {
1131 1162          zfsvfs->z_use_fuids = USE_FUIDS(zfsvfs->z_version, zfsvfs->z_os);
1132 1163          if (zfsvfs->z_vfs) {
1133 1164                  if (zfsvfs->z_use_fuids) {
1134 1165                          vfs_set_feature(zfsvfs->z_vfs, VFSFT_XVATTR);
↓ open down ↓ 14 lines elided ↑ open up ↑
1149 1180          zfsvfs->z_use_sa = USE_SA(zfsvfs->z_version, zfsvfs->z_os);
1150 1181  }
1151 1182  
1152 1183  static int
1153 1184  zfs_domount(vfs_t *vfsp, char *osname)
1154 1185  {
1155 1186          dev_t mount_dev;
1156 1187          uint64_t recordsize, fsid_guid;
1157 1188          int error = 0;
1158 1189          zfsvfs_t *zfsvfs;
     1190 +        char    worminfo[13] = {0};
1159 1191  
1160 1192          ASSERT(vfsp);
1161 1193          ASSERT(osname);
1162 1194  
1163 1195          error = zfsvfs_create(osname, &zfsvfs);
1164 1196          if (error)
1165 1197                  return (error);
1166 1198          zfsvfs->z_vfs = vfsp;
1167 1199  
1168 1200          /* Initialize the generic filesystem structure. */
↓ open down ↓ 3 lines elided ↑ open up ↑
1172 1204          if (zfs_create_unique_device(&mount_dev) == -1) {
1173 1205                  error = SET_ERROR(ENODEV);
1174 1206                  goto out;
1175 1207          }
1176 1208          ASSERT(vfs_devismounted(mount_dev) == 0);
1177 1209  
1178 1210          if (error = dsl_prop_get_integer(osname, "recordsize", &recordsize,
1179 1211              NULL))
1180 1212                  goto out;
1181 1213  
     1214 +        if (dsl_prop_get(osname, "nms:worm", 1, 12, &worminfo, NULL) == 0 &&
     1215 +            worminfo[0] && strcmp(worminfo, "0") != 0 &&
     1216 +            strcmp(worminfo, "off") != 0 && strcmp(worminfo, "-") != 0) {
     1217 +                zfsvfs->z_isworm = B_TRUE;
     1218 +        } else {
     1219 +                zfsvfs->z_isworm = B_FALSE;
     1220 +        }
     1221 +
1182 1222          vfsp->vfs_dev = mount_dev;
1183 1223          vfsp->vfs_fstype = zfsfstype;
1184 1224          vfsp->vfs_bsize = recordsize;
1185 1225          vfsp->vfs_flag |= VFS_NOTRUNC;
1186 1226          vfsp->vfs_data = zfsvfs;
1187 1227  
1188 1228          /*
1189 1229           * The fsid is 64 bits, composed of an 8-bit fs type, which
1190 1230           * separates our fsid from any other filesystem types, and a
1191 1231           * 56-bit objset unique ID.  The objset unique ID is unique to
↓ open down ↓ 546 lines elided ↑ open up ↑
1738 1778   * Teardown the zfsvfs::z_os.
1739 1779   *
1740 1780   * Note, if 'unmounting' is FALSE, we return with the 'z_teardown_lock'
1741 1781   * and 'z_teardown_inactive_lock' held.
1742 1782   */
1743 1783  static int
1744 1784  zfsvfs_teardown(zfsvfs_t *zfsvfs, boolean_t unmounting)
1745 1785  {
1746 1786          znode_t *zp;
1747 1787  
     1788 +        zfs_unlinked_drain_stop_wait(zfsvfs);
1748 1789          rrm_enter(&zfsvfs->z_teardown_lock, RW_WRITER, FTAG);
1749 1790  
1750 1791          if (!unmounting) {
1751 1792                  /*
1752 1793                   * We purge the parent filesystem's vfsp as the parent
1753 1794                   * filesystem and all of its snapshots have their vnode's
1754 1795                   * v_vfsp set to the parent's filesystem's vfsp.  Note,
1755 1796                   * 'z_parent' is self referential for non-snapshots.
1756 1797                   */
1757 1798                  (void) dnlc_purge_vfsp(zfsvfs->z_parent->z_vfs, 0);
↓ open down ↓ 60 lines elided ↑ open up ↑
1818 1859           * Unregister properties.
1819 1860           */
1820 1861          zfs_unregister_callbacks(zfsvfs);
1821 1862  
1822 1863          /*
1823 1864           * Evict cached data
1824 1865           */
1825 1866          if (dsl_dataset_is_dirty(dmu_objset_ds(zfsvfs->z_os)) &&
1826 1867              !(zfsvfs->z_vfs->vfs_flag & VFS_RDONLY))
1827 1868                  txg_wait_synced(dmu_objset_pool(zfsvfs->z_os), 0);
1828      -        dmu_objset_evict_dbufs(zfsvfs->z_os);
     1869 +        (void) dmu_objset_evict_dbufs(zfsvfs->z_os);
1829 1870  
1830 1871          return (0);
1831 1872  }
1832 1873  
1833 1874  /*ARGSUSED*/
1834 1875  static int
1835 1876  zfs_umount(vfs_t *vfsp, int fflag, cred_t *cr)
1836 1877  {
1837 1878          zfsvfs_t *zfsvfs = vfsp->vfs_data;
1838 1879          objset_t *os;
↓ open down ↓ 17 lines elided ↑ open up ↑
1856 1897          /*
1857 1898           * Unmount any snapshots mounted under .zfs before unmounting the
1858 1899           * dataset itself.
1859 1900           */
1860 1901          if (zfsvfs->z_ctldir != NULL &&
1861 1902              (ret = zfsctl_umount_snapshots(vfsp, fflag, cr)) != 0) {
1862 1903                  return (ret);
1863 1904          }
1864 1905  
1865 1906          if (!(fflag & MS_FORCE)) {
     1907 +                uint_t active_vnodes;
     1908 +
1866 1909                  /*
1867 1910                   * Check the number of active vnodes in the file system.
1868 1911                   * Our count is maintained in the vfs structure, but the
1869 1912                   * number is off by 1 to indicate a hold on the vfs
1870 1913                   * structure itself.
1871 1914                   *
1872 1915                   * The '.zfs' directory maintains a reference of its
1873 1916                   * own, and any active references underneath are
1874 1917                   * reflected in the vnode count.
     1918 +                 *
     1919 +                 * Active vnodes: vnodes that were held by an user
1875 1920                   */
     1921 +
     1922 +                active_vnodes =
     1923 +                    vfsp->vfs_count - zfsvfs->z_znodes_freeing_cnt;
     1924 +
1876 1925                  if (zfsvfs->z_ctldir == NULL) {
1877      -                        if (vfsp->vfs_count > 1)
     1926 +                        if (active_vnodes > 1)
1878 1927                                  return (SET_ERROR(EBUSY));
1879 1928                  } else {
1880      -                        if (vfsp->vfs_count > 2 ||
     1929 +                        if (active_vnodes > 2 ||
1881 1930                              zfsvfs->z_ctldir->v_count > 1)
1882 1931                                  return (SET_ERROR(EBUSY));
1883 1932                  }
1884 1933          }
1885 1934  
1886 1935          vfsp->vfs_flag |= VFS_UNMOUNTED;
1887 1936  
1888 1937          VERIFY(zfsvfs_teardown(zfsvfs, B_TRUE) == 0);
1889 1938          os = zfsvfs->z_os;
1890 1939  
↓ open down ↓ 116 lines elided ↑ open up ↑
2007 2056   * Note, if successful, then we return with the 'z_teardown_lock' and
2008 2057   * 'z_teardown_inactive_lock' write held.  We leave ownership of the underlying
2009 2058   * dataset and objset intact so that they can be atomically handed off during
2010 2059   * a subsequent rollback or recv operation and the resume thereafter.
2011 2060   */
2012 2061  int
2013 2062  zfs_suspend_fs(zfsvfs_t *zfsvfs)
2014 2063  {
2015 2064          int error;
2016 2065  
2017      -        if ((error = zfsvfs_teardown(zfsvfs, B_FALSE)) != 0)
     2066 +        mutex_enter(&zfsvfs->z_lock);
     2067 +        if (zfsvfs->z_busy) {
     2068 +                mutex_exit(&zfsvfs->z_lock);
     2069 +                return (SET_ERROR(EBUSY));
     2070 +        }
     2071 +        zfsvfs->z_busy = B_TRUE;
     2072 +        mutex_exit(&zfsvfs->z_lock);
     2073 +
     2074 +        if ((error = zfsvfs_teardown(zfsvfs, B_FALSE)) != 0) {
     2075 +                mutex_enter(&zfsvfs->z_lock);
     2076 +                zfsvfs->z_busy = B_FALSE;
     2077 +                mutex_exit(&zfsvfs->z_lock);
2018 2078                  return (error);
     2079 +        }
2019 2080  
2020 2081          return (0);
2021 2082  }
2022 2083  
2023 2084  /*
2024 2085   * Rebuild SA and release VOPs.  Note that ownership of the underlying dataset
2025 2086   * is an invariant across any of the operations that can be performed while the
2026 2087   * filesystem was suspended.  Whether it succeeded or failed, the preconditions
2027 2088   * are the same: the relevant objset and associated dataset are owned by
2028 2089   * zfsvfs, held, and long held on entry.
↓ open down ↓ 30 lines elided ↑ open up ↑
2059 2120           * any potential callers discover that via ZFS_ENTER_VERIFY_VP
2060 2121           * when they try to use their znode.
2061 2122           */
2062 2123          mutex_enter(&zfsvfs->z_znodes_lock);
2063 2124          for (zp = list_head(&zfsvfs->z_all_znodes); zp;
2064 2125              zp = list_next(&zfsvfs->z_all_znodes, zp)) {
2065 2126                  (void) zfs_rezget(zp);
2066 2127          }
2067 2128          mutex_exit(&zfsvfs->z_znodes_lock);
2068 2129  
     2130 +        if (((zfsvfs->z_vfs->vfs_flag & VFS_RDONLY) == 0) &&
     2131 +            !zfsvfs->z_unmounted) {
     2132 +                /*
     2133 +                 * zfs_suspend_fs() could have interrupted freeing
     2134 +                 * of dnodes. We need to restart this freeing so
     2135 +                 * that we don't "leak" the space.
     2136 +                 */
     2137 +                zfs_unlinked_drain(zfsvfs);
     2138 +        }
     2139 +
2069 2140  bail:
2070 2141          /* release the VOPs */
2071 2142          rw_exit(&zfsvfs->z_teardown_inactive_lock);
2072 2143          rrm_exit(&zfsvfs->z_teardown_lock, FTAG);
2073 2144  
2074 2145          if (err) {
2075 2146                  /*
2076 2147                   * Since we couldn't setup the sa framework, try to force
2077 2148                   * unmount this file system.
2078 2149                   */
2079 2150                  if (vn_vfswlock(zfsvfs->z_vfs->vfs_vnodecovered) == 0)
2080 2151                          (void) dounmount(zfsvfs->z_vfs, MS_FORCE, CRED());
2081 2152          }
     2153 +        mutex_enter(&zfsvfs->z_lock);
     2154 +        zfsvfs->z_busy = B_FALSE;
     2155 +        mutex_exit(&zfsvfs->z_lock);
     2156 +
2082 2157          return (err);
2083 2158  }
2084 2159  
2085 2160  static void
2086 2161  zfs_freevfs(vfs_t *vfsp)
2087 2162  {
2088 2163          zfsvfs_t *zfsvfs = vfsp->vfs_data;
2089 2164  
2090 2165          /*
2091 2166           * If this is a snapshot, we have an extra VFS_HOLD on our parent
↓ open down ↓ 133 lines elided ↑ open up ↑
2225 2300                  VERIFY(0 == sa_set_sa_object(os, sa_obj));
2226 2301                  sa_register_update_callback(os, zfs_sa_upgrade);
2227 2302          }
2228 2303  
2229 2304          spa_history_log_internal_ds(dmu_objset_ds(os), "upgrade", tx,
2230 2305              "from %llu to %llu", zfsvfs->z_version, newvers);
2231 2306  
2232 2307          dmu_tx_commit(tx);
2233 2308  
2234 2309          zfsvfs->z_version = newvers;
     2310 +        os->os_version = newvers;
2235 2311  
2236 2312          zfs_set_fuid_feature(zfsvfs);
2237 2313  
2238 2314          return (0);
2239 2315  }
2240 2316  
2241 2317  /*
2242 2318   * Read a property stored within the master node.
2243 2319   */
2244 2320  int
2245 2321  zfs_get_zplprop(objset_t *os, zfs_prop_t prop, uint64_t *value)
2246 2322  {
2247      -        const char *pname;
2248      -        int error = ENOENT;
     2323 +        uint64_t *cached_copy = NULL;
2249 2324  
2250 2325          /*
2251      -         * Look up the file system's value for the property.  For the
2252      -         * version property, we look up a slightly different string.
     2326 +         * Figure out where in the objset_t the cached copy would live, if it
     2327 +         * is available for the requested property.
2253 2328           */
2254      -        if (prop == ZFS_PROP_VERSION)
     2329 +        if (os != NULL) {
     2330 +                switch (prop) {
     2331 +                case ZFS_PROP_VERSION:
     2332 +                        cached_copy = &os->os_version;
     2333 +                        break;
     2334 +                case ZFS_PROP_NORMALIZE:
     2335 +                        cached_copy = &os->os_normalization;
     2336 +                        break;
     2337 +                case ZFS_PROP_UTF8ONLY:
     2338 +                        cached_copy = &os->os_utf8only;
     2339 +                        break;
     2340 +                case ZFS_PROP_CASE:
     2341 +                        cached_copy = &os->os_casesensitivity;
     2342 +                        break;
     2343 +                default:
     2344 +                        break;
     2345 +                }
     2346 +        }
     2347 +        if (cached_copy != NULL && *cached_copy != OBJSET_PROP_UNINITIALIZED) {
     2348 +                *value = *cached_copy;
     2349 +                return (0);
     2350 +        }
     2351 +
     2352 +        /*
     2353 +         * If the property wasn't cached, look up the file system's value for
     2354 +         * the property. For the version property, we look up a slightly
     2355 +         * different string.
     2356 +         */
     2357 +        const char *pname;
     2358 +        int error = ENOENT;
     2359 +        if (prop == ZFS_PROP_VERSION) {
2255 2360                  pname = ZPL_VERSION_STR;
2256      -        else
     2361 +        } else {
2257 2362                  pname = zfs_prop_to_name(prop);
     2363 +        }
2258 2364  
2259 2365          if (os != NULL) {
2260 2366                  ASSERT3U(os->os_phys->os_type, ==, DMU_OST_ZFS);
2261 2367                  error = zap_lookup(os, MASTER_NODE_OBJ, pname, 8, 1, value);
2262 2368          }
2263 2369  
2264 2370          if (error == ENOENT) {
2265 2371                  /* No value set, use the default value */
2266 2372                  switch (prop) {
2267 2373                  case ZFS_PROP_VERSION:
↓ open down ↓ 4 lines elided ↑ open up ↑
2272 2378                          *value = 0;
2273 2379                          break;
2274 2380                  case ZFS_PROP_CASE:
2275 2381                          *value = ZFS_CASE_SENSITIVE;
2276 2382                          break;
2277 2383                  default:
2278 2384                          return (error);
2279 2385                  }
2280 2386                  error = 0;
2281 2387          }
     2388 +
     2389 +        /*
     2390 +         * If one of the methods for getting the property value above worked,
     2391 +         * copy it into the objset_t's cache.
     2392 +         */
     2393 +        if (error == 0 && cached_copy != NULL) {
     2394 +                *cached_copy = *value;
     2395 +        }
     2396 +
2282 2397          return (error);
2283 2398  }
2284 2399  
2285 2400  /*
2286 2401   * Return true if the coresponding vfs's unmounted flag is set.
2287 2402   * Otherwise return false.
2288 2403   * If this function returns true we know VFS unmount has been initiated.
2289 2404   */
2290 2405  boolean_t
2291 2406  zfs_get_vfs_flag_unmounted(objset_t *os)
↓ open down ↓ 28 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX