diff options
-rw-r--r-- | fs/gfs2/eaops.c | 41 | ||||
-rw-r--r-- | fs/gfs2/eaops.h | 2 | ||||
-rw-r--r-- | fs/gfs2/eattr.c | 15 | ||||
-rw-r--r-- | fs/gfs2/eattr.h | 17 | ||||
-rw-r--r-- | include/linux/gfs2_ondisk.h | 3 |
5 files changed, 71 insertions, 7 deletions
diff --git a/fs/gfs2/eaops.c b/fs/gfs2/eaops.c index 85c1dbace88b..2243b44ecb07 100644 --- a/fs/gfs2/eaops.c +++ b/fs/gfs2/eaops.c | |||
@@ -43,6 +43,10 @@ unsigned int gfs2_ea_name2type(const char *name, char **truncated_name) | |||
43 | type = GFS2_EATYPE_USR; | 43 | type = GFS2_EATYPE_USR; |
44 | if (truncated_name) | 44 | if (truncated_name) |
45 | *truncated_name = strchr(name, '.') + 1; | 45 | *truncated_name = strchr(name, '.') + 1; |
46 | } else if (strncmp(name, "security.", 9) == 0) { | ||
47 | type = GFS2_EATYPE_SECURITY; | ||
48 | if (truncated_name) | ||
49 | *truncated_name = strchr(name, '.') + 1; | ||
46 | } else { | 50 | } else { |
47 | type = GFS2_EATYPE_UNUSED; | 51 | type = GFS2_EATYPE_UNUSED; |
48 | if (truncated_name) | 52 | if (truncated_name) |
@@ -166,6 +170,36 @@ static int system_eo_remove(struct gfs2_inode *ip, struct gfs2_ea_request *er) | |||
166 | return gfs2_ea_remove_i(ip, er); | 170 | return gfs2_ea_remove_i(ip, er); |
167 | } | 171 | } |
168 | 172 | ||
173 | static int security_eo_get(struct gfs2_inode *ip, struct gfs2_ea_request *er) | ||
174 | { | ||
175 | struct inode *inode = ip->i_vnode; | ||
176 | int error = permission(inode, MAY_READ, NULL); | ||
177 | if (error) | ||
178 | return error; | ||
179 | |||
180 | return gfs2_ea_get_i(ip, er); | ||
181 | } | ||
182 | |||
183 | static int security_eo_set(struct gfs2_inode *ip, struct gfs2_ea_request *er) | ||
184 | { | ||
185 | struct inode *inode = ip->i_vnode; | ||
186 | int error = permission(inode, MAY_WRITE, NULL); | ||
187 | if (error) | ||
188 | return error; | ||
189 | |||
190 | return gfs2_ea_set_i(ip, er); | ||
191 | } | ||
192 | |||
193 | static int security_eo_remove(struct gfs2_inode *ip, struct gfs2_ea_request *er) | ||
194 | { | ||
195 | struct inode *inode = ip->i_vnode; | ||
196 | int error = permission(inode, MAY_WRITE, NULL); | ||
197 | if (error) | ||
198 | return error; | ||
199 | |||
200 | return gfs2_ea_remove_i(ip, er); | ||
201 | } | ||
202 | |||
169 | static struct gfs2_eattr_operations gfs2_user_eaops = { | 203 | static struct gfs2_eattr_operations gfs2_user_eaops = { |
170 | .eo_get = user_eo_get, | 204 | .eo_get = user_eo_get, |
171 | .eo_set = user_eo_set, | 205 | .eo_set = user_eo_set, |
@@ -180,6 +214,13 @@ struct gfs2_eattr_operations gfs2_system_eaops = { | |||
180 | .eo_name = "system", | 214 | .eo_name = "system", |
181 | }; | 215 | }; |
182 | 216 | ||
217 | struct gfs2_eattr_operations gfs2_security_eaops = { | ||
218 | .eo_get = security_eo_get, | ||
219 | .eo_set = security_eo_set, | ||
220 | .eo_remove = security_eo_remove, | ||
221 | .eo_name = "security", | ||
222 | }; | ||
223 | |||
183 | struct gfs2_eattr_operations *gfs2_ea_ops[] = { | 224 | struct gfs2_eattr_operations *gfs2_ea_ops[] = { |
184 | NULL, | 225 | NULL, |
185 | &gfs2_user_eaops, | 226 | &gfs2_user_eaops, |
diff --git a/fs/gfs2/eaops.h b/fs/gfs2/eaops.h index 3dece17e3116..965a235c96e8 100644 --- a/fs/gfs2/eaops.h +++ b/fs/gfs2/eaops.h | |||
@@ -23,6 +23,8 @@ unsigned int gfs2_ea_name2type(const char *name, char **truncated_name); | |||
23 | 23 | ||
24 | extern struct gfs2_eattr_operations gfs2_system_eaops; | 24 | extern struct gfs2_eattr_operations gfs2_system_eaops; |
25 | 25 | ||
26 | extern struct gfs2_eattr_operations gfs2_security_eaops; | ||
27 | |||
26 | extern struct gfs2_eattr_operations *gfs2_ea_ops[]; | 28 | extern struct gfs2_eattr_operations *gfs2_ea_ops[]; |
27 | 29 | ||
28 | #endif /* __EAOPS_DOT_H__ */ | 30 | #endif /* __EAOPS_DOT_H__ */ |
diff --git a/fs/gfs2/eattr.c b/fs/gfs2/eattr.c index f5169a42a919..187fba1c4678 100644 --- a/fs/gfs2/eattr.c +++ b/fs/gfs2/eattr.c | |||
@@ -368,7 +368,7 @@ static int ea_list_i(struct gfs2_inode *ip, struct buffer_head *bh, | |||
368 | { | 368 | { |
369 | struct ea_list *ei = private; | 369 | struct ea_list *ei = private; |
370 | struct gfs2_ea_request *er = ei->ei_er; | 370 | struct gfs2_ea_request *er = ei->ei_er; |
371 | unsigned int ea_size = GFS2_EA_STRLEN(ea); | 371 | unsigned int ea_size = gfs2_ea_strlen(ea); |
372 | 372 | ||
373 | if (ea->ea_type == GFS2_EATYPE_UNUSED) | 373 | if (ea->ea_type == GFS2_EATYPE_UNUSED) |
374 | return 0; | 374 | return 0; |
@@ -381,12 +381,21 @@ static int ea_list_i(struct gfs2_inode *ip, struct buffer_head *bh, | |||
381 | if (ei->ei_size + ea_size > er->er_data_len) | 381 | if (ei->ei_size + ea_size > er->er_data_len) |
382 | return -ERANGE; | 382 | return -ERANGE; |
383 | 383 | ||
384 | if (ea->ea_type == GFS2_EATYPE_USR) { | 384 | switch (ea->ea_type) { |
385 | case GFS2_EATYPE_USR: | ||
385 | prefix = "user."; | 386 | prefix = "user."; |
386 | l = 5; | 387 | l = 5; |
387 | } else { | 388 | break; |
389 | case GFS2_EATYPE_SYS: | ||
388 | prefix = "system."; | 390 | prefix = "system."; |
389 | l = 7; | 391 | l = 7; |
392 | break; | ||
393 | case GFS2_EATYPE_SECURITY: | ||
394 | prefix = "security."; | ||
395 | l = 9; | ||
396 | break; | ||
397 | default: | ||
398 | break; | ||
390 | } | 399 | } |
391 | 400 | ||
392 | memcpy(er->er_data + ei->ei_size, | 401 | memcpy(er->er_data + ei->ei_size, |
diff --git a/fs/gfs2/eattr.h b/fs/gfs2/eattr.h index 19fb1dc4ddc4..ae199692e51d 100644 --- a/fs/gfs2/eattr.h +++ b/fs/gfs2/eattr.h | |||
@@ -18,9 +18,6 @@ ALIGN(sizeof(struct gfs2_ea_header) + (ea)->ea_name_len + \ | |||
18 | ((GFS2_EA_IS_STUFFED(ea)) ? GFS2_EA_DATA_LEN(ea) : \ | 18 | ((GFS2_EA_IS_STUFFED(ea)) ? GFS2_EA_DATA_LEN(ea) : \ |
19 | (sizeof(uint64_t) * (ea)->ea_num_ptrs)), 8) | 19 | (sizeof(uint64_t) * (ea)->ea_num_ptrs)), 8) |
20 | 20 | ||
21 | #define GFS2_EA_STRLEN(ea) \ | ||
22 | ((((ea)->ea_type == GFS2_EATYPE_USR) ? 5 : 7) + (ea)->ea_name_len + 1) | ||
23 | |||
24 | #define GFS2_EA_IS_STUFFED(ea) (!(ea)->ea_num_ptrs) | 21 | #define GFS2_EA_IS_STUFFED(ea) (!(ea)->ea_num_ptrs) |
25 | #define GFS2_EA_IS_LAST(ea) ((ea)->ea_flags & GFS2_EAFLAG_LAST) | 22 | #define GFS2_EA_IS_LAST(ea) ((ea)->ea_flags & GFS2_EAFLAG_LAST) |
26 | 23 | ||
@@ -83,4 +80,18 @@ int gfs2_ea_get_copy(struct gfs2_inode *ip, | |||
83 | int gfs2_ea_acl_chmod(struct gfs2_inode *ip, struct gfs2_ea_location *el, | 80 | int gfs2_ea_acl_chmod(struct gfs2_inode *ip, struct gfs2_ea_location *el, |
84 | struct iattr *attr, char *data); | 81 | struct iattr *attr, char *data); |
85 | 82 | ||
83 | static inline unsigned int gfs2_ea_strlen(struct gfs2_ea_header *ea) | ||
84 | { | ||
85 | switch (ea->ea_type) { | ||
86 | case GFS2_EATYPE_USR: | ||
87 | return (5 + (ea->ea_name_len + 1)); | ||
88 | case GFS2_EATYPE_SYS: | ||
89 | return (7 + (ea->ea_name_len + 1)); | ||
90 | case GFS2_EATYPE_SECURITY: | ||
91 | return (9 + (ea->ea_name_len + 1)); | ||
92 | default: | ||
93 | return (0); | ||
94 | } | ||
95 | } | ||
96 | |||
86 | #endif /* __EATTR_DOT_H__ */ | 97 | #endif /* __EATTR_DOT_H__ */ |
diff --git a/include/linux/gfs2_ondisk.h b/include/linux/gfs2_ondisk.h index 4356e3864643..3893aac4e3ae 100644 --- a/include/linux/gfs2_ondisk.h +++ b/include/linux/gfs2_ondisk.h | |||
@@ -311,8 +311,9 @@ struct gfs2_leaf { | |||
311 | #define GFS2_EATYPE_UNUSED 0 | 311 | #define GFS2_EATYPE_UNUSED 0 |
312 | #define GFS2_EATYPE_USR 1 | 312 | #define GFS2_EATYPE_USR 1 |
313 | #define GFS2_EATYPE_SYS 2 | 313 | #define GFS2_EATYPE_SYS 2 |
314 | #define GFS2_EATYPE_SECURITY 3 | ||
314 | 315 | ||
315 | #define GFS2_EATYPE_LAST 2 | 316 | #define GFS2_EATYPE_LAST 3 |
316 | #define GFS2_EATYPE_VALID(x) ((x) <= GFS2_EATYPE_LAST) | 317 | #define GFS2_EATYPE_VALID(x) ((x) <= GFS2_EATYPE_LAST) |
317 | 318 | ||
318 | #define GFS2_EAFLAG_LAST 0x01 /* last ea in block */ | 319 | #define GFS2_EAFLAG_LAST 0x01 /* last ea in block */ |