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>


 589         uint64_t        acl_obj;
 590         uint64_t        xattr_obj;
 591         int             error;
 592 
 593         ASSERT(zp->z_links == 0);
 594         ASSERT(ZTOV(zp)->v_count == 0);
 595 
 596         /*
 597          * If this is an attribute directory, purge its contents.
 598          */
 599         if (ZTOV(zp)->v_type == VDIR && (zp->z_pflags & ZFS_XATTR)) {
 600                 if (zfs_purgedir(zp) != 0) {
 601                         /*
 602                          * Not enough space to delete some xattrs.
 603                          * Leave it in the unlinked set.
 604                          */
 605                         zfs_znode_dmu_fini(zp);
 606                         zfs_znode_free(zp);
 607                         return;
 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) {
 616                 /*
 617                  * Not enough space.  Leave the file in the unlinked set.

 618                  */
 619                 zfs_znode_dmu_fini(zp);
 620                 zfs_znode_free(zp);
 621                 return;
 622         }

 623 
 624         /*
 625          * If the file has extended attributes, we're going to unlink
 626          * the xattr dir.
 627          */
 628         error = sa_lookup(zp->z_sa_hdl, SA_ZPL_XATTR(zfsvfs),
 629             &xattr_obj, sizeof (xattr_obj));
 630         if (error == 0 && xattr_obj) {
 631                 error = zfs_zget(zfsvfs, xattr_obj, &xzp);
 632                 ASSERT(error == 0);
 633         }
 634 
 635         acl_obj = zfs_external_acl(zp);
 636 
 637         /*
 638          * Set up the final transaction.
 639          */
 640         tx = dmu_tx_create(os);
 641         dmu_tx_hold_free(tx, zp->z_id, 0, DMU_OBJECT_END);
 642         dmu_tx_hold_zap(tx, zfsvfs->z_unlinkedobj, FALSE, NULL);




 589         uint64_t        acl_obj;
 590         uint64_t        xattr_obj;
 591         int             error;
 592 
 593         ASSERT(zp->z_links == 0);
 594         ASSERT(ZTOV(zp)->v_count == 0);
 595 
 596         /*
 597          * If this is an attribute directory, purge its contents.
 598          */
 599         if (ZTOV(zp)->v_type == VDIR && (zp->z_pflags & ZFS_XATTR)) {
 600                 if (zfs_purgedir(zp) != 0) {
 601                         /*
 602                          * Not enough space to delete some xattrs.
 603                          * Leave it in the unlinked set.
 604                          */
 605                         zfs_znode_dmu_fini(zp);
 606                         zfs_znode_free(zp);
 607                         return;
 608                 }
 609         } else {

 610                 /*
 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.
 617                  */
 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                 }
 628         }
 629 
 630         /*
 631          * If the file has extended attributes, we're going to unlink
 632          * the xattr dir.
 633          */
 634         error = sa_lookup(zp->z_sa_hdl, SA_ZPL_XATTR(zfsvfs),
 635             &xattr_obj, sizeof (xattr_obj));
 636         if (error == 0 && xattr_obj) {
 637                 error = zfs_zget(zfsvfs, xattr_obj, &xzp);
 638                 ASSERT(error == 0);
 639         }
 640 
 641         acl_obj = zfs_external_acl(zp);
 642 
 643         /*
 644          * Set up the final transaction.
 645          */
 646         tx = dmu_tx_create(os);
 647         dmu_tx_hold_free(tx, zp->z_id, 0, DMU_OBJECT_END);
 648         dmu_tx_hold_zap(tx, zfsvfs->z_unlinkedobj, FALSE, NULL);