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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright (c) 2013 by Delphix. All rights reserved.
24 * Copyright (c) 2013 Martin Matuska. All rights reserved.
25 */
26
27 #include <sys/dmu.h>
28 #include <sys/dmu_objset.h>
29 #include <sys/dmu_tx.h>
30 #include <sys/dsl_dataset.h>
31 #include <sys/dsl_dir.h>
32 #include <sys/dsl_prop.h>
33 #include <sys/dsl_synctask.h>
34 #include <sys/dsl_deleg.h>
35 #include <sys/spa.h>
36 #include <sys/metaslab.h>
37 #include <sys/zap.h>
38 #include <sys/zio.h>
39 #include <sys/arc.h>
40 #include <sys/sunddi.h>
41 #include "zfs_namecheck.h"
42
43 static uint64_t dsl_dir_space_towrite(dsl_dir_t *dd);
44
45 /* ARGSUSED */
46 static void
47 dsl_dir_evict(dmu_buf_t *db, void *arg)
48 {
49 dsl_dir_t *dd = arg;
50 dsl_pool_t *dp = dd->dd_pool;
51 int t;
52
53 for (t = 0; t < TXG_SIZE; t++) {
54 ASSERT(!txg_list_member(&dp->dp_dirty_dirs, dd, t));
71 }
72
73 int
74 dsl_dir_hold_obj(dsl_pool_t *dp, uint64_t ddobj,
75 const char *tail, void *tag, dsl_dir_t **ddp)
76 {
77 dmu_buf_t *dbuf;
78 dsl_dir_t *dd;
79 int err;
80
81 ASSERT(dsl_pool_config_held(dp));
82
83 err = dmu_bonus_hold(dp->dp_meta_objset, ddobj, tag, &dbuf);
84 if (err != 0)
85 return (err);
86 dd = dmu_buf_get_user(dbuf);
87 #ifdef ZFS_DEBUG
88 {
89 dmu_object_info_t doi;
90 dmu_object_info_from_db(dbuf, &doi);
91 ASSERT3U(doi.doi_type, ==, DMU_OT_DSL_DIR);
92 ASSERT3U(doi.doi_bonus_size, >=, sizeof (dsl_dir_phys_t));
93 }
94 #endif
95 if (dd == NULL) {
96 dsl_dir_t *winner;
97
98 dd = kmem_zalloc(sizeof (dsl_dir_t), KM_SLEEP);
99 dd->dd_object = ddobj;
100 dd->dd_dbuf = dbuf;
101 dd->dd_pool = dp;
102 dd->dd_phys = dbuf->db_data;
103 mutex_init(&dd->dd_lock, NULL, MUTEX_DEFAULT, NULL);
104
105 list_create(&dd->dd_prop_cbs, sizeof (dsl_prop_cb_record_t),
106 offsetof(dsl_prop_cb_record_t, cbr_node));
107
108 dsl_dir_snap_cmtime_update(dd);
109
110 if (dd->dd_phys->dd_parent_obj) {
111 err = dsl_dir_hold_obj(dp, dd->dd_phys->dd_parent_obj,
1334 dsl_dir_snap_cmtime(dsl_dir_t *dd)
1335 {
1336 timestruc_t t;
1337
1338 mutex_enter(&dd->dd_lock);
1339 t = dd->dd_snap_cmtime;
1340 mutex_exit(&dd->dd_lock);
1341
1342 return (t);
1343 }
1344
1345 void
1346 dsl_dir_snap_cmtime_update(dsl_dir_t *dd)
1347 {
1348 timestruc_t t;
1349
1350 gethrestime(&t);
1351 mutex_enter(&dd->dd_lock);
1352 dd->dd_snap_cmtime = t;
1353 mutex_exit(&dd->dd_lock);
1354 }
|
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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright (c) 2013 by Delphix. All rights reserved.
24 * Copyright (c) 2013 Martin Matuska. All rights reserved.
25 */
26
27 #include <sys/dmu.h>
28 #include <sys/dmu_objset.h>
29 #include <sys/dmu_tx.h>
30 #include <sys/dsl_dataset.h>
31 #include <sys/dsl_dir.h>
32 #include <sys/dsl_prop.h>
33 #include <sys/dsl_synctask.h>
34 #include <sys/dsl_deleg.h>
35 #include <sys/dmu_impl.h>
36 #include <sys/spa.h>
37 #include <sys/metaslab.h>
38 #include <sys/zap.h>
39 #include <sys/zio.h>
40 #include <sys/arc.h>
41 #include <sys/sunddi.h>
42 #include "zfs_namecheck.h"
43
44 static uint64_t dsl_dir_space_towrite(dsl_dir_t *dd);
45
46 /* ARGSUSED */
47 static void
48 dsl_dir_evict(dmu_buf_t *db, void *arg)
49 {
50 dsl_dir_t *dd = arg;
51 dsl_pool_t *dp = dd->dd_pool;
52 int t;
53
54 for (t = 0; t < TXG_SIZE; t++) {
55 ASSERT(!txg_list_member(&dp->dp_dirty_dirs, dd, t));
72 }
73
74 int
75 dsl_dir_hold_obj(dsl_pool_t *dp, uint64_t ddobj,
76 const char *tail, void *tag, dsl_dir_t **ddp)
77 {
78 dmu_buf_t *dbuf;
79 dsl_dir_t *dd;
80 int err;
81
82 ASSERT(dsl_pool_config_held(dp));
83
84 err = dmu_bonus_hold(dp->dp_meta_objset, ddobj, tag, &dbuf);
85 if (err != 0)
86 return (err);
87 dd = dmu_buf_get_user(dbuf);
88 #ifdef ZFS_DEBUG
89 {
90 dmu_object_info_t doi;
91 dmu_object_info_from_db(dbuf, &doi);
92 ASSERT3U(doi.doi_bonus_type, ==, DMU_OT_DSL_DIR);
93 ASSERT3U(doi.doi_bonus_size, >=, sizeof (dsl_dir_phys_t));
94 }
95 #endif
96 if (dd == NULL) {
97 dsl_dir_t *winner;
98
99 dd = kmem_zalloc(sizeof (dsl_dir_t), KM_SLEEP);
100 dd->dd_object = ddobj;
101 dd->dd_dbuf = dbuf;
102 dd->dd_pool = dp;
103 dd->dd_phys = dbuf->db_data;
104 mutex_init(&dd->dd_lock, NULL, MUTEX_DEFAULT, NULL);
105
106 list_create(&dd->dd_prop_cbs, sizeof (dsl_prop_cb_record_t),
107 offsetof(dsl_prop_cb_record_t, cbr_node));
108
109 dsl_dir_snap_cmtime_update(dd);
110
111 if (dd->dd_phys->dd_parent_obj) {
112 err = dsl_dir_hold_obj(dp, dd->dd_phys->dd_parent_obj,
1335 dsl_dir_snap_cmtime(dsl_dir_t *dd)
1336 {
1337 timestruc_t t;
1338
1339 mutex_enter(&dd->dd_lock);
1340 t = dd->dd_snap_cmtime;
1341 mutex_exit(&dd->dd_lock);
1342
1343 return (t);
1344 }
1345
1346 void
1347 dsl_dir_snap_cmtime_update(dsl_dir_t *dd)
1348 {
1349 timestruc_t t;
1350
1351 gethrestime(&t);
1352 mutex_enter(&dd->dd_lock);
1353 dd->dd_snap_cmtime = t;
1354 mutex_exit(&dd->dd_lock);
1355 }
1356
1357 void
1358 dsl_dir_zapify(dsl_dir_t *dd, dmu_tx_t *tx)
1359 {
1360 objset_t *mos = dd->dd_pool->dp_meta_objset;
1361 dmu_object_zapify(mos, dd->dd_object, DMU_OT_DSL_DIR, tx);
1362 }
|