/[gentoo-x86]/sys-fs/zfs/files/zfs-0.6.0_rc9-range-lock-caller-allocate.patch
Gentoo

Contents of /sys-fs/zfs/files/zfs-0.6.0_rc9-range-lock-caller-allocate.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (show annotations) (download)
Mon Jun 25 00:50:51 2012 UTC (2 years, 3 months ago) by ryao
Branch: MAIN
Fix swap deadlock involving zfs_range_lock() and zvols

(Portage version: 2.1.10.49/cvs/Linux x86_64)

1 commit 59c247716c71837b0071fb933f731e7b82c98dd8
2 Author: Gunnar Beutner <gunnar@beutner.name>
3 Date: Mon Jun 18 11:44:34 2012 -0400
4
5 Fix znode corruption when using xattr=sa.
6
7 Using a separate SA handle (rather than zp->z_sa_hdl) to update
8 attributes corrupts the znode's mode flags (and possibly other
9 attributes as well).
10
11 This patch changes the zfs_sa_get_xattr/zfs_sa_set_xattr functions
12 so that they use zp->z_sa_hdl.
13
14 Signed-off-by: Richard Yao <ryao@cs.stonybrook.edu>
15
16 diff --git a/module/zfs/zfs_sa.c b/module/zfs/zfs_sa.c
17 index f35f6f6..7f14706 100644
18 --- a/module/zfs/zfs_sa.c
19 +++ b/module/zfs/zfs_sa.c
20 @@ -188,7 +188,6 @@ int
21 zfs_sa_get_xattr(znode_t *zp)
22 {
23 zfs_sb_t *zsb = ZTOZSB(zp);
24 - sa_handle_t *sa;
25 char *obj;
26 int size;
27 int error;
28 @@ -197,14 +196,8 @@ zfs_sa_get_xattr(znode_t *zp)
29 ASSERT(!zp->z_xattr_cached);
30 ASSERT(zp->z_is_sa);
31
32 - error = sa_handle_get(zsb->z_os, zp->z_id, NULL, SA_HDL_PRIVATE, &sa);
33 - if (error)
34 - return (error);
35 -
36 - error = sa_size(sa, SA_ZPL_DXATTR(zsb), &size);
37 + error = sa_size(zp->z_sa_hdl, SA_ZPL_DXATTR(zsb), &size);
38 if (error) {
39 - sa_handle_destroy(sa);
40 -
41 if (error == ENOENT)
42 return nvlist_alloc(&zp->z_xattr_cached,
43 NV_UNIQUE_NAME, KM_SLEEP);
44 @@ -212,14 +205,13 @@ zfs_sa_get_xattr(znode_t *zp)
45 return (error);
46 }
47
48 - obj = sa_spill_alloc(KM_SLEEP);
49 + obj = kmem_alloc(size, KM_SLEEP);
50
51 - error = sa_lookup(sa, SA_ZPL_DXATTR(zsb), obj, size);
52 + error = sa_lookup(zp->z_sa_hdl, SA_ZPL_DXATTR(zsb), obj, size);
53 if (error == 0)
54 error = nvlist_unpack(obj, size, &zp->z_xattr_cached, KM_SLEEP);
55
56 - sa_spill_free(obj);
57 - sa_handle_destroy(sa);
58 + kmem_free(obj, size);
59
60 return (error);
61 }
62 @@ -228,7 +220,6 @@ int
63 zfs_sa_set_xattr(znode_t *zp)
64 {
65 zfs_sb_t *zsb = ZTOZSB(zp);
66 - sa_handle_t *sa;
67 dmu_tx_t *tx;
68 char *obj;
69 size_t size;
70 @@ -242,44 +233,27 @@ zfs_sa_set_xattr(znode_t *zp)
71 if (error)
72 goto out;
73
74 - obj = sa_spill_alloc(KM_SLEEP);
75 + obj = kmem_alloc(size, KM_SLEEP);
76
77 error = nvlist_pack(zp->z_xattr_cached, &obj, &size,
78 NV_ENCODE_XDR, KM_SLEEP);
79 if (error)
80 - goto out_free;
81 -
82 - /*
83 - * A private SA handle must be used to ensure we can drop the hold
84 - * on the spill block prior to calling dmu_tx_commit(). If we call
85 - * dmu_tx_commit() before sa_handle_destroy(), then our hold will
86 - * trigger a copy of the buffer at txg sync time. This is done to
87 - * prevent data from leaking in to the syncing txg. As a result
88 - * the original dirty spill block will be remain dirty in the arc
89 - * while the copy is written and laundered.
90 - */
91 - error = sa_handle_get(zsb->z_os, zp->z_id, NULL, SA_HDL_PRIVATE, &sa);
92 - if (error)
93 - goto out_free;
94 + goto out;
95
96 tx = dmu_tx_create(zsb->z_os);
97 dmu_tx_hold_sa_create(tx, size);
98 - dmu_tx_hold_sa(tx, sa, B_TRUE);
99 + dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_TRUE);
100
101 error = dmu_tx_assign(tx, TXG_WAIT);
102 if (error) {
103 dmu_tx_abort(tx);
104 - sa_handle_destroy(sa);
105 } else {
106 - error = sa_update(sa, SA_ZPL_DXATTR(zsb), obj, size, tx);
107 - sa_handle_destroy(sa);
108 - if (error)
109 - dmu_tx_abort(tx);
110 - else
111 - dmu_tx_commit(tx);
112 + VERIFY(0 == sa_update(zp->z_sa_hdl, SA_ZPL_DXATTR(zsb), obj,
113 + size, tx));
114 + dmu_tx_commit(tx);
115 }
116 -out_free:
117 - sa_spill_free(obj);
118 +
119 + kmem_free(obj, size);
120 out:
121 return (error);
122 }

  ViewVC Help
Powered by ViewVC 1.1.20