]>
Commit | Line | Data |
---|---|---|
2cb7cef9 BS |
1 | From: Tiger Yang <tiger.yang@oracle.com> |
2 | Subject: [PATCH 16/16] ocfs2: Add incompatible flag for extended attribute | |
3 | Patch-mainline: 2.6.28? | |
4 | References: FATE302067 | |
5 | ||
6 | This patch adds the s_incompat flag for extended attribute support. This | |
7 | helps us ensure that older versions of Ocfs2 or ocfs2-tools will not be able | |
8 | to mount a volume with xattr support. | |
9 | ||
10 | Signed-off-by: Tiger Yang <tiger.yang@oracle.com> | |
11 | Signed-off-by: Mark Fasheh <mfasheh@suse.com> | |
12 | --- | |
13 | fs/ocfs2/ocfs2.h | 7 +++++++ | |
14 | fs/ocfs2/ocfs2_fs.h | 19 +++++++++++++------ | |
15 | fs/ocfs2/super.c | 3 ++- | |
16 | fs/ocfs2/xattr.c | 12 ++++++++++++ | |
17 | 4 files changed, 34 insertions(+), 7 deletions(-) | |
18 | ||
19 | diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h | |
20 | index 35ed7eb..487487a 100644 | |
21 | --- a/fs/ocfs2/ocfs2.h | |
22 | +++ b/fs/ocfs2/ocfs2.h | |
23 | @@ -343,6 +343,13 @@ static inline int ocfs2_supports_inline_data(struct ocfs2_super *osb) | |
24 | return 0; | |
25 | } | |
26 | ||
27 | +static inline int ocfs2_supports_xattr(struct ocfs2_super *osb) | |
28 | +{ | |
29 | + if (osb->s_feature_incompat & OCFS2_FEATURE_INCOMPAT_XATTR) | |
30 | + return 1; | |
31 | + return 0; | |
32 | +} | |
33 | + | |
34 | /* set / clear functions because cluster events can make these happen | |
35 | * in parallel so we want the transitions to be atomic. this also | |
36 | * means that any future flags osb_flags must be protected by spinlock | |
37 | diff --git a/fs/ocfs2/ocfs2_fs.h b/fs/ocfs2/ocfs2_fs.h | |
38 | index 8d5e72f..f24ce3d 100644 | |
39 | --- a/fs/ocfs2/ocfs2_fs.h | |
40 | +++ b/fs/ocfs2/ocfs2_fs.h | |
41 | @@ -91,7 +91,8 @@ | |
42 | | OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC \ | |
43 | | OCFS2_FEATURE_INCOMPAT_INLINE_DATA \ | |
44 | | OCFS2_FEATURE_INCOMPAT_EXTENDED_SLOT_MAP \ | |
45 | - | OCFS2_FEATURE_INCOMPAT_USERSPACE_STACK) | |
46 | + | OCFS2_FEATURE_INCOMPAT_USERSPACE_STACK \ | |
47 | + | OCFS2_FEATURE_INCOMPAT_XATTR) | |
48 | #define OCFS2_FEATURE_RO_COMPAT_SUPP OCFS2_FEATURE_RO_COMPAT_UNWRITTEN | |
49 | ||
50 | /* | |
51 | @@ -128,10 +129,6 @@ | |
52 | /* Support for data packed into inode blocks */ | |
53 | #define OCFS2_FEATURE_INCOMPAT_INLINE_DATA 0x0040 | |
54 | ||
55 | -/* Support for the extended slot map */ | |
56 | -#define OCFS2_FEATURE_INCOMPAT_EXTENDED_SLOT_MAP 0x100 | |
57 | - | |
58 | - | |
59 | /* | |
60 | * Support for alternate, userspace cluster stacks. If set, the superblock | |
61 | * field s_cluster_info contains a tag for the alternate stack in use as | |
62 | @@ -143,6 +140,12 @@ | |
63 | */ | |
64 | #define OCFS2_FEATURE_INCOMPAT_USERSPACE_STACK 0x0080 | |
65 | ||
66 | +/* Support for the extended slot map */ | |
67 | +#define OCFS2_FEATURE_INCOMPAT_EXTENDED_SLOT_MAP 0x100 | |
68 | + | |
69 | +/* Support for extended attributes */ | |
70 | +#define OCFS2_FEATURE_INCOMPAT_XATTR 0x0200 | |
71 | + | |
72 | /* | |
73 | * backup superblock flag is used to indicate that this volume | |
74 | * has backup superblocks. | |
75 | @@ -578,7 +581,11 @@ struct ocfs2_super_block { | |
76 | /*A0*/ struct ocfs2_cluster_info s_cluster_info; /* Selected userspace | |
77 | stack. Only valid | |
78 | with INCOMPAT flag. */ | |
79 | -/*B8*/ __le64 s_reserved2[17]; /* Fill out superblock */ | |
80 | +/*B8*/ __le16 s_xattr_inline_size; /* extended attribute inline size | |
81 | + for this fs*/ | |
82 | + __le16 s_reserved0; | |
83 | + __le32 s_reserved1; | |
84 | +/*C0*/ __le64 s_reserved2[16]; /* Fill out superblock */ | |
85 | /*140*/ | |
86 | ||
87 | /* | |
88 | diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c | |
89 | index 03a25c4..2173169 100644 | |
90 | --- a/fs/ocfs2/super.c | |
91 | +++ b/fs/ocfs2/super.c | |
92 | @@ -1434,7 +1434,8 @@ static int ocfs2_initialize_super(struct super_block *sb, | |
93 | ||
94 | osb->slot_num = OCFS2_INVALID_SLOT; | |
95 | ||
96 | - osb->s_xattr_inline_size = OCFS2_MIN_XATTR_INLINE_SIZE; | |
97 | + osb->s_xattr_inline_size = le16_to_cpu( | |
98 | + di->id2.i_super.s_xattr_inline_size); | |
99 | ||
100 | osb->local_alloc_state = OCFS2_LA_UNUSED; | |
101 | osb->local_alloc_bh = NULL; | |
102 | diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c | |
103 | index e78ed7a..505fb40 100644 | |
104 | --- a/fs/ocfs2/xattr.c | |
105 | +++ b/fs/ocfs2/xattr.c | |
106 | @@ -580,6 +580,9 @@ ssize_t ocfs2_listxattr(struct dentry *dentry, | |
107 | struct ocfs2_dinode *di = NULL; | |
108 | struct ocfs2_inode_info *oi = OCFS2_I(dentry->d_inode); | |
109 | ||
110 | + if (!ocfs2_supports_xattr(OCFS2_SB(dentry->d_sb))) | |
111 | + return -EOPNOTSUPP; | |
112 | + | |
113 | if (!(oi->ip_dyn_features & OCFS2_HAS_XATTR_FL)) | |
114 | return ret; | |
115 | ||
116 | @@ -859,6 +862,9 @@ int ocfs2_xattr_get(struct inode *inode, | |
117 | .not_found = -ENODATA, | |
118 | }; | |
119 | ||
120 | + if (!ocfs2_supports_xattr(OCFS2_SB(inode->i_sb))) | |
121 | + return -EOPNOTSUPP; | |
122 | + | |
123 | if (!(oi->ip_dyn_features & OCFS2_HAS_XATTR_FL)) | |
124 | ret = -ENODATA; | |
125 | ||
126 | @@ -1557,6 +1563,9 @@ int ocfs2_xattr_remove(struct inode *inode, struct buffer_head *di_bh) | |
127 | handle_t *handle; | |
128 | int ret; | |
129 | ||
130 | + if (!ocfs2_supports_xattr(OCFS2_SB(inode->i_sb))) | |
131 | + return 0; | |
132 | + | |
133 | if (!(oi->ip_dyn_features & OCFS2_HAS_XATTR_FL)) | |
134 | return 0; | |
135 | ||
136 | @@ -1993,6 +2002,9 @@ int ocfs2_xattr_set(struct inode *inode, | |
137 | .not_found = -ENODATA, | |
138 | }; | |
139 | ||
140 | + if (!ocfs2_supports_xattr(OCFS2_SB(inode->i_sb))) | |
141 | + return -EOPNOTSUPP; | |
142 | + | |
143 | ret = ocfs2_inode_lock(inode, &di_bh, 1); | |
144 | if (ret < 0) { | |
145 | mlog_errno(ret); | |
146 | -- | |
147 | 1.5.4.5 | |
148 |