diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-24 20:57:05 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-24 20:57:05 -0400 |
commit | 801b03653fc04de2cc5bc83c06de504d41345b63 (patch) | |
tree | e77de2bc0198d82c5286a8f28f58cd0945212880 /fs/gfs2/inode.c | |
parent | 614a6d4341b3760ca98a1c2c09141b71db5d1e90 (diff) | |
parent | 15e1c960227dc22d976c270fc854dfe363c04bbd (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-3.0-nmw
Pull GFS2 updates from Steven Whitehouse.
* git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-3.0-nmw:
GFS2: Eliminate 64-bit divides
GFS2: Reduce file fragmentation
GFS2: kernel panic with small gfs2 filesystems - 1 RG
GFS2: Fixing double brelse'ing bh allocated in gfs2_meta_read when EIO occurs
GFS2: Combine functions get_local_rgrp and gfs2_inplace_reserve
GFS2: Add kobject release method
GFS2: Size seq_file buffer more carefully
GFS2: Use seq_vprintf for glocks debugfs file
seq_file: Add seq_vprintf function and export it
GFS2: Use lvbs for storing rgrp information with mount option
GFS2: Cache last hash bucket for glock seq_files
GFS2: Increase buffer size for glocks and glstats debugfs files
GFS2: Fix error handling when reading an invalid block from the journal
GFS2: Add "top dir" flag support
GFS2: Fold quota data into the reservations struct
GFS2: Extend the life of the reservations
Diffstat (limited to 'fs/gfs2/inode.c')
-rw-r--r-- | fs/gfs2/inode.c | 94 |
1 files changed, 49 insertions, 45 deletions
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 867674785fcf..4ce22e547308 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
@@ -521,12 +521,13 @@ static int make_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | |||
521 | int error; | 521 | int error; |
522 | 522 | ||
523 | munge_mode_uid_gid(dip, &mode, &uid, &gid); | 523 | munge_mode_uid_gid(dip, &mode, &uid, &gid); |
524 | if (!gfs2_qadata_get(dip)) | 524 | error = gfs2_rindex_update(sdp); |
525 | return -ENOMEM; | 525 | if (error) |
526 | return error; | ||
526 | 527 | ||
527 | error = gfs2_quota_lock(dip, uid, gid); | 528 | error = gfs2_quota_lock(dip, uid, gid); |
528 | if (error) | 529 | if (error) |
529 | goto out; | 530 | return error; |
530 | 531 | ||
531 | error = gfs2_quota_check(dip, uid, gid); | 532 | error = gfs2_quota_check(dip, uid, gid); |
532 | if (error) | 533 | if (error) |
@@ -542,8 +543,6 @@ static int make_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | |||
542 | 543 | ||
543 | out_quota: | 544 | out_quota: |
544 | gfs2_quota_unlock(dip); | 545 | gfs2_quota_unlock(dip); |
545 | out: | ||
546 | gfs2_qadata_put(dip); | ||
547 | return error; | 546 | return error; |
548 | } | 547 | } |
549 | 548 | ||
@@ -551,14 +550,13 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name, | |||
551 | struct gfs2_inode *ip) | 550 | struct gfs2_inode *ip) |
552 | { | 551 | { |
553 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 552 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
554 | struct gfs2_qadata *qa; | ||
555 | int alloc_required; | 553 | int alloc_required; |
556 | struct buffer_head *dibh; | 554 | struct buffer_head *dibh; |
557 | int error; | 555 | int error; |
558 | 556 | ||
559 | qa = gfs2_qadata_get(dip); | 557 | error = gfs2_rindex_update(sdp); |
560 | if (!qa) | 558 | if (error) |
561 | return -ENOMEM; | 559 | return error; |
562 | 560 | ||
563 | error = gfs2_quota_lock(dip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); | 561 | error = gfs2_quota_lock(dip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); |
564 | if (error) | 562 | if (error) |
@@ -605,13 +603,13 @@ fail_end_trans: | |||
605 | gfs2_trans_end(sdp); | 603 | gfs2_trans_end(sdp); |
606 | 604 | ||
607 | fail_ipreserv: | 605 | fail_ipreserv: |
608 | gfs2_inplace_release(dip); | 606 | if (alloc_required) |
607 | gfs2_inplace_release(dip); | ||
609 | 608 | ||
610 | fail_quota_locks: | 609 | fail_quota_locks: |
611 | gfs2_quota_unlock(dip); | 610 | gfs2_quota_unlock(dip); |
612 | 611 | ||
613 | fail: | 612 | fail: |
614 | gfs2_qadata_put(dip); | ||
615 | return error; | 613 | return error; |
616 | } | 614 | } |
617 | 615 | ||
@@ -657,7 +655,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, | |||
657 | const struct qstr *name = &dentry->d_name; | 655 | const struct qstr *name = &dentry->d_name; |
658 | struct gfs2_holder ghs[2]; | 656 | struct gfs2_holder ghs[2]; |
659 | struct inode *inode = NULL; | 657 | struct inode *inode = NULL; |
660 | struct gfs2_inode *dip = GFS2_I(dir); | 658 | struct gfs2_inode *dip = GFS2_I(dir), *ip; |
661 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 659 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
662 | struct gfs2_inum_host inum = { .no_addr = 0, .no_formal_ino = 0 }; | 660 | struct gfs2_inum_host inum = { .no_addr = 0, .no_formal_ino = 0 }; |
663 | int error; | 661 | int error; |
@@ -667,6 +665,15 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, | |||
667 | if (!name->len || name->len > GFS2_FNAMESIZE) | 665 | if (!name->len || name->len > GFS2_FNAMESIZE) |
668 | return -ENAMETOOLONG; | 666 | return -ENAMETOOLONG; |
669 | 667 | ||
668 | /* We need a reservation to allocate the new dinode block. The | ||
669 | directory ip temporarily points to the reservation, but this is | ||
670 | being done to get a set of contiguous blocks for the new dinode. | ||
671 | Since this is a create, we don't have a sizehint yet, so it will | ||
672 | have to use the minimum reservation size. */ | ||
673 | error = gfs2_rs_alloc(dip); | ||
674 | if (error) | ||
675 | return error; | ||
676 | |||
670 | error = gfs2_glock_nq_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); | 677 | error = gfs2_glock_nq_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); |
671 | if (error) | 678 | if (error) |
672 | goto fail; | 679 | goto fail; |
@@ -700,19 +707,29 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, | |||
700 | if (IS_ERR(inode)) | 707 | if (IS_ERR(inode)) |
701 | goto fail_gunlock2; | 708 | goto fail_gunlock2; |
702 | 709 | ||
703 | error = gfs2_inode_refresh(GFS2_I(inode)); | 710 | ip = GFS2_I(inode); |
711 | error = gfs2_inode_refresh(ip); | ||
704 | if (error) | 712 | if (error) |
705 | goto fail_gunlock2; | 713 | goto fail_gunlock2; |
706 | 714 | ||
715 | /* The newly created inode needs a reservation so it can allocate | ||
716 | xattrs. At the same time, we want new blocks allocated to the new | ||
717 | dinode to be as contiguous as possible. Since we allocated the | ||
718 | dinode block under the directory's reservation, we transfer | ||
719 | ownership of that reservation to the new inode. The directory | ||
720 | doesn't need a reservation unless it needs a new allocation. */ | ||
721 | ip->i_res = dip->i_res; | ||
722 | dip->i_res = NULL; | ||
723 | |||
707 | error = gfs2_acl_create(dip, inode); | 724 | error = gfs2_acl_create(dip, inode); |
708 | if (error) | 725 | if (error) |
709 | goto fail_gunlock2; | 726 | goto fail_gunlock2; |
710 | 727 | ||
711 | error = gfs2_security_init(dip, GFS2_I(inode), name); | 728 | error = gfs2_security_init(dip, ip, name); |
712 | if (error) | 729 | if (error) |
713 | goto fail_gunlock2; | 730 | goto fail_gunlock2; |
714 | 731 | ||
715 | error = link_dinode(dip, name, GFS2_I(inode)); | 732 | error = link_dinode(dip, name, ip); |
716 | if (error) | 733 | if (error) |
717 | goto fail_gunlock2; | 734 | goto fail_gunlock2; |
718 | 735 | ||
@@ -722,10 +739,9 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, | |||
722 | gfs2_trans_end(sdp); | 739 | gfs2_trans_end(sdp); |
723 | /* Check if we reserved space in the rgrp. Function link_dinode may | 740 | /* Check if we reserved space in the rgrp. Function link_dinode may |
724 | not, depending on whether alloc is required. */ | 741 | not, depending on whether alloc is required. */ |
725 | if (dip->i_res) | 742 | if (gfs2_mb_reserved(dip)) |
726 | gfs2_inplace_release(dip); | 743 | gfs2_inplace_release(dip); |
727 | gfs2_quota_unlock(dip); | 744 | gfs2_quota_unlock(dip); |
728 | gfs2_qadata_put(dip); | ||
729 | mark_inode_dirty(inode); | 745 | mark_inode_dirty(inode); |
730 | gfs2_glock_dq_uninit_m(2, ghs); | 746 | gfs2_glock_dq_uninit_m(2, ghs); |
731 | d_instantiate(dentry, inode); | 747 | d_instantiate(dentry, inode); |
@@ -740,6 +756,7 @@ fail_gunlock: | |||
740 | iput(inode); | 756 | iput(inode); |
741 | } | 757 | } |
742 | fail: | 758 | fail: |
759 | gfs2_rs_delete(dip); | ||
743 | if (bh) | 760 | if (bh) |
744 | brelse(bh); | 761 | brelse(bh); |
745 | return error; | 762 | return error; |
@@ -816,6 +833,10 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir, | |||
816 | if (S_ISDIR(inode->i_mode)) | 833 | if (S_ISDIR(inode->i_mode)) |
817 | return -EPERM; | 834 | return -EPERM; |
818 | 835 | ||
836 | error = gfs2_rs_alloc(dip); | ||
837 | if (error) | ||
838 | return error; | ||
839 | |||
819 | gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); | 840 | gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); |
820 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1); | 841 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1); |
821 | 842 | ||
@@ -867,16 +888,9 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir, | |||
867 | error = 0; | 888 | error = 0; |
868 | 889 | ||
869 | if (alloc_required) { | 890 | if (alloc_required) { |
870 | struct gfs2_qadata *qa = gfs2_qadata_get(dip); | ||
871 | |||
872 | if (!qa) { | ||
873 | error = -ENOMEM; | ||
874 | goto out_gunlock; | ||
875 | } | ||
876 | |||
877 | error = gfs2_quota_lock_check(dip); | 891 | error = gfs2_quota_lock_check(dip); |
878 | if (error) | 892 | if (error) |
879 | goto out_alloc; | 893 | goto out_gunlock; |
880 | 894 | ||
881 | error = gfs2_inplace_reserve(dip, sdp->sd_max_dirres); | 895 | error = gfs2_inplace_reserve(dip, sdp->sd_max_dirres); |
882 | if (error) | 896 | if (error) |
@@ -919,9 +933,6 @@ out_ipres: | |||
919 | out_gunlock_q: | 933 | out_gunlock_q: |
920 | if (alloc_required) | 934 | if (alloc_required) |
921 | gfs2_quota_unlock(dip); | 935 | gfs2_quota_unlock(dip); |
922 | out_alloc: | ||
923 | if (alloc_required) | ||
924 | gfs2_qadata_put(dip); | ||
925 | out_gunlock: | 936 | out_gunlock: |
926 | gfs2_glock_dq(ghs + 1); | 937 | gfs2_glock_dq(ghs + 1); |
927 | out_child: | 938 | out_child: |
@@ -1231,6 +1242,10 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
1231 | if (error) | 1242 | if (error) |
1232 | return error; | 1243 | return error; |
1233 | 1244 | ||
1245 | error = gfs2_rs_alloc(ndip); | ||
1246 | if (error) | ||
1247 | return error; | ||
1248 | |||
1234 | if (odip != ndip) { | 1249 | if (odip != ndip) { |
1235 | error = gfs2_glock_nq_init(sdp->sd_rename_gl, LM_ST_EXCLUSIVE, | 1250 | error = gfs2_glock_nq_init(sdp->sd_rename_gl, LM_ST_EXCLUSIVE, |
1236 | 0, &r_gh); | 1251 | 0, &r_gh); |
@@ -1354,16 +1369,9 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
1354 | goto out_gunlock; | 1369 | goto out_gunlock; |
1355 | 1370 | ||
1356 | if (alloc_required) { | 1371 | if (alloc_required) { |
1357 | struct gfs2_qadata *qa = gfs2_qadata_get(ndip); | ||
1358 | |||
1359 | if (!qa) { | ||
1360 | error = -ENOMEM; | ||
1361 | goto out_gunlock; | ||
1362 | } | ||
1363 | |||
1364 | error = gfs2_quota_lock_check(ndip); | 1372 | error = gfs2_quota_lock_check(ndip); |
1365 | if (error) | 1373 | if (error) |
1366 | goto out_alloc; | 1374 | goto out_gunlock; |
1367 | 1375 | ||
1368 | error = gfs2_inplace_reserve(ndip, sdp->sd_max_dirres); | 1376 | error = gfs2_inplace_reserve(ndip, sdp->sd_max_dirres); |
1369 | if (error) | 1377 | if (error) |
@@ -1424,9 +1432,6 @@ out_ipreserv: | |||
1424 | out_gunlock_q: | 1432 | out_gunlock_q: |
1425 | if (alloc_required) | 1433 | if (alloc_required) |
1426 | gfs2_quota_unlock(ndip); | 1434 | gfs2_quota_unlock(ndip); |
1427 | out_alloc: | ||
1428 | if (alloc_required) | ||
1429 | gfs2_qadata_put(ndip); | ||
1430 | out_gunlock: | 1435 | out_gunlock: |
1431 | while (x--) { | 1436 | while (x--) { |
1432 | gfs2_glock_dq(ghs + x); | 1437 | gfs2_glock_dq(ghs + x); |
@@ -1587,12 +1592,9 @@ static int setattr_chown(struct inode *inode, struct iattr *attr) | |||
1587 | if (!(attr->ia_valid & ATTR_GID) || ogid == ngid) | 1592 | if (!(attr->ia_valid & ATTR_GID) || ogid == ngid) |
1588 | ogid = ngid = NO_QUOTA_CHANGE; | 1593 | ogid = ngid = NO_QUOTA_CHANGE; |
1589 | 1594 | ||
1590 | if (!gfs2_qadata_get(ip)) | ||
1591 | return -ENOMEM; | ||
1592 | |||
1593 | error = gfs2_quota_lock(ip, nuid, ngid); | 1595 | error = gfs2_quota_lock(ip, nuid, ngid); |
1594 | if (error) | 1596 | if (error) |
1595 | goto out_alloc; | 1597 | return error; |
1596 | 1598 | ||
1597 | if (ouid != NO_QUOTA_CHANGE || ogid != NO_QUOTA_CHANGE) { | 1599 | if (ouid != NO_QUOTA_CHANGE || ogid != NO_QUOTA_CHANGE) { |
1598 | error = gfs2_quota_check(ip, nuid, ngid); | 1600 | error = gfs2_quota_check(ip, nuid, ngid); |
@@ -1618,8 +1620,6 @@ out_end_trans: | |||
1618 | gfs2_trans_end(sdp); | 1620 | gfs2_trans_end(sdp); |
1619 | out_gunlock_q: | 1621 | out_gunlock_q: |
1620 | gfs2_quota_unlock(ip); | 1622 | gfs2_quota_unlock(ip); |
1621 | out_alloc: | ||
1622 | gfs2_qadata_put(ip); | ||
1623 | return error; | 1623 | return error; |
1624 | } | 1624 | } |
1625 | 1625 | ||
@@ -1641,6 +1641,10 @@ static int gfs2_setattr(struct dentry *dentry, struct iattr *attr) | |||
1641 | struct gfs2_holder i_gh; | 1641 | struct gfs2_holder i_gh; |
1642 | int error; | 1642 | int error; |
1643 | 1643 | ||
1644 | error = gfs2_rs_alloc(ip); | ||
1645 | if (error) | ||
1646 | return error; | ||
1647 | |||
1644 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh); | 1648 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh); |
1645 | if (error) | 1649 | if (error) |
1646 | return error; | 1650 | return error; |