Print this page
6843 Make xattr dir truncate and remove in one tx
Reviewed by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed by: Dan McDonald <danmcd@omniti.com>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/zfs/zfs_dir.c
          +++ new/usr/src/uts/common/fs/zfs/zfs_dir.c
↓ open down ↓ 598 lines elided ↑ open up ↑
 599  599          if (ZTOV(zp)->v_type == VDIR && (zp->z_pflags & ZFS_XATTR)) {
 600  600                  if (zfs_purgedir(zp) != 0) {
 601  601                          /*
 602  602                           * Not enough space to delete some xattrs.
 603  603                           * Leave it in the unlinked set.
 604  604                           */
 605  605                          zfs_znode_dmu_fini(zp);
 606  606                          zfs_znode_free(zp);
 607  607                          return;
 608  608                  }
 609      -        }
 610      -
 611      -        /*
 612      -         * Free up all the data in the file.
 613      -         */
 614      -        error = dmu_free_long_range(os, zp->z_id, 0, DMU_OBJECT_END);
 615      -        if (error) {
      609 +        } else {
 616  610                  /*
 617      -                 * Not enough space.  Leave the file in the unlinked set.
      611 +                 * Free up all the data in the file.  We don't do this for
      612 +                 * XATTR directories because we need truncate and remove to be
      613 +                 * in the same tx, like in zfs_znode_delete(). Otherwise, if
      614 +                 * we crash here we'll end up with an inconsistent truncated
      615 +                 * zap object in the delete queue.  Note a truncated file is
      616 +                 * harmless since it only contains user data.
 618  617                   */
 619      -                zfs_znode_dmu_fini(zp);
 620      -                zfs_znode_free(zp);
 621      -                return;
      618 +                error = dmu_free_long_range(os, zp->z_id, 0, DMU_OBJECT_END);
      619 +                if (error) {
      620 +                        /*
      621 +                         * Not enough space.  Leave the file in the unlinked
      622 +                         * set.
      623 +                         */
      624 +                        zfs_znode_dmu_fini(zp);
      625 +                        zfs_znode_free(zp);
      626 +                        return;
      627 +                }
 622  628          }
 623  629  
 624  630          /*
 625  631           * If the file has extended attributes, we're going to unlink
 626  632           * the xattr dir.
 627  633           */
 628  634          error = sa_lookup(zp->z_sa_hdl, SA_ZPL_XATTR(zfsvfs),
 629  635              &xattr_obj, sizeof (xattr_obj));
 630  636          if (error == 0 && xattr_obj) {
 631  637                  error = zfs_zget(zfsvfs, xattr_obj, &xzp);
↓ open down ↓ 454 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX