Deleted Added
full compact
dmu.c (177698) dmu.c (185029)
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE

--- 5 unchanged lines hidden (view full) ---

14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
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/*
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE

--- 5 unchanged lines hidden (view full) ---

14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
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 2007 Sun Microsystems, Inc. All rights reserved.
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
23 * Use is subject to license terms.
24 */
25
26#pragma ident "%Z%%M% %I% %E% SMI"
27
28#include <sys/dmu.h>
29#include <sys/dmu_impl.h>
30#include <sys/dmu_tx.h>
31#include <sys/dbuf.h>
32#include <sys/dnode.h>
33#include <sys/zfs_context.h>
34#include <sys/dmu_objset.h>
35#include <sys/dmu_traverse.h>
36#include <sys/dsl_dataset.h>
37#include <sys/dsl_dir.h>
38#include <sys/dsl_pool.h>
39#include <sys/dsl_synctask.h>
40#include <sys/dsl_prop.h>
41#include <sys/dmu_zfetch.h>
42#include <sys/zfs_ioctl.h>
43#include <sys/zap.h>
44#include <sys/zio_checksum.h>
26#include <sys/dmu.h>
27#include <sys/dmu_impl.h>
28#include <sys/dmu_tx.h>
29#include <sys/dbuf.h>
30#include <sys/dnode.h>
31#include <sys/zfs_context.h>
32#include <sys/dmu_objset.h>
33#include <sys/dmu_traverse.h>
34#include <sys/dsl_dataset.h>
35#include <sys/dsl_dir.h>
36#include <sys/dsl_pool.h>
37#include <sys/dsl_synctask.h>
38#include <sys/dsl_prop.h>
39#include <sys/dmu_zfetch.h>
40#include <sys/zfs_ioctl.h>
41#include <sys/zap.h>
42#include <sys/zio_checksum.h>
43#include <sys/zfs_znode.h>
45
46const dmu_object_type_info_t dmu_ot[DMU_OT_NUMTYPES] = {
47 { byteswap_uint8_array, TRUE, "unallocated" },
48 { zap_byteswap, TRUE, "object directory" },
49 { byteswap_uint64_array, TRUE, "object array" },
50 { byteswap_uint8_array, TRUE, "packed nvlist" },
51 { byteswap_uint64_array, TRUE, "packed nvlist size" },
52 { byteswap_uint64_array, TRUE, "bplist" },

--- 4 unchanged lines hidden (view full) ---

57 { dnode_buf_byteswap, TRUE, "DMU dnode" },
58 { dmu_objset_byteswap, TRUE, "DMU objset" },
59 { byteswap_uint64_array, TRUE, "DSL directory" },
60 { zap_byteswap, TRUE, "DSL directory child map"},
61 { zap_byteswap, TRUE, "DSL dataset snap map" },
62 { zap_byteswap, TRUE, "DSL props" },
63 { byteswap_uint64_array, TRUE, "DSL dataset" },
64 { zfs_znode_byteswap, TRUE, "ZFS znode" },
44
45const dmu_object_type_info_t dmu_ot[DMU_OT_NUMTYPES] = {
46 { byteswap_uint8_array, TRUE, "unallocated" },
47 { zap_byteswap, TRUE, "object directory" },
48 { byteswap_uint64_array, TRUE, "object array" },
49 { byteswap_uint8_array, TRUE, "packed nvlist" },
50 { byteswap_uint64_array, TRUE, "packed nvlist size" },
51 { byteswap_uint64_array, TRUE, "bplist" },

--- 4 unchanged lines hidden (view full) ---

56 { dnode_buf_byteswap, TRUE, "DMU dnode" },
57 { dmu_objset_byteswap, TRUE, "DMU objset" },
58 { byteswap_uint64_array, TRUE, "DSL directory" },
59 { zap_byteswap, TRUE, "DSL directory child map"},
60 { zap_byteswap, TRUE, "DSL dataset snap map" },
61 { zap_byteswap, TRUE, "DSL props" },
62 { byteswap_uint64_array, TRUE, "DSL dataset" },
63 { zfs_znode_byteswap, TRUE, "ZFS znode" },
65 { zfs_acl_byteswap, TRUE, "ZFS ACL" },
64 { zfs_oldacl_byteswap, TRUE, "ZFS V0 ACL" },
66 { byteswap_uint8_array, FALSE, "ZFS plain file" },
67 { zap_byteswap, TRUE, "ZFS directory" },
68 { zap_byteswap, TRUE, "ZFS master node" },
69 { zap_byteswap, TRUE, "ZFS delete queue" },
70 { byteswap_uint8_array, FALSE, "zvol object" },
71 { zap_byteswap, TRUE, "zvol prop" },
72 { byteswap_uint8_array, FALSE, "other uint8[]" },
73 { byteswap_uint64_array, FALSE, "other uint64[]" },
74 { zap_byteswap, TRUE, "other ZAP" },
75 { zap_byteswap, TRUE, "persistent error log" },
76 { byteswap_uint8_array, TRUE, "SPA history" },
77 { byteswap_uint64_array, TRUE, "SPA history offsets" },
65 { byteswap_uint8_array, FALSE, "ZFS plain file" },
66 { zap_byteswap, TRUE, "ZFS directory" },
67 { zap_byteswap, TRUE, "ZFS master node" },
68 { zap_byteswap, TRUE, "ZFS delete queue" },
69 { byteswap_uint8_array, FALSE, "zvol object" },
70 { zap_byteswap, TRUE, "zvol prop" },
71 { byteswap_uint8_array, FALSE, "other uint8[]" },
72 { byteswap_uint64_array, FALSE, "other uint64[]" },
73 { zap_byteswap, TRUE, "other ZAP" },
74 { zap_byteswap, TRUE, "persistent error log" },
75 { byteswap_uint8_array, TRUE, "SPA history" },
76 { byteswap_uint64_array, TRUE, "SPA history offsets" },
78 { zap_byteswap, TRUE, "Pool properties" },
77 { zap_byteswap, TRUE, "Pool properties" },
78 { zap_byteswap, TRUE, "DSL permissions" },
79 { zfs_acl_byteswap, TRUE, "ZFS ACL" },
80 { byteswap_uint8_array, TRUE, "ZFS SYSACL" },
81 { byteswap_uint8_array, TRUE, "FUID table" },
82 { byteswap_uint64_array, TRUE, "FUID table size" },
83 { zap_byteswap, TRUE, "DSL dataset next clones"},
84 { zap_byteswap, TRUE, "scrub work queue" },
79};
80
81int
82dmu_buf_hold(objset_t *os, uint64_t object, uint64_t offset,
83 void *tag, dmu_buf_t **dbp)
84{
85 dnode_t *dn;
86 uint64_t blkid;

--- 23 unchanged lines hidden (view full) ---

110}
111
112int
113dmu_bonus_max(void)
114{
115 return (DN_MAX_BONUSLEN);
116}
117
85};
86
87int
88dmu_buf_hold(objset_t *os, uint64_t object, uint64_t offset,
89 void *tag, dmu_buf_t **dbp)
90{
91 dnode_t *dn;
92 uint64_t blkid;

--- 23 unchanged lines hidden (view full) ---

116}
117
118int
119dmu_bonus_max(void)
120{
121 return (DN_MAX_BONUSLEN);
122}
123
124int
125dmu_set_bonus(dmu_buf_t *db, int newsize, dmu_tx_t *tx)
126{
127 dnode_t *dn = ((dmu_buf_impl_t *)db)->db_dnode;
128
129 if (dn->dn_bonus != (dmu_buf_impl_t *)db)
130 return (EINVAL);
131 if (newsize < 0 || newsize > db->db_size)
132 return (EINVAL);
133 dnode_setbonuslen(dn, newsize, tx);
134 return (0);
135}
136
118/*
119 * returns ENOENT, EIO, or 0.
120 */
121int
122dmu_bonus_hold(objset_t *os, uint64_t object, void *tag, dmu_buf_t **dbp)
123{
124 dnode_t *dn;
137/*
138 * returns ENOENT, EIO, or 0.
139 */
140int
141dmu_bonus_hold(objset_t *os, uint64_t object, void *tag, dmu_buf_t **dbp)
142{
143 dnode_t *dn;
125 int err, count;
126 dmu_buf_impl_t *db;
144 dmu_buf_impl_t *db;
145 int error;
127
146
128 err = dnode_hold(os->os, object, FTAG, &dn);
129 if (err)
130 return (err);
147 error = dnode_hold(os->os, object, FTAG, &dn);
148 if (error)
149 return (error);
131
132 rw_enter(&dn->dn_struct_rwlock, RW_READER);
133 if (dn->dn_bonus == NULL) {
134 rw_exit(&dn->dn_struct_rwlock);
135 rw_enter(&dn->dn_struct_rwlock, RW_WRITER);
136 if (dn->dn_bonus == NULL)
150
151 rw_enter(&dn->dn_struct_rwlock, RW_READER);
152 if (dn->dn_bonus == NULL) {
153 rw_exit(&dn->dn_struct_rwlock);
154 rw_enter(&dn->dn_struct_rwlock, RW_WRITER);
155 if (dn->dn_bonus == NULL)
137 dn->dn_bonus = dbuf_create_bonus(dn);
156 dbuf_create_bonus(dn);
138 }
139 db = dn->dn_bonus;
140 rw_exit(&dn->dn_struct_rwlock);
157 }
158 db = dn->dn_bonus;
159 rw_exit(&dn->dn_struct_rwlock);
141 mutex_enter(&db->db_mtx);
142 count = refcount_add(&db->db_holds, tag);
143 mutex_exit(&db->db_mtx);
144 if (count == 1)
145 dnode_add_ref(dn, db);
160
161 /* as long as the bonus buf is held, the dnode will be held */
162 if (refcount_add(&db->db_holds, tag) == 1)
163 VERIFY(dnode_add_ref(dn, db));
164
146 dnode_rele(dn, FTAG);
147
148 VERIFY(0 == dbuf_read(db, NULL, DB_RF_MUST_SUCCEED));
149
150 *dbp = &db->db;
151 return (0);
152}
153
154/*
155 * Note: longer-term, we should modify all of the dmu_buf_*() interfaces
156 * to take a held dnode rather than <os, object> -- the lookup is wasteful,
157 * and can induce severe lock contention when writing to several files
158 * whose dnodes are in the same block.
159 */
160static int
161dmu_buf_hold_array_by_dnode(dnode_t *dn, uint64_t offset,
162 uint64_t length, int read, void *tag, int *numbufsp, dmu_buf_t ***dbpp)
163{
165 dnode_rele(dn, FTAG);
166
167 VERIFY(0 == dbuf_read(db, NULL, DB_RF_MUST_SUCCEED));
168
169 *dbp = &db->db;
170 return (0);
171}
172
173/*
174 * Note: longer-term, we should modify all of the dmu_buf_*() interfaces
175 * to take a held dnode rather than <os, object> -- the lookup is wasteful,
176 * and can induce severe lock contention when writing to several files
177 * whose dnodes are in the same block.
178 */
179static int
180dmu_buf_hold_array_by_dnode(dnode_t *dn, uint64_t offset,
181 uint64_t length, int read, void *tag, int *numbufsp, dmu_buf_t ***dbpp)
182{
183 dsl_pool_t *dp = NULL;
164 dmu_buf_t **dbp;
165 uint64_t blkid, nblks, i;
166 uint32_t flags;
167 int err;
168 zio_t *zio;
184 dmu_buf_t **dbp;
185 uint64_t blkid, nblks, i;
186 uint32_t flags;
187 int err;
188 zio_t *zio;
189 hrtime_t start;
169
170 ASSERT(length <= DMU_MAX_ACCESS);
171
172 flags = DB_RF_CANFAIL | DB_RF_NEVERWAIT;
173 if (length > zfetch_array_rd_sz)
174 flags |= DB_RF_NOPREFETCH;
175
176 rw_enter(&dn->dn_struct_rwlock, RW_READER);

--- 10 unchanged lines hidden (view full) ---

187 (longlong_t)dn->dn_object, dn->dn_datablksz,
188 (longlong_t)offset, (longlong_t)length);
189 return (EIO);
190 }
191 nblks = 1;
192 }
193 dbp = kmem_zalloc(sizeof (dmu_buf_t *) * nblks, KM_SLEEP);
194
190
191 ASSERT(length <= DMU_MAX_ACCESS);
192
193 flags = DB_RF_CANFAIL | DB_RF_NEVERWAIT;
194 if (length > zfetch_array_rd_sz)
195 flags |= DB_RF_NOPREFETCH;
196
197 rw_enter(&dn->dn_struct_rwlock, RW_READER);

