aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/gfs2/eaops.c41
-rw-r--r--fs/gfs2/eaops.h2
-rw-r--r--fs/gfs2/eattr.c15
-rw-r--r--fs/gfs2/eattr.h17
-rw-r--r--include/linux/gfs2_ondisk.h3
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
173static 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
183static 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
193static 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
169static struct gfs2_eattr_operations gfs2_user_eaops = { 203static 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
217struct 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
183struct gfs2_eattr_operations *gfs2_ea_ops[] = { 224struct 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
24extern struct gfs2_eattr_operations gfs2_system_eaops; 24extern struct gfs2_eattr_operations gfs2_system_eaops;
25 25
26extern struct gfs2_eattr_operations gfs2_security_eaops;
27
26extern struct gfs2_eattr_operations *gfs2_ea_ops[]; 28extern 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,
83int gfs2_ea_acl_chmod(struct gfs2_inode *ip, struct gfs2_ea_location *el, 80int 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
83static 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 */