Gentoo Archives: gentoo-commits

From: "Richard Yao (ryao)" <ryao@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] gentoo-x86 commit in sys-fs/zfs/files: zfs-0.6.0_rc9-range-lock-caller-allocate.patch
Date: Mon, 25 Jun 2012 00:51:01
Message-Id: 20120625005051.811CA2004C@flycatcher.gentoo.org
ryao        12/06/25 00:50:51

  Added:                zfs-0.6.0_rc9-range-lock-caller-allocate.patch
  Log:
  Fix swap deadlock involving zfs_range_lock() and zvols
  
  (Portage version: 2.1.10.49/cvs/Linux x86_64)

Revision  Changes    Path
1.1                  sys-fs/zfs/files/zfs-0.6.0_rc9-range-lock-caller-allocate.patch

file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/sys-fs/zfs/files/zfs-0.6.0_rc9-range-lock-caller-allocate.patch?rev=1.1&view=markup
plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/sys-fs/zfs/files/zfs-0.6.0_rc9-range-lock-caller-allocate.patch?rev=1.1&content-type=text/plain

Index: zfs-0.6.0_rc9-range-lock-caller-allocate.patch
===================================================================
commit 59c247716c71837b0071fb933f731e7b82c98dd8
Author: Gunnar Beutner <gunnar@×××××××.name>
Date:   Mon Jun 18 11:44:34 2012 -0400

    Fix znode corruption when using xattr=sa.
    
    Using a separate SA handle (rather than zp->z_sa_hdl) to update
    attributes corrupts the znode's mode flags (and possibly other
    attributes as well).
    
    This patch changes the zfs_sa_get_xattr/zfs_sa_set_xattr functions
    so that they use zp->z_sa_hdl.
    
    Signed-off-by: Richard Yao <ryao@×××××××××××××.edu>

diff --git a/module/zfs/zfs_sa.c b/module/zfs/zfs_sa.c
index f35f6f6..7f14706 100644
--- a/module/zfs/zfs_sa.c
+++ b/module/zfs/zfs_sa.c
@@ -188,7 +188,6 @@ int
 zfs_sa_get_xattr(znode_t *zp)
 {
 	zfs_sb_t *zsb = ZTOZSB(zp);
-	sa_handle_t *sa;
 	char *obj;
 	int size;
 	int error;
@@ -197,14 +196,8 @@ zfs_sa_get_xattr(znode_t *zp)
 	ASSERT(!zp->z_xattr_cached);
 	ASSERT(zp->z_is_sa);
 
-	error = sa_handle_get(zsb->z_os, zp->z_id, NULL, SA_HDL_PRIVATE, &sa);
-	if (error)
-		return (error);
-
-	error = sa_size(sa, SA_ZPL_DXATTR(zsb), &size);
+	error = sa_size(zp->z_sa_hdl, SA_ZPL_DXATTR(zsb), &size);
 	if (error) {
-		sa_handle_destroy(sa);
-
 		if (error == ENOENT)
 			return nvlist_alloc(&zp->z_xattr_cached,
 			    NV_UNIQUE_NAME, KM_SLEEP);
@@ -212,14 +205,13 @@ zfs_sa_get_xattr(znode_t *zp)
 			return (error);
 	}
 
-	obj = sa_spill_alloc(KM_SLEEP);
+	obj = kmem_alloc(size, KM_SLEEP);
 
-	error = sa_lookup(sa, SA_ZPL_DXATTR(zsb), obj, size);
+	error = sa_lookup(zp->z_sa_hdl, SA_ZPL_DXATTR(zsb), obj, size);
 	if (error == 0)
 		error = nvlist_unpack(obj, size, &zp->z_xattr_cached, KM_SLEEP);
 
-	sa_spill_free(obj);
-	sa_handle_destroy(sa);
+	kmem_free(obj, size);
 
 	return (error);
 }
@@ -228,7 +220,6 @@ int
 zfs_sa_set_xattr(znode_t *zp)
 {
 	zfs_sb_t *zsb = ZTOZSB(zp);
-	sa_handle_t *sa;
 	dmu_tx_t *tx;
 	char *obj;
 	size_t size;
@@ -242,44 +233,27 @@ zfs_sa_set_xattr(znode_t *zp)
 	if (error)
 		goto out;
 
-	obj = sa_spill_alloc(KM_SLEEP);
+	obj = kmem_alloc(size, KM_SLEEP);
 
 	error = nvlist_pack(zp->z_xattr_cached, &obj, &size,
 	    NV_ENCODE_XDR, KM_SLEEP);
 	if (error)
-		goto out_free;
-
-	/*
-	 * A private SA handle must be used to ensure we can drop the hold
-	 * on the spill block prior to calling dmu_tx_commit().  If we call
-	 * dmu_tx_commit() before sa_handle_destroy(), then our hold will
-	 * trigger a copy of the buffer at txg sync time.  This is done to
-	 * prevent data from leaking in to the syncing txg.  As a result
-	 * the original dirty spill block will be remain dirty in the arc
-	 * while the copy is written and laundered.
-	 */
-	error = sa_handle_get(zsb->z_os, zp->z_id, NULL, SA_HDL_PRIVATE, &sa);
-	if (error)
-		goto out_free;
+		goto out;
 
 	tx = dmu_tx_create(zsb->z_os);
 	dmu_tx_hold_sa_create(tx, size);
-	dmu_tx_hold_sa(tx, sa, B_TRUE);
+	dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_TRUE);
 
 	error = dmu_tx_assign(tx, TXG_WAIT);
 	if (error) {
 		dmu_tx_abort(tx);
-		sa_handle_destroy(sa);
 	} else {
-		error = sa_update(sa, SA_ZPL_DXATTR(zsb), obj, size, tx);
-		sa_handle_destroy(sa);
-		if (error)
-			dmu_tx_abort(tx);
-		else
-			dmu_tx_commit(tx);
+		VERIFY(0 == sa_update(zp->z_sa_hdl, SA_ZPL_DXATTR(zsb), obj,
+		    size, tx));
+		dmu_tx_commit(tx);
 	}
-out_free:
-	sa_spill_free(obj);
+
+	kmem_free(obj, size);
 out:
 	return (error);
 }