--- 10 unchanged lines hidden (view full) ---

208 (longlong_t)dn->dn_object, dn->dn_datablksz,
209 (longlong_t)offset, (longlong_t)length);
210 return (EIO);
211 }
212 nblks = 1;
213 }
214 dbp = kmem_zalloc(sizeof (dmu_buf_t *) * nblks, KM_SLEEP);
215
195 zio = zio_root(dn->dn_objset->os_spa, NULL, NULL, TRUE);
216 if (dn->dn_objset->os_dsl_dataset)
217 dp = dn->dn_objset->os_dsl_dataset->ds_dir->dd_pool;
218 if (dp && dsl_pool_sync_context(dp))
219 start = gethrtime();
220 zio = zio_root(dn->dn_objset->os_spa, NULL, NULL, ZIO_FLAG_CANFAIL);
196 blkid = dbuf_whichblock(dn, offset);
197 for (i = 0; i < nblks; i++) {
198 dmu_buf_impl_t *db = dbuf_hold(dn, blkid+i, tag);
199 if (db == NULL) {
200 rw_exit(&dn->dn_struct_rwlock);
201 dmu_buf_rele_array(dbp, nblks, tag);
202 zio_nowait(zio);
203 return (EIO);

--- 5 unchanged lines hidden (view full) ---

209 rw_enter(&dn->dn_struct_rwlock, RW_READER);
210 }
211 dbp[i] = &db->db;
212 }
213 rw_exit(&dn->dn_struct_rwlock);
214
215 /* wait for async i/o */
216 err = zio_wait(zio);
221 blkid = dbuf_whichblock(dn, offset);
222 for (i = 0; i < nblks; i++) {
223 dmu_buf_impl_t *db = dbuf_hold(dn, blkid+i, tag);
224 if (db == NULL) {
225 rw_exit(&dn->dn_struct_rwlock);
226 dmu_buf_rele_array(dbp, nblks, tag);
227 zio_nowait(zio);
228 return (EIO);

--- 5 unchanged lines hidden (view full) ---

234 rw_enter(&dn->dn_struct_rwlock, RW_READER);
235 }
236 dbp[i] = &db->db;
237 }
238 rw_exit(&dn->dn_struct_rwlock);
239
240 /* wait for async i/o */
241 err = zio_wait(zio);
242 /* track read overhead when we are in sync context */
243 if (dp && dsl_pool_sync_context(dp))
244 dp->dp_read_overhead += gethrtime() - start;
217 if (err) {
218 dmu_buf_rele_array(dbp, nblks, tag);
219 return (err);
220 }
221
222 /* wait for other io to complete */
223 if (read) {
224 for (i = 0; i < nblks; i++) {

--- 113 unchanged lines hidden (view full) ---

338 dbuf_prefetch(dn, blkid+i);
339 }
340
341 rw_exit(&dn->dn_struct_rwlock);
342
343 dnode_rele(dn, FTAG);
344}
345
245 if (err) {
246 dmu_buf_rele_array(dbp, nblks, tag);
247 return (err);
248 }
249
250 /* wait for other io to complete */
251 if (read) {
252 for (i = 0; i < nblks; i++) {

--- 113 unchanged lines hidden (view full) ---

366 dbuf_prefetch(dn, blkid+i);
367 }
368
369 rw_exit(&dn->dn_struct_rwlock);
370
371 dnode_rele(dn, FTAG);
372}
373
374static int
375get_next_chunk(dnode_t *dn, uint64_t *offset, uint64_t limit)
376{
377 uint64_t len = *offset - limit;
378 uint64_t chunk_len = dn->dn_datablksz * DMU_MAX_DELETEBLKCNT;
379 uint64_t subchunk =
380 dn->dn_datablksz * EPB(dn->dn_indblkshift, SPA_BLKPTRSHIFT);
381
382 ASSERT(limit <= *offset);
383
384 if (len <= chunk_len) {
385 *offset = limit;
386 return (0);
387 }
388
389 ASSERT(ISP2(subchunk));
390
391 while (*offset > limit) {
392 uint64_t initial_offset = P2ROUNDUP(*offset, subchunk);
393 uint64_t delta;
394 int err;
395
396 /* skip over allocated data */
397 err = dnode_next_offset(dn,
398 DNODE_FIND_HOLE|DNODE_FIND_BACKWARDS, offset, 1, 1, 0);
399 if (err == ESRCH)
400 *offset = limit;
401 else if (err)
402 return (err);
403
404 ASSERT3U(*offset, <=, initial_offset);
405 *offset = P2ALIGN(*offset, subchunk);
406 delta = initial_offset - *offset;
407 if (delta >= chunk_len) {
408 *offset += delta - chunk_len;
409 return (0);
410 }
411 chunk_len -= delta;
412
413 /* skip over unallocated data */
414 err = dnode_next_offset(dn,
415 DNODE_FIND_BACKWARDS, offset, 1, 1, 0);
416 if (err == ESRCH)
417 *offset = limit;
418 else if (err)
419 return (err);
420
421 if (*offset < limit)
422 *offset = limit;
423 ASSERT3U(*offset, <, initial_offset);
424 }
425 return (0);
426}
427
428static int
429dmu_free_long_range_impl(objset_t *os, dnode_t *dn, uint64_t offset,
430 uint64_t length, boolean_t free_dnode)
431{
432 dmu_tx_t *tx;
433 uint64_t object_size, start, end, len;
434 boolean_t trunc = (length == DMU_OBJECT_END);
435 int align, err;
436
437 align = 1 << dn->dn_datablkshift;
438 ASSERT(align > 0);
439 object_size = align == 1 ? dn->dn_datablksz :
440 (dn->dn_maxblkid + 1) << dn->dn_datablkshift;
441
442 if (trunc || (end = offset + length) > object_size)
443 end = object_size;
444 if (end <= offset)
445 return (0);
446 length = end - offset;
447
448 while (length) {
449 start = end;
450 err = get_next_chunk(dn, &start, offset);
451 if (err)
452 return (err);
453 len = trunc ? DMU_OBJECT_END : end - start;
454
455 tx = dmu_tx_create(os);
456 dmu_tx_hold_free(tx, dn->dn_object, start, len);
457 err = dmu_tx_assign(tx, TXG_WAIT);
458 if (err) {
459 dmu_tx_abort(tx);
460 return (err);
461 }
462
463 dnode_free_range(dn, start, trunc ? -1 : len, tx);
464
465 if (start == 0 && free_dnode) {
466 ASSERT(trunc);
467 dnode_free(dn, tx);
468 }
469
470 length -= end - start;
471
472 dmu_tx_commit(tx);
473 end = start;
474 }
475 return (0);
476}
477
346int
478int
479dmu_free_long_range(objset_t *os, uint64_t object,
480 uint64_t offset, uint64_t length)
481{
482 dnode_t *dn;
483 int err;
484
485 err = dnode_hold(os->os, object, FTAG, &dn);
486 if (err != 0)
487 return (err);
488 err = dmu_free_long_range_impl(os, dn, offset, length, FALSE);
489 dnode_rele(dn, FTAG);
490 return (err);
491}
492
493int
494dmu_free_object(objset_t *os, uint64_t object)
495{
496 dnode_t *dn;
497 dmu_tx_t *tx;
498 int err;
499
500 err = dnode_hold_impl(os->os, object, DNODE_MUST_BE_ALLOCATED,
501 FTAG, &dn);
502 if (err != 0)
503 return (err);
504 if (dn->dn_nlevels == 1) {
505 tx = dmu_tx_create(os);
506 dmu_tx_hold_bonus(tx, object);
507 dmu_tx_hold_free(tx, dn->dn_object, 0, DMU_OBJECT_END);
508 err = dmu_tx_assign(tx, TXG_WAIT);
509 if (err == 0) {
510 dnode_free_range(dn, 0, DMU_OBJECT_END, tx);
511 dnode_free(dn, tx);
512 dmu_tx_commit(tx);
513 } else {
514 dmu_tx_abort(tx);
515 }
516 } else {
517 err = dmu_free_long_range_impl(os, dn, 0, DMU_OBJECT_END, TRUE);
518 }
519 dnode_rele(dn, FTAG);
520 return (err);
521}
522
523int
347dmu_free_range(objset_t *os, uint64_t object, uint64_t offset,
348 uint64_t size, dmu_tx_t *tx)
349{
350 dnode_t *dn;
351 int err = dnode_hold(os->os, object, FTAG, &dn);
352 if (err)
353 return (err);
354 ASSERT(offset < UINT64_MAX);

--- 24 unchanged lines hidden (view full) ---

379 int newsz = offset > dn->dn_datablksz ? 0 :
380 MIN(size, dn->dn_datablksz - offset);
381 bzero((char *)buf + newsz, size - newsz);
382 size = newsz;
383 }
384
385 while (size > 0) {
386 uint64_t mylen = MIN(size, DMU_MAX_ACCESS / 2);
524dmu_free_range(objset_t *os, uint64_t object, uint64_t offset,
525 uint64_t size, dmu_tx_t *tx)
526{
527 dnode_t *dn;
528 int err = dnode_hold(os->os, object, FTAG, &dn);
529 if (err)
530 return (err);
531 ASSERT(offset < UINT64_MAX);

--- 24 unchanged lines hidden (view full) ---

556 int newsz = offset > dn->dn_datablksz ? 0 :
557 MIN(size, dn->dn_datablksz - offset);
558 bzero((char *)buf + newsz, size - newsz);
559 size = newsz;
560 }
561
562 while (size > 0) {
563 uint64_t mylen = MIN(size, DMU_MAX_ACCESS / 2);
387 int err;
388
389 /*
390 * NB: we could do this block-at-a-time, but it's nice
391 * to be reading in parallel.
392 */
393 err = dmu_buf_hold_array_by_dnode(dn, offset, mylen,
394 TRUE, FTAG, &numbufs, &dbp);
395 if (err)
564
565 /*
566 * NB: we could do this block-at-a-time, but it's nice
567 * to be reading in parallel.
568 */
569 err = dmu_buf_hold_array_by_dnode(dn, offset, mylen,
570 TRUE, FTAG, &numbufs, &dbp);
571 if (err)
396 return (err);
572 break;
397
398 for (i = 0; i < numbufs; i++) {
399 int tocpy;
400 int bufoff;
401 dmu_buf_t *db = dbp[i];
402
403 ASSERT(size > 0);
404

--- 4 unchanged lines hidden (view full) ---

409
410 offset += tocpy;
411 size -= tocpy;
412 buf = (char *)buf + tocpy;
413 }
414 dmu_buf_rele_array(dbp, numbufs, FTAG);
415 }
416 dnode_rele(dn, FTAG);
573
574 for (i = 0; i < numbufs; i++) {
575 int tocpy;
576 int bufoff;
577 dmu_buf_t *db = dbp[i];
578
579 ASSERT(size > 0);
580

--- 4 unchanged lines hidden (view full) ---

585
586 offset += tocpy;
587 size -= tocpy;
588 buf = (char *)buf + tocpy;
589 }
590 dmu_buf_rele_array(dbp, numbufs, FTAG);
591 }
592 dnode_rele(dn, FTAG);
417 return (0);
593 return (err);
418}
419
420void
421dmu_write(objset_t *os, uint64_t object, uint64_t offset, uint64_t size,
422 const void *buf, dmu_tx_t *tx)
423{
424 dmu_buf_t **dbp;
425 int numbufs, i;

--- 159 unchanged lines hidden (view full) ---

585 if (tocpy == db->db_size)
586 dmu_buf_will_fill(db, tx);
587 else
588 dmu_buf_will_dirty(db, tx);
589
590 for (copied = 0; copied < tocpy; copied += PAGESIZE) {
591 ASSERT3U(pp->p_offset, ==, db->db_offset + bufoff);
592 thiscpy = MIN(PAGESIZE, tocpy - copied);
594}
595
596void
597dmu_write(objset_t *os, uint64_t object, uint64_t offset, uint64_t size,
598 const void *buf, dmu_tx_t *tx)
599{
600 dmu_buf_t **dbp;
601 int numbufs, i;

--- 159 unchanged lines hidden (view full) ---

761 if (tocpy == db->db_size)
762 dmu_buf_will_fill(db, tx);
763 else
764 dmu_buf_will_dirty(db, tx);
765
766 for (copied = 0; copied < tocpy; copied += PAGESIZE) {
767 ASSERT3U(pp->p_offset, ==, db->db_offset + bufoff);
768 thiscpy = MIN(PAGESIZE, tocpy - copied);
593 va = ppmapin(pp, PROT_READ, (caddr_t)-1);
769 va = zfs_map_page(pp, S_READ);
594 bcopy(va, (char *)db->db_data + bufoff, thiscpy);
770 bcopy(va, (char *)db->db_data + bufoff, thiscpy);
595 ppmapout(va);
771 zfs_unmap_page(pp, va);
596 pp = pp->p_next;
597 bufoff += PAGESIZE;
598 }
599
600 if (tocpy == db->db_size)
601 dmu_buf_fill_done(db, tx);
602
603 if (err)

--- 11 unchanged lines hidden (view full) ---

615typedef struct {
616 dbuf_dirty_record_t *dr;
617 dmu_sync_cb_t *done;
618 void *arg;
619} dmu_sync_arg_t;
620
621/* ARGSUSED */
622static void
772 pp = pp->p_next;
773 bufoff += PAGESIZE;
774 }
775
776 if (tocpy == db->db_size)
777 dmu_buf_fill_done(db, tx);
778
779 if (err)

--- 11 unchanged lines hidden (view full) ---

791typedef struct {
792 dbuf_dirty_record_t *dr;
793 dmu_sync_cb_t *done;
794 void *arg;
795} dmu_sync_arg_t;
796
797/* ARGSUSED */
798static void
799dmu_sync_ready(zio_t *zio, arc_buf_t *buf, void *varg)
800{
801 blkptr_t *bp = zio->io_bp;
802
803 if (!BP_IS_HOLE(bp)) {
804 dmu_sync_arg_t *in = varg;
805 dbuf_dirty_record_t *dr = in->dr;
806 dmu_buf_impl_t *db = dr->dr_dbuf;
807 ASSERT(BP_GET_TYPE(bp) == db->db_dnode->dn_type);
808 ASSERT(BP_GET_LEVEL(bp) == 0);
809 bp->blk_fill = 1;
810 }
811}
812
813/* ARGSUSED */
814static void
623dmu_sync_done(zio_t *zio, arc_buf_t *buf, void *varg)
624{
625 dmu_sync_arg_t *in = varg;
626 dbuf_dirty_record_t *dr = in->dr;
627 dmu_buf_impl_t *db = dr->dr_dbuf;
628 dmu_sync_cb_t *done = in->done;
629
815dmu_sync_done(zio_t *zio, arc_buf_t *buf, void *varg)
816{
817 dmu_sync_arg_t *in = varg;
818 dbuf_dirty_record_t *dr = in->dr;
819 dmu_buf_impl_t *db = dr->dr_dbuf;
820 dmu_sync_cb_t *done = in->done;
821
630 if (!BP_IS_HOLE(zio->io_bp)) {
631 zio->io_bp->blk_fill = 1;
632 BP_SET_TYPE(zio->io_bp, db->db_dnode->dn_type);
633 BP_SET_LEVEL(zio->io_bp, 0);
634 }
635
636 mutex_enter(&db->db_mtx);
637 ASSERT(dr->dt.dl.dr_override_state == DR_IN_DMU_SYNC);
638 dr->dt.dl.dr_overridden_by = *zio->io_bp; /* structure assignment */
639 dr->dt.dl.dr_override_state = DR_OVERRIDDEN;
640 cv_broadcast(&db->db_changed);
641 mutex_exit(&db->db_mtx);
642
643 if (done)

--- 30 unchanged lines hidden (view full) ---

674{
675 dmu_buf_impl_t *db = (dmu_buf_impl_t *)db_fake;
676 objset_impl_t *os = db->db_objset;
677 dsl_pool_t *dp = os->os_dsl_dataset->ds_dir->dd_pool;
678 tx_state_t *tx = &dp->dp_tx;
679 dbuf_dirty_record_t *dr;
680 dmu_sync_arg_t *in;
681 zbookmark_t zb;
822 mutex_enter(&db->db_mtx);
823 ASSERT(dr->dt.dl.dr_override_state == DR_IN_DMU_SYNC);
824 dr->dt.dl.dr_overridden_by = *zio->io_bp; /* structure assignment */
825 dr->dt.dl.dr_override_state = DR_OVERRIDDEN;
826 cv_broadcast(&db->db_changed);
827 mutex_exit(&db->db_mtx);
828
829 if (done)

--- 30 unchanged lines hidden (view full) ---

860{
861 dmu_buf_impl_t *db = (dmu_buf_impl_t *)db_fake;
862 objset_impl_t *os = db->db_objset;
863 dsl_pool_t *dp = os->os_dsl_dataset->ds_dir->dd_pool;
864 tx_state_t *tx = &dp->dp_tx;
865 dbuf_dirty_record_t *dr;
866 dmu_sync_arg_t *in;
867 zbookmark_t zb;
868 writeprops_t wp = { 0 };
682 zio_t *zio;
869 zio_t *zio;
683 int zio_flags;
684 int err;
685
686 ASSERT(BP_IS_HOLE(bp));
687 ASSERT(txg != 0);
688
870 int err;
871
872 ASSERT(BP_IS_HOLE(bp));
873 ASSERT(txg != 0);
874
689
690 dprintf("dmu_sync txg=%llu, s,o,q %llu %llu %llu\n",
691 txg, tx->tx_synced_txg, tx->tx_open_txg, tx->tx_quiesced_txg);
692
693 /*
694 * XXX - would be nice if we could do this without suspending...
695 */
696 txg_suspend(dp);
697

--- 88 unchanged lines hidden (view full) ---

786 in->arg = arg;
787 mutex_exit(&db->db_mtx);
788 txg_resume(dp);
789
790 zb.zb_objset = os->os_dsl_dataset->ds_object;
791 zb.zb_object = db->db.db_object;
792 zb.zb_level = db->db_level;
793 zb.zb_blkid = db->db_blkid;
875 dprintf("dmu_sync txg=%llu, s,o,q %llu %llu %llu\n",
876 txg, tx->tx_synced_txg, tx->tx_open_txg, tx->tx_quiesced_txg);
877
878 /*
879 * XXX - would be nice if we could do this without suspending...
880 */
881 txg_suspend(dp);
882

--- 88 unchanged lines hidden (view full) ---

971 in->arg = arg;
972 mutex_exit(&db->db_mtx);
973 txg_resume(dp);
974
975 zb.zb_objset = os->os_dsl_dataset->ds_object;
976 zb.zb_object = db->db.db_object;
977 zb.zb_level = db->db_level;
978 zb.zb_blkid = db->db_blkid;
794 zio_flags = ZIO_FLAG_MUSTSUCCEED;
795 if (dmu_ot[db->db_dnode->dn_type].ot_metadata || zb.zb_level != 0)
796 zio_flags |= ZIO_FLAG_METADATA;
797 zio = arc_write(pio, os->os_spa,
798 zio_checksum_select(db->db_dnode->dn_checksum, os->os_checksum),
799 zio_compress_select(db->db_dnode->dn_compress, os->os_compress),
800 dmu_get_replication_level(os, &zb, db->db_dnode->dn_type),
801 txg, bp, dr->dt.dl.dr_data, NULL, dmu_sync_done, in,
802 ZIO_PRIORITY_SYNC_WRITE, zio_flags, &zb);
803
979
980 wp.wp_type = db->db_dnode->dn_type;
981 wp.wp_level = db->db_level;
982 wp.wp_copies = os->os_copies;
983 wp.wp_dnchecksum = db->db_dnode->dn_checksum;
984 wp.wp_oschecksum = os->os_checksum;
985 wp.wp_dncompress = db->db_dnode->dn_compress;
986 wp.wp_oscompress = os->os_compress;
987
988 ASSERT(BP_IS_HOLE(bp));
989
990 zio = arc_write(pio, os->os_spa, &wp, DBUF_IS_L2CACHEABLE(db),
991 txg, bp, dr->dt.dl.dr_data, dmu_sync_ready, dmu_sync_done, in,
992 ZIO_PRIORITY_SYNC_WRITE, ZIO_FLAG_MUSTSUCCEED, &zb);
993
804 if (pio) {
805 zio_nowait(zio);
806 err = EINPROGRESS;
807 } else {
808 err = zio_wait(zio);
809 ASSERT(err == 0);
810 }
811 return (err);

--- 38 unchanged lines hidden (view full) ---

850 (void) dnode_hold(os->os, object, FTAG, &dn);
851 ASSERT(compress < ZIO_COMPRESS_FUNCTIONS);
852 dn->dn_compress = compress;
853 dnode_setdirty(dn, tx);
854 dnode_rele(dn, FTAG);
855}
856
857int
994 if (pio) {
995 zio_nowait(zio);
996 err = EINPROGRESS;
997 } else {
998 err = zio_wait(zio);
999 ASSERT(err == 0);
1000 }
1001 return (err);

--- 38 unchanged lines hidden (view full) ---

1040 (void) dnode_hold(os->os, object, FTAG, &dn);
1041 ASSERT(compress < ZIO_COMPRESS_FUNCTIONS);
1042 dn->dn_compress = compress;
1043 dnode_setdirty(dn, tx);
1044 dnode_rele(dn, FTAG);
1045}
1046
1047int
858dmu_get_replication_level(objset_impl_t *os,
859 zbookmark_t *zb, dmu_object_type_t ot)
860{
861 int ncopies = os->os_copies;
862
863 /* If it's the mos, it should have max copies set. */
864 ASSERT(zb->zb_objset != 0 ||
865 ncopies == spa_max_replication(os->os_spa));
866
867 if (dmu_ot[ot].ot_metadata || zb->zb_level != 0)
868 ncopies++;
869 return (MIN(ncopies, spa_max_replication(os->os_spa)));
870}
871
872int
873dmu_offset_next(objset_t *os, uint64_t object, boolean_t hole, uint64_t *off)
874{
875 dnode_t *dn;
876 int i, err;
877
878 err = dnode_hold(os->os, object, FTAG, &dn);
879 if (err)
880 return (err);

--- 8 unchanged lines hidden (view full) ---

889 if (i != TXG_SIZE) {
890 dnode_rele(dn, FTAG);
891 txg_wait_synced(dmu_objset_pool(os), 0);
892 err = dnode_hold(os->os, object, FTAG, &dn);
893 if (err)
894 return (err);
895 }
896
1048dmu_offset_next(objset_t *os, uint64_t object, boolean_t hole, uint64_t *off)
1049{
1050 dnode_t *dn;
1051 int i, err;
1052
1053 err = dnode_hold(os->os, object, FTAG, &dn);
1054 if (err)
1055 return (err);

--- 8 unchanged lines hidden (view full) ---

1064 if (i != TXG_SIZE) {
1065 dnode_rele(dn, FTAG);
1066 txg_wait_synced(dmu_objset_pool(os), 0);
1067 err = dnode_hold(os->os, object, FTAG, &dn);
1068 if (err)
1069 return (err);
1070 }
1071
897 err = dnode_next_offset(dn, hole, off, 1, 1, 0);
1072 err = dnode_next_offset(dn, (hole ? DNODE_FIND_HOLE : 0), off, 1, 1, 0);
898 dnode_rele(dn, FTAG);
899
900 return (err);
901}
902
903void
904dmu_object_info_from_dnode(dnode_t *dn, dmu_object_info_t *doi)
905{

--- 107 unchanged lines hidden (view full) ---

1013}
1014
1015void
1016dmu_init(void)
1017{
1018 dbuf_init();
1019 dnode_init();
1020 arc_init();
1073 dnode_rele(dn, FTAG);
1074
1075 return (err);
1076}
1077
1078void
1079dmu_object_info_from_dnode(dnode_t *dn, dmu_object_info_t *doi)
1080{

--- 107 unchanged lines hidden (view full) ---

1188}
1189
1190void
1191dmu_init(void)
1192{
1193 dbuf_init();
1194 dnode_init();
1195 arc_init();
1196 l2arc_init();
1021}
1022
1023void
1024dmu_fini(void)
1025{
1026 arc_fini();
1027 dnode_fini();
1028 dbuf_fini();
1197}
1198
1199void
1200dmu_fini(void)
1201{
1202 arc_fini();
1203 dnode_fini();
1204 dbuf_fini();
1205 l2arc_fini();
1029}
1206}