aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/gfs2/eaops.c8
-rw-r--r--fs/gfs2/eaops.h2
-rw-r--r--fs/gfs2/eattr.c102
-rw-r--r--fs/gfs2/eattr.h10
4 files changed, 48 insertions, 74 deletions
diff --git a/fs/gfs2/eaops.c b/fs/gfs2/eaops.c
index 3b8749c22731..adb898ceaa18 100644
--- a/fs/gfs2/eaops.c
+++ b/fs/gfs2/eaops.c
@@ -31,22 +31,22 @@
31 * Returns: GFS2_EATYPE_XXX 31 * Returns: GFS2_EATYPE_XXX
32 */ 32 */
33 33
34unsigned int gfs2_ea_name2type(const char *name, char **truncated_name) 34unsigned int gfs2_ea_name2type(const char *name, const char **truncated_name)
35{ 35{
36 unsigned int type; 36 unsigned int type;
37 37
38 if (strncmp(name, "system.", 7) == 0) { 38 if (strncmp(name, "system.", 7) == 0) {
39 type = GFS2_EATYPE_SYS; 39 type = GFS2_EATYPE_SYS;
40 if (truncated_name) 40 if (truncated_name)
41 *truncated_name = strchr(name, '.') + 1; 41 *truncated_name = name + sizeof("system.") - 1;
42 } else if (strncmp(name, "user.", 5) == 0) { 42 } else if (strncmp(name, "user.", 5) == 0) {
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 = name + sizeof("user.") - 1;
46 } else if (strncmp(name, "security.", 9) == 0) { 46 } else if (strncmp(name, "security.", 9) == 0) {
47 type = GFS2_EATYPE_SECURITY; 47 type = GFS2_EATYPE_SECURITY;
48 if (truncated_name) 48 if (truncated_name)
49 *truncated_name = strchr(name, '.') + 1; 49 *truncated_name = name + sizeof("security.") - 1;
50 } else { 50 } else {
51 type = GFS2_EATYPE_UNUSED; 51 type = GFS2_EATYPE_UNUSED;
52 if (truncated_name) 52 if (truncated_name)
diff --git a/fs/gfs2/eaops.h b/fs/gfs2/eaops.h
index b045897e1e83..508b4f7a2449 100644
--- a/fs/gfs2/eaops.h
+++ b/fs/gfs2/eaops.h
@@ -20,7 +20,7 @@ struct gfs2_eattr_operations {
20 char *eo_name; 20 char *eo_name;
21}; 21};
22 22
23unsigned int gfs2_ea_name2type(const char *name, char **truncated_name); 23unsigned int gfs2_ea_name2type(const char *name, const char **truncated_name);
24 24
25extern struct gfs2_eattr_operations gfs2_system_eaops; 25extern struct gfs2_eattr_operations gfs2_system_eaops;
26 26
diff --git a/fs/gfs2/eattr.c b/fs/gfs2/eattr.c
index f6b5e306a6c8..d7b92fba6998 100644
--- a/fs/gfs2/eattr.c
+++ b/fs/gfs2/eattr.c
@@ -68,11 +68,9 @@ static int ea_check_size(struct gfs2_sbd *sdp, struct gfs2_ea_request *er)
68 return 0; 68 return 0;
69} 69}
70 70
71typedef int (*ea_call_t) (struct gfs2_inode *ip, 71typedef int (*ea_call_t) (struct gfs2_inode *ip, struct buffer_head *bh,
72 struct buffer_head *bh,
73 struct gfs2_ea_header *ea, 72 struct gfs2_ea_header *ea,
74 struct gfs2_ea_header *prev, 73 struct gfs2_ea_header *prev, void *private);
75 void *private);
76 74
77static int ea_foreach_i(struct gfs2_inode *ip, struct buffer_head *bh, 75static int ea_foreach_i(struct gfs2_inode *ip, struct buffer_head *bh,
78 ea_call_t ea_call, void *data) 76 ea_call_t ea_call, void *data)
@@ -86,9 +84,8 @@ static int ea_foreach_i(struct gfs2_inode *ip, struct buffer_head *bh,
86 for (ea = GFS2_EA_BH2FIRST(bh);; prev = ea, ea = GFS2_EA2NEXT(ea)) { 84 for (ea = GFS2_EA_BH2FIRST(bh);; prev = ea, ea = GFS2_EA2NEXT(ea)) {
87 if (!GFS2_EA_REC_LEN(ea)) 85 if (!GFS2_EA_REC_LEN(ea))
88 goto fail; 86 goto fail;
89 if (!(bh->b_data <= (char *)ea && 87 if (!(bh->b_data <= (char *)ea && (char *)GFS2_EA2NEXT(ea) <=
90 (char *)GFS2_EA2NEXT(ea) <= 88 bh->b_data + bh->b_size))
91 bh->b_data + bh->b_size))
92 goto fail; 89 goto fail;
93 if (!GFS2_EATYPE_VALID(ea->ea_type)) 90 if (!GFS2_EATYPE_VALID(ea->ea_type))
94 goto fail; 91 goto fail;
@@ -118,8 +115,7 @@ static int ea_foreach(struct gfs2_inode *ip, ea_call_t ea_call, void *data)
118 u64 *eablk, *end; 115 u64 *eablk, *end;
119 int error; 116 int error;
120 117
121 error = gfs2_meta_read(ip->i_gl, ip->i_di.di_eattr, 118 error = gfs2_meta_read(ip->i_gl, ip->i_di.di_eattr, DIO_START | DIO_WAIT, &bh);
122 DIO_START | DIO_WAIT, &bh);
123 if (error) 119 if (error)
124 return error; 120 return error;
125 121
@@ -143,8 +139,7 @@ static int ea_foreach(struct gfs2_inode *ip, ea_call_t ea_call, void *data)
143 break; 139 break;
144 bn = be64_to_cpu(*eablk); 140 bn = be64_to_cpu(*eablk);
145 141
146 error = gfs2_meta_read(ip->i_gl, bn, DIO_START | DIO_WAIT, 142 error = gfs2_meta_read(ip->i_gl, bn, DIO_START | DIO_WAIT, &eabh);
147 &eabh);
148 if (error) 143 if (error)
149 break; 144 break;
150 error = ea_foreach_i(ip, eabh, ea_call, data); 145 error = ea_foreach_i(ip, eabh, ea_call, data);
@@ -184,12 +179,6 @@ static int ea_find_i(struct gfs2_inode *ip, struct buffer_head *bh,
184 } 179 }
185 } 180 }
186 181
187#if 0
188 else if ((ip->i_di.di_flags & GFS2_DIF_EA_PACKED) &&
189 er->er_type == GFS2_EATYPE_SYS)
190 return 1;
191#endif
192
193 return 0; 182 return 0;
194} 183}
195 184
@@ -246,11 +235,12 @@ static int ea_dealloc_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh,
246 return 0; 235 return 0;
247 236
248 dataptrs = GFS2_EA2DATAPTRS(ea); 237 dataptrs = GFS2_EA2DATAPTRS(ea);
249 for (x = 0; x < ea->ea_num_ptrs; x++, dataptrs++) 238 for (x = 0; x < ea->ea_num_ptrs; x++, dataptrs++) {
250 if (*dataptrs) { 239 if (*dataptrs) {
251 blks++; 240 blks++;
252 bn = be64_to_cpu(*dataptrs); 241 bn = be64_to_cpu(*dataptrs);
253 } 242 }
243 }
254 if (!blks) 244 if (!blks)
255 return 0; 245 return 0;
256 246
@@ -264,9 +254,8 @@ static int ea_dealloc_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh,
264 if (error) 254 if (error)
265 return error; 255 return error;
266 256
267 error = gfs2_trans_begin(sdp, rgd->rd_ri.ri_length + 257 error = gfs2_trans_begin(sdp, rgd->rd_ri.ri_length + RES_DINODE +
268 RES_DINODE + RES_EATTR + RES_STATFS + 258 RES_EATTR + RES_STATFS + RES_QUOTA, blks);
269 RES_QUOTA, blks);
270 if (error) 259 if (error)
271 goto out_gunlock; 260 goto out_gunlock;
272 261
@@ -340,9 +329,7 @@ static int ea_remove_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh,
340 if (error) 329 if (error)
341 goto out_quota; 330 goto out_quota;
342 331
343 error = ea_dealloc_unstuffed(ip, 332 error = ea_dealloc_unstuffed(ip, bh, ea, prev, (leave) ? &error : NULL);
344 bh, ea, prev,
345 (leave) ? &error : NULL);
346 333
347 gfs2_glock_dq_uninit(&al->al_ri_gh); 334 gfs2_glock_dq_uninit(&al->al_ri_gh);
348 335
@@ -423,9 +410,7 @@ int gfs2_ea_list(struct gfs2_inode *ip, struct gfs2_ea_request *er)
423 er->er_data_len = 0; 410 er->er_data_len = 0;
424 } 411 }
425 412
426 error = gfs2_glock_nq_init(ip->i_gl, 413 error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh);
427 LM_ST_SHARED, LM_FLAG_ANY,
428 &i_gh);
429 if (error) 414 if (error)
430 return error; 415 return error;
431 416
@@ -445,9 +430,9 @@ int gfs2_ea_list(struct gfs2_inode *ip, struct gfs2_ea_request *er)
445/** 430/**
446 * ea_get_unstuffed - actually copies the unstuffed data into the 431 * ea_get_unstuffed - actually copies the unstuffed data into the
447 * request buffer 432 * request buffer
448 * @ip: 433 * @ip: The GFS2 inode
449 * @ea: 434 * @ea: The extended attribute header structure
450 * @data: 435 * @data: The data to be copied
451 * 436 *
452 * Returns: errno 437 * Returns: errno
453 */ 438 */
@@ -492,8 +477,7 @@ static int ea_get_unstuffed(struct gfs2_inode *ip, struct gfs2_ea_header *ea,
492 goto out; 477 goto out;
493 } 478 }
494 479
495 memcpy(data, 480 memcpy(data, bh[x]->b_data + sizeof(struct gfs2_meta_header),
496 bh[x]->b_data + sizeof(struct gfs2_meta_header),
497 (sdp->sd_jbsize > amount) ? amount : sdp->sd_jbsize); 481 (sdp->sd_jbsize > amount) ? amount : sdp->sd_jbsize);
498 482
499 amount -= sdp->sd_jbsize; 483 amount -= sdp->sd_jbsize;
@@ -511,9 +495,7 @@ int gfs2_ea_get_copy(struct gfs2_inode *ip, struct gfs2_ea_location *el,
511 char *data) 495 char *data)
512{ 496{
513 if (GFS2_EA_IS_STUFFED(el->el_ea)) { 497 if (GFS2_EA_IS_STUFFED(el->el_ea)) {
514 memcpy(data, 498 memcpy(data, GFS2_EA2DATA(el->el_ea), GFS2_EA_DATA_LEN(el->el_ea));
515 GFS2_EA2DATA(el->el_ea),
516 GFS2_EA_DATA_LEN(el->el_ea));
517 return 0; 499 return 0;
518 } else 500 } else
519 return ea_get_unstuffed(ip, el->el_ea, data); 501 return ea_get_unstuffed(ip, el->el_ea, data);
@@ -521,8 +503,8 @@ int gfs2_ea_get_copy(struct gfs2_inode *ip, struct gfs2_ea_location *el,
521 503
522/** 504/**
523 * gfs2_ea_get_i - 505 * gfs2_ea_get_i -
524 * @ip: 506 * @ip: The GFS2 inode
525 * @er: 507 * @er: The request structure
526 * 508 *
527 * Returns: actual size of data on success, -errno on error 509 * Returns: actual size of data on success, -errno on error
528 */ 510 */
@@ -557,8 +539,8 @@ int gfs2_ea_get_i(struct gfs2_inode *ip, struct gfs2_ea_request *er)
557 539
558/** 540/**
559 * gfs2_ea_get - 541 * gfs2_ea_get -
560 * @ip: 542 * @ip: The GFS2 inode
561 * @er: 543 * @er: The request structure
562 * 544 *
563 * Returns: actual size of data on success, -errno on error 545 * Returns: actual size of data on success, -errno on error
564 */ 546 */
@@ -576,9 +558,7 @@ int gfs2_ea_get(struct gfs2_inode *ip, struct gfs2_ea_request *er)
576 er->er_data_len = 0; 558 er->er_data_len = 0;
577 } 559 }
578 560
579 error = gfs2_glock_nq_init(ip->i_gl, 561 error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh);
580 LM_ST_SHARED, LM_FLAG_ANY,
581 &i_gh);
582 if (error) 562 if (error)
583 return error; 563 return error;
584 564
@@ -592,7 +572,7 @@ int gfs2_ea_get(struct gfs2_inode *ip, struct gfs2_ea_request *er)
592/** 572/**
593 * ea_alloc_blk - allocates a new block for extended attributes. 573 * ea_alloc_blk - allocates a new block for extended attributes.
594 * @ip: A pointer to the inode that's getting extended attributes 574 * @ip: A pointer to the inode that's getting extended attributes
595 * @bhp: 575 * @bhp: Pointer to pointer to a struct buffer_head
596 * 576 *
597 * Returns: errno 577 * Returns: errno
598 */ 578 */
@@ -624,8 +604,8 @@ static int ea_alloc_blk(struct gfs2_inode *ip, struct buffer_head **bhp)
624/** 604/**
625 * ea_write - writes the request info to an ea, creating new blocks if 605 * ea_write - writes the request info to an ea, creating new blocks if
626 * necessary 606 * necessary
627 * @ip: inode that is being modified 607 * @ip: inode that is being modified
628 * @ea: the location of the new ea in a block 608 * @ea: the location of the new ea in a block
629 * @er: the write request 609 * @er: the write request
630 * 610 *
631 * Note: does not update ea_rec_len or the GFS2_EAFLAG_LAST bin of ea_flags 611 * Note: does not update ea_rec_len or the GFS2_EAFLAG_LAST bin of ea_flags
@@ -669,14 +649,14 @@ static int ea_write(struct gfs2_inode *ip, struct gfs2_ea_header *ea,
669 649
670 ip->i_di.di_blocks++; 650 ip->i_di.di_blocks++;
671 651
672 copy = (data_len > sdp->sd_jbsize) ? sdp->sd_jbsize : 652 copy = data_len > sdp->sd_jbsize ? sdp->sd_jbsize :
673 data_len; 653 data_len;
674 memcpy(bh->b_data + mh_size, data, copy); 654 memcpy(bh->b_data + mh_size, data, copy);
675 if (copy < sdp->sd_jbsize) 655 if (copy < sdp->sd_jbsize)
676 memset(bh->b_data + mh_size + copy, 0, 656 memset(bh->b_data + mh_size + copy, 0,
677 sdp->sd_jbsize - copy); 657 sdp->sd_jbsize - copy);
678 658
679 *dataptr++ = cpu_to_be64((u64)bh->b_blocknr); 659 *dataptr++ = cpu_to_be64(bh->b_blocknr);
680 data += copy; 660 data += copy;
681 data_len -= copy; 661 data_len -= copy;
682 662
@@ -690,13 +670,11 @@ static int ea_write(struct gfs2_inode *ip, struct gfs2_ea_header *ea,
690} 670}
691 671
692typedef int (*ea_skeleton_call_t) (struct gfs2_inode *ip, 672typedef int (*ea_skeleton_call_t) (struct gfs2_inode *ip,
693 struct gfs2_ea_request *er, 673 struct gfs2_ea_request *er, void *private);
694 void *private);
695 674
696static int ea_alloc_skeleton(struct gfs2_inode *ip, struct gfs2_ea_request *er, 675static int ea_alloc_skeleton(struct gfs2_inode *ip, struct gfs2_ea_request *er,
697 unsigned int blks, 676 unsigned int blks,
698 ea_skeleton_call_t skeleton_call, 677 ea_skeleton_call_t skeleton_call, void *private)
699 void *private)
700{ 678{
701 struct gfs2_alloc *al; 679 struct gfs2_alloc *al;
702 struct buffer_head *dibh; 680 struct buffer_head *dibh;
@@ -1013,7 +991,7 @@ static int ea_set_block(struct gfs2_inode *ip, struct gfs2_ea_request *er,
1013 goto out; 991 goto out;
1014 992
1015 if (private) 993 if (private)
1016 ea_set_remove_stuffed(ip, (struct gfs2_ea_location *)private); 994 ea_set_remove_stuffed(ip, private);
1017 995
1018out: 996out:
1019 brelse(indbh); 997 brelse(indbh);
@@ -1101,8 +1079,7 @@ int gfs2_ea_set(struct gfs2_inode *ip, struct gfs2_ea_request *er)
1101 struct gfs2_holder i_gh; 1079 struct gfs2_holder i_gh;
1102 int error; 1080 int error;
1103 1081
1104 if (!er->er_name_len || 1082 if (!er->er_name_len || er->er_name_len > GFS2_EA_MAX_NAME_LEN)
1105 er->er_name_len > GFS2_EA_MAX_NAME_LEN)
1106 return -EINVAL; 1083 return -EINVAL;
1107 if (!er->er_data || !er->er_data_len) { 1084 if (!er->er_data || !er->er_data_len) {
1108 er->er_data = NULL; 1085 er->er_data = NULL;
@@ -1264,8 +1241,7 @@ static int ea_acl_chmod_unstuffed(struct gfs2_inode *ip,
1264 1241
1265 gfs2_trans_add_bh(ip->i_gl, bh[x], 1); 1242 gfs2_trans_add_bh(ip->i_gl, bh[x], 1);
1266 1243
1267 memcpy(bh[x]->b_data + sizeof(struct gfs2_meta_header), 1244 memcpy(bh[x]->b_data + sizeof(struct gfs2_meta_header), data,
1268 data,
1269 (sdp->sd_jbsize > amount) ? amount : sdp->sd_jbsize); 1245 (sdp->sd_jbsize > amount) ? amount : sdp->sd_jbsize);
1270 1246
1271 amount -= sdp->sd_jbsize; 1247 amount -= sdp->sd_jbsize;
@@ -1296,8 +1272,7 @@ int gfs2_ea_acl_chmod(struct gfs2_inode *ip, struct gfs2_ea_location *el,
1296 return error; 1272 return error;
1297 1273
1298 gfs2_trans_add_bh(ip->i_gl, el->el_bh, 1); 1274 gfs2_trans_add_bh(ip->i_gl, el->el_bh, 1);
1299 memcpy(GFS2_EA2DATA(el->el_ea), 1275 memcpy(GFS2_EA2DATA(el->el_ea), data,
1300 data,
1301 GFS2_EA_DATA_LEN(el->el_ea)); 1276 GFS2_EA_DATA_LEN(el->el_ea));
1302 } else 1277 } else
1303 error = ea_acl_chmod_unstuffed(ip, el->el_ea, data); 1278 error = ea_acl_chmod_unstuffed(ip, el->el_ea, data);
@@ -1382,9 +1357,8 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip)
1382 if (error) 1357 if (error)
1383 goto out_rlist_free; 1358 goto out_rlist_free;
1384 1359
1385 error = gfs2_trans_begin(sdp, rg_blocks + RES_DINODE + 1360 error = gfs2_trans_begin(sdp, rg_blocks + RES_DINODE + RES_INDIRECT +
1386 RES_INDIRECT + RES_STATFS + 1361 RES_STATFS + RES_QUOTA, blks);
1387 RES_QUOTA, blks);
1388 if (error) 1362 if (error)
1389 goto out_gunlock; 1363 goto out_gunlock;
1390 1364
@@ -1457,8 +1431,8 @@ static int ea_dealloc_block(struct gfs2_inode *ip)
1457 if (error) 1431 if (error)
1458 return error; 1432 return error;
1459 1433
1460 error = gfs2_trans_begin(sdp, RES_RG_BIT + RES_DINODE + 1434 error = gfs2_trans_begin(sdp, RES_RG_BIT + RES_DINODE + RES_STATFS +
1461 RES_STATFS + RES_QUOTA, 1); 1435 RES_QUOTA, 1);
1462 if (error) 1436 if (error)
1463 goto out_gunlock; 1437 goto out_gunlock;
1464 1438
diff --git a/fs/gfs2/eattr.h b/fs/gfs2/eattr.h
index cb7c2d846765..ffa65947d686 100644
--- a/fs/gfs2/eattr.h
+++ b/fs/gfs2/eattr.h
@@ -46,7 +46,7 @@ ALIGN(sizeof(struct gfs2_ea_header) + (er)->er_name_len + \
46#define GFS2_ERF_MODE 0x80000000 46#define GFS2_ERF_MODE 0x80000000
47 47
48struct gfs2_ea_request { 48struct gfs2_ea_request {
49 char *er_name; 49 const char *er_name;
50 char *er_data; 50 char *er_data;
51 unsigned int er_name_len; 51 unsigned int er_name_len;
52 unsigned int er_data_len; 52 unsigned int er_data_len;
@@ -87,13 +87,13 @@ static inline unsigned int gfs2_ea_strlen(struct gfs2_ea_header *ea)
87{ 87{
88 switch (ea->ea_type) { 88 switch (ea->ea_type) {
89 case GFS2_EATYPE_USR: 89 case GFS2_EATYPE_USR:
90 return (5 + (ea->ea_name_len + 1)); 90 return 5 + ea->ea_name_len + 1;
91 case GFS2_EATYPE_SYS: 91 case GFS2_EATYPE_SYS:
92 return (7 + (ea->ea_name_len + 1)); 92 return 7 + ea->ea_name_len + 1;
93 case GFS2_EATYPE_SECURITY: 93 case GFS2_EATYPE_SECURITY:
94 return (9 + (ea->ea_name_len + 1)); 94 return 9 + ea->ea_name_len + 1;
95 default: 95 default:
96 return (0); 96 return 0;
97 } 97 }
98} 98}
99 99