aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/xattr.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /fs/gfs2/xattr.c
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'fs/gfs2/xattr.c')
-rw-r--r--fs/gfs2/xattr.c192
1 files changed, 118 insertions, 74 deletions
diff --git a/fs/gfs2/xattr.c b/fs/gfs2/xattr.c
index 76c144b3c9b..439b61c0326 100644
--- a/fs/gfs2/xattr.c
+++ b/fs/gfs2/xattr.c
@@ -238,10 +238,6 @@ static int ea_dealloc_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh,
238 unsigned int x; 238 unsigned int x;
239 int error; 239 int error;
240 240
241 error = gfs2_rindex_update(sdp);
242 if (error)
243 return error;
244
245 if (GFS2_EA_IS_STUFFED(ea)) 241 if (GFS2_EA_IS_STUFFED(ea))
246 return 0; 242 return 0;
247 243
@@ -255,7 +251,7 @@ static int ea_dealloc_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh,
255 if (!blks) 251 if (!blks)
256 return 0; 252 return 0;
257 253
258 rgd = gfs2_blk2rgrpd(sdp, bn, 1); 254 rgd = gfs2_blk2rgrpd(sdp, bn);
259 if (!rgd) { 255 if (!rgd) {
260 gfs2_consist_inode(ip); 256 gfs2_consist_inode(ip);
261 return -EIO; 257 return -EIO;
@@ -325,20 +321,29 @@ static int ea_remove_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh,
325 struct gfs2_ea_header *ea, 321 struct gfs2_ea_header *ea,
326 struct gfs2_ea_header *prev, int leave) 322 struct gfs2_ea_header *prev, int leave)
327{ 323{
324 struct gfs2_alloc *al;
328 int error; 325 int error;
329 326
330 error = gfs2_rindex_update(GFS2_SB(&ip->i_inode)); 327 al = gfs2_alloc_get(ip);
331 if (error) 328 if (!al)
332 return error; 329 return -ENOMEM;
333 330
334 error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); 331 error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE);
335 if (error) 332 if (error)
336 goto out_alloc; 333 goto out_alloc;
337 334
335 error = gfs2_rindex_hold(GFS2_SB(&ip->i_inode), &al->al_ri_gh);
336 if (error)
337 goto out_quota;
338
338 error = ea_dealloc_unstuffed(ip, bh, ea, prev, (leave) ? &error : NULL); 339 error = ea_dealloc_unstuffed(ip, bh, ea, prev, (leave) ? &error : NULL);
339 340
341 gfs2_glock_dq_uninit(&al->al_ri_gh);
342
343out_quota:
340 gfs2_quota_unhold(ip); 344 gfs2_quota_unhold(ip);
341out_alloc: 345out_alloc:
346 gfs2_alloc_put(ip);
342 return error; 347 return error;
343} 348}
344 349
@@ -448,18 +453,17 @@ ssize_t gfs2_listxattr(struct dentry *dentry, char *buffer, size_t size)
448} 453}
449 454
450/** 455/**
451 * ea_iter_unstuffed - copies the unstuffed xattr data to/from the 456 * ea_get_unstuffed - actually copies the unstuffed data into the
452 * request buffer 457 * request buffer
453 * @ip: The GFS2 inode 458 * @ip: The GFS2 inode
454 * @ea: The extended attribute header structure 459 * @ea: The extended attribute header structure
455 * @din: The data to be copied in 460 * @data: The data to be copied
456 * @dout: The data to be copied out (one of din,dout will be NULL)
457 * 461 *
458 * Returns: errno 462 * Returns: errno
459 */ 463 */
460 464
461static int gfs2_iter_unstuffed(struct gfs2_inode *ip, struct gfs2_ea_header *ea, 465static int ea_get_unstuffed(struct gfs2_inode *ip, struct gfs2_ea_header *ea,
462 const char *din, char *dout) 466 char *data)
463{ 467{
464 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); 468 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
465 struct buffer_head **bh; 469 struct buffer_head **bh;
@@ -468,8 +472,6 @@ static int gfs2_iter_unstuffed(struct gfs2_inode *ip, struct gfs2_ea_header *ea,
468 __be64 *dataptrs = GFS2_EA2DATAPTRS(ea); 472 __be64 *dataptrs = GFS2_EA2DATAPTRS(ea);
469 unsigned int x; 473 unsigned int x;
470 int error = 0; 474 int error = 0;
471 unsigned char *pos;
472 unsigned cp_size;
473 475
474 bh = kcalloc(nptrs, sizeof(struct buffer_head *), GFP_NOFS); 476 bh = kcalloc(nptrs, sizeof(struct buffer_head *), GFP_NOFS);
475 if (!bh) 477 if (!bh)
@@ -500,21 +502,12 @@ static int gfs2_iter_unstuffed(struct gfs2_inode *ip, struct gfs2_ea_header *ea,
500 goto out; 502 goto out;
501 } 503 }
502 504
503 pos = bh[x]->b_data + sizeof(struct gfs2_meta_header); 505 memcpy(data, bh[x]->b_data + sizeof(struct gfs2_meta_header),
504 cp_size = (sdp->sd_jbsize > amount) ? amount : sdp->sd_jbsize; 506 (sdp->sd_jbsize > amount) ? amount : sdp->sd_jbsize);
505
506 if (dout) {
507 memcpy(dout, pos, cp_size);
508 dout += sdp->sd_jbsize;
509 }
510
511 if (din) {
512 gfs2_trans_add_bh(ip->i_gl, bh[x], 1);
513 memcpy(pos, din, cp_size);
514 din += sdp->sd_jbsize;
515 }
516 507
517 amount -= sdp->sd_jbsize; 508 amount -= sdp->sd_jbsize;
509 data += sdp->sd_jbsize;
510
518 brelse(bh[x]); 511 brelse(bh[x]);
519 } 512 }
520 513
@@ -535,7 +528,7 @@ static int gfs2_ea_get_copy(struct gfs2_inode *ip, struct gfs2_ea_location *el,
535 memcpy(data, GFS2_EA2DATA(el->el_ea), len); 528 memcpy(data, GFS2_EA2DATA(el->el_ea), len);
536 return len; 529 return len;
537 } 530 }
538 ret = gfs2_iter_unstuffed(ip, el->el_ea, NULL, data); 531 ret = ea_get_unstuffed(ip, el->el_ea, data);
539 if (ret < 0) 532 if (ret < 0)
540 return ret; 533 return ret;
541 return len; 534 return len;
@@ -563,10 +556,9 @@ int gfs2_xattr_acl_get(struct gfs2_inode *ip, const char *name, char **ppdata)
563 goto out; 556 goto out;
564 557
565 error = gfs2_ea_get_copy(ip, &el, data, len); 558 error = gfs2_ea_get_copy(ip, &el, data, len);
566 if (error < 0) 559 if (error == 0)
567 kfree(data); 560 error = len;
568 else 561 *ppdata = data;
569 *ppdata = data;
570out: 562out:
571 brelse(el.el_bh); 563 brelse(el.el_bh);
572 return error; 564 return error;
@@ -624,7 +616,7 @@ static int ea_alloc_blk(struct gfs2_inode *ip, struct buffer_head **bhp)
624 u64 block; 616 u64 block;
625 int error; 617 int error;
626 618
627 error = gfs2_alloc_blocks(ip, &block, &n, 0, NULL); 619 error = gfs2_alloc_block(ip, &block, &n);
628 if (error) 620 if (error)
629 return error; 621 return error;
630 gfs2_trans_add_unrevoke(sdp, block, 1); 622 gfs2_trans_add_unrevoke(sdp, block, 1);
@@ -686,7 +678,7 @@ static int ea_write(struct gfs2_inode *ip, struct gfs2_ea_header *ea,
686 int mh_size = sizeof(struct gfs2_meta_header); 678 int mh_size = sizeof(struct gfs2_meta_header);
687 unsigned int n = 1; 679 unsigned int n = 1;
688 680
689 error = gfs2_alloc_blocks(ip, &block, &n, 0, NULL); 681 error = gfs2_alloc_block(ip, &block, &n);
690 if (error) 682 if (error)
691 return error; 683 return error;
692 gfs2_trans_add_unrevoke(sdp, block, 1); 684 gfs2_trans_add_unrevoke(sdp, block, 1);
@@ -723,23 +715,26 @@ static int ea_alloc_skeleton(struct gfs2_inode *ip, struct gfs2_ea_request *er,
723 unsigned int blks, 715 unsigned int blks,
724 ea_skeleton_call_t skeleton_call, void *private) 716 ea_skeleton_call_t skeleton_call, void *private)
725{ 717{
718 struct gfs2_alloc *al;
726 struct buffer_head *dibh; 719 struct buffer_head *dibh;
727 int error; 720 int error;
728 721
729 error = gfs2_rindex_update(GFS2_SB(&ip->i_inode)); 722 al = gfs2_alloc_get(ip);
730 if (error) 723 if (!al)
731 return error; 724 return -ENOMEM;
732 725
733 error = gfs2_quota_lock_check(ip); 726 error = gfs2_quota_lock_check(ip);
734 if (error) 727 if (error)
735 return error; 728 goto out;
729
730 al->al_requested = blks;
736 731
737 error = gfs2_inplace_reserve(ip, blks, 0); 732 error = gfs2_inplace_reserve(ip);
738 if (error) 733 if (error)
739 goto out_gunlock_q; 734 goto out_gunlock_q;
740 735
741 error = gfs2_trans_begin(GFS2_SB(&ip->i_inode), 736 error = gfs2_trans_begin(GFS2_SB(&ip->i_inode),
742 blks + gfs2_rg_blocks(ip, blks) + 737 blks + gfs2_rg_blocks(al) +
743 RES_DINODE + RES_STATFS + RES_QUOTA, 0); 738 RES_DINODE + RES_STATFS + RES_QUOTA, 0);
744 if (error) 739 if (error)
745 goto out_ipres; 740 goto out_ipres;
@@ -762,6 +757,8 @@ out_ipres:
762 gfs2_inplace_release(ip); 757 gfs2_inplace_release(ip);
763out_gunlock_q: 758out_gunlock_q:
764 gfs2_quota_unlock(ip); 759 gfs2_quota_unlock(ip);
760out:
761 gfs2_alloc_put(ip);
765 return error; 762 return error;
766} 763}
767 764
@@ -1001,7 +998,7 @@ static int ea_set_block(struct gfs2_inode *ip, struct gfs2_ea_request *er,
1001 } else { 998 } else {
1002 u64 blk; 999 u64 blk;
1003 unsigned int n = 1; 1000 unsigned int n = 1;
1004 error = gfs2_alloc_blocks(ip, &blk, &n, 0, NULL); 1001 error = gfs2_alloc_block(ip, &blk, &n);
1005 if (error) 1002 if (error)
1006 return error; 1003 return error;
1007 gfs2_trans_add_unrevoke(sdp, blk, 1); 1004 gfs2_trans_add_unrevoke(sdp, blk, 1);
@@ -1232,29 +1229,74 @@ static int gfs2_xattr_set(struct dentry *dentry, const char *name,
1232 size, flags, type); 1229 size, flags, type);
1233} 1230}
1234 1231
1235
1236static int ea_acl_chmod_unstuffed(struct gfs2_inode *ip, 1232static int ea_acl_chmod_unstuffed(struct gfs2_inode *ip,
1237 struct gfs2_ea_header *ea, char *data) 1233 struct gfs2_ea_header *ea, char *data)
1238{ 1234{
1239 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); 1235 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
1236 struct buffer_head **bh;
1240 unsigned int amount = GFS2_EA_DATA_LEN(ea); 1237 unsigned int amount = GFS2_EA_DATA_LEN(ea);
1241 unsigned int nptrs = DIV_ROUND_UP(amount, sdp->sd_jbsize); 1238 unsigned int nptrs = DIV_ROUND_UP(amount, sdp->sd_jbsize);
1242 int ret; 1239 __be64 *dataptrs = GFS2_EA2DATAPTRS(ea);
1240 unsigned int x;
1241 int error;
1243 1242
1244 ret = gfs2_trans_begin(sdp, nptrs + RES_DINODE, 0); 1243 bh = kcalloc(nptrs, sizeof(struct buffer_head *), GFP_NOFS);
1245 if (ret) 1244 if (!bh)
1246 return ret; 1245 return -ENOMEM;
1247 1246
1248 ret = gfs2_iter_unstuffed(ip, ea, data, NULL); 1247 error = gfs2_trans_begin(sdp, nptrs + RES_DINODE, 0);
1249 gfs2_trans_end(sdp); 1248 if (error)
1249 goto out;
1250
1251 for (x = 0; x < nptrs; x++) {
1252 error = gfs2_meta_read(ip->i_gl, be64_to_cpu(*dataptrs), 0,
1253 bh + x);
1254 if (error) {
1255 while (x--)
1256 brelse(bh[x]);
1257 goto fail;
1258 }
1259 dataptrs++;
1260 }
1250 1261
1251 return ret; 1262 for (x = 0; x < nptrs; x++) {
1263 error = gfs2_meta_wait(sdp, bh[x]);
1264 if (error) {
1265 for (; x < nptrs; x++)
1266 brelse(bh[x]);
1267 goto fail;
1268 }
1269 if (gfs2_metatype_check(sdp, bh[x], GFS2_METATYPE_ED)) {
1270 for (; x < nptrs; x++)
1271 brelse(bh[x]);
1272 error = -EIO;
1273 goto fail;
1274 }
1275
1276 gfs2_trans_add_bh(ip->i_gl, bh[x], 1);
1277
1278 memcpy(bh[x]->b_data + sizeof(struct gfs2_meta_header), data,
1279 (sdp->sd_jbsize > amount) ? amount : sdp->sd_jbsize);
1280
1281 amount -= sdp->sd_jbsize;
1282 data += sdp->sd_jbsize;
1283
1284 brelse(bh[x]);
1285 }
1286
1287out:
1288 kfree(bh);
1289 return error;
1290
1291fail:
1292 gfs2_trans_end(sdp);
1293 kfree(bh);
1294 return error;
1252} 1295}
1253 1296
1254int gfs2_xattr_acl_chmod(struct gfs2_inode *ip, struct iattr *attr, char *data) 1297int gfs2_xattr_acl_chmod(struct gfs2_inode *ip, struct iattr *attr, char *data)
1255{ 1298{
1256 struct inode *inode = &ip->i_inode; 1299 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
1257 struct gfs2_sbd *sdp = GFS2_SB(inode);
1258 struct gfs2_ea_location el; 1300 struct gfs2_ea_location el;
1259 int error; 1301 int error;
1260 1302
@@ -1277,7 +1319,7 @@ int gfs2_xattr_acl_chmod(struct gfs2_inode *ip, struct iattr *attr, char *data)
1277 if (error) 1319 if (error)
1278 return error; 1320 return error;
1279 1321
1280 error = gfs2_setattr_simple(inode, attr); 1322 error = gfs2_setattr_simple(ip, attr);
1281 gfs2_trans_end(sdp); 1323 gfs2_trans_end(sdp);
1282 return error; 1324 return error;
1283} 1325}
@@ -1295,10 +1337,6 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip)
1295 unsigned int x; 1337 unsigned int x;
1296 int error; 1338 int error;
1297 1339
1298 error = gfs2_rindex_update(sdp);
1299 if (error)
1300 return error;
1301
1302 memset(&rlist, 0, sizeof(struct gfs2_rgrp_list)); 1340 memset(&rlist, 0, sizeof(struct gfs2_rgrp_list));
1303 1341
1304 error = gfs2_meta_read(ip->i_gl, ip->i_eattr, DIO_WAIT, &indbh); 1342 error = gfs2_meta_read(ip->i_gl, ip->i_eattr, DIO_WAIT, &indbh);
@@ -1324,14 +1362,14 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip)
1324 blen++; 1362 blen++;
1325 else { 1363 else {
1326 if (bstart) 1364 if (bstart)
1327 gfs2_rlist_add(ip, &rlist, bstart); 1365 gfs2_rlist_add(sdp, &rlist, bstart);
1328 bstart = bn; 1366 bstart = bn;
1329 blen = 1; 1367 blen = 1;
1330 } 1368 }
1331 blks++; 1369 blks++;
1332 } 1370 }
1333 if (bstart) 1371 if (bstart)
1334 gfs2_rlist_add(ip, &rlist, bstart); 1372 gfs2_rlist_add(sdp, &rlist, bstart);
1335 else 1373 else
1336 goto out; 1374 goto out;
1337 1375
@@ -1403,22 +1441,19 @@ out:
1403static int ea_dealloc_block(struct gfs2_inode *ip) 1441static int ea_dealloc_block(struct gfs2_inode *ip)
1404{ 1442{
1405 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); 1443 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
1444 struct gfs2_alloc *al = ip->i_alloc;
1406 struct gfs2_rgrpd *rgd; 1445 struct gfs2_rgrpd *rgd;
1407 struct buffer_head *dibh; 1446 struct buffer_head *dibh;
1408 struct gfs2_holder gh;
1409 int error; 1447 int error;
1410 1448
1411 error = gfs2_rindex_update(sdp); 1449 rgd = gfs2_blk2rgrpd(sdp, ip->i_eattr);
1412 if (error)
1413 return error;
1414
1415 rgd = gfs2_blk2rgrpd(sdp, ip->i_eattr, 1);
1416 if (!rgd) { 1450 if (!rgd) {
1417 gfs2_consist_inode(ip); 1451 gfs2_consist_inode(ip);
1418 return -EIO; 1452 return -EIO;
1419 } 1453 }
1420 1454
1421 error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, &gh); 1455 error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0,
1456 &al->al_rgd_gh);
1422 if (error) 1457 if (error)
1423 return error; 1458 return error;
1424 1459
@@ -1442,7 +1477,7 @@ static int ea_dealloc_block(struct gfs2_inode *ip)
1442 gfs2_trans_end(sdp); 1477 gfs2_trans_end(sdp);
1443 1478
1444out_gunlock: 1479out_gunlock:
1445 gfs2_glock_dq_uninit(&gh); 1480 gfs2_glock_dq_uninit(&al->al_rgd_gh);
1446 return error; 1481 return error;
1447} 1482}
1448 1483
@@ -1455,30 +1490,39 @@ out_gunlock:
1455 1490
1456int gfs2_ea_dealloc(struct gfs2_inode *ip) 1491int gfs2_ea_dealloc(struct gfs2_inode *ip)
1457{ 1492{
1493 struct gfs2_alloc *al;
1458 int error; 1494 int error;
1459 1495
1460 error = gfs2_rindex_update(GFS2_SB(&ip->i_inode)); 1496 al = gfs2_alloc_get(ip);
1461 if (error) 1497 if (!al)
1462 return error; 1498 return -ENOMEM;
1463 1499
1464 error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); 1500 error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE);
1465 if (error) 1501 if (error)
1466 return error; 1502 goto out_alloc;
1467 1503
1468 error = ea_foreach(ip, ea_dealloc_unstuffed, NULL); 1504 error = gfs2_rindex_hold(GFS2_SB(&ip->i_inode), &al->al_ri_gh);
1469 if (error) 1505 if (error)
1470 goto out_quota; 1506 goto out_quota;
1471 1507
1508 error = ea_foreach(ip, ea_dealloc_unstuffed, NULL);
1509 if (error)
1510 goto out_rindex;
1511
1472 if (ip->i_diskflags & GFS2_DIF_EA_INDIRECT) { 1512 if (ip->i_diskflags & GFS2_DIF_EA_INDIRECT) {
1473 error = ea_dealloc_indirect(ip); 1513 error = ea_dealloc_indirect(ip);
1474 if (error) 1514 if (error)
1475 goto out_quota; 1515 goto out_rindex;
1476 } 1516 }
1477 1517
1478 error = ea_dealloc_block(ip); 1518 error = ea_dealloc_block(ip);
1479 1519
1520out_rindex:
1521 gfs2_glock_dq_uninit(&al->al_ri_gh);
1480out_quota: 1522out_quota:
1481 gfs2_quota_unhold(ip); 1523 gfs2_quota_unhold(ip);
1524out_alloc:
1525 gfs2_alloc_put(ip);
1482 return error; 1526 return error;
1483} 1527}
1484 1528