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 */
25
26 #include <sys/bpobj.h>
27 #include <sys/zfs_context.h>
28 #include <sys/refcount.h>
29 #include <sys/dsl_pool.h>
30 #include <sys/zfeature.h>
31 #include <sys/zap.h>
32
33 /*
34 * Return an empty bpobj, preferably the empty dummy one (dp_empty_bpobj).
35 */
36 uint64_t
37 bpobj_alloc_empty(objset_t *os, int blocksize, dmu_tx_t *tx)
38 {
39 zfeature_info_t *empty_bpobj_feat =
40 &spa_feature_table[SPA_FEATURE_EMPTY_BPOBJ];
41 spa_t *spa = dmu_objset_spa(os);
42 dsl_pool_t *dp = dmu_objset_pool(os);
43
44 if (spa_feature_is_enabled(spa, empty_bpobj_feat)) {
45 if (!spa_feature_is_active(spa, empty_bpobj_feat)) {
46 ASSERT0(dp->dp_empty_bpobj);
47 dp->dp_empty_bpobj =
48 bpobj_alloc(os, SPA_MAXBLOCKSIZE, tx);
49 VERIFY(zap_add(os,
50 DMU_POOL_DIRECTORY_OBJECT,
51 DMU_POOL_EMPTY_BPOBJ, sizeof (uint64_t), 1,
52 &dp->dp_empty_bpobj, tx) == 0);
53 }
54 spa_feature_incr(spa, empty_bpobj_feat, tx);
55 ASSERT(dp->dp_empty_bpobj != 0);
56 return (dp->dp_empty_bpobj);
57 } else {
58 return (bpobj_alloc(os, blocksize, tx));
59 }
60 }
61
62 void
63 bpobj_decr_empty(objset_t *os, dmu_tx_t *tx)
64 {
65 zfeature_info_t *empty_bpobj_feat =
66 &spa_feature_table[SPA_FEATURE_EMPTY_BPOBJ];
67 dsl_pool_t *dp = dmu_objset_pool(os);
68
69 spa_feature_decr(dmu_objset_spa(os), empty_bpobj_feat, tx);
70 if (!spa_feature_is_active(dmu_objset_spa(os), empty_bpobj_feat)) {
71 VERIFY3U(0, ==, zap_remove(dp->dp_meta_objset,
72 DMU_POOL_DIRECTORY_OBJECT,
73 DMU_POOL_EMPTY_BPOBJ, tx));
74 VERIFY3U(0, ==, dmu_object_free(os, dp->dp_empty_bpobj, tx));
75 dp->dp_empty_bpobj = 0;
76 }
77 }
78
79 uint64_t
80 bpobj_alloc(objset_t *os, int blocksize, dmu_tx_t *tx)
81 {
82 int size;
83
84 if (spa_version(dmu_objset_spa(os)) < SPA_VERSION_BPOBJ_ACCOUNT)
85 size = BPOBJ_SIZE_V0;
86 else if (spa_version(dmu_objset_spa(os)) < SPA_VERSION_DEADLISTS)
87 size = BPOBJ_SIZE_V1;
88 else
89 size = sizeof (bpobj_phys_t);
90
248 }
249 }
250 if (dbuf) {
251 dmu_buf_rele(dbuf, FTAG);
252 dbuf = NULL;
253 }
254 if (free) {
255 i++;
256 VERIFY3U(0, ==, dmu_free_range(bpo->bpo_os, bpo->bpo_object,
257 i * sizeof (blkptr_t), -1ULL, tx));
258 }
259 if (err || !bpo->bpo_havesubobj || bpo->bpo_phys->bpo_subobjs == 0)
260 goto out;
261
262 ASSERT(bpo->bpo_havecomp);
263 err = dmu_object_info(bpo->bpo_os, bpo->bpo_phys->bpo_subobjs, &doi);
264 if (err) {
265 mutex_exit(&bpo->bpo_lock);
266 return (err);
267 }
268 epb = doi.doi_data_block_size / sizeof (uint64_t);
269
270 for (i = bpo->bpo_phys->bpo_num_subobjs - 1; i >= 0; i--) {
271 uint64_t *objarray;
272 uint64_t offset, blkoff;
273 bpobj_t sublist;
274 uint64_t used_before, comp_before, uncomp_before;
275 uint64_t used_after, comp_after, uncomp_after;
276
277 offset = i * sizeof (uint64_t);
278 blkoff = P2PHASE(i, epb);
279
280 if (dbuf == NULL || dbuf->db_offset > offset) {
281 if (dbuf)
282 dmu_buf_rele(dbuf, FTAG);
283 err = dmu_buf_hold(bpo->bpo_os,
284 bpo->bpo_phys->bpo_subobjs, offset, FTAG, &dbuf, 0);
285 if (err)
286 break;
287 }
|
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 */
25
26 #include <sys/bpobj.h>
27 #include <sys/zfs_context.h>
28 #include <sys/refcount.h>
29 #include <sys/dsl_pool.h>
30 #include <sys/zfeature.h>
31 #include <sys/zap.h>
32
33 /*
34 * Return an empty bpobj, preferably the empty dummy one (dp_empty_bpobj).
35 */
36 uint64_t
37 bpobj_alloc_empty(objset_t *os, int blocksize, dmu_tx_t *tx)
38 {
39 spa_t *spa = dmu_objset_spa(os);
40 dsl_pool_t *dp = dmu_objset_pool(os);
41
42 if (spa_feature_is_enabled(spa, SPA_FEATURE_EMPTY_BPOBJ)) {
43 if (!spa_feature_is_active(spa, SPA_FEATURE_EMPTY_BPOBJ)) {
44 ASSERT0(dp->dp_empty_bpobj);
45 dp->dp_empty_bpobj =
46 bpobj_alloc(os, SPA_MAXBLOCKSIZE, tx);
47 VERIFY(zap_add(os,
48 DMU_POOL_DIRECTORY_OBJECT,
49 DMU_POOL_EMPTY_BPOBJ, sizeof (uint64_t), 1,
50 &dp->dp_empty_bpobj, tx) == 0);
51 }
52 spa_feature_incr(spa, SPA_FEATURE_EMPTY_BPOBJ, tx);
53 ASSERT(dp->dp_empty_bpobj != 0);
54 return (dp->dp_empty_bpobj);
55 } else {
56 return (bpobj_alloc(os, blocksize, tx));
57 }
58 }
59
60 void
61 bpobj_decr_empty(objset_t *os, dmu_tx_t *tx)
62 {
63 dsl_pool_t *dp = dmu_objset_pool(os);
64
65 spa_feature_decr(dmu_objset_spa(os), SPA_FEATURE_EMPTY_BPOBJ, tx);
66 if (!spa_feature_is_active(dmu_objset_spa(os),
67 SPA_FEATURE_EMPTY_BPOBJ)) {
68 VERIFY3U(0, ==, zap_remove(dp->dp_meta_objset,
69 DMU_POOL_DIRECTORY_OBJECT,
70 DMU_POOL_EMPTY_BPOBJ, tx));
71 VERIFY3U(0, ==, dmu_object_free(os, dp->dp_empty_bpobj, tx));
72 dp->dp_empty_bpobj = 0;
73 }
74 }
75
76 uint64_t
77 bpobj_alloc(objset_t *os, int blocksize, dmu_tx_t *tx)
78 {
79 int size;
80
81 if (spa_version(dmu_objset_spa(os)) < SPA_VERSION_BPOBJ_ACCOUNT)
82 size = BPOBJ_SIZE_V0;
83 else if (spa_version(dmu_objset_spa(os)) < SPA_VERSION_DEADLISTS)
84 size = BPOBJ_SIZE_V1;
85 else
86 size = sizeof (bpobj_phys_t);
87
245 }
246 }
247 if (dbuf) {
248 dmu_buf_rele(dbuf, FTAG);
249 dbuf = NULL;
250 }
251 if (free) {
252 i++;
253 VERIFY3U(0, ==, dmu_free_range(bpo->bpo_os, bpo->bpo_object,
254 i * sizeof (blkptr_t), -1ULL, tx));
255 }
256 if (err || !bpo->bpo_havesubobj || bpo->bpo_phys->bpo_subobjs == 0)
257 goto out;
258
259 ASSERT(bpo->bpo_havecomp);
260 err = dmu_object_info(bpo->bpo_os, bpo->bpo_phys->bpo_subobjs, &doi);
261 if (err) {
262 mutex_exit(&bpo->bpo_lock);
263 return (err);
264 }
265 ASSERT3U(doi.doi_type, ==, DMU_OT_BPOBJ_SUBOBJ);
266 epb = doi.doi_data_block_size / sizeof (uint64_t);
267
268 for (i = bpo->bpo_phys->bpo_num_subobjs - 1; i >= 0; i--) {
269 uint64_t *objarray;
270 uint64_t offset, blkoff;
271 bpobj_t sublist;
272 uint64_t used_before, comp_before, uncomp_before;
273 uint64_t used_after, comp_after, uncomp_after;
274
275 offset = i * sizeof (uint64_t);
276 blkoff = P2PHASE(i, epb);
277
278 if (dbuf == NULL || dbuf->db_offset > offset) {
279 if (dbuf)
280 dmu_buf_rele(dbuf, FTAG);
281 err = dmu_buf_hold(bpo->bpo_os,
282 bpo->bpo_phys->bpo_subobjs, offset, FTAG, &dbuf, 0);
283 if (err)
284 break;
285 }
|