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} |