110 * For consistency, the filesystem limit is also not enforced if the user can
111 * modify the limit.
112 *
113 * The filesystem and snapshot limits are validated by dsl_fs_ss_limit_check()
114 * and updated by dsl_fs_ss_count_adjust(). A new limit value is setup in
115 * dsl_dir_activate_fs_ss_limit() and the counts are adjusted, if necessary, by
116 * dsl_dir_init_fs_ss_count().
117 *
118 * There is a special case when we receive a filesystem that already exists. In
119 * this case a temporary clone name of %X is created (see dmu_recv_begin). We
120 * never update the filesystem counts for temporary clones.
121 *
122 * Likewise, we do not update the snapshot counts for temporary snapshots,
123 * such as those created by zfs diff.
124 */
125
126 extern inline dsl_dir_phys_t *dsl_dir_phys(dsl_dir_t *dd);
127
128 static uint64_t dsl_dir_space_towrite(dsl_dir_t *dd);
129
130 typedef struct ddulrt_arg {
131 dsl_dir_t *ddulrta_dd;
132 uint64_t ddlrta_txg;
133 } ddulrt_arg_t;
134
135 static void
136 dsl_dir_evict_async(void *dbu)
137 {
138 dsl_dir_t *dd = dbu;
139 dsl_pool_t *dp = dd->dd_pool;
140 int t;
141
142 dd->dd_dbuf = NULL;
143
144 for (t = 0; t < TXG_SIZE; t++) {
145 ASSERT(!txg_list_member(&dp->dp_dirty_dirs, dd, t));
146 ASSERT(dd->dd_tempreserved[t] == 0);
147 ASSERT(dd->dd_space_towrite[t] == 0);
148 }
149
150 if (dd->dd_parent)
151 dsl_dir_async_rele(dd->dd_parent, dd);
152
153 spa_async_close(dd->dd_pool->dp_spa, dd);
154
717 if ((obj = dsl_dir_phys(dd)->dd_head_dataset_obj) == 0)
718 return (ENFORCE_ALWAYS);
719
720 ASSERT(dsl_pool_config_held(dd->dd_pool));
721
722 if (dsl_dataset_hold_obj(dd->dd_pool, obj, FTAG, &ds) != 0)
723 return (ENFORCE_ALWAYS);
724
725 if (dsl_prop_get_ds(ds, "zoned", 8, 1, &zoned, NULL) || zoned) {
726 /* Only root can access zoned fs's from the GZ */
727 enforce = ENFORCE_ALWAYS;
728 } else {
729 if (dsl_deleg_access_impl(ds, zfs_prop_to_name(prop), cr) == 0)
730 enforce = ENFORCE_ABOVE;
731 }
732
733 dsl_dataset_rele(ds, FTAG);
734 return (enforce);
735 }
736
737 static void
738 dsl_dir_update_last_remap_txg_sync(void *varg, dmu_tx_t *tx)
739 {
740 ddulrt_arg_t *arg = varg;
741 uint64_t last_remap_txg;
742 dsl_dir_t *dd = arg->ddulrta_dd;
743 objset_t *mos = dd->dd_pool->dp_meta_objset;
744
745 dsl_dir_zapify(dd, tx);
746 if (zap_lookup(mos, dd->dd_object, DD_FIELD_LAST_REMAP_TXG,
747 sizeof (last_remap_txg), 1, &last_remap_txg) != 0 ||
748 last_remap_txg < arg->ddlrta_txg) {
749 VERIFY0(zap_update(mos, dd->dd_object, DD_FIELD_LAST_REMAP_TXG,
750 sizeof (arg->ddlrta_txg), 1, &arg->ddlrta_txg, tx));
751 }
752 }
753
754 int
755 dsl_dir_update_last_remap_txg(dsl_dir_t *dd, uint64_t txg)
756 {
757 ddulrt_arg_t arg;
758 arg.ddulrta_dd = dd;
759 arg.ddlrta_txg = txg;
760
761 return (dsl_sync_task(spa_name(dd->dd_pool->dp_spa),
762 NULL, dsl_dir_update_last_remap_txg_sync, &arg,
763 1, ZFS_SPACE_CHECK_RESERVED));
764 }
765
766 /*
767 * Check if adding additional child filesystem(s) would exceed any filesystem
768 * limits or adding additional snapshot(s) would exceed any snapshot limits.
769 * The prop argument indicates which limit to check.
770 *
771 * Note that all filesystem limits up to the root (or the highest
772 * initialized) filesystem or the given ancestor must be satisfied.
773 */
774 int
775 dsl_fs_ss_limit_check(dsl_dir_t *dd, uint64_t delta, zfs_prop_t prop,
776 dsl_dir_t *ancestor, cred_t *cr)
777 {
778 objset_t *os = dd->dd_pool->dp_meta_objset;
779 uint64_t limit, count;
780 char *count_prop;
781 enforce_res_t enforce;
782 int err = 0;
783
784 ASSERT(dsl_pool_config_held(dd->dd_pool));
785 ASSERT(prop == ZFS_PROP_FILESYSTEM_LIMIT ||
1037 objset_t *os = dd->dd_pool->dp_meta_objset;
1038 return (zap_lookup(os, dd->dd_object, DD_FIELD_FILESYSTEM_COUNT,
1039 sizeof (*count), 1, count));
1040 } else {
1041 return (ENOENT);
1042 }
1043 }
1044
1045 int
1046 dsl_dir_get_snapshot_count(dsl_dir_t *dd, uint64_t *count)
1047 {
1048 if (dsl_dir_is_zapified(dd)) {
1049 objset_t *os = dd->dd_pool->dp_meta_objset;
1050 return (zap_lookup(os, dd->dd_object, DD_FIELD_SNAPSHOT_COUNT,
1051 sizeof (*count), 1, count));
1052 } else {
1053 return (ENOENT);
1054 }
1055 }
1056
1057 int
1058 dsl_dir_get_remaptxg(dsl_dir_t *dd, uint64_t *count)
1059 {
1060 if (dsl_dir_is_zapified(dd)) {
1061 objset_t *os = dd->dd_pool->dp_meta_objset;
1062 return (zap_lookup(os, dd->dd_object, DD_FIELD_LAST_REMAP_TXG,
1063 sizeof (*count), 1, count));
1064 } else {
1065 return (ENOENT);
1066 }
1067 }
1068
1069 void
1070 dsl_dir_stats(dsl_dir_t *dd, nvlist_t *nv)
1071 {
1072 mutex_enter(&dd->dd_lock);
1073 dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_QUOTA,
1074 dsl_dir_get_quota(dd));
1075 dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_RESERVATION,
1076 dsl_dir_get_reservation(dd));
1077 dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_LOGICALUSED,
1078 dsl_dir_get_logicalused(dd));
1079 if (dsl_dir_phys(dd)->dd_flags & DD_FLAG_USED_BREAKDOWN) {
1080 dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USEDSNAP,
1081 dsl_dir_get_usedsnap(dd));
1082 dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USEDDS,
1083 dsl_dir_get_usedds(dd));
1084 dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USEDREFRESERV,
1085 dsl_dir_get_usedrefreserv(dd));
1086 dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USEDCHILD,
1087 dsl_dir_get_usedchild(dd));
1088 }
1089 mutex_exit(&dd->dd_lock);
1090
1091 uint64_t count;
1092 if (dsl_dir_get_filesystem_count(dd, &count) == 0) {
1093 dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_FILESYSTEM_COUNT,
1094 count);
1095 }
1096 if (dsl_dir_get_snapshot_count(dd, &count) == 0) {
1097 dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_SNAPSHOT_COUNT,
1098 count);
1099 }
1100 if (dsl_dir_get_remaptxg(dd, &count) == 0) {
1101 dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_REMAPTXG,
1102 count);
1103 }
1104
1105 if (dsl_dir_is_clone(dd)) {
1106 char buf[ZFS_MAX_DATASET_NAME_LEN];
1107 dsl_dir_get_origin(dd, buf);
1108 dsl_prop_nvlist_add_string(nv, ZFS_PROP_ORIGIN, buf);
1109 }
1110
1111 }
1112
1113 void
1114 dsl_dir_dirty(dsl_dir_t *dd, dmu_tx_t *tx)
1115 {
1116 dsl_pool_t *dp = dd->dd_pool;
1117
1118 ASSERT(dsl_dir_phys(dd));
1119
1120 if (txg_list_add(&dp->dp_dirty_dirs, dd, tx->tx_txg)) {
1121 /* up the hold count until we can be written out */
1122 dmu_buf_add_ref(dd->dd_dbuf, dd);
1123 }
|
110 * For consistency, the filesystem limit is also not enforced if the user can
111 * modify the limit.
112 *
113 * The filesystem and snapshot limits are validated by dsl_fs_ss_limit_check()
114 * and updated by dsl_fs_ss_count_adjust(). A new limit value is setup in
115 * dsl_dir_activate_fs_ss_limit() and the counts are adjusted, if necessary, by
116 * dsl_dir_init_fs_ss_count().
117 *
118 * There is a special case when we receive a filesystem that already exists. In
119 * this case a temporary clone name of %X is created (see dmu_recv_begin). We
120 * never update the filesystem counts for temporary clones.
121 *
122 * Likewise, we do not update the snapshot counts for temporary snapshots,
123 * such as those created by zfs diff.
124 */
125
126 extern inline dsl_dir_phys_t *dsl_dir_phys(dsl_dir_t *dd);
127
128 static uint64_t dsl_dir_space_towrite(dsl_dir_t *dd);
129
130 static void
131 dsl_dir_evict_async(void *dbu)
132 {
133 dsl_dir_t *dd = dbu;
134 dsl_pool_t *dp = dd->dd_pool;
135 int t;
136
137 dd->dd_dbuf = NULL;
138
139 for (t = 0; t < TXG_SIZE; t++) {
140 ASSERT(!txg_list_member(&dp->dp_dirty_dirs, dd, t));
141 ASSERT(dd->dd_tempreserved[t] == 0);
142 ASSERT(dd->dd_space_towrite[t] == 0);
143 }
144
145 if (dd->dd_parent)
146 dsl_dir_async_rele(dd->dd_parent, dd);
147
148 spa_async_close(dd->dd_pool->dp_spa, dd);
149
712 if ((obj = dsl_dir_phys(dd)->dd_head_dataset_obj) == 0)
713 return (ENFORCE_ALWAYS);
714
715 ASSERT(dsl_pool_config_held(dd->dd_pool));
716
717 if (dsl_dataset_hold_obj(dd->dd_pool, obj, FTAG, &ds) != 0)
718 return (ENFORCE_ALWAYS);
719
720 if (dsl_prop_get_ds(ds, "zoned", 8, 1, &zoned, NULL) || zoned) {
721 /* Only root can access zoned fs's from the GZ */
722 enforce = ENFORCE_ALWAYS;
723 } else {
724 if (dsl_deleg_access_impl(ds, zfs_prop_to_name(prop), cr) == 0)
725 enforce = ENFORCE_ABOVE;
726 }
727
728 dsl_dataset_rele(ds, FTAG);
729 return (enforce);
730 }
731
732 /*
733 * Check if adding additional child filesystem(s) would exceed any filesystem
734 * limits or adding additional snapshot(s) would exceed any snapshot limits.
735 * The prop argument indicates which limit to check.
736 *
737 * Note that all filesystem limits up to the root (or the highest
738 * initialized) filesystem or the given ancestor must be satisfied.
739 */
740 int
741 dsl_fs_ss_limit_check(dsl_dir_t *dd, uint64_t delta, zfs_prop_t prop,
742 dsl_dir_t *ancestor, cred_t *cr)
743 {
744 objset_t *os = dd->dd_pool->dp_meta_objset;
745 uint64_t limit, count;
746 char *count_prop;
747 enforce_res_t enforce;
748 int err = 0;
749
750 ASSERT(dsl_pool_config_held(dd->dd_pool));
751 ASSERT(prop == ZFS_PROP_FILESYSTEM_LIMIT ||
1003 objset_t *os = dd->dd_pool->dp_meta_objset;
1004 return (zap_lookup(os, dd->dd_object, DD_FIELD_FILESYSTEM_COUNT,
1005 sizeof (*count), 1, count));
1006 } else {
1007 return (ENOENT);
1008 }
1009 }
1010
1011 int
1012 dsl_dir_get_snapshot_count(dsl_dir_t *dd, uint64_t *count)
1013 {
1014 if (dsl_dir_is_zapified(dd)) {
1015 objset_t *os = dd->dd_pool->dp_meta_objset;
1016 return (zap_lookup(os, dd->dd_object, DD_FIELD_SNAPSHOT_COUNT,
1017 sizeof (*count), 1, count));
1018 } else {
1019 return (ENOENT);
1020 }
1021 }
1022
1023 void
1024 dsl_dir_stats(dsl_dir_t *dd, nvlist_t *nv)
1025 {
1026 mutex_enter(&dd->dd_lock);
1027 dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_QUOTA,
1028 dsl_dir_get_quota(dd));
1029 dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_RESERVATION,
1030 dsl_dir_get_reservation(dd));
1031 dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_LOGICALUSED,
1032 dsl_dir_get_logicalused(dd));
1033 if (dsl_dir_phys(dd)->dd_flags & DD_FLAG_USED_BREAKDOWN) {
1034 dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USEDSNAP,
1035 dsl_dir_get_usedsnap(dd));
1036 dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USEDDS,
1037 dsl_dir_get_usedds(dd));
1038 dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USEDREFRESERV,
1039 dsl_dir_get_usedrefreserv(dd));
1040 dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USEDCHILD,
1041 dsl_dir_get_usedchild(dd));
1042 }
1043 mutex_exit(&dd->dd_lock);
1044
1045 uint64_t count;
1046 if (dsl_dir_get_filesystem_count(dd, &count) == 0) {
1047 dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_FILESYSTEM_COUNT,
1048 count);
1049 }
1050 if (dsl_dir_get_snapshot_count(dd, &count) == 0) {
1051 dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_SNAPSHOT_COUNT,
1052 count);
1053 }
1054
1055 if (dsl_dir_is_clone(dd)) {
1056 char buf[ZFS_MAX_DATASET_NAME_LEN];
1057 dsl_dir_get_origin(dd, buf);
1058 dsl_prop_nvlist_add_string(nv, ZFS_PROP_ORIGIN, buf);
1059 }
1060
1061 }
1062
1063 void
1064 dsl_dir_dirty(dsl_dir_t *dd, dmu_tx_t *tx)
1065 {
1066 dsl_pool_t *dp = dd->dd_pool;
1067
1068 ASSERT(dsl_dir_phys(dd));
1069
1070 if (txg_list_add(&dp->dp_dirty_dirs, dd, tx->tx_txg)) {
1071 /* up the hold count until we can be written out */
1072 dmu_buf_add_ref(dd->dd_dbuf, dd);
1073 }
|