Print this page
NEX-9752 backport illumos 6950 ARC should cache compressed data
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
6950 ARC should cache compressed data
Reviewed by: Prakash Surya <prakash.surya@delphix.com>
Reviewed by: Dan Kimmel <dan.kimmel@delphix.com>
Reviewed by: Matt Ahrens <mahrens@delphix.com>
Reviewed by: Paul Dagnelie <pcd@delphix.com>
Reviewed by: Don Brady <don.brady@intel.com>
Reviewed by: Richard Elling <Richard.Elling@RichardElling.com>
Approved by: Richard Lowe <richlowe@richlowe.net>
6267 dn_bonus evicted too early
Reviewed by: Richard Yao <ryao@gentoo.org>
Reviewed by: Xin LI <delphij@freebsd.org>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Approved by: Richard Lowe <richlowe@richlowe.net>
NEX-4582 update wrc test cases for allow to use write back cache per tree of datasets
Reviewed by: Steve Peng <steve.peng@nexenta.com>
Reviewed by: Alex Aizman <alex.aizman@nexenta.com>
5960 zfs recv should prefetch indirect blocks
5925 zfs receive -o origin=
Reviewed by: Prakash Surya <prakash.surya@delphix.com>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
NEX-1823 Slow performance doing of a large dataset
5911 ZFS "hangs" while deleting file
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
Reviewed by: Bayard Bell <bayard.bell@nexenta.com>
NEX-3266 5630 stale bonus buffer in recycled dnode_t leads to data corruption
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed by: George Wilson <george@delphix.com>
Reviewed by: Will Andrews <will@freebsd.org>
Approved by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Dan Fields <dan.fields@nexenta.com>
SUP-507 Delete or truncate of large files delayed on datasets with small recordsize
Reviewed by: Albert Lee <trisk@nexenta.com>
Reviewed by: Alek Pinchuk <alek.pinchuk@nexenta.com>
Reviewed by: Ilya Usvyatsky <ilya.usvyatsky@nexenta.com>
Reviewed by: Tony Nguyen <tony.nguyen@nexenta.com>
4370 avoid transmitting holes during zfs send
4371 DMU code clean up
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed by: George Wilson <george.wilson@delphix.com>
Reviewed by: Christopher Siden <christopher.siden@delphix.com>
Reviewed by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
Approved by: Garrett D'Amore <garrett@damore.org>


   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
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  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 /*
  23  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.

  24  * Copyright (c) 2012, 2017 by Delphix. All rights reserved.
  25  * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
  26  */
  27 
  28 #include <sys/zfs_context.h>
  29 #include <sys/dbuf.h>
  30 #include <sys/dnode.h>
  31 #include <sys/dmu.h>
  32 #include <sys/dmu_tx.h>
  33 #include <sys/dmu_objset.h>
  34 #include <sys/dsl_dataset.h>
  35 #include <sys/spa.h>
  36 #include <sys/range_tree.h>
  37 #include <sys/zfeature.h>
  38 
  39 static void
  40 dnode_increase_indirection(dnode_t *dn, dmu_tx_t *tx)
  41 {
  42         dmu_buf_impl_t *db;
  43         int txgoff = tx->tx_txg & TXG_MASK;


 380 typedef struct dnode_sync_free_range_arg {
 381         dnode_t *dsfra_dnode;
 382         dmu_tx_t *dsfra_tx;
 383 } dnode_sync_free_range_arg_t;
 384 
 385 static void
 386 dnode_sync_free_range(void *arg, uint64_t blkid, uint64_t nblks)
 387 {
 388         dnode_sync_free_range_arg_t *dsfra = arg;
 389         dnode_t *dn = dsfra->dsfra_dnode;
 390 
 391         mutex_exit(&dn->dn_mtx);
 392         dnode_sync_free_range_impl(dn, blkid, nblks, dsfra->dsfra_tx);
 393         mutex_enter(&dn->dn_mtx);
 394 }
 395 
 396 /*
 397  * Try to kick all the dnode's dbufs out of the cache...
 398  */
 399 void
 400 dnode_evict_dbufs(dnode_t *dn)
 401 {
 402         dmu_buf_impl_t db_marker;
 403         dmu_buf_impl_t *db, *db_next;
 404 
 405         mutex_enter(&dn->dn_dbufs_mtx);
 406         for (db = avl_first(&dn->dn_dbufs); db != NULL; db = db_next) {
 407 
 408 #ifdef  DEBUG
 409                 DB_DNODE_ENTER(db);
 410                 ASSERT3P(DB_DNODE(db), ==, dn);
 411                 DB_DNODE_EXIT(db);
 412 #endif  /* DEBUG */
 413 
 414                 mutex_enter(&db->db_mtx);






 415                 if (db->db_state != DB_EVICTING &&
 416                     refcount_is_zero(&db->db_holds)) {
 417                         db_marker.db_level = db->db_level;
 418                         db_marker.db_blkid = db->db_blkid;
 419                         db_marker.db_state = DB_SEARCH;
 420                         avl_insert_here(&dn->dn_dbufs, &db_marker, db,
 421                             AVL_BEFORE);
 422 
 423                         dbuf_destroy(db);
 424 
 425                         db_next = AVL_NEXT(&dn->dn_dbufs, &db_marker);
 426                         avl_remove(&dn->dn_dbufs, &db_marker);
 427                 } else {
 428                         db->db_pending_evict = TRUE;
 429                         mutex_exit(&db->db_mtx);
 430                         db_next = AVL_NEXT(&dn->dn_dbufs, db);
 431                 }
 432         }
 433         mutex_exit(&dn->dn_dbufs_mtx);
 434 


 480                 kmem_free(dr, sizeof (dbuf_dirty_record_t));
 481                 dbuf_rele_and_unlock(db, (void *)(uintptr_t)txg);
 482         }
 483 }
 484 
 485 static void
 486 dnode_sync_free(dnode_t *dn, dmu_tx_t *tx)
 487 {
 488         int txgoff = tx->tx_txg & TXG_MASK;
 489 
 490         ASSERT(dmu_tx_is_syncing(tx));
 491 
 492         /*
 493          * Our contents should have been freed in dnode_sync() by the
 494          * free range record inserted by the caller of dnode_free().
 495          */
 496         ASSERT0(DN_USED_BYTES(dn->dn_phys));
 497         ASSERT(BP_IS_HOLE(dn->dn_phys->dn_blkptr));
 498 
 499         dnode_undirty_dbufs(&dn->dn_dirty_records[txgoff]);
 500         dnode_evict_dbufs(dn);

 501 
 502         /*
 503          * XXX - It would be nice to assert this, but we may still
 504          * have residual holds from async evictions from the arc...
 505          *
 506          * zfs_obj_to_path() also depends on this being
 507          * commented out.
 508          *
 509          * ASSERT3U(refcount_count(&dn->dn_holds), ==, 1);
 510          */
 511 
 512         /* Undirty next bits */
 513         dn->dn_next_nlevels[txgoff] = 0;
 514         dn->dn_next_indblkshift[txgoff] = 0;
 515         dn->dn_next_blksz[txgoff] = 0;
 516 
 517         /* ASSERT(blkptrs are zero); */
 518         ASSERT(dn->dn_phys->dn_type != DMU_OT_NONE);
 519         ASSERT(dn->dn_type != DMU_OT_NONE);
 520 




   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
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  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 /*
  23  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright (c) 2014 Nexenta Systems, Inc. All rights reserved.
  25  * Copyright (c) 2012, 2017 by Delphix. All rights reserved.
  26  * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
  27  */
  28 
  29 #include <sys/zfs_context.h>
  30 #include <sys/dbuf.h>
  31 #include <sys/dnode.h>
  32 #include <sys/dmu.h>
  33 #include <sys/dmu_tx.h>
  34 #include <sys/dmu_objset.h>
  35 #include <sys/dsl_dataset.h>
  36 #include <sys/spa.h>
  37 #include <sys/range_tree.h>
  38 #include <sys/zfeature.h>
  39 
  40 static void
  41 dnode_increase_indirection(dnode_t *dn, dmu_tx_t *tx)
  42 {
  43         dmu_buf_impl_t *db;
  44         int txgoff = tx->tx_txg & TXG_MASK;


 381 typedef struct dnode_sync_free_range_arg {
 382         dnode_t *dsfra_dnode;
 383         dmu_tx_t *dsfra_tx;
 384 } dnode_sync_free_range_arg_t;
 385 
 386 static void
 387 dnode_sync_free_range(void *arg, uint64_t blkid, uint64_t nblks)
 388 {
 389         dnode_sync_free_range_arg_t *dsfra = arg;
 390         dnode_t *dn = dsfra->dsfra_dnode;
 391 
 392         mutex_exit(&dn->dn_mtx);
 393         dnode_sync_free_range_impl(dn, blkid, nblks, dsfra->dsfra_tx);
 394         mutex_enter(&dn->dn_mtx);
 395 }
 396 
 397 /*
 398  * Try to kick all the dnode's dbufs out of the cache...
 399  */
 400 void
 401 dnode_evict_dbufs(dnode_t *dn, int level)
 402 {
 403         dmu_buf_impl_t db_marker;
 404         dmu_buf_impl_t *db, *db_next;
 405 
 406         mutex_enter(&dn->dn_dbufs_mtx);
 407         for (db = avl_first(&dn->dn_dbufs); db != NULL; db = db_next) {
 408 
 409 #ifdef  DEBUG
 410                 DB_DNODE_ENTER(db);
 411                 ASSERT3P(DB_DNODE(db), ==, dn);
 412                 DB_DNODE_EXIT(db);
 413 #endif  /* DEBUG */
 414 
 415                 mutex_enter(&db->db_mtx);
 416                 if (level != DBUF_EVICT_ALL && db->db_level != level) {
 417                         mutex_exit(&db->db_mtx);
 418                         db_next = AVL_NEXT(&dn->dn_dbufs, db);
 419                         continue;
 420                 }
 421 
 422                 if (db->db_state != DB_EVICTING &&
 423                     refcount_is_zero(&db->db_holds)) {
 424                         db_marker.db_level = db->db_level;
 425                         db_marker.db_blkid = db->db_blkid;
 426                         db_marker.db_state = DB_SEARCH;
 427                         avl_insert_here(&dn->dn_dbufs, &db_marker, db,
 428                             AVL_BEFORE);
 429 
 430                         dbuf_destroy(db);
 431 
 432                         db_next = AVL_NEXT(&dn->dn_dbufs, &db_marker);
 433                         avl_remove(&dn->dn_dbufs, &db_marker);
 434                 } else {
 435                         db->db_pending_evict = TRUE;
 436                         mutex_exit(&db->db_mtx);
 437                         db_next = AVL_NEXT(&dn->dn_dbufs, db);
 438                 }
 439         }
 440         mutex_exit(&dn->dn_dbufs_mtx);
 441 


 487                 kmem_free(dr, sizeof (dbuf_dirty_record_t));
 488                 dbuf_rele_and_unlock(db, (void *)(uintptr_t)txg);
 489         }
 490 }
 491 
 492 static void
 493 dnode_sync_free(dnode_t *dn, dmu_tx_t *tx)
 494 {
 495         int txgoff = tx->tx_txg & TXG_MASK;
 496 
 497         ASSERT(dmu_tx_is_syncing(tx));
 498 
 499         /*
 500          * Our contents should have been freed in dnode_sync() by the
 501          * free range record inserted by the caller of dnode_free().
 502          */
 503         ASSERT0(DN_USED_BYTES(dn->dn_phys));
 504         ASSERT(BP_IS_HOLE(dn->dn_phys->dn_blkptr));
 505 
 506         dnode_undirty_dbufs(&dn->dn_dirty_records[txgoff]);
 507         dnode_evict_dbufs(dn, DBUF_EVICT_ALL);
 508         ASSERT(avl_is_empty(&dn->dn_dbufs));
 509 
 510         /*
 511          * XXX - It would be nice to assert this, but we may still
 512          * have residual holds from async evictions from the arc...
 513          *
 514          * zfs_obj_to_path() also depends on this being
 515          * commented out.
 516          *
 517          * ASSERT3U(refcount_count(&dn->dn_holds), ==, 1);
 518          */
 519 
 520         /* Undirty next bits */
 521         dn->dn_next_nlevels[txgoff] = 0;
 522         dn->dn_next_indblkshift[txgoff] = 0;
 523         dn->dn_next_blksz[txgoff] = 0;
 524 
 525         /* ASSERT(blkptrs are zero); */
 526         ASSERT(dn->dn_phys->dn_type != DMU_OT_NONE);
 527         ASSERT(dn->dn_type != DMU_OT_NONE);
 528