]>
Commit | Line | Data |
---|---|---|
00e5a55c BS |
1 | From: Tao Ma <tao.ma@oracle.com> |
2 | Date: Thu, 12 Mar 2009 08:37:34 +0800 | |
3 | Subject: [PATCH] ocfs2: Use xs->bucket to set xattr value outside | |
4 | Patch-mainline: 2.6.29 | |
5 | ||
6 | A long time ago, xs->base is allocated a 4K size and all the contents | |
7 | in the bucket are copied to the it. Now we use ocfs2_xattr_bucket to | |
8 | abstract xattr bucket and xs->base is initialized to the start of the | |
9 | bu_bhs[0]. So xs->base + offset will overflow when the value root is | |
10 | stored outside the first block. | |
11 | ||
12 | Then why we can survive the xattr test by now? It is because we always | |
13 | read the bucket contiguously now and kernel mm allocate continguous | |
14 | memory for us. We are lucky, but we should fix it. So just get the | |
15 | right value root as other callers do. | |
16 | ||
17 | Signed-off-by: Tao Ma <tao.ma@oracle.com> | |
18 | Acked-by: Joel Becker <joel.becker@oracle.com> | |
19 | Signed-off-by: Mark Fasheh <mfasheh@suse.com> | |
20 | --- | |
21 | fs/ocfs2/xattr.c | 26 ++++++++++++++++++++------ | |
22 | 1 files changed, 20 insertions(+), 6 deletions(-) | |
23 | ||
24 | Index: linux-2.6.27-sle11_ocfs2_update2/fs/ocfs2/xattr.c | |
25 | =================================================================== | |
26 | --- linux-2.6.27-sle11_ocfs2_update2.orig/fs/ocfs2/xattr.c | |
27 | +++ linux-2.6.27-sle11_ocfs2_update2/fs/ocfs2/xattr.c | |
28 | @@ -4649,19 +4649,33 @@ static int ocfs2_xattr_bucket_set_value_ | |
29 | char *val, | |
30 | int value_len) | |
31 | { | |
32 | - int offset; | |
33 | + int ret, offset, block_off; | |
34 | struct ocfs2_xattr_value_root *xv; | |
35 | struct ocfs2_xattr_entry *xe = xs->here; | |
36 | + struct ocfs2_xattr_header *xh = bucket_xh(xs->bucket); | |
37 | + void *base; | |
38 | ||
39 | BUG_ON(!xs->base || !xe || ocfs2_xattr_is_local(xe)); | |
40 | ||
41 | - offset = le16_to_cpu(xe->xe_name_offset) + | |
42 | - OCFS2_XATTR_SIZE(xe->xe_name_len); | |
43 | + ret = ocfs2_xattr_bucket_get_name_value(inode, xh, | |
44 | + xe - xh->xh_entries, | |
45 | + &block_off, | |
46 | + &offset); | |
47 | + if (ret) { | |
48 | + mlog_errno(ret); | |
49 | + goto out; | |
50 | + } | |
51 | ||
52 | - xv = (struct ocfs2_xattr_value_root *)(xs->base + offset); | |
53 | + base = bucket_block(xs->bucket, block_off); | |
54 | + xv = (struct ocfs2_xattr_value_root *)(base + offset + | |
55 | + OCFS2_XATTR_SIZE(xe->xe_name_len)); | |
56 | ||
57 | - return __ocfs2_xattr_set_value_outside(inode, handle, | |
58 | - xv, val, value_len); | |
59 | + ret = __ocfs2_xattr_set_value_outside(inode, handle, | |
60 | + xv, val, value_len); | |
61 | + if (ret) | |
62 | + mlog_errno(ret); | |
63 | +out: | |
64 | + return ret; | |
65 | } | |
66 | ||
67 | static int ocfs2_rm_xattr_cluster(struct inode *inode, |