Print this page
3469 dbuf_read_impl shows too much enthusiasm
Reviewed by: Bryan Cantrill <bryan@joyent.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/zfs/dbuf.c
          +++ new/usr/src/uts/common/fs/zfs/dbuf.c
↓ open down ↓ 14 lines elided ↑ open up ↑
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  23   23   * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
  24   24   * Copyright (c) 2012 by Delphix. All rights reserved.
       25 + * Copyright (c) 2013, Joyent, Inc. All rights reserved.
  25   26   */
  26   27  
  27   28  #include <sys/zfs_context.h>
  28   29  #include <sys/dmu.h>
  29   30  #include <sys/dmu_impl.h>
  30   31  #include <sys/dbuf.h>
  31   32  #include <sys/dmu_objset.h>
  32   33  #include <sys/dsl_dataset.h>
  33   34  #include <sys/dsl_dir.h>
  34   35  #include <sys/dmu_tx.h>
↓ open down ↓ 490 lines elided ↑ open up ↑
 525  526          ASSERT(db->db_buf == NULL);
 526  527  
 527  528          if (db->db_blkid == DMU_BONUS_BLKID) {
 528  529                  int bonuslen = MIN(dn->dn_bonuslen, dn->dn_phys->dn_bonuslen);
 529  530  
 530  531                  ASSERT3U(bonuslen, <=, db->db.db_size);
 531  532                  db->db.db_data = zio_buf_alloc(DN_MAX_BONUSLEN);
 532  533                  arc_space_consume(DN_MAX_BONUSLEN, ARC_SPACE_OTHER);
 533  534                  if (bonuslen < DN_MAX_BONUSLEN)
 534  535                          bzero(db->db.db_data, DN_MAX_BONUSLEN);
 535      -                if (bonuslen)
 536      -                        bcopy(DN_BONUS(dn->dn_phys), db->db.db_data, bonuslen);
      536 +
      537 +                if (bonuslen) {
      538 +                        /*
      539 +                         * Absent byzantine on-disk corruption, we fully expect
      540 +                         * our bonuslen to be no more than DN_MAX_BONUSLEN --
      541 +                         * but we nonetheless explicitly clamp it on the bcopy()
      542 +                         * to prevent any on-disk corruption from becoming
      543 +                         * rampant in-kernel corruption.
      544 +                         */
      545 +                        bcopy(DN_BONUS(dn->dn_phys), db->db.db_data,
      546 +                            MIN(bonuslen, DN_MAX_BONUSLEN));
      547 +                }
      548 +
 537  549                  DB_DNODE_EXIT(db);
 538  550                  dbuf_update_data(db);
 539  551                  db->db_state = DB_CACHED;
 540  552                  mutex_exit(&db->db_mtx);
 541  553                  return;
 542  554          }
 543  555  
 544  556          /*
 545  557           * Recheck BP_IS_HOLE() after dnode_block_freed() in case dnode_sync()
 546  558           * processes the delete record and clears the bp while we are waiting
↓ open down ↓ 2204 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX