diff options
author | Steve French <sfrench@us.ibm.com> | 2007-07-18 20:38:57 -0400 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2007-07-18 20:38:57 -0400 |
commit | 1ff8392c32a2645d2665ca779ecb91bb29361c13 (patch) | |
tree | 860b95e9a499ade4060848740fc6ce1fbb4e4e8d /fs/gfs2 | |
parent | 70b315b0dd3879cb3ab8aadffb14f10b2d19b9c3 (diff) | |
parent | 5bae7ac9feba925fd0099057f6b23d7be80b7b41 (diff) |
Merge branch 'master' of /pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts:
fs/cifs/export.c
Diffstat (limited to 'fs/gfs2')
44 files changed, 1195 insertions, 788 deletions
diff --git a/fs/gfs2/Makefile b/fs/gfs2/Makefile index e3f1ada643ac..04ad0caebedb 100644 --- a/fs/gfs2/Makefile +++ b/fs/gfs2/Makefile | |||
@@ -1,7 +1,7 @@ | |||
1 | obj-$(CONFIG_GFS2_FS) += gfs2.o | 1 | obj-$(CONFIG_GFS2_FS) += gfs2.o |
2 | gfs2-y := acl.o bmap.o daemon.o dir.o eaops.o eattr.o glock.o \ | 2 | gfs2-y := acl.o bmap.o daemon.o dir.o eaops.o eattr.o glock.o \ |
3 | glops.o inode.o lm.o log.o lops.o locking.o main.o meta_io.o \ | 3 | glops.o inode.o lm.o log.o lops.o locking.o main.o meta_io.o \ |
4 | mount.o ondisk.o ops_address.o ops_dentry.o ops_export.o ops_file.o \ | 4 | mount.o ops_address.o ops_dentry.o ops_export.o ops_file.o \ |
5 | ops_fstype.o ops_inode.o ops_super.o ops_vm.o quota.o \ | 5 | ops_fstype.o ops_inode.o ops_super.o ops_vm.o quota.o \ |
6 | recovery.o rgrp.o super.o sys.o trans.o util.o | 6 | recovery.o rgrp.o super.o sys.o trans.o util.o |
7 | 7 | ||
diff --git a/fs/gfs2/acl.c b/fs/gfs2/acl.c index 6e80844367ee..1047a8c7226a 100644 --- a/fs/gfs2/acl.c +++ b/fs/gfs2/acl.c | |||
@@ -74,7 +74,7 @@ int gfs2_acl_validate_remove(struct gfs2_inode *ip, int access) | |||
74 | { | 74 | { |
75 | if (!GFS2_SB(&ip->i_inode)->sd_args.ar_posix_acl) | 75 | if (!GFS2_SB(&ip->i_inode)->sd_args.ar_posix_acl) |
76 | return -EOPNOTSUPP; | 76 | return -EOPNOTSUPP; |
77 | if (current->fsuid != ip->i_inode.i_uid && !capable(CAP_FOWNER)) | 77 | if (!is_owner_or_cap(&ip->i_inode)) |
78 | return -EPERM; | 78 | return -EPERM; |
79 | if (S_ISLNK(ip->i_inode.i_mode)) | 79 | if (S_ISLNK(ip->i_inode.i_mode)) |
80 | return -EOPNOTSUPP; | 80 | return -EOPNOTSUPP; |
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index c53a5d2d0590..cd805a66880d 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c | |||
@@ -718,7 +718,7 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh, | |||
718 | for (x = 0; x < rlist.rl_rgrps; x++) { | 718 | for (x = 0; x < rlist.rl_rgrps; x++) { |
719 | struct gfs2_rgrpd *rgd; | 719 | struct gfs2_rgrpd *rgd; |
720 | rgd = rlist.rl_ghs[x].gh_gl->gl_object; | 720 | rgd = rlist.rl_ghs[x].gh_gl->gl_object; |
721 | rg_blocks += rgd->rd_ri.ri_length; | 721 | rg_blocks += rgd->rd_length; |
722 | } | 722 | } |
723 | 723 | ||
724 | error = gfs2_glock_nq_m(rlist.rl_rgrps, rlist.rl_ghs); | 724 | error = gfs2_glock_nq_m(rlist.rl_rgrps, rlist.rl_ghs); |
@@ -772,7 +772,7 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh, | |||
772 | gfs2_free_data(ip, bstart, blen); | 772 | gfs2_free_data(ip, bstart, blen); |
773 | } | 773 | } |
774 | 774 | ||
775 | ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC; | 775 | ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; |
776 | 776 | ||
777 | gfs2_dinode_out(ip, dibh->b_data); | 777 | gfs2_dinode_out(ip, dibh->b_data); |
778 | 778 | ||
@@ -824,7 +824,7 @@ static int do_grow(struct gfs2_inode *ip, u64 size) | |||
824 | goto out_gunlock_q; | 824 | goto out_gunlock_q; |
825 | 825 | ||
826 | error = gfs2_trans_begin(sdp, | 826 | error = gfs2_trans_begin(sdp, |
827 | sdp->sd_max_height + al->al_rgd->rd_ri.ri_length + | 827 | sdp->sd_max_height + al->al_rgd->rd_length + |
828 | RES_JDATA + RES_DINODE + RES_STATFS + RES_QUOTA, 0); | 828 | RES_JDATA + RES_DINODE + RES_STATFS + RES_QUOTA, 0); |
829 | if (error) | 829 | if (error) |
830 | goto out_ipres; | 830 | goto out_ipres; |
@@ -847,7 +847,7 @@ static int do_grow(struct gfs2_inode *ip, u64 size) | |||
847 | } | 847 | } |
848 | 848 | ||
849 | ip->i_di.di_size = size; | 849 | ip->i_di.di_size = size; |
850 | ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC; | 850 | ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; |
851 | 851 | ||
852 | error = gfs2_meta_inode_buffer(ip, &dibh); | 852 | error = gfs2_meta_inode_buffer(ip, &dibh); |
853 | if (error) | 853 | if (error) |
@@ -885,7 +885,6 @@ static int gfs2_block_truncate_page(struct address_space *mapping) | |||
885 | unsigned blocksize, iblock, length, pos; | 885 | unsigned blocksize, iblock, length, pos; |
886 | struct buffer_head *bh; | 886 | struct buffer_head *bh; |
887 | struct page *page; | 887 | struct page *page; |
888 | void *kaddr; | ||
889 | int err; | 888 | int err; |
890 | 889 | ||
891 | page = grab_cache_page(mapping, index); | 890 | page = grab_cache_page(mapping, index); |
@@ -928,15 +927,13 @@ static int gfs2_block_truncate_page(struct address_space *mapping) | |||
928 | /* Uhhuh. Read error. Complain and punt. */ | 927 | /* Uhhuh. Read error. Complain and punt. */ |
929 | if (!buffer_uptodate(bh)) | 928 | if (!buffer_uptodate(bh)) |
930 | goto unlock; | 929 | goto unlock; |
930 | err = 0; | ||
931 | } | 931 | } |
932 | 932 | ||
933 | if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED || gfs2_is_jdata(ip)) | 933 | if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED || gfs2_is_jdata(ip)) |
934 | gfs2_trans_add_bh(ip->i_gl, bh, 0); | 934 | gfs2_trans_add_bh(ip->i_gl, bh, 0); |
935 | 935 | ||
936 | kaddr = kmap_atomic(page, KM_USER0); | 936 | zero_user_page(page, offset, length, KM_USER0); |
937 | memset(kaddr + offset, 0, length); | ||
938 | flush_dcache_page(page); | ||
939 | kunmap_atomic(kaddr, KM_USER0); | ||
940 | 937 | ||
941 | unlock: | 938 | unlock: |
942 | unlock_page(page); | 939 | unlock_page(page); |
@@ -962,7 +959,7 @@ static int trunc_start(struct gfs2_inode *ip, u64 size) | |||
962 | 959 | ||
963 | if (gfs2_is_stuffed(ip)) { | 960 | if (gfs2_is_stuffed(ip)) { |
964 | ip->i_di.di_size = size; | 961 | ip->i_di.di_size = size; |
965 | ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC; | 962 | ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; |
966 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 963 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
967 | gfs2_dinode_out(ip, dibh->b_data); | 964 | gfs2_dinode_out(ip, dibh->b_data); |
968 | gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode) + size); | 965 | gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode) + size); |
@@ -974,7 +971,7 @@ static int trunc_start(struct gfs2_inode *ip, u64 size) | |||
974 | 971 | ||
975 | if (!error) { | 972 | if (!error) { |
976 | ip->i_di.di_size = size; | 973 | ip->i_di.di_size = size; |
977 | ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC; | 974 | ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; |
978 | ip->i_di.di_flags |= GFS2_DIF_TRUNC_IN_PROG; | 975 | ip->i_di.di_flags |= GFS2_DIF_TRUNC_IN_PROG; |
979 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 976 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
980 | gfs2_dinode_out(ip, dibh->b_data); | 977 | gfs2_dinode_out(ip, dibh->b_data); |
@@ -1044,10 +1041,10 @@ static int trunc_end(struct gfs2_inode *ip) | |||
1044 | ip->i_di.di_height = 0; | 1041 | ip->i_di.di_height = 0; |
1045 | ip->i_di.di_goal_meta = | 1042 | ip->i_di.di_goal_meta = |
1046 | ip->i_di.di_goal_data = | 1043 | ip->i_di.di_goal_data = |
1047 | ip->i_num.no_addr; | 1044 | ip->i_no_addr; |
1048 | gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode)); | 1045 | gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode)); |
1049 | } | 1046 | } |
1050 | ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC; | 1047 | ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; |
1051 | ip->i_di.di_flags &= ~GFS2_DIF_TRUNC_IN_PROG; | 1048 | ip->i_di.di_flags &= ~GFS2_DIF_TRUNC_IN_PROG; |
1052 | 1049 | ||
1053 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 1050 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
diff --git a/fs/gfs2/daemon.c b/fs/gfs2/daemon.c index 683cb5bda870..3548d9f31e0d 100644 --- a/fs/gfs2/daemon.c +++ b/fs/gfs2/daemon.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/delay.h> | 16 | #include <linux/delay.h> |
17 | #include <linux/gfs2_ondisk.h> | 17 | #include <linux/gfs2_ondisk.h> |
18 | #include <linux/lm_interface.h> | 18 | #include <linux/lm_interface.h> |
19 | #include <linux/freezer.h> | ||
19 | 20 | ||
20 | #include "gfs2.h" | 21 | #include "gfs2.h" |
21 | #include "incore.h" | 22 | #include "incore.h" |
@@ -49,6 +50,8 @@ int gfs2_scand(void *data) | |||
49 | while (!kthread_should_stop()) { | 50 | while (!kthread_should_stop()) { |
50 | gfs2_scand_internal(sdp); | 51 | gfs2_scand_internal(sdp); |
51 | t = gfs2_tune_get(sdp, gt_scand_secs) * HZ; | 52 | t = gfs2_tune_get(sdp, gt_scand_secs) * HZ; |
53 | if (freezing(current)) | ||
54 | refrigerator(); | ||
52 | schedule_timeout_interruptible(t); | 55 | schedule_timeout_interruptible(t); |
53 | } | 56 | } |
54 | 57 | ||
@@ -74,6 +77,8 @@ int gfs2_glockd(void *data) | |||
74 | wait_event_interruptible(sdp->sd_reclaim_wq, | 77 | wait_event_interruptible(sdp->sd_reclaim_wq, |
75 | (atomic_read(&sdp->sd_reclaim_count) || | 78 | (atomic_read(&sdp->sd_reclaim_count) || |
76 | kthread_should_stop())); | 79 | kthread_should_stop())); |
80 | if (freezing(current)) | ||
81 | refrigerator(); | ||
77 | } | 82 | } |
78 | 83 | ||
79 | return 0; | 84 | return 0; |
@@ -93,6 +98,8 @@ int gfs2_recoverd(void *data) | |||
93 | while (!kthread_should_stop()) { | 98 | while (!kthread_should_stop()) { |
94 | gfs2_check_journals(sdp); | 99 | gfs2_check_journals(sdp); |
95 | t = gfs2_tune_get(sdp, gt_recoverd_secs) * HZ; | 100 | t = gfs2_tune_get(sdp, gt_recoverd_secs) * HZ; |
101 | if (freezing(current)) | ||
102 | refrigerator(); | ||
96 | schedule_timeout_interruptible(t); | 103 | schedule_timeout_interruptible(t); |
97 | } | 104 | } |
98 | 105 | ||
@@ -141,6 +148,8 @@ int gfs2_logd(void *data) | |||
141 | } | 148 | } |
142 | 149 | ||
143 | t = gfs2_tune_get(sdp, gt_logd_secs) * HZ; | 150 | t = gfs2_tune_get(sdp, gt_logd_secs) * HZ; |
151 | if (freezing(current)) | ||
152 | refrigerator(); | ||
144 | schedule_timeout_interruptible(t); | 153 | schedule_timeout_interruptible(t); |
145 | } | 154 | } |
146 | 155 | ||
@@ -191,6 +200,8 @@ int gfs2_quotad(void *data) | |||
191 | gfs2_quota_scan(sdp); | 200 | gfs2_quota_scan(sdp); |
192 | 201 | ||
193 | t = gfs2_tune_get(sdp, gt_quotad_secs) * HZ; | 202 | t = gfs2_tune_get(sdp, gt_quotad_secs) * HZ; |
203 | if (freezing(current)) | ||
204 | refrigerator(); | ||
194 | schedule_timeout_interruptible(t); | 205 | schedule_timeout_interruptible(t); |
195 | } | 206 | } |
196 | 207 | ||
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c index a96fa07b3f3b..2beb2f401aa2 100644 --- a/fs/gfs2/dir.c +++ b/fs/gfs2/dir.c | |||
@@ -130,7 +130,7 @@ static int gfs2_dir_write_stuffed(struct gfs2_inode *ip, const char *buf, | |||
130 | memcpy(dibh->b_data + offset + sizeof(struct gfs2_dinode), buf, size); | 130 | memcpy(dibh->b_data + offset + sizeof(struct gfs2_dinode), buf, size); |
131 | if (ip->i_di.di_size < offset + size) | 131 | if (ip->i_di.di_size < offset + size) |
132 | ip->i_di.di_size = offset + size; | 132 | ip->i_di.di_size = offset + size; |
133 | ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC; | 133 | ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; |
134 | gfs2_dinode_out(ip, dibh->b_data); | 134 | gfs2_dinode_out(ip, dibh->b_data); |
135 | 135 | ||
136 | brelse(dibh); | 136 | brelse(dibh); |
@@ -228,7 +228,7 @@ out: | |||
228 | 228 | ||
229 | if (ip->i_di.di_size < offset + copied) | 229 | if (ip->i_di.di_size < offset + copied) |
230 | ip->i_di.di_size = offset + copied; | 230 | ip->i_di.di_size = offset + copied; |
231 | ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC; | 231 | ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; |
232 | 232 | ||
233 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 233 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
234 | gfs2_dinode_out(ip, dibh->b_data); | 234 | gfs2_dinode_out(ip, dibh->b_data); |
@@ -1456,7 +1456,7 @@ int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque, | |||
1456 | if (dip->i_di.di_entries != g.offset) { | 1456 | if (dip->i_di.di_entries != g.offset) { |
1457 | fs_warn(sdp, "Number of entries corrupt in dir %llu, " | 1457 | fs_warn(sdp, "Number of entries corrupt in dir %llu, " |
1458 | "ip->i_di.di_entries (%u) != g.offset (%u)\n", | 1458 | "ip->i_di.di_entries (%u) != g.offset (%u)\n", |
1459 | (unsigned long long)dip->i_num.no_addr, | 1459 | (unsigned long long)dip->i_no_addr, |
1460 | dip->i_di.di_entries, | 1460 | dip->i_di.di_entries, |
1461 | g.offset); | 1461 | g.offset); |
1462 | error = -EIO; | 1462 | error = -EIO; |
@@ -1488,24 +1488,55 @@ out: | |||
1488 | * Returns: errno | 1488 | * Returns: errno |
1489 | */ | 1489 | */ |
1490 | 1490 | ||
1491 | int gfs2_dir_search(struct inode *dir, const struct qstr *name, | 1491 | struct inode *gfs2_dir_search(struct inode *dir, const struct qstr *name) |
1492 | struct gfs2_inum_host *inum, unsigned int *type) | ||
1493 | { | 1492 | { |
1494 | struct buffer_head *bh; | 1493 | struct buffer_head *bh; |
1495 | struct gfs2_dirent *dent; | 1494 | struct gfs2_dirent *dent; |
1495 | struct inode *inode; | ||
1496 | |||
1497 | dent = gfs2_dirent_search(dir, name, gfs2_dirent_find, &bh); | ||
1498 | if (dent) { | ||
1499 | if (IS_ERR(dent)) | ||
1500 | return ERR_PTR(PTR_ERR(dent)); | ||
1501 | inode = gfs2_inode_lookup(dir->i_sb, | ||
1502 | be16_to_cpu(dent->de_type), | ||
1503 | be64_to_cpu(dent->de_inum.no_addr), | ||
1504 | be64_to_cpu(dent->de_inum.no_formal_ino)); | ||
1505 | brelse(bh); | ||
1506 | return inode; | ||
1507 | } | ||
1508 | return ERR_PTR(-ENOENT); | ||
1509 | } | ||
1510 | |||
1511 | int gfs2_dir_check(struct inode *dir, const struct qstr *name, | ||
1512 | const struct gfs2_inode *ip) | ||
1513 | { | ||
1514 | struct buffer_head *bh; | ||
1515 | struct gfs2_dirent *dent; | ||
1516 | int ret = -ENOENT; | ||
1496 | 1517 | ||
1497 | dent = gfs2_dirent_search(dir, name, gfs2_dirent_find, &bh); | 1518 | dent = gfs2_dirent_search(dir, name, gfs2_dirent_find, &bh); |
1498 | if (dent) { | 1519 | if (dent) { |
1499 | if (IS_ERR(dent)) | 1520 | if (IS_ERR(dent)) |
1500 | return PTR_ERR(dent); | 1521 | return PTR_ERR(dent); |
1501 | if (inum) | 1522 | if (ip) { |
1502 | gfs2_inum_in(inum, (char *)&dent->de_inum); | 1523 | if (be64_to_cpu(dent->de_inum.no_addr) != ip->i_no_addr) |
1503 | if (type) | 1524 | goto out; |
1504 | *type = be16_to_cpu(dent->de_type); | 1525 | if (be64_to_cpu(dent->de_inum.no_formal_ino) != |
1526 | ip->i_no_formal_ino) | ||
1527 | goto out; | ||
1528 | if (unlikely(IF2DT(ip->i_inode.i_mode) != | ||
1529 | be16_to_cpu(dent->de_type))) { | ||
1530 | gfs2_consist_inode(GFS2_I(dir)); | ||
1531 | ret = -EIO; | ||
1532 | goto out; | ||
1533 | } | ||
1534 | } | ||
1535 | ret = 0; | ||
1536 | out: | ||
1505 | brelse(bh); | 1537 | brelse(bh); |
1506 | return 0; | ||
1507 | } | 1538 | } |
1508 | return -ENOENT; | 1539 | return ret; |
1509 | } | 1540 | } |
1510 | 1541 | ||
1511 | static int dir_new_leaf(struct inode *inode, const struct qstr *name) | 1542 | static int dir_new_leaf(struct inode *inode, const struct qstr *name) |
@@ -1565,7 +1596,7 @@ static int dir_new_leaf(struct inode *inode, const struct qstr *name) | |||
1565 | */ | 1596 | */ |
1566 | 1597 | ||
1567 | int gfs2_dir_add(struct inode *inode, const struct qstr *name, | 1598 | int gfs2_dir_add(struct inode *inode, const struct qstr *name, |
1568 | const struct gfs2_inum_host *inum, unsigned type) | 1599 | const struct gfs2_inode *nip, unsigned type) |
1569 | { | 1600 | { |
1570 | struct gfs2_inode *ip = GFS2_I(inode); | 1601 | struct gfs2_inode *ip = GFS2_I(inode); |
1571 | struct buffer_head *bh; | 1602 | struct buffer_head *bh; |
@@ -1580,7 +1611,7 @@ int gfs2_dir_add(struct inode *inode, const struct qstr *name, | |||
1580 | if (IS_ERR(dent)) | 1611 | if (IS_ERR(dent)) |
1581 | return PTR_ERR(dent); | 1612 | return PTR_ERR(dent); |
1582 | dent = gfs2_init_dirent(inode, dent, name, bh); | 1613 | dent = gfs2_init_dirent(inode, dent, name, bh); |
1583 | gfs2_inum_out(inum, (char *)&dent->de_inum); | 1614 | gfs2_inum_out(nip, dent); |
1584 | dent->de_type = cpu_to_be16(type); | 1615 | dent->de_type = cpu_to_be16(type); |
1585 | if (ip->i_di.di_flags & GFS2_DIF_EXHASH) { | 1616 | if (ip->i_di.di_flags & GFS2_DIF_EXHASH) { |
1586 | leaf = (struct gfs2_leaf *)bh->b_data; | 1617 | leaf = (struct gfs2_leaf *)bh->b_data; |
@@ -1592,7 +1623,7 @@ int gfs2_dir_add(struct inode *inode, const struct qstr *name, | |||
1592 | break; | 1623 | break; |
1593 | gfs2_trans_add_bh(ip->i_gl, bh, 1); | 1624 | gfs2_trans_add_bh(ip->i_gl, bh, 1); |
1594 | ip->i_di.di_entries++; | 1625 | ip->i_di.di_entries++; |
1595 | ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC; | 1626 | ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; |
1596 | gfs2_dinode_out(ip, bh->b_data); | 1627 | gfs2_dinode_out(ip, bh->b_data); |
1597 | brelse(bh); | 1628 | brelse(bh); |
1598 | error = 0; | 1629 | error = 0; |
@@ -1678,7 +1709,7 @@ int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *name) | |||
1678 | gfs2_consist_inode(dip); | 1709 | gfs2_consist_inode(dip); |
1679 | gfs2_trans_add_bh(dip->i_gl, bh, 1); | 1710 | gfs2_trans_add_bh(dip->i_gl, bh, 1); |
1680 | dip->i_di.di_entries--; | 1711 | dip->i_di.di_entries--; |
1681 | dip->i_inode.i_mtime = dip->i_inode.i_ctime = CURRENT_TIME_SEC; | 1712 | dip->i_inode.i_mtime = dip->i_inode.i_ctime = CURRENT_TIME; |
1682 | gfs2_dinode_out(dip, bh->b_data); | 1713 | gfs2_dinode_out(dip, bh->b_data); |
1683 | brelse(bh); | 1714 | brelse(bh); |
1684 | mark_inode_dirty(&dip->i_inode); | 1715 | mark_inode_dirty(&dip->i_inode); |
@@ -1700,7 +1731,7 @@ int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *name) | |||
1700 | */ | 1731 | */ |
1701 | 1732 | ||
1702 | int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename, | 1733 | int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename, |
1703 | struct gfs2_inum_host *inum, unsigned int new_type) | 1734 | const struct gfs2_inode *nip, unsigned int new_type) |
1704 | { | 1735 | { |
1705 | struct buffer_head *bh; | 1736 | struct buffer_head *bh; |
1706 | struct gfs2_dirent *dent; | 1737 | struct gfs2_dirent *dent; |
@@ -1715,7 +1746,7 @@ int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename, | |||
1715 | return PTR_ERR(dent); | 1746 | return PTR_ERR(dent); |
1716 | 1747 | ||
1717 | gfs2_trans_add_bh(dip->i_gl, bh, 1); | 1748 | gfs2_trans_add_bh(dip->i_gl, bh, 1); |
1718 | gfs2_inum_out(inum, (char *)&dent->de_inum); | 1749 | gfs2_inum_out(nip, dent); |
1719 | dent->de_type = cpu_to_be16(new_type); | 1750 | dent->de_type = cpu_to_be16(new_type); |
1720 | 1751 | ||
1721 | if (dip->i_di.di_flags & GFS2_DIF_EXHASH) { | 1752 | if (dip->i_di.di_flags & GFS2_DIF_EXHASH) { |
@@ -1726,7 +1757,7 @@ int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename, | |||
1726 | gfs2_trans_add_bh(dip->i_gl, bh, 1); | 1757 | gfs2_trans_add_bh(dip->i_gl, bh, 1); |
1727 | } | 1758 | } |
1728 | 1759 | ||
1729 | dip->i_inode.i_mtime = dip->i_inode.i_ctime = CURRENT_TIME_SEC; | 1760 | dip->i_inode.i_mtime = dip->i_inode.i_ctime = CURRENT_TIME; |
1730 | gfs2_dinode_out(dip, bh->b_data); | 1761 | gfs2_dinode_out(dip, bh->b_data); |
1731 | brelse(bh); | 1762 | brelse(bh); |
1732 | return 0; | 1763 | return 0; |
@@ -1867,7 +1898,7 @@ static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len, | |||
1867 | for (x = 0; x < rlist.rl_rgrps; x++) { | 1898 | for (x = 0; x < rlist.rl_rgrps; x++) { |
1868 | struct gfs2_rgrpd *rgd; | 1899 | struct gfs2_rgrpd *rgd; |
1869 | rgd = rlist.rl_ghs[x].gh_gl->gl_object; | 1900 | rgd = rlist.rl_ghs[x].gh_gl->gl_object; |
1870 | rg_blocks += rgd->rd_ri.ri_length; | 1901 | rg_blocks += rgd->rd_length; |
1871 | } | 1902 | } |
1872 | 1903 | ||
1873 | error = gfs2_glock_nq_m(rlist.rl_rgrps, rlist.rl_ghs); | 1904 | error = gfs2_glock_nq_m(rlist.rl_rgrps, rlist.rl_ghs); |
diff --git a/fs/gfs2/dir.h b/fs/gfs2/dir.h index 48fe89046bba..8a468cac9328 100644 --- a/fs/gfs2/dir.h +++ b/fs/gfs2/dir.h | |||
@@ -16,15 +16,16 @@ struct inode; | |||
16 | struct gfs2_inode; | 16 | struct gfs2_inode; |
17 | struct gfs2_inum; | 17 | struct gfs2_inum; |
18 | 18 | ||
19 | int gfs2_dir_search(struct inode *dir, const struct qstr *filename, | 19 | struct inode *gfs2_dir_search(struct inode *dir, const struct qstr *filename); |
20 | struct gfs2_inum_host *inum, unsigned int *type); | 20 | int gfs2_dir_check(struct inode *dir, const struct qstr *filename, |
21 | const struct gfs2_inode *ip); | ||
21 | int gfs2_dir_add(struct inode *inode, const struct qstr *filename, | 22 | int gfs2_dir_add(struct inode *inode, const struct qstr *filename, |
22 | const struct gfs2_inum_host *inum, unsigned int type); | 23 | const struct gfs2_inode *ip, unsigned int type); |
23 | int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *filename); | 24 | int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *filename); |
24 | int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque, | 25 | int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque, |
25 | filldir_t filldir); | 26 | filldir_t filldir); |
26 | int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename, | 27 | int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename, |
27 | struct gfs2_inum_host *new_inum, unsigned int new_type); | 28 | const struct gfs2_inode *nip, unsigned int new_type); |
28 | 29 | ||
29 | int gfs2_dir_exhash_dealloc(struct gfs2_inode *dip); | 30 | int gfs2_dir_exhash_dealloc(struct gfs2_inode *dip); |
30 | 31 | ||
diff --git a/fs/gfs2/eaops.c b/fs/gfs2/eaops.c index c1f44009853f..1ab3e9d73886 100644 --- a/fs/gfs2/eaops.c +++ b/fs/gfs2/eaops.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/spinlock.h> | 11 | #include <linux/spinlock.h> |
12 | #include <linux/completion.h> | 12 | #include <linux/completion.h> |
13 | #include <linux/buffer_head.h> | 13 | #include <linux/buffer_head.h> |
14 | #include <linux/capability.h> | ||
14 | #include <linux/xattr.h> | 15 | #include <linux/xattr.h> |
15 | #include <linux/gfs2_ondisk.h> | 16 | #include <linux/gfs2_ondisk.h> |
16 | #include <linux/lm_interface.h> | 17 | #include <linux/lm_interface.h> |
diff --git a/fs/gfs2/eattr.c b/fs/gfs2/eattr.c index 5b83ca6acab1..2a7435b5c4dc 100644 --- a/fs/gfs2/eattr.c +++ b/fs/gfs2/eattr.c | |||
@@ -254,7 +254,7 @@ static int ea_dealloc_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh, | |||
254 | if (error) | 254 | if (error) |
255 | return error; | 255 | return error; |
256 | 256 | ||
257 | error = gfs2_trans_begin(sdp, rgd->rd_ri.ri_length + RES_DINODE + | 257 | error = gfs2_trans_begin(sdp, rgd->rd_length + RES_DINODE + |
258 | RES_EATTR + RES_STATFS + RES_QUOTA, blks); | 258 | RES_EATTR + RES_STATFS + RES_QUOTA, blks); |
259 | if (error) | 259 | if (error) |
260 | goto out_gunlock; | 260 | goto out_gunlock; |
@@ -300,7 +300,7 @@ static int ea_dealloc_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh, | |||
300 | 300 | ||
301 | error = gfs2_meta_inode_buffer(ip, &dibh); | 301 | error = gfs2_meta_inode_buffer(ip, &dibh); |
302 | if (!error) { | 302 | if (!error) { |
303 | ip->i_inode.i_ctime = CURRENT_TIME_SEC; | 303 | ip->i_inode.i_ctime = CURRENT_TIME; |
304 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 304 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
305 | gfs2_dinode_out(ip, dibh->b_data); | 305 | gfs2_dinode_out(ip, dibh->b_data); |
306 | brelse(dibh); | 306 | brelse(dibh); |
@@ -700,7 +700,7 @@ static int ea_alloc_skeleton(struct gfs2_inode *ip, struct gfs2_ea_request *er, | |||
700 | goto out_gunlock_q; | 700 | goto out_gunlock_q; |
701 | 701 | ||
702 | error = gfs2_trans_begin(GFS2_SB(&ip->i_inode), | 702 | error = gfs2_trans_begin(GFS2_SB(&ip->i_inode), |
703 | blks + al->al_rgd->rd_ri.ri_length + | 703 | blks + al->al_rgd->rd_length + |
704 | RES_DINODE + RES_STATFS + RES_QUOTA, 0); | 704 | RES_DINODE + RES_STATFS + RES_QUOTA, 0); |
705 | if (error) | 705 | if (error) |
706 | goto out_ipres; | 706 | goto out_ipres; |
@@ -717,7 +717,7 @@ static int ea_alloc_skeleton(struct gfs2_inode *ip, struct gfs2_ea_request *er, | |||
717 | (er->er_mode & S_IFMT)); | 717 | (er->er_mode & S_IFMT)); |
718 | ip->i_inode.i_mode = er->er_mode; | 718 | ip->i_inode.i_mode = er->er_mode; |
719 | } | 719 | } |
720 | ip->i_inode.i_ctime = CURRENT_TIME_SEC; | 720 | ip->i_inode.i_ctime = CURRENT_TIME; |
721 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 721 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
722 | gfs2_dinode_out(ip, dibh->b_data); | 722 | gfs2_dinode_out(ip, dibh->b_data); |
723 | brelse(dibh); | 723 | brelse(dibh); |
@@ -852,7 +852,7 @@ static int ea_set_simple_noalloc(struct gfs2_inode *ip, struct buffer_head *bh, | |||
852 | (ip->i_inode.i_mode & S_IFMT) == (er->er_mode & S_IFMT)); | 852 | (ip->i_inode.i_mode & S_IFMT) == (er->er_mode & S_IFMT)); |
853 | ip->i_inode.i_mode = er->er_mode; | 853 | ip->i_inode.i_mode = er->er_mode; |
854 | } | 854 | } |
855 | ip->i_inode.i_ctime = CURRENT_TIME_SEC; | 855 | ip->i_inode.i_ctime = CURRENT_TIME; |
856 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 856 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
857 | gfs2_dinode_out(ip, dibh->b_data); | 857 | gfs2_dinode_out(ip, dibh->b_data); |
858 | brelse(dibh); | 858 | brelse(dibh); |
@@ -1133,7 +1133,7 @@ static int ea_remove_stuffed(struct gfs2_inode *ip, struct gfs2_ea_location *el) | |||
1133 | 1133 | ||
1134 | error = gfs2_meta_inode_buffer(ip, &dibh); | 1134 | error = gfs2_meta_inode_buffer(ip, &dibh); |
1135 | if (!error) { | 1135 | if (!error) { |
1136 | ip->i_inode.i_ctime = CURRENT_TIME_SEC; | 1136 | ip->i_inode.i_ctime = CURRENT_TIME; |
1137 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 1137 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
1138 | gfs2_dinode_out(ip, dibh->b_data); | 1138 | gfs2_dinode_out(ip, dibh->b_data); |
1139 | brelse(dibh); | 1139 | brelse(dibh); |
@@ -1352,7 +1352,7 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip) | |||
1352 | for (x = 0; x < rlist.rl_rgrps; x++) { | 1352 | for (x = 0; x < rlist.rl_rgrps; x++) { |
1353 | struct gfs2_rgrpd *rgd; | 1353 | struct gfs2_rgrpd *rgd; |
1354 | rgd = rlist.rl_ghs[x].gh_gl->gl_object; | 1354 | rgd = rlist.rl_ghs[x].gh_gl->gl_object; |
1355 | rg_blocks += rgd->rd_ri.ri_length; | 1355 | rg_blocks += rgd->rd_length; |
1356 | } | 1356 | } |
1357 | 1357 | ||
1358 | error = gfs2_glock_nq_m(rlist.rl_rgrps, rlist.rl_ghs); | 1358 | error = gfs2_glock_nq_m(rlist.rl_rgrps, rlist.rl_ghs); |
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 1815429a2978..3f0974e1afef 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c | |||
@@ -422,11 +422,11 @@ void gfs2_holder_uninit(struct gfs2_holder *gh) | |||
422 | static void gfs2_holder_wake(struct gfs2_holder *gh) | 422 | static void gfs2_holder_wake(struct gfs2_holder *gh) |
423 | { | 423 | { |
424 | clear_bit(HIF_WAIT, &gh->gh_iflags); | 424 | clear_bit(HIF_WAIT, &gh->gh_iflags); |
425 | smp_mb(); | 425 | smp_mb__after_clear_bit(); |
426 | wake_up_bit(&gh->gh_iflags, HIF_WAIT); | 426 | wake_up_bit(&gh->gh_iflags, HIF_WAIT); |
427 | } | 427 | } |
428 | 428 | ||
429 | static int holder_wait(void *word) | 429 | static int just_schedule(void *word) |
430 | { | 430 | { |
431 | schedule(); | 431 | schedule(); |
432 | return 0; | 432 | return 0; |
@@ -435,7 +435,20 @@ static int holder_wait(void *word) | |||
435 | static void wait_on_holder(struct gfs2_holder *gh) | 435 | static void wait_on_holder(struct gfs2_holder *gh) |
436 | { | 436 | { |
437 | might_sleep(); | 437 | might_sleep(); |
438 | wait_on_bit(&gh->gh_iflags, HIF_WAIT, holder_wait, TASK_UNINTERRUPTIBLE); | 438 | wait_on_bit(&gh->gh_iflags, HIF_WAIT, just_schedule, TASK_UNINTERRUPTIBLE); |
439 | } | ||
440 | |||
441 | static void gfs2_demote_wake(struct gfs2_glock *gl) | ||
442 | { | ||
443 | clear_bit(GLF_DEMOTE, &gl->gl_flags); | ||
444 | smp_mb__after_clear_bit(); | ||
445 | wake_up_bit(&gl->gl_flags, GLF_DEMOTE); | ||
446 | } | ||
447 | |||
448 | static void wait_on_demote(struct gfs2_glock *gl) | ||
449 | { | ||
450 | might_sleep(); | ||
451 | wait_on_bit(&gl->gl_flags, GLF_DEMOTE, just_schedule, TASK_UNINTERRUPTIBLE); | ||
439 | } | 452 | } |
440 | 453 | ||
441 | /** | 454 | /** |
@@ -528,7 +541,7 @@ static int rq_demote(struct gfs2_glock *gl) | |||
528 | 541 | ||
529 | if (gl->gl_state == gl->gl_demote_state || | 542 | if (gl->gl_state == gl->gl_demote_state || |
530 | gl->gl_state == LM_ST_UNLOCKED) { | 543 | gl->gl_state == LM_ST_UNLOCKED) { |
531 | clear_bit(GLF_DEMOTE, &gl->gl_flags); | 544 | gfs2_demote_wake(gl); |
532 | return 0; | 545 | return 0; |
533 | } | 546 | } |
534 | set_bit(GLF_LOCK, &gl->gl_flags); | 547 | set_bit(GLF_LOCK, &gl->gl_flags); |
@@ -666,12 +679,22 @@ static void gfs2_glmutex_unlock(struct gfs2_glock *gl) | |||
666 | * practise: LM_ST_SHARED and LM_ST_UNLOCKED | 679 | * practise: LM_ST_SHARED and LM_ST_UNLOCKED |
667 | */ | 680 | */ |
668 | 681 | ||
669 | static void handle_callback(struct gfs2_glock *gl, unsigned int state) | 682 | static void handle_callback(struct gfs2_glock *gl, unsigned int state, int remote) |
670 | { | 683 | { |
671 | spin_lock(&gl->gl_spin); | 684 | spin_lock(&gl->gl_spin); |
672 | if (test_and_set_bit(GLF_DEMOTE, &gl->gl_flags) == 0) { | 685 | if (test_and_set_bit(GLF_DEMOTE, &gl->gl_flags) == 0) { |
673 | gl->gl_demote_state = state; | 686 | gl->gl_demote_state = state; |
674 | gl->gl_demote_time = jiffies; | 687 | gl->gl_demote_time = jiffies; |
688 | if (remote && gl->gl_ops->go_type == LM_TYPE_IOPEN && | ||
689 | gl->gl_object) { | ||
690 | struct inode *inode = igrab(gl->gl_object); | ||
691 | spin_unlock(&gl->gl_spin); | ||
692 | if (inode) { | ||
693 | d_prune_aliases(inode); | ||
694 | iput(inode); | ||
695 | } | ||
696 | return; | ||
697 | } | ||
675 | } else if (gl->gl_demote_state != LM_ST_UNLOCKED) { | 698 | } else if (gl->gl_demote_state != LM_ST_UNLOCKED) { |
676 | gl->gl_demote_state = state; | 699 | gl->gl_demote_state = state; |
677 | } | 700 | } |
@@ -740,7 +763,7 @@ static void xmote_bh(struct gfs2_glock *gl, unsigned int ret) | |||
740 | if (ret & LM_OUT_CANCELED) | 763 | if (ret & LM_OUT_CANCELED) |
741 | op_done = 0; | 764 | op_done = 0; |
742 | else | 765 | else |
743 | clear_bit(GLF_DEMOTE, &gl->gl_flags); | 766 | gfs2_demote_wake(gl); |
744 | } else { | 767 | } else { |
745 | spin_lock(&gl->gl_spin); | 768 | spin_lock(&gl->gl_spin); |
746 | list_del_init(&gh->gh_list); | 769 | list_del_init(&gh->gh_list); |
@@ -848,7 +871,7 @@ static void drop_bh(struct gfs2_glock *gl, unsigned int ret) | |||
848 | gfs2_assert_warn(sdp, !ret); | 871 | gfs2_assert_warn(sdp, !ret); |
849 | 872 | ||
850 | state_change(gl, LM_ST_UNLOCKED); | 873 | state_change(gl, LM_ST_UNLOCKED); |
851 | clear_bit(GLF_DEMOTE, &gl->gl_flags); | 874 | gfs2_demote_wake(gl); |
852 | 875 | ||
853 | if (glops->go_inval) | 876 | if (glops->go_inval) |
854 | glops->go_inval(gl, DIO_METADATA); | 877 | glops->go_inval(gl, DIO_METADATA); |
@@ -1174,7 +1197,7 @@ void gfs2_glock_dq(struct gfs2_holder *gh) | |||
1174 | const struct gfs2_glock_operations *glops = gl->gl_ops; | 1197 | const struct gfs2_glock_operations *glops = gl->gl_ops; |
1175 | 1198 | ||
1176 | if (gh->gh_flags & GL_NOCACHE) | 1199 | if (gh->gh_flags & GL_NOCACHE) |
1177 | handle_callback(gl, LM_ST_UNLOCKED); | 1200 | handle_callback(gl, LM_ST_UNLOCKED, 0); |
1178 | 1201 | ||
1179 | gfs2_glmutex_lock(gl); | 1202 | gfs2_glmutex_lock(gl); |
1180 | 1203 | ||
@@ -1196,6 +1219,13 @@ void gfs2_glock_dq(struct gfs2_holder *gh) | |||
1196 | spin_unlock(&gl->gl_spin); | 1219 | spin_unlock(&gl->gl_spin); |
1197 | } | 1220 | } |
1198 | 1221 | ||
1222 | void gfs2_glock_dq_wait(struct gfs2_holder *gh) | ||
1223 | { | ||
1224 | struct gfs2_glock *gl = gh->gh_gl; | ||
1225 | gfs2_glock_dq(gh); | ||
1226 | wait_on_demote(gl); | ||
1227 | } | ||
1228 | |||
1199 | /** | 1229 | /** |
1200 | * gfs2_glock_dq_uninit - dequeue a holder from a glock and initialize it | 1230 | * gfs2_glock_dq_uninit - dequeue a holder from a glock and initialize it |
1201 | * @gh: the holder structure | 1231 | * @gh: the holder structure |
@@ -1297,10 +1327,6 @@ static int nq_m_sync(unsigned int num_gh, struct gfs2_holder *ghs, | |||
1297 | * @num_gh: the number of structures | 1327 | * @num_gh: the number of structures |
1298 | * @ghs: an array of struct gfs2_holder structures | 1328 | * @ghs: an array of struct gfs2_holder structures |
1299 | * | 1329 | * |
1300 | * Figure out how big an impact this function has. Either: | ||
1301 | * 1) Replace this code with code that calls gfs2_glock_prefetch() | ||
1302 | * 2) Forget async stuff and just call nq_m_sync() | ||
1303 | * 3) Leave it like it is | ||
1304 | * | 1330 | * |
1305 | * Returns: 0 on success (all glocks acquired), | 1331 | * Returns: 0 on success (all glocks acquired), |
1306 | * errno on failure (no glocks acquired) | 1332 | * errno on failure (no glocks acquired) |
@@ -1308,62 +1334,28 @@ static int nq_m_sync(unsigned int num_gh, struct gfs2_holder *ghs, | |||
1308 | 1334 | ||
1309 | int gfs2_glock_nq_m(unsigned int num_gh, struct gfs2_holder *ghs) | 1335 | int gfs2_glock_nq_m(unsigned int num_gh, struct gfs2_holder *ghs) |
1310 | { | 1336 | { |
1311 | int *e; | 1337 | struct gfs2_holder *tmp[4]; |
1312 | unsigned int x; | 1338 | struct gfs2_holder **pph = tmp; |
1313 | int borked = 0, serious = 0; | ||
1314 | int error = 0; | 1339 | int error = 0; |
1315 | 1340 | ||
1316 | if (!num_gh) | 1341 | switch(num_gh) { |
1342 | case 0: | ||
1317 | return 0; | 1343 | return 0; |
1318 | 1344 | case 1: | |
1319 | if (num_gh == 1) { | ||
1320 | ghs->gh_flags &= ~(LM_FLAG_TRY | GL_ASYNC); | 1345 | ghs->gh_flags &= ~(LM_FLAG_TRY | GL_ASYNC); |
1321 | return gfs2_glock_nq(ghs); | 1346 | return gfs2_glock_nq(ghs); |
1322 | } | 1347 | default: |
1323 | 1348 | if (num_gh <= 4) | |
1324 | e = kcalloc(num_gh, sizeof(struct gfs2_holder *), GFP_KERNEL); | ||
1325 | if (!e) | ||
1326 | return -ENOMEM; | ||
1327 | |||
1328 | for (x = 0; x < num_gh; x++) { | ||
1329 | ghs[x].gh_flags |= LM_FLAG_TRY | GL_ASYNC; | ||
1330 | error = gfs2_glock_nq(&ghs[x]); | ||
1331 | if (error) { | ||
1332 | borked = 1; | ||
1333 | serious = error; | ||
1334 | num_gh = x; | ||
1335 | break; | 1349 | break; |
1336 | } | 1350 | pph = kmalloc(num_gh * sizeof(struct gfs2_holder *), GFP_NOFS); |
1337 | } | 1351 | if (!pph) |
1338 | 1352 | return -ENOMEM; | |
1339 | for (x = 0; x < num_gh; x++) { | ||
1340 | error = e[x] = glock_wait_internal(&ghs[x]); | ||
1341 | if (error) { | ||
1342 | borked = 1; | ||
1343 | if (error != GLR_TRYFAILED && error != GLR_CANCELED) | ||
1344 | serious = error; | ||
1345 | } | ||
1346 | } | 1353 | } |
1347 | 1354 | ||
1348 | if (!borked) { | 1355 | error = nq_m_sync(num_gh, ghs, pph); |
1349 | kfree(e); | ||
1350 | return 0; | ||
1351 | } | ||
1352 | |||
1353 | for (x = 0; x < num_gh; x++) | ||
1354 | if (!e[x]) | ||
1355 | gfs2_glock_dq(&ghs[x]); | ||
1356 | |||
1357 | if (serious) | ||
1358 | error = serious; | ||
1359 | else { | ||
1360 | for (x = 0; x < num_gh; x++) | ||
1361 | gfs2_holder_reinit(ghs[x].gh_state, ghs[x].gh_flags, | ||
1362 | &ghs[x]); | ||
1363 | error = nq_m_sync(num_gh, ghs, (struct gfs2_holder **)e); | ||
1364 | } | ||
1365 | 1356 | ||
1366 | kfree(e); | 1357 | if (pph != tmp) |
1358 | kfree(pph); | ||
1367 | 1359 | ||
1368 | return error; | 1360 | return error; |
1369 | } | 1361 | } |
@@ -1456,7 +1448,7 @@ static void blocking_cb(struct gfs2_sbd *sdp, struct lm_lockname *name, | |||
1456 | if (!gl) | 1448 | if (!gl) |
1457 | return; | 1449 | return; |
1458 | 1450 | ||
1459 | handle_callback(gl, state); | 1451 | handle_callback(gl, state, 1); |
1460 | 1452 | ||
1461 | spin_lock(&gl->gl_spin); | 1453 | spin_lock(&gl->gl_spin); |
1462 | run_queue(gl); | 1454 | run_queue(gl); |
@@ -1596,7 +1588,7 @@ void gfs2_reclaim_glock(struct gfs2_sbd *sdp) | |||
1596 | if (gfs2_glmutex_trylock(gl)) { | 1588 | if (gfs2_glmutex_trylock(gl)) { |
1597 | if (list_empty(&gl->gl_holders) && | 1589 | if (list_empty(&gl->gl_holders) && |
1598 | gl->gl_state != LM_ST_UNLOCKED && demote_ok(gl)) | 1590 | gl->gl_state != LM_ST_UNLOCKED && demote_ok(gl)) |
1599 | handle_callback(gl, LM_ST_UNLOCKED); | 1591 | handle_callback(gl, LM_ST_UNLOCKED, 0); |
1600 | gfs2_glmutex_unlock(gl); | 1592 | gfs2_glmutex_unlock(gl); |
1601 | } | 1593 | } |
1602 | 1594 | ||
@@ -1709,7 +1701,7 @@ static void clear_glock(struct gfs2_glock *gl) | |||
1709 | if (gfs2_glmutex_trylock(gl)) { | 1701 | if (gfs2_glmutex_trylock(gl)) { |
1710 | if (list_empty(&gl->gl_holders) && | 1702 | if (list_empty(&gl->gl_holders) && |
1711 | gl->gl_state != LM_ST_UNLOCKED) | 1703 | gl->gl_state != LM_ST_UNLOCKED) |
1712 | handle_callback(gl, LM_ST_UNLOCKED); | 1704 | handle_callback(gl, LM_ST_UNLOCKED, 0); |
1713 | gfs2_glmutex_unlock(gl); | 1705 | gfs2_glmutex_unlock(gl); |
1714 | } | 1706 | } |
1715 | } | 1707 | } |
@@ -1823,7 +1815,8 @@ static int dump_inode(struct glock_iter *gi, struct gfs2_inode *ip) | |||
1823 | 1815 | ||
1824 | print_dbg(gi, " Inode:\n"); | 1816 | print_dbg(gi, " Inode:\n"); |
1825 | print_dbg(gi, " num = %llu/%llu\n", | 1817 | print_dbg(gi, " num = %llu/%llu\n", |
1826 | ip->i_num.no_formal_ino, ip->i_num.no_addr); | 1818 | (unsigned long long)ip->i_no_formal_ino, |
1819 | (unsigned long long)ip->i_no_addr); | ||
1827 | print_dbg(gi, " type = %u\n", IF2DT(ip->i_inode.i_mode)); | 1820 | print_dbg(gi, " type = %u\n", IF2DT(ip->i_inode.i_mode)); |
1828 | print_dbg(gi, " i_flags ="); | 1821 | print_dbg(gi, " i_flags ="); |
1829 | for (x = 0; x < 32; x++) | 1822 | for (x = 0; x < 32; x++) |
@@ -1909,8 +1902,8 @@ static int dump_glock(struct glock_iter *gi, struct gfs2_glock *gl) | |||
1909 | } | 1902 | } |
1910 | if (test_bit(GLF_DEMOTE, &gl->gl_flags)) { | 1903 | if (test_bit(GLF_DEMOTE, &gl->gl_flags)) { |
1911 | print_dbg(gi, " Demotion req to state %u (%llu uS ago)\n", | 1904 | print_dbg(gi, " Demotion req to state %u (%llu uS ago)\n", |
1912 | gl->gl_demote_state, | 1905 | gl->gl_demote_state, (unsigned long long) |
1913 | (u64)(jiffies - gl->gl_demote_time)*(1000000/HZ)); | 1906 | (jiffies - gl->gl_demote_time)*(1000000/HZ)); |
1914 | } | 1907 | } |
1915 | if (gl->gl_ops == &gfs2_inode_glops && gl->gl_object) { | 1908 | if (gl->gl_ops == &gfs2_inode_glops && gl->gl_object) { |
1916 | if (!test_bit(GLF_LOCK, &gl->gl_flags) && | 1909 | if (!test_bit(GLF_LOCK, &gl->gl_flags) && |
diff --git a/fs/gfs2/glock.h b/fs/gfs2/glock.h index b3e152db70c8..7721ca3fff9e 100644 --- a/fs/gfs2/glock.h +++ b/fs/gfs2/glock.h | |||
@@ -87,6 +87,7 @@ int gfs2_glock_nq(struct gfs2_holder *gh); | |||
87 | int gfs2_glock_poll(struct gfs2_holder *gh); | 87 | int gfs2_glock_poll(struct gfs2_holder *gh); |
88 | int gfs2_glock_wait(struct gfs2_holder *gh); | 88 | int gfs2_glock_wait(struct gfs2_holder *gh); |
89 | void gfs2_glock_dq(struct gfs2_holder *gh); | 89 | void gfs2_glock_dq(struct gfs2_holder *gh); |
90 | void gfs2_glock_dq_wait(struct gfs2_holder *gh); | ||
90 | 91 | ||
91 | void gfs2_glock_dq_uninit(struct gfs2_holder *gh); | 92 | void gfs2_glock_dq_uninit(struct gfs2_holder *gh); |
92 | int gfs2_glock_nq_num(struct gfs2_sbd *sdp, | 93 | int gfs2_glock_nq_num(struct gfs2_sbd *sdp, |
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c index 7b82657a9910..777ca46010e8 100644 --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c | |||
@@ -156,9 +156,9 @@ static void inode_go_sync(struct gfs2_glock *gl) | |||
156 | ip = NULL; | 156 | ip = NULL; |
157 | 157 | ||
158 | if (test_bit(GLF_DIRTY, &gl->gl_flags)) { | 158 | if (test_bit(GLF_DIRTY, &gl->gl_flags)) { |
159 | gfs2_log_flush(gl->gl_sbd, gl); | ||
160 | if (ip) | 159 | if (ip) |
161 | filemap_fdatawrite(ip->i_inode.i_mapping); | 160 | filemap_fdatawrite(ip->i_inode.i_mapping); |
161 | gfs2_log_flush(gl->gl_sbd, gl); | ||
162 | gfs2_meta_sync(gl); | 162 | gfs2_meta_sync(gl); |
163 | if (ip) { | 163 | if (ip) { |
164 | struct address_space *mapping = ip->i_inode.i_mapping; | 164 | struct address_space *mapping = ip->i_inode.i_mapping; |
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index d995441373ab..170ba93829c0 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h | |||
@@ -28,6 +28,14 @@ struct gfs2_sbd; | |||
28 | 28 | ||
29 | typedef void (*gfs2_glop_bh_t) (struct gfs2_glock *gl, unsigned int ret); | 29 | typedef void (*gfs2_glop_bh_t) (struct gfs2_glock *gl, unsigned int ret); |
30 | 30 | ||
31 | struct gfs2_log_header_host { | ||
32 | u64 lh_sequence; /* Sequence number of this transaction */ | ||
33 | u32 lh_flags; /* GFS2_LOG_HEAD_... */ | ||
34 | u32 lh_tail; /* Block number of log tail */ | ||
35 | u32 lh_blkno; | ||
36 | u32 lh_hash; | ||
37 | }; | ||
38 | |||
31 | /* | 39 | /* |
32 | * Structure of operations that are associated with each | 40 | * Structure of operations that are associated with each |
33 | * type of element in the log. | 41 | * type of element in the log. |
@@ -60,12 +68,23 @@ struct gfs2_bitmap { | |||
60 | u32 bi_len; | 68 | u32 bi_len; |
61 | }; | 69 | }; |
62 | 70 | ||
71 | struct gfs2_rgrp_host { | ||
72 | u32 rg_flags; | ||
73 | u32 rg_free; | ||
74 | u32 rg_dinodes; | ||
75 | u64 rg_igeneration; | ||
76 | }; | ||
77 | |||
63 | struct gfs2_rgrpd { | 78 | struct gfs2_rgrpd { |
64 | struct list_head rd_list; /* Link with superblock */ | 79 | struct list_head rd_list; /* Link with superblock */ |
65 | struct list_head rd_list_mru; | 80 | struct list_head rd_list_mru; |
66 | struct list_head rd_recent; /* Recently used rgrps */ | 81 | struct list_head rd_recent; /* Recently used rgrps */ |
67 | struct gfs2_glock *rd_gl; /* Glock for this rgrp */ | 82 | struct gfs2_glock *rd_gl; /* Glock for this rgrp */ |
68 | struct gfs2_rindex_host rd_ri; | 83 | u64 rd_addr; /* grp block disk address */ |
84 | u64 rd_data0; /* first data location */ | ||
85 | u32 rd_length; /* length of rgrp header in fs blocks */ | ||
86 | u32 rd_data; /* num of data blocks in rgrp */ | ||
87 | u32 rd_bitbytes; /* number of bytes in data bitmaps */ | ||
69 | struct gfs2_rgrp_host rd_rg; | 88 | struct gfs2_rgrp_host rd_rg; |
70 | u64 rd_rg_vn; | 89 | u64 rd_rg_vn; |
71 | struct gfs2_bitmap *rd_bits; | 90 | struct gfs2_bitmap *rd_bits; |
@@ -76,6 +95,8 @@ struct gfs2_rgrpd { | |||
76 | u32 rd_last_alloc_data; | 95 | u32 rd_last_alloc_data; |
77 | u32 rd_last_alloc_meta; | 96 | u32 rd_last_alloc_meta; |
78 | struct gfs2_sbd *rd_sbd; | 97 | struct gfs2_sbd *rd_sbd; |
98 | unsigned long rd_flags; | ||
99 | #define GFS2_RDF_CHECK 0x0001 /* Need to check for unlinked inodes */ | ||
79 | }; | 100 | }; |
80 | 101 | ||
81 | enum gfs2_state_bits { | 102 | enum gfs2_state_bits { |
@@ -211,10 +232,24 @@ enum { | |||
211 | GIF_SW_PAGED = 3, | 232 | GIF_SW_PAGED = 3, |
212 | }; | 233 | }; |
213 | 234 | ||
235 | struct gfs2_dinode_host { | ||
236 | u64 di_size; /* number of bytes in file */ | ||
237 | u64 di_blocks; /* number of blocks in file */ | ||
238 | u64 di_goal_meta; /* rgrp to alloc from next */ | ||
239 | u64 di_goal_data; /* data block goal */ | ||
240 | u64 di_generation; /* generation number for NFS */ | ||
241 | u32 di_flags; /* GFS2_DIF_... */ | ||
242 | u16 di_height; /* height of metadata */ | ||
243 | /* These only apply to directories */ | ||
244 | u16 di_depth; /* Number of bits in the table */ | ||
245 | u32 di_entries; /* The number of entries in the directory */ | ||
246 | u64 di_eattr; /* extended attribute block number */ | ||
247 | }; | ||
248 | |||
214 | struct gfs2_inode { | 249 | struct gfs2_inode { |
215 | struct inode i_inode; | 250 | struct inode i_inode; |
216 | struct gfs2_inum_host i_num; | 251 | u64 i_no_addr; |
217 | 252 | u64 i_no_formal_ino; | |
218 | unsigned long i_flags; /* GIF_... */ | 253 | unsigned long i_flags; /* GIF_... */ |
219 | 254 | ||
220 | struct gfs2_dinode_host i_di; /* To be replaced by ref to block */ | 255 | struct gfs2_dinode_host i_di; /* To be replaced by ref to block */ |
@@ -275,14 +310,6 @@ enum { | |||
275 | QDF_LOCKED = 2, | 310 | QDF_LOCKED = 2, |
276 | }; | 311 | }; |
277 | 312 | ||
278 | struct gfs2_quota_lvb { | ||
279 | __be32 qb_magic; | ||
280 | u32 __pad; | ||
281 | __be64 qb_limit; /* Hard limit of # blocks to alloc */ | ||
282 | __be64 qb_warn; /* Warn user when alloc is above this # */ | ||
283 | __be64 qb_value; /* Current # blocks allocated */ | ||
284 | }; | ||
285 | |||
286 | struct gfs2_quota_data { | 313 | struct gfs2_quota_data { |
287 | struct list_head qd_list; | 314 | struct list_head qd_list; |
288 | unsigned int qd_count; | 315 | unsigned int qd_count; |
@@ -327,7 +354,9 @@ struct gfs2_trans { | |||
327 | 354 | ||
328 | unsigned int tr_num_buf; | 355 | unsigned int tr_num_buf; |
329 | unsigned int tr_num_buf_new; | 356 | unsigned int tr_num_buf_new; |
357 | unsigned int tr_num_databuf_new; | ||
330 | unsigned int tr_num_buf_rm; | 358 | unsigned int tr_num_buf_rm; |
359 | unsigned int tr_num_databuf_rm; | ||
331 | struct list_head tr_list_buf; | 360 | struct list_head tr_list_buf; |
332 | 361 | ||
333 | unsigned int tr_num_revoke; | 362 | unsigned int tr_num_revoke; |
@@ -354,6 +383,12 @@ struct gfs2_jdesc { | |||
354 | unsigned int jd_blocks; | 383 | unsigned int jd_blocks; |
355 | }; | 384 | }; |
356 | 385 | ||
386 | struct gfs2_statfs_change_host { | ||
387 | s64 sc_total; | ||
388 | s64 sc_free; | ||
389 | s64 sc_dinodes; | ||
390 | }; | ||
391 | |||
357 | #define GFS2_GLOCKD_DEFAULT 1 | 392 | #define GFS2_GLOCKD_DEFAULT 1 |
358 | #define GFS2_GLOCKD_MAX 16 | 393 | #define GFS2_GLOCKD_MAX 16 |
359 | 394 | ||
@@ -426,6 +461,28 @@ enum { | |||
426 | 461 | ||
427 | #define GFS2_FSNAME_LEN 256 | 462 | #define GFS2_FSNAME_LEN 256 |
428 | 463 | ||
464 | struct gfs2_inum_host { | ||
465 | u64 no_formal_ino; | ||
466 | u64 no_addr; | ||
467 | }; | ||
468 | |||
469 | struct gfs2_sb_host { | ||
470 | u32 sb_magic; | ||
471 | u32 sb_type; | ||
472 | u32 sb_format; | ||
473 | |||
474 | u32 sb_fs_format; | ||
475 | u32 sb_multihost_format; | ||
476 | u32 sb_bsize; | ||
477 | u32 sb_bsize_shift; | ||
478 | |||
479 | struct gfs2_inum_host sb_master_dir; | ||
480 | struct gfs2_inum_host sb_root_dir; | ||
481 | |||
482 | char sb_lockproto[GFS2_LOCKNAME_LEN]; | ||
483 | char sb_locktable[GFS2_LOCKNAME_LEN]; | ||
484 | }; | ||
485 | |||
429 | struct gfs2_sbd { | 486 | struct gfs2_sbd { |
430 | struct super_block *sd_vfs; | 487 | struct super_block *sd_vfs; |
431 | struct super_block *sd_vfs_meta; | 488 | struct super_block *sd_vfs_meta; |
@@ -544,6 +601,7 @@ struct gfs2_sbd { | |||
544 | 601 | ||
545 | unsigned int sd_log_blks_reserved; | 602 | unsigned int sd_log_blks_reserved; |
546 | unsigned int sd_log_commited_buf; | 603 | unsigned int sd_log_commited_buf; |
604 | unsigned int sd_log_commited_databuf; | ||
547 | unsigned int sd_log_commited_revoke; | 605 | unsigned int sd_log_commited_revoke; |
548 | 606 | ||
549 | unsigned int sd_log_num_gl; | 607 | unsigned int sd_log_num_gl; |
@@ -552,7 +610,6 @@ struct gfs2_sbd { | |||
552 | unsigned int sd_log_num_rg; | 610 | unsigned int sd_log_num_rg; |
553 | unsigned int sd_log_num_databuf; | 611 | unsigned int sd_log_num_databuf; |
554 | unsigned int sd_log_num_jdata; | 612 | unsigned int sd_log_num_jdata; |
555 | unsigned int sd_log_num_hdrs; | ||
556 | 613 | ||
557 | struct list_head sd_log_le_gl; | 614 | struct list_head sd_log_le_gl; |
558 | struct list_head sd_log_le_buf; | 615 | struct list_head sd_log_le_buf; |
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index df0b8b3018b9..34f7bcdea1e9 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
@@ -38,12 +38,17 @@ | |||
38 | #include "trans.h" | 38 | #include "trans.h" |
39 | #include "util.h" | 39 | #include "util.h" |
40 | 40 | ||
41 | struct gfs2_inum_range_host { | ||
42 | u64 ir_start; | ||
43 | u64 ir_length; | ||
44 | }; | ||
45 | |||
41 | static int iget_test(struct inode *inode, void *opaque) | 46 | static int iget_test(struct inode *inode, void *opaque) |
42 | { | 47 | { |
43 | struct gfs2_inode *ip = GFS2_I(inode); | 48 | struct gfs2_inode *ip = GFS2_I(inode); |
44 | struct gfs2_inum_host *inum = opaque; | 49 | u64 *no_addr = opaque; |
45 | 50 | ||
46 | if (ip->i_num.no_addr == inum->no_addr && | 51 | if (ip->i_no_addr == *no_addr && |
47 | inode->i_private != NULL) | 52 | inode->i_private != NULL) |
48 | return 1; | 53 | return 1; |
49 | 54 | ||
@@ -53,37 +58,70 @@ static int iget_test(struct inode *inode, void *opaque) | |||
53 | static int iget_set(struct inode *inode, void *opaque) | 58 | static int iget_set(struct inode *inode, void *opaque) |
54 | { | 59 | { |
55 | struct gfs2_inode *ip = GFS2_I(inode); | 60 | struct gfs2_inode *ip = GFS2_I(inode); |
56 | struct gfs2_inum_host *inum = opaque; | 61 | u64 *no_addr = opaque; |
57 | 62 | ||
58 | ip->i_num = *inum; | 63 | inode->i_ino = (unsigned long)*no_addr; |
59 | inode->i_ino = inum->no_addr; | 64 | ip->i_no_addr = *no_addr; |
60 | return 0; | 65 | return 0; |
61 | } | 66 | } |
62 | 67 | ||
63 | struct inode *gfs2_ilookup(struct super_block *sb, struct gfs2_inum_host *inum) | 68 | struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr) |
69 | { | ||
70 | unsigned long hash = (unsigned long)no_addr; | ||
71 | return ilookup5(sb, hash, iget_test, &no_addr); | ||
72 | } | ||
73 | |||
74 | static struct inode *gfs2_iget(struct super_block *sb, u64 no_addr) | ||
64 | { | 75 | { |
65 | return ilookup5(sb, (unsigned long)inum->no_addr, | 76 | unsigned long hash = (unsigned long)no_addr; |
66 | iget_test, inum); | 77 | return iget5_locked(sb, hash, iget_test, iget_set, &no_addr); |
67 | } | 78 | } |
68 | 79 | ||
69 | static struct inode *gfs2_iget(struct super_block *sb, struct gfs2_inum_host *inum) | 80 | /** |
81 | * GFS2 lookup code fills in vfs inode contents based on info obtained | ||
82 | * from directory entry inside gfs2_inode_lookup(). This has caused issues | ||
83 | * with NFS code path since its get_dentry routine doesn't have the relevant | ||
84 | * directory entry when gfs2_inode_lookup() is invoked. Part of the code | ||
85 | * segment inside gfs2_inode_lookup code needs to get moved around. | ||
86 | * | ||
87 | * Clean up I_LOCK and I_NEW as well. | ||
88 | **/ | ||
89 | |||
90 | void gfs2_set_iop(struct inode *inode) | ||
70 | { | 91 | { |
71 | return iget5_locked(sb, (unsigned long)inum->no_addr, | 92 | umode_t mode = inode->i_mode; |
72 | iget_test, iget_set, inum); | 93 | |
94 | if (S_ISREG(mode)) { | ||
95 | inode->i_op = &gfs2_file_iops; | ||
96 | inode->i_fop = &gfs2_file_fops; | ||
97 | inode->i_mapping->a_ops = &gfs2_file_aops; | ||
98 | } else if (S_ISDIR(mode)) { | ||
99 | inode->i_op = &gfs2_dir_iops; | ||
100 | inode->i_fop = &gfs2_dir_fops; | ||
101 | } else if (S_ISLNK(mode)) { | ||
102 | inode->i_op = &gfs2_symlink_iops; | ||
103 | } else { | ||
104 | inode->i_op = &gfs2_dev_iops; | ||
105 | } | ||
106 | |||
107 | unlock_new_inode(inode); | ||
73 | } | 108 | } |
74 | 109 | ||
75 | /** | 110 | /** |
76 | * gfs2_inode_lookup - Lookup an inode | 111 | * gfs2_inode_lookup - Lookup an inode |
77 | * @sb: The super block | 112 | * @sb: The super block |
78 | * @inum: The inode number | 113 | * @no_addr: The inode number |
79 | * @type: The type of the inode | 114 | * @type: The type of the inode |
80 | * | 115 | * |
81 | * Returns: A VFS inode, or an error | 116 | * Returns: A VFS inode, or an error |
82 | */ | 117 | */ |
83 | 118 | ||
84 | struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum_host *inum, unsigned int type) | 119 | struct inode *gfs2_inode_lookup(struct super_block *sb, |
120 | unsigned int type, | ||
121 | u64 no_addr, | ||
122 | u64 no_formal_ino) | ||
85 | { | 123 | { |
86 | struct inode *inode = gfs2_iget(sb, inum); | 124 | struct inode *inode = gfs2_iget(sb, no_addr); |
87 | struct gfs2_inode *ip = GFS2_I(inode); | 125 | struct gfs2_inode *ip = GFS2_I(inode); |
88 | struct gfs2_glock *io_gl; | 126 | struct gfs2_glock *io_gl; |
89 | int error; | 127 | int error; |
@@ -93,29 +131,15 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum_host *i | |||
93 | 131 | ||
94 | if (inode->i_state & I_NEW) { | 132 | if (inode->i_state & I_NEW) { |
95 | struct gfs2_sbd *sdp = GFS2_SB(inode); | 133 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
96 | umode_t mode = DT2IF(type); | ||
97 | inode->i_private = ip; | 134 | inode->i_private = ip; |
98 | inode->i_mode = mode; | 135 | ip->i_no_formal_ino = no_formal_ino; |
99 | |||
100 | if (S_ISREG(mode)) { | ||
101 | inode->i_op = &gfs2_file_iops; | ||
102 | inode->i_fop = &gfs2_file_fops; | ||
103 | inode->i_mapping->a_ops = &gfs2_file_aops; | ||
104 | } else if (S_ISDIR(mode)) { | ||
105 | inode->i_op = &gfs2_dir_iops; | ||
106 | inode->i_fop = &gfs2_dir_fops; | ||
107 | } else if (S_ISLNK(mode)) { | ||
108 | inode->i_op = &gfs2_symlink_iops; | ||
109 | } else { | ||
110 | inode->i_op = &gfs2_dev_iops; | ||
111 | } | ||
112 | 136 | ||
113 | error = gfs2_glock_get(sdp, inum->no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl); | 137 | error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl); |
114 | if (unlikely(error)) | 138 | if (unlikely(error)) |
115 | goto fail; | 139 | goto fail; |
116 | ip->i_gl->gl_object = ip; | 140 | ip->i_gl->gl_object = ip; |
117 | 141 | ||
118 | error = gfs2_glock_get(sdp, inum->no_addr, &gfs2_iopen_glops, CREATE, &io_gl); | 142 | error = gfs2_glock_get(sdp, no_addr, &gfs2_iopen_glops, CREATE, &io_gl); |
119 | if (unlikely(error)) | 143 | if (unlikely(error)) |
120 | goto fail_put; | 144 | goto fail_put; |
121 | 145 | ||
@@ -123,12 +147,38 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum_host *i | |||
123 | error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh); | 147 | error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh); |
124 | if (unlikely(error)) | 148 | if (unlikely(error)) |
125 | goto fail_iopen; | 149 | goto fail_iopen; |
150 | ip->i_iopen_gh.gh_gl->gl_object = ip; | ||
126 | 151 | ||
127 | gfs2_glock_put(io_gl); | 152 | gfs2_glock_put(io_gl); |
128 | unlock_new_inode(inode); | 153 | |
154 | if ((type == DT_UNKNOWN) && (no_formal_ino == 0)) | ||
155 | goto gfs2_nfsbypass; | ||
156 | |||
157 | inode->i_mode = DT2IF(type); | ||
158 | |||
159 | /* | ||
160 | * We must read the inode in order to work out its type in | ||
161 | * this case. Note that this doesn't happen often as we normally | ||
162 | * know the type beforehand. This code path only occurs during | ||
163 | * unlinked inode recovery (where it is safe to do this glock, | ||
164 | * which is not true in the general case). | ||
165 | */ | ||
166 | if (type == DT_UNKNOWN) { | ||
167 | struct gfs2_holder gh; | ||
168 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); | ||
169 | if (unlikely(error)) | ||
170 | goto fail_glock; | ||
171 | /* Inode is now uptodate */ | ||
172 | gfs2_glock_dq_uninit(&gh); | ||
173 | } | ||
174 | |||
175 | gfs2_set_iop(inode); | ||
129 | } | 176 | } |
130 | 177 | ||
178 | gfs2_nfsbypass: | ||
131 | return inode; | 179 | return inode; |
180 | fail_glock: | ||
181 | gfs2_glock_dq(&ip->i_iopen_gh); | ||
132 | fail_iopen: | 182 | fail_iopen: |
133 | gfs2_glock_put(io_gl); | 183 | gfs2_glock_put(io_gl); |
134 | fail_put: | 184 | fail_put: |
@@ -144,14 +194,12 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) | |||
144 | struct gfs2_dinode_host *di = &ip->i_di; | 194 | struct gfs2_dinode_host *di = &ip->i_di; |
145 | const struct gfs2_dinode *str = buf; | 195 | const struct gfs2_dinode *str = buf; |
146 | 196 | ||
147 | if (ip->i_num.no_addr != be64_to_cpu(str->di_num.no_addr)) { | 197 | if (ip->i_no_addr != be64_to_cpu(str->di_num.no_addr)) { |
148 | if (gfs2_consist_inode(ip)) | 198 | if (gfs2_consist_inode(ip)) |
149 | gfs2_dinode_print(ip); | 199 | gfs2_dinode_print(ip); |
150 | return -EIO; | 200 | return -EIO; |
151 | } | 201 | } |
152 | if (ip->i_num.no_formal_ino != be64_to_cpu(str->di_num.no_formal_ino)) | 202 | ip->i_no_formal_ino = be64_to_cpu(str->di_num.no_formal_ino); |
153 | return -ESTALE; | ||
154 | |||
155 | ip->i_inode.i_mode = be32_to_cpu(str->di_mode); | 203 | ip->i_inode.i_mode = be32_to_cpu(str->di_mode); |
156 | ip->i_inode.i_rdev = 0; | 204 | ip->i_inode.i_rdev = 0; |
157 | switch (ip->i_inode.i_mode & S_IFMT) { | 205 | switch (ip->i_inode.i_mode & S_IFMT) { |
@@ -175,11 +223,11 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) | |||
175 | di->di_blocks = be64_to_cpu(str->di_blocks); | 223 | di->di_blocks = be64_to_cpu(str->di_blocks); |
176 | gfs2_set_inode_blocks(&ip->i_inode); | 224 | gfs2_set_inode_blocks(&ip->i_inode); |
177 | ip->i_inode.i_atime.tv_sec = be64_to_cpu(str->di_atime); | 225 | ip->i_inode.i_atime.tv_sec = be64_to_cpu(str->di_atime); |
178 | ip->i_inode.i_atime.tv_nsec = 0; | 226 | ip->i_inode.i_atime.tv_nsec = be32_to_cpu(str->di_atime_nsec); |
179 | ip->i_inode.i_mtime.tv_sec = be64_to_cpu(str->di_mtime); | 227 | ip->i_inode.i_mtime.tv_sec = be64_to_cpu(str->di_mtime); |
180 | ip->i_inode.i_mtime.tv_nsec = 0; | 228 | ip->i_inode.i_mtime.tv_nsec = be32_to_cpu(str->di_mtime_nsec); |
181 | ip->i_inode.i_ctime.tv_sec = be64_to_cpu(str->di_ctime); | 229 | ip->i_inode.i_ctime.tv_sec = be64_to_cpu(str->di_ctime); |
182 | ip->i_inode.i_ctime.tv_nsec = 0; | 230 | ip->i_inode.i_ctime.tv_nsec = be32_to_cpu(str->di_ctime_nsec); |
183 | 231 | ||
184 | di->di_goal_meta = be64_to_cpu(str->di_goal_meta); | 232 | di->di_goal_meta = be64_to_cpu(str->di_goal_meta); |
185 | di->di_goal_data = be64_to_cpu(str->di_goal_data); | 233 | di->di_goal_data = be64_to_cpu(str->di_goal_data); |
@@ -247,7 +295,7 @@ int gfs2_dinode_dealloc(struct gfs2_inode *ip) | |||
247 | if (error) | 295 | if (error) |
248 | goto out_qs; | 296 | goto out_qs; |
249 | 297 | ||
250 | rgd = gfs2_blk2rgrpd(sdp, ip->i_num.no_addr); | 298 | rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr); |
251 | if (!rgd) { | 299 | if (!rgd) { |
252 | gfs2_consist_inode(ip); | 300 | gfs2_consist_inode(ip); |
253 | error = -EIO; | 301 | error = -EIO; |
@@ -314,7 +362,7 @@ int gfs2_change_nlink(struct gfs2_inode *ip, int diff) | |||
314 | else | 362 | else |
315 | drop_nlink(&ip->i_inode); | 363 | drop_nlink(&ip->i_inode); |
316 | 364 | ||
317 | ip->i_inode.i_ctime = CURRENT_TIME_SEC; | 365 | ip->i_inode.i_ctime = CURRENT_TIME; |
318 | 366 | ||
319 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 367 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
320 | gfs2_dinode_out(ip, dibh->b_data); | 368 | gfs2_dinode_out(ip, dibh->b_data); |
@@ -366,9 +414,7 @@ struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name, | |||
366 | struct super_block *sb = dir->i_sb; | 414 | struct super_block *sb = dir->i_sb; |
367 | struct gfs2_inode *dip = GFS2_I(dir); | 415 | struct gfs2_inode *dip = GFS2_I(dir); |
368 | struct gfs2_holder d_gh; | 416 | struct gfs2_holder d_gh; |
369 | struct gfs2_inum_host inum; | 417 | int error = 0; |
370 | unsigned int type; | ||
371 | int error; | ||
372 | struct inode *inode = NULL; | 418 | struct inode *inode = NULL; |
373 | int unlock = 0; | 419 | int unlock = 0; |
374 | 420 | ||
@@ -395,12 +441,9 @@ struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name, | |||
395 | goto out; | 441 | goto out; |
396 | } | 442 | } |
397 | 443 | ||
398 | error = gfs2_dir_search(dir, name, &inum, &type); | 444 | inode = gfs2_dir_search(dir, name); |
399 | if (error) | 445 | if (IS_ERR(inode)) |
400 | goto out; | 446 | error = PTR_ERR(inode); |
401 | |||
402 | inode = gfs2_inode_lookup(sb, &inum, type); | ||
403 | |||
404 | out: | 447 | out: |
405 | if (unlock) | 448 | if (unlock) |
406 | gfs2_glock_dq_uninit(&d_gh); | 449 | gfs2_glock_dq_uninit(&d_gh); |
@@ -409,6 +452,22 @@ out: | |||
409 | return inode ? inode : ERR_PTR(error); | 452 | return inode ? inode : ERR_PTR(error); |
410 | } | 453 | } |
411 | 454 | ||
455 | static void gfs2_inum_range_in(struct gfs2_inum_range_host *ir, const void *buf) | ||
456 | { | ||
457 | const struct gfs2_inum_range *str = buf; | ||
458 | |||
459 | ir->ir_start = be64_to_cpu(str->ir_start); | ||
460 | ir->ir_length = be64_to_cpu(str->ir_length); | ||
461 | } | ||
462 | |||
463 | static void gfs2_inum_range_out(const struct gfs2_inum_range_host *ir, void *buf) | ||
464 | { | ||
465 | struct gfs2_inum_range *str = buf; | ||
466 | |||
467 | str->ir_start = cpu_to_be64(ir->ir_start); | ||
468 | str->ir_length = cpu_to_be64(ir->ir_length); | ||
469 | } | ||
470 | |||
412 | static int pick_formal_ino_1(struct gfs2_sbd *sdp, u64 *formal_ino) | 471 | static int pick_formal_ino_1(struct gfs2_sbd *sdp, u64 *formal_ino) |
413 | { | 472 | { |
414 | struct gfs2_inode *ip = GFS2_I(sdp->sd_ir_inode); | 473 | struct gfs2_inode *ip = GFS2_I(sdp->sd_ir_inode); |
@@ -548,7 +607,7 @@ static int create_ok(struct gfs2_inode *dip, const struct qstr *name, | |||
548 | if (!dip->i_inode.i_nlink) | 607 | if (!dip->i_inode.i_nlink) |
549 | return -EPERM; | 608 | return -EPERM; |
550 | 609 | ||
551 | error = gfs2_dir_search(&dip->i_inode, name, NULL, NULL); | 610 | error = gfs2_dir_check(&dip->i_inode, name, NULL); |
552 | switch (error) { | 611 | switch (error) { |
553 | case -ENOENT: | 612 | case -ENOENT: |
554 | error = 0; | 613 | error = 0; |
@@ -588,8 +647,7 @@ static void munge_mode_uid_gid(struct gfs2_inode *dip, unsigned int *mode, | |||
588 | *gid = current->fsgid; | 647 | *gid = current->fsgid; |
589 | } | 648 | } |
590 | 649 | ||
591 | static int alloc_dinode(struct gfs2_inode *dip, struct gfs2_inum_host *inum, | 650 | static int alloc_dinode(struct gfs2_inode *dip, u64 *no_addr, u64 *generation) |
592 | u64 *generation) | ||
593 | { | 651 | { |
594 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 652 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
595 | int error; | 653 | int error; |
@@ -605,7 +663,7 @@ static int alloc_dinode(struct gfs2_inode *dip, struct gfs2_inum_host *inum, | |||
605 | if (error) | 663 | if (error) |
606 | goto out_ipreserv; | 664 | goto out_ipreserv; |
607 | 665 | ||
608 | inum->no_addr = gfs2_alloc_di(dip, generation); | 666 | *no_addr = gfs2_alloc_di(dip, generation); |
609 | 667 | ||
610 | gfs2_trans_end(sdp); | 668 | gfs2_trans_end(sdp); |
611 | 669 | ||
@@ -635,6 +693,7 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | |||
635 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 693 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
636 | struct gfs2_dinode *di; | 694 | struct gfs2_dinode *di; |
637 | struct buffer_head *dibh; | 695 | struct buffer_head *dibh; |
696 | struct timespec tv = CURRENT_TIME; | ||
638 | 697 | ||
639 | dibh = gfs2_meta_new(gl, inum->no_addr); | 698 | dibh = gfs2_meta_new(gl, inum->no_addr); |
640 | gfs2_trans_add_bh(gl, dibh, 1); | 699 | gfs2_trans_add_bh(gl, dibh, 1); |
@@ -650,7 +709,7 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | |||
650 | di->di_nlink = 0; | 709 | di->di_nlink = 0; |
651 | di->di_size = 0; | 710 | di->di_size = 0; |
652 | di->di_blocks = cpu_to_be64(1); | 711 | di->di_blocks = cpu_to_be64(1); |
653 | di->di_atime = di->di_mtime = di->di_ctime = cpu_to_be64(get_seconds()); | 712 | di->di_atime = di->di_mtime = di->di_ctime = cpu_to_be64(tv.tv_sec); |
654 | di->di_major = cpu_to_be32(MAJOR(dev)); | 713 | di->di_major = cpu_to_be32(MAJOR(dev)); |
655 | di->di_minor = cpu_to_be32(MINOR(dev)); | 714 | di->di_minor = cpu_to_be32(MINOR(dev)); |
656 | di->di_goal_meta = di->di_goal_data = cpu_to_be64(inum->no_addr); | 715 | di->di_goal_meta = di->di_goal_data = cpu_to_be64(inum->no_addr); |
@@ -680,6 +739,9 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | |||
680 | di->di_entries = 0; | 739 | di->di_entries = 0; |
681 | memset(&di->__pad4, 0, sizeof(di->__pad4)); | 740 | memset(&di->__pad4, 0, sizeof(di->__pad4)); |
682 | di->di_eattr = 0; | 741 | di->di_eattr = 0; |
742 | di->di_atime_nsec = cpu_to_be32(tv.tv_nsec); | ||
743 | di->di_mtime_nsec = cpu_to_be32(tv.tv_nsec); | ||
744 | di->di_ctime_nsec = cpu_to_be32(tv.tv_nsec); | ||
683 | memset(&di->di_reserved, 0, sizeof(di->di_reserved)); | 745 | memset(&di->di_reserved, 0, sizeof(di->di_reserved)); |
684 | 746 | ||
685 | brelse(dibh); | 747 | brelse(dibh); |
@@ -749,7 +811,7 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name, | |||
749 | goto fail_quota_locks; | 811 | goto fail_quota_locks; |
750 | 812 | ||
751 | error = gfs2_trans_begin(sdp, sdp->sd_max_dirres + | 813 | error = gfs2_trans_begin(sdp, sdp->sd_max_dirres + |
752 | al->al_rgd->rd_ri.ri_length + | 814 | al->al_rgd->rd_length + |
753 | 2 * RES_DINODE + | 815 | 2 * RES_DINODE + |
754 | RES_STATFS + RES_QUOTA, 0); | 816 | RES_STATFS + RES_QUOTA, 0); |
755 | if (error) | 817 | if (error) |
@@ -760,7 +822,7 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name, | |||
760 | goto fail_quota_locks; | 822 | goto fail_quota_locks; |
761 | } | 823 | } |
762 | 824 | ||
763 | error = gfs2_dir_add(&dip->i_inode, name, &ip->i_num, IF2DT(ip->i_inode.i_mode)); | 825 | error = gfs2_dir_add(&dip->i_inode, name, ip, IF2DT(ip->i_inode.i_mode)); |
764 | if (error) | 826 | if (error) |
765 | goto fail_end_trans; | 827 | goto fail_end_trans; |
766 | 828 | ||
@@ -840,11 +902,11 @@ static int gfs2_security_init(struct gfs2_inode *dip, struct gfs2_inode *ip) | |||
840 | struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, | 902 | struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, |
841 | unsigned int mode, dev_t dev) | 903 | unsigned int mode, dev_t dev) |
842 | { | 904 | { |
843 | struct inode *inode; | 905 | struct inode *inode = NULL; |
844 | struct gfs2_inode *dip = ghs->gh_gl->gl_object; | 906 | struct gfs2_inode *dip = ghs->gh_gl->gl_object; |
845 | struct inode *dir = &dip->i_inode; | 907 | struct inode *dir = &dip->i_inode; |
846 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 908 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
847 | struct gfs2_inum_host inum; | 909 | struct gfs2_inum_host inum = { .no_addr = 0, .no_formal_ino = 0 }; |
848 | int error; | 910 | int error; |
849 | u64 generation; | 911 | u64 generation; |
850 | 912 | ||
@@ -864,7 +926,7 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, | |||
864 | if (error) | 926 | if (error) |
865 | goto fail_gunlock; | 927 | goto fail_gunlock; |
866 | 928 | ||
867 | error = alloc_dinode(dip, &inum, &generation); | 929 | error = alloc_dinode(dip, &inum.no_addr, &generation); |
868 | if (error) | 930 | if (error) |
869 | goto fail_gunlock; | 931 | goto fail_gunlock; |
870 | 932 | ||
@@ -877,34 +939,36 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, | |||
877 | if (error) | 939 | if (error) |
878 | goto fail_gunlock2; | 940 | goto fail_gunlock2; |
879 | 941 | ||
880 | inode = gfs2_inode_lookup(dir->i_sb, &inum, IF2DT(mode)); | 942 | inode = gfs2_inode_lookup(dir->i_sb, IF2DT(mode), |
943 | inum.no_addr, | ||
944 | inum.no_formal_ino); | ||
881 | if (IS_ERR(inode)) | 945 | if (IS_ERR(inode)) |
882 | goto fail_gunlock2; | 946 | goto fail_gunlock2; |
883 | 947 | ||
884 | error = gfs2_inode_refresh(GFS2_I(inode)); | 948 | error = gfs2_inode_refresh(GFS2_I(inode)); |
885 | if (error) | 949 | if (error) |
886 | goto fail_iput; | 950 | goto fail_gunlock2; |
887 | 951 | ||
888 | error = gfs2_acl_create(dip, GFS2_I(inode)); | 952 | error = gfs2_acl_create(dip, GFS2_I(inode)); |
889 | if (error) | 953 | if (error) |
890 | goto fail_iput; | 954 | goto fail_gunlock2; |
891 | 955 | ||
892 | error = gfs2_security_init(dip, GFS2_I(inode)); | 956 | error = gfs2_security_init(dip, GFS2_I(inode)); |
893 | if (error) | 957 | if (error) |
894 | goto fail_iput; | 958 | goto fail_gunlock2; |
895 | 959 | ||
896 | error = link_dinode(dip, name, GFS2_I(inode)); | 960 | error = link_dinode(dip, name, GFS2_I(inode)); |
897 | if (error) | 961 | if (error) |
898 | goto fail_iput; | 962 | goto fail_gunlock2; |
899 | 963 | ||
900 | if (!inode) | 964 | if (!inode) |
901 | return ERR_PTR(-ENOMEM); | 965 | return ERR_PTR(-ENOMEM); |
902 | return inode; | 966 | return inode; |
903 | 967 | ||
904 | fail_iput: | ||
905 | iput(inode); | ||
906 | fail_gunlock2: | 968 | fail_gunlock2: |
907 | gfs2_glock_dq_uninit(ghs + 1); | 969 | gfs2_glock_dq_uninit(ghs + 1); |
970 | if (inode) | ||
971 | iput(inode); | ||
908 | fail_gunlock: | 972 | fail_gunlock: |
909 | gfs2_glock_dq(ghs); | 973 | gfs2_glock_dq(ghs); |
910 | fail: | 974 | fail: |
@@ -976,10 +1040,8 @@ int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name, | |||
976 | */ | 1040 | */ |
977 | 1041 | ||
978 | int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, | 1042 | int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, |
979 | struct gfs2_inode *ip) | 1043 | const struct gfs2_inode *ip) |
980 | { | 1044 | { |
981 | struct gfs2_inum_host inum; | ||
982 | unsigned int type; | ||
983 | int error; | 1045 | int error; |
984 | 1046 | ||
985 | if (IS_IMMUTABLE(&ip->i_inode) || IS_APPEND(&ip->i_inode)) | 1047 | if (IS_IMMUTABLE(&ip->i_inode) || IS_APPEND(&ip->i_inode)) |
@@ -997,18 +1059,10 @@ int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, | |||
997 | if (error) | 1059 | if (error) |
998 | return error; | 1060 | return error; |
999 | 1061 | ||
1000 | error = gfs2_dir_search(&dip->i_inode, name, &inum, &type); | 1062 | error = gfs2_dir_check(&dip->i_inode, name, ip); |
1001 | if (error) | 1063 | if (error) |
1002 | return error; | 1064 | return error; |
1003 | 1065 | ||
1004 | if (!gfs2_inum_equal(&inum, &ip->i_num)) | ||
1005 | return -ENOENT; | ||
1006 | |||
1007 | if (IF2DT(ip->i_inode.i_mode) != type) { | ||
1008 | gfs2_consist_inode(dip); | ||
1009 | return -EIO; | ||
1010 | } | ||
1011 | |||
1012 | return 0; | 1066 | return 0; |
1013 | } | 1067 | } |
1014 | 1068 | ||
@@ -1132,10 +1186,11 @@ int gfs2_glock_nq_atime(struct gfs2_holder *gh) | |||
1132 | struct gfs2_glock *gl = gh->gh_gl; | 1186 | struct gfs2_glock *gl = gh->gh_gl; |
1133 | struct gfs2_sbd *sdp = gl->gl_sbd; | 1187 | struct gfs2_sbd *sdp = gl->gl_sbd; |
1134 | struct gfs2_inode *ip = gl->gl_object; | 1188 | struct gfs2_inode *ip = gl->gl_object; |
1135 | s64 curtime, quantum = gfs2_tune_get(sdp, gt_atime_quantum); | 1189 | s64 quantum = gfs2_tune_get(sdp, gt_atime_quantum); |
1136 | unsigned int state; | 1190 | unsigned int state; |
1137 | int flags; | 1191 | int flags; |
1138 | int error; | 1192 | int error; |
1193 | struct timespec tv = CURRENT_TIME; | ||
1139 | 1194 | ||
1140 | if (gfs2_assert_warn(sdp, gh->gh_flags & GL_ATIME) || | 1195 | if (gfs2_assert_warn(sdp, gh->gh_flags & GL_ATIME) || |
1141 | gfs2_assert_warn(sdp, !(gh->gh_flags & GL_ASYNC)) || | 1196 | gfs2_assert_warn(sdp, !(gh->gh_flags & GL_ASYNC)) || |
@@ -1153,8 +1208,7 @@ int gfs2_glock_nq_atime(struct gfs2_holder *gh) | |||
1153 | (sdp->sd_vfs->s_flags & MS_RDONLY)) | 1208 | (sdp->sd_vfs->s_flags & MS_RDONLY)) |
1154 | return 0; | 1209 | return 0; |
1155 | 1210 | ||
1156 | curtime = get_seconds(); | 1211 | if (tv.tv_sec - ip->i_inode.i_atime.tv_sec >= quantum) { |
1157 | if (curtime - ip->i_inode.i_atime.tv_sec >= quantum) { | ||
1158 | gfs2_glock_dq(gh); | 1212 | gfs2_glock_dq(gh); |
1159 | gfs2_holder_reinit(LM_ST_EXCLUSIVE, gh->gh_flags & ~LM_FLAG_ANY, | 1213 | gfs2_holder_reinit(LM_ST_EXCLUSIVE, gh->gh_flags & ~LM_FLAG_ANY, |
1160 | gh); | 1214 | gh); |
@@ -1165,8 +1219,8 @@ int gfs2_glock_nq_atime(struct gfs2_holder *gh) | |||
1165 | /* Verify that atime hasn't been updated while we were | 1219 | /* Verify that atime hasn't been updated while we were |
1166 | trying to get exclusive lock. */ | 1220 | trying to get exclusive lock. */ |
1167 | 1221 | ||
1168 | curtime = get_seconds(); | 1222 | tv = CURRENT_TIME; |
1169 | if (curtime - ip->i_inode.i_atime.tv_sec >= quantum) { | 1223 | if (tv.tv_sec - ip->i_inode.i_atime.tv_sec >= quantum) { |
1170 | struct buffer_head *dibh; | 1224 | struct buffer_head *dibh; |
1171 | struct gfs2_dinode *di; | 1225 | struct gfs2_dinode *di; |
1172 | 1226 | ||
@@ -1180,11 +1234,12 @@ int gfs2_glock_nq_atime(struct gfs2_holder *gh) | |||
1180 | if (error) | 1234 | if (error) |
1181 | goto fail_end_trans; | 1235 | goto fail_end_trans; |
1182 | 1236 | ||
1183 | ip->i_inode.i_atime.tv_sec = curtime; | 1237 | ip->i_inode.i_atime = tv; |
1184 | 1238 | ||
1185 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 1239 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
1186 | di = (struct gfs2_dinode *)dibh->b_data; | 1240 | di = (struct gfs2_dinode *)dibh->b_data; |
1187 | di->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec); | 1241 | di->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec); |
1242 | di->di_atime_nsec = cpu_to_be32(ip->i_inode.i_atime.tv_nsec); | ||
1188 | brelse(dibh); | 1243 | brelse(dibh); |
1189 | 1244 | ||
1190 | gfs2_trans_end(sdp); | 1245 | gfs2_trans_end(sdp); |
@@ -1252,3 +1307,66 @@ int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr) | |||
1252 | return error; | 1307 | return error; |
1253 | } | 1308 | } |
1254 | 1309 | ||
1310 | void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf) | ||
1311 | { | ||
1312 | const struct gfs2_dinode_host *di = &ip->i_di; | ||
1313 | struct gfs2_dinode *str = buf; | ||
1314 | |||
1315 | str->di_header.mh_magic = cpu_to_be32(GFS2_MAGIC); | ||
1316 | str->di_header.mh_type = cpu_to_be32(GFS2_METATYPE_DI); | ||
1317 | str->di_header.__pad0 = 0; | ||
1318 | str->di_header.mh_format = cpu_to_be32(GFS2_FORMAT_DI); | ||
1319 | str->di_header.__pad1 = 0; | ||
1320 | str->di_num.no_addr = cpu_to_be64(ip->i_no_addr); | ||
1321 | str->di_num.no_formal_ino = cpu_to_be64(ip->i_no_formal_ino); | ||
1322 | str->di_mode = cpu_to_be32(ip->i_inode.i_mode); | ||
1323 | str->di_uid = cpu_to_be32(ip->i_inode.i_uid); | ||
1324 | str->di_gid = cpu_to_be32(ip->i_inode.i_gid); | ||
1325 | str->di_nlink = cpu_to_be32(ip->i_inode.i_nlink); | ||
1326 | str->di_size = cpu_to_be64(di->di_size); | ||
1327 | str->di_blocks = cpu_to_be64(di->di_blocks); | ||
1328 | str->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec); | ||
1329 | str->di_mtime = cpu_to_be64(ip->i_inode.i_mtime.tv_sec); | ||
1330 | str->di_ctime = cpu_to_be64(ip->i_inode.i_ctime.tv_sec); | ||
1331 | |||
1332 | str->di_goal_meta = cpu_to_be64(di->di_goal_meta); | ||
1333 | str->di_goal_data = cpu_to_be64(di->di_goal_data); | ||
1334 | str->di_generation = cpu_to_be64(di->di_generation); | ||
1335 | |||
1336 | str->di_flags = cpu_to_be32(di->di_flags); | ||
1337 | str->di_height = cpu_to_be16(di->di_height); | ||
1338 | str->di_payload_format = cpu_to_be32(S_ISDIR(ip->i_inode.i_mode) && | ||
1339 | !(ip->i_di.di_flags & GFS2_DIF_EXHASH) ? | ||
1340 | GFS2_FORMAT_DE : 0); | ||
1341 | str->di_depth = cpu_to_be16(di->di_depth); | ||
1342 | str->di_entries = cpu_to_be32(di->di_entries); | ||
1343 | |||
1344 | str->di_eattr = cpu_to_be64(di->di_eattr); | ||
1345 | str->di_atime_nsec = cpu_to_be32(ip->i_inode.i_atime.tv_nsec); | ||
1346 | str->di_mtime_nsec = cpu_to_be32(ip->i_inode.i_mtime.tv_nsec); | ||
1347 | str->di_ctime_nsec = cpu_to_be32(ip->i_inode.i_ctime.tv_nsec); | ||
1348 | } | ||
1349 | |||
1350 | void gfs2_dinode_print(const struct gfs2_inode *ip) | ||
1351 | { | ||
1352 | const struct gfs2_dinode_host *di = &ip->i_di; | ||
1353 | |||
1354 | printk(KERN_INFO " no_formal_ino = %llu\n", | ||
1355 | (unsigned long long)ip->i_no_formal_ino); | ||
1356 | printk(KERN_INFO " no_addr = %llu\n", | ||
1357 | (unsigned long long)ip->i_no_addr); | ||
1358 | printk(KERN_INFO " di_size = %llu\n", (unsigned long long)di->di_size); | ||
1359 | printk(KERN_INFO " di_blocks = %llu\n", | ||
1360 | (unsigned long long)di->di_blocks); | ||
1361 | printk(KERN_INFO " di_goal_meta = %llu\n", | ||
1362 | (unsigned long long)di->di_goal_meta); | ||
1363 | printk(KERN_INFO " di_goal_data = %llu\n", | ||
1364 | (unsigned long long)di->di_goal_data); | ||
1365 | printk(KERN_INFO " di_flags = 0x%.8X\n", di->di_flags); | ||
1366 | printk(KERN_INFO " di_height = %u\n", di->di_height); | ||
1367 | printk(KERN_INFO " di_depth = %u\n", di->di_depth); | ||
1368 | printk(KERN_INFO " di_entries = %u\n", di->di_entries); | ||
1369 | printk(KERN_INFO " di_eattr = %llu\n", | ||
1370 | (unsigned long long)di->di_eattr); | ||
1371 | } | ||
1372 | |||
diff --git a/fs/gfs2/inode.h b/fs/gfs2/inode.h index b57f448b15bc..4517ac82c01c 100644 --- a/fs/gfs2/inode.h +++ b/fs/gfs2/inode.h | |||
@@ -10,17 +10,17 @@ | |||
10 | #ifndef __INODE_DOT_H__ | 10 | #ifndef __INODE_DOT_H__ |
11 | #define __INODE_DOT_H__ | 11 | #define __INODE_DOT_H__ |
12 | 12 | ||
13 | static inline int gfs2_is_stuffed(struct gfs2_inode *ip) | 13 | static inline int gfs2_is_stuffed(const struct gfs2_inode *ip) |
14 | { | 14 | { |
15 | return !ip->i_di.di_height; | 15 | return !ip->i_di.di_height; |
16 | } | 16 | } |
17 | 17 | ||
18 | static inline int gfs2_is_jdata(struct gfs2_inode *ip) | 18 | static inline int gfs2_is_jdata(const struct gfs2_inode *ip) |
19 | { | 19 | { |
20 | return ip->i_di.di_flags & GFS2_DIF_JDATA; | 20 | return ip->i_di.di_flags & GFS2_DIF_JDATA; |
21 | } | 21 | } |
22 | 22 | ||
23 | static inline int gfs2_is_dir(struct gfs2_inode *ip) | 23 | static inline int gfs2_is_dir(const struct gfs2_inode *ip) |
24 | { | 24 | { |
25 | return S_ISDIR(ip->i_inode.i_mode); | 25 | return S_ISDIR(ip->i_inode.i_mode); |
26 | } | 26 | } |
@@ -32,9 +32,25 @@ static inline void gfs2_set_inode_blocks(struct inode *inode) | |||
32 | (GFS2_SB(inode)->sd_sb.sb_bsize_shift - GFS2_BASIC_BLOCK_SHIFT); | 32 | (GFS2_SB(inode)->sd_sb.sb_bsize_shift - GFS2_BASIC_BLOCK_SHIFT); |
33 | } | 33 | } |
34 | 34 | ||
35 | static inline int gfs2_check_inum(const struct gfs2_inode *ip, u64 no_addr, | ||
36 | u64 no_formal_ino) | ||
37 | { | ||
38 | return ip->i_no_addr == no_addr && ip->i_no_formal_ino == no_formal_ino; | ||
39 | } | ||
40 | |||
41 | static inline void gfs2_inum_out(const struct gfs2_inode *ip, | ||
42 | struct gfs2_dirent *dent) | ||
43 | { | ||
44 | dent->de_inum.no_formal_ino = cpu_to_be64(ip->i_no_formal_ino); | ||
45 | dent->de_inum.no_addr = cpu_to_be64(ip->i_no_addr); | ||
46 | } | ||
47 | |||
48 | |||
35 | void gfs2_inode_attr_in(struct gfs2_inode *ip); | 49 | void gfs2_inode_attr_in(struct gfs2_inode *ip); |
36 | struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum_host *inum, unsigned type); | 50 | void gfs2_set_iop(struct inode *inode); |
37 | struct inode *gfs2_ilookup(struct super_block *sb, struct gfs2_inum_host *inum); | 51 | struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned type, |
52 | u64 no_addr, u64 no_formal_ino); | ||
53 | struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr); | ||
38 | 54 | ||
39 | int gfs2_inode_refresh(struct gfs2_inode *ip); | 55 | int gfs2_inode_refresh(struct gfs2_inode *ip); |
40 | 56 | ||
@@ -47,12 +63,14 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, | |||
47 | int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name, | 63 | int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name, |
48 | struct gfs2_inode *ip); | 64 | struct gfs2_inode *ip); |
49 | int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, | 65 | int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, |
50 | struct gfs2_inode *ip); | 66 | const struct gfs2_inode *ip); |
51 | int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to); | 67 | int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to); |
52 | int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len); | 68 | int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len); |
53 | int gfs2_glock_nq_atime(struct gfs2_holder *gh); | 69 | int gfs2_glock_nq_atime(struct gfs2_holder *gh); |
54 | int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr); | 70 | int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr); |
55 | struct inode *gfs2_lookup_simple(struct inode *dip, const char *name); | 71 | struct inode *gfs2_lookup_simple(struct inode *dip, const char *name); |
72 | void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf); | ||
73 | void gfs2_dinode_print(const struct gfs2_inode *ip); | ||
56 | 74 | ||
57 | #endif /* __INODE_DOT_H__ */ | 75 | #endif /* __INODE_DOT_H__ */ |
58 | 76 | ||
diff --git a/fs/gfs2/locking/dlm/lock.c b/fs/gfs2/locking/dlm/lock.c index c305255bfe8a..542a797ac89a 100644 --- a/fs/gfs2/locking/dlm/lock.c +++ b/fs/gfs2/locking/dlm/lock.c | |||
@@ -174,7 +174,6 @@ static int gdlm_create_lp(struct gdlm_ls *ls, struct lm_lockname *name, | |||
174 | lp->cur = DLM_LOCK_IV; | 174 | lp->cur = DLM_LOCK_IV; |
175 | lp->lvb = NULL; | 175 | lp->lvb = NULL; |
176 | lp->hold_null = NULL; | 176 | lp->hold_null = NULL; |
177 | init_completion(&lp->ast_wait); | ||
178 | INIT_LIST_HEAD(&lp->clist); | 177 | INIT_LIST_HEAD(&lp->clist); |
179 | INIT_LIST_HEAD(&lp->blist); | 178 | INIT_LIST_HEAD(&lp->blist); |
180 | INIT_LIST_HEAD(&lp->delay_list); | 179 | INIT_LIST_HEAD(&lp->delay_list); |
@@ -399,6 +398,12 @@ static void gdlm_del_lvb(struct gdlm_lock *lp) | |||
399 | lp->lksb.sb_lvbptr = NULL; | 398 | lp->lksb.sb_lvbptr = NULL; |
400 | } | 399 | } |
401 | 400 | ||
401 | static int gdlm_ast_wait(void *word) | ||
402 | { | ||
403 | schedule(); | ||
404 | return 0; | ||
405 | } | ||
406 | |||
402 | /* This can do a synchronous dlm request (requiring a lock_dlm thread to get | 407 | /* This can do a synchronous dlm request (requiring a lock_dlm thread to get |
403 | the completion) because gfs won't call hold_lvb() during a callback (from | 408 | the completion) because gfs won't call hold_lvb() during a callback (from |
404 | the context of a lock_dlm thread). */ | 409 | the context of a lock_dlm thread). */ |
@@ -424,10 +429,10 @@ static int hold_null_lock(struct gdlm_lock *lp) | |||
424 | lpn->lkf = DLM_LKF_VALBLK | DLM_LKF_EXPEDITE; | 429 | lpn->lkf = DLM_LKF_VALBLK | DLM_LKF_EXPEDITE; |
425 | set_bit(LFL_NOBAST, &lpn->flags); | 430 | set_bit(LFL_NOBAST, &lpn->flags); |
426 | set_bit(LFL_INLOCK, &lpn->flags); | 431 | set_bit(LFL_INLOCK, &lpn->flags); |
432 | set_bit(LFL_AST_WAIT, &lpn->flags); | ||
427 | 433 | ||
428 | init_completion(&lpn->ast_wait); | ||
429 | gdlm_do_lock(lpn); | 434 | gdlm_do_lock(lpn); |
430 | wait_for_completion(&lpn->ast_wait); | 435 | wait_on_bit(&lpn->flags, LFL_AST_WAIT, gdlm_ast_wait, TASK_UNINTERRUPTIBLE); |
431 | error = lpn->lksb.sb_status; | 436 | error = lpn->lksb.sb_status; |
432 | if (error) { | 437 | if (error) { |
433 | printk(KERN_INFO "lock_dlm: hold_null_lock dlm error %d\n", | 438 | printk(KERN_INFO "lock_dlm: hold_null_lock dlm error %d\n", |
diff --git a/fs/gfs2/locking/dlm/lock_dlm.h b/fs/gfs2/locking/dlm/lock_dlm.h index d074c6e6f9bf..24d70f73b651 100644 --- a/fs/gfs2/locking/dlm/lock_dlm.h +++ b/fs/gfs2/locking/dlm/lock_dlm.h | |||
@@ -101,6 +101,7 @@ enum { | |||
101 | LFL_NOBAST = 10, | 101 | LFL_NOBAST = 10, |
102 | LFL_HEADQUE = 11, | 102 | LFL_HEADQUE = 11, |
103 | LFL_UNLOCK_DELETE = 12, | 103 | LFL_UNLOCK_DELETE = 12, |
104 | LFL_AST_WAIT = 13, | ||
104 | }; | 105 | }; |
105 | 106 | ||
106 | struct gdlm_lock { | 107 | struct gdlm_lock { |
@@ -117,7 +118,6 @@ struct gdlm_lock { | |||
117 | unsigned long flags; /* lock_dlm flags LFL_ */ | 118 | unsigned long flags; /* lock_dlm flags LFL_ */ |
118 | 119 | ||
119 | int bast_mode; /* protected by async_lock */ | 120 | int bast_mode; /* protected by async_lock */ |
120 | struct completion ast_wait; | ||
121 | 121 | ||
122 | struct list_head clist; /* complete */ | 122 | struct list_head clist; /* complete */ |
123 | struct list_head blist; /* blocking */ | 123 | struct list_head blist; /* blocking */ |
diff --git a/fs/gfs2/locking/dlm/mount.c b/fs/gfs2/locking/dlm/mount.c index 1d8faa3da8af..41c5b04caaba 100644 --- a/fs/gfs2/locking/dlm/mount.c +++ b/fs/gfs2/locking/dlm/mount.c | |||
@@ -147,7 +147,7 @@ static int gdlm_mount(char *table_name, char *host_data, | |||
147 | 147 | ||
148 | error = dlm_new_lockspace(ls->fsname, strlen(ls->fsname), | 148 | error = dlm_new_lockspace(ls->fsname, strlen(ls->fsname), |
149 | &ls->dlm_lockspace, | 149 | &ls->dlm_lockspace, |
150 | nodir ? DLM_LSFL_NODIR : 0, | 150 | DLM_LSFL_FS | (nodir ? DLM_LSFL_NODIR : 0), |
151 | GDLM_LVB_SIZE); | 151 | GDLM_LVB_SIZE); |
152 | if (error) { | 152 | if (error) { |
153 | log_error("dlm_new_lockspace error %d", error); | 153 | log_error("dlm_new_lockspace error %d", error); |
diff --git a/fs/gfs2/locking/dlm/plock.c b/fs/gfs2/locking/dlm/plock.c index f82495e18c2d..fba1f1d87e4f 100644 --- a/fs/gfs2/locking/dlm/plock.c +++ b/fs/gfs2/locking/dlm/plock.c | |||
@@ -242,7 +242,7 @@ int gdlm_plock_get(void *lockspace, struct lm_lockname *name, | |||
242 | op->info.number = name->ln_number; | 242 | op->info.number = name->ln_number; |
243 | op->info.start = fl->fl_start; | 243 | op->info.start = fl->fl_start; |
244 | op->info.end = fl->fl_end; | 244 | op->info.end = fl->fl_end; |
245 | 245 | op->info.owner = (__u64)(long) fl->fl_owner; | |
246 | 246 | ||
247 | send_op(op); | 247 | send_op(op); |
248 | wait_event(recv_wq, (op->done != 0)); | 248 | wait_event(recv_wq, (op->done != 0)); |
@@ -254,16 +254,20 @@ int gdlm_plock_get(void *lockspace, struct lm_lockname *name, | |||
254 | } | 254 | } |
255 | spin_unlock(&ops_lock); | 255 | spin_unlock(&ops_lock); |
256 | 256 | ||
257 | /* info.rv from userspace is 1 for conflict, 0 for no-conflict, | ||
258 | -ENOENT if there are no locks on the file */ | ||
259 | |||
257 | rv = op->info.rv; | 260 | rv = op->info.rv; |
258 | 261 | ||
259 | fl->fl_type = F_UNLCK; | 262 | fl->fl_type = F_UNLCK; |
260 | if (rv == -ENOENT) | 263 | if (rv == -ENOENT) |
261 | rv = 0; | 264 | rv = 0; |
262 | else if (rv == 0 && op->info.pid != fl->fl_pid) { | 265 | else if (rv > 0) { |
263 | fl->fl_type = (op->info.ex) ? F_WRLCK : F_RDLCK; | 266 | fl->fl_type = (op->info.ex) ? F_WRLCK : F_RDLCK; |
264 | fl->fl_pid = op->info.pid; | 267 | fl->fl_pid = op->info.pid; |
265 | fl->fl_start = op->info.start; | 268 | fl->fl_start = op->info.start; |
266 | fl->fl_end = op->info.end; | 269 | fl->fl_end = op->info.end; |
270 | rv = 0; | ||
267 | } | 271 | } |
268 | 272 | ||
269 | kfree(op); | 273 | kfree(op); |
diff --git a/fs/gfs2/locking/dlm/thread.c b/fs/gfs2/locking/dlm/thread.c index 9cf1f168eaf8..1aca51e45092 100644 --- a/fs/gfs2/locking/dlm/thread.c +++ b/fs/gfs2/locking/dlm/thread.c | |||
@@ -44,6 +44,13 @@ static void process_blocking(struct gdlm_lock *lp, int bast_mode) | |||
44 | ls->fscb(ls->sdp, cb, &lp->lockname); | 44 | ls->fscb(ls->sdp, cb, &lp->lockname); |
45 | } | 45 | } |
46 | 46 | ||
47 | static void wake_up_ast(struct gdlm_lock *lp) | ||
48 | { | ||
49 | clear_bit(LFL_AST_WAIT, &lp->flags); | ||
50 | smp_mb__after_clear_bit(); | ||
51 | wake_up_bit(&lp->flags, LFL_AST_WAIT); | ||
52 | } | ||
53 | |||
47 | static void process_complete(struct gdlm_lock *lp) | 54 | static void process_complete(struct gdlm_lock *lp) |
48 | { | 55 | { |
49 | struct gdlm_ls *ls = lp->ls; | 56 | struct gdlm_ls *ls = lp->ls; |
@@ -136,7 +143,7 @@ static void process_complete(struct gdlm_lock *lp) | |||
136 | */ | 143 | */ |
137 | 144 | ||
138 | if (test_and_clear_bit(LFL_SYNC_LVB, &lp->flags)) { | 145 | if (test_and_clear_bit(LFL_SYNC_LVB, &lp->flags)) { |
139 | complete(&lp->ast_wait); | 146 | wake_up_ast(lp); |
140 | return; | 147 | return; |
141 | } | 148 | } |
142 | 149 | ||
@@ -214,7 +221,7 @@ out: | |||
214 | if (test_bit(LFL_INLOCK, &lp->flags)) { | 221 | if (test_bit(LFL_INLOCK, &lp->flags)) { |
215 | clear_bit(LFL_NOBLOCK, &lp->flags); | 222 | clear_bit(LFL_NOBLOCK, &lp->flags); |
216 | lp->cur = lp->req; | 223 | lp->cur = lp->req; |
217 | complete(&lp->ast_wait); | 224 | wake_up_ast(lp); |
218 | return; | 225 | return; |
219 | } | 226 | } |
220 | 227 | ||
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index 291415ddfe51..f49a12e24086 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c | |||
@@ -83,6 +83,11 @@ static void gfs2_ail1_start_one(struct gfs2_sbd *sdp, struct gfs2_ail *ai) | |||
83 | 83 | ||
84 | gfs2_assert(sdp, bd->bd_ail == ai); | 84 | gfs2_assert(sdp, bd->bd_ail == ai); |
85 | 85 | ||
86 | if (!bh){ | ||
87 | list_move(&bd->bd_ail_st_list, &ai->ai_ail2_list); | ||
88 | continue; | ||
89 | } | ||
90 | |||
86 | if (!buffer_busy(bh)) { | 91 | if (!buffer_busy(bh)) { |
87 | if (!buffer_uptodate(bh)) { | 92 | if (!buffer_uptodate(bh)) { |
88 | gfs2_log_unlock(sdp); | 93 | gfs2_log_unlock(sdp); |
@@ -125,6 +130,11 @@ static int gfs2_ail1_empty_one(struct gfs2_sbd *sdp, struct gfs2_ail *ai, int fl | |||
125 | bd_ail_st_list) { | 130 | bd_ail_st_list) { |
126 | bh = bd->bd_bh; | 131 | bh = bd->bd_bh; |
127 | 132 | ||
133 | if (!bh){ | ||
134 | list_move(&bd->bd_ail_st_list, &ai->ai_ail2_list); | ||
135 | continue; | ||
136 | } | ||
137 | |||
128 | gfs2_assert(sdp, bd->bd_ail == ai); | 138 | gfs2_assert(sdp, bd->bd_ail == ai); |
129 | 139 | ||
130 | if (buffer_busy(bh)) { | 140 | if (buffer_busy(bh)) { |
@@ -262,8 +272,8 @@ static void ail2_empty(struct gfs2_sbd *sdp, unsigned int new_tail) | |||
262 | * @sdp: The GFS2 superblock | 272 | * @sdp: The GFS2 superblock |
263 | * @blks: The number of blocks to reserve | 273 | * @blks: The number of blocks to reserve |
264 | * | 274 | * |
265 | * Note that we never give out the last 6 blocks of the journal. Thats | 275 | * Note that we never give out the last few blocks of the journal. Thats |
266 | * due to the fact that there is are a small number of header blocks | 276 | * due to the fact that there is a small number of header blocks |
267 | * associated with each log flush. The exact number can't be known until | 277 | * associated with each log flush. The exact number can't be known until |
268 | * flush time, so we ensure that we have just enough free blocks at all | 278 | * flush time, so we ensure that we have just enough free blocks at all |
269 | * times to avoid running out during a log flush. | 279 | * times to avoid running out during a log flush. |
@@ -274,6 +284,7 @@ static void ail2_empty(struct gfs2_sbd *sdp, unsigned int new_tail) | |||
274 | int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks) | 284 | int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks) |
275 | { | 285 | { |
276 | unsigned int try = 0; | 286 | unsigned int try = 0; |
287 | unsigned reserved_blks = 6 * (4096 / sdp->sd_vfs->s_blocksize); | ||
277 | 288 | ||
278 | if (gfs2_assert_warn(sdp, blks) || | 289 | if (gfs2_assert_warn(sdp, blks) || |
279 | gfs2_assert_warn(sdp, blks <= sdp->sd_jdesc->jd_blocks)) | 290 | gfs2_assert_warn(sdp, blks <= sdp->sd_jdesc->jd_blocks)) |
@@ -281,7 +292,7 @@ int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks) | |||
281 | 292 | ||
282 | mutex_lock(&sdp->sd_log_reserve_mutex); | 293 | mutex_lock(&sdp->sd_log_reserve_mutex); |
283 | gfs2_log_lock(sdp); | 294 | gfs2_log_lock(sdp); |
284 | while(sdp->sd_log_blks_free <= (blks + 6)) { | 295 | while(sdp->sd_log_blks_free <= (blks + reserved_blks)) { |
285 | gfs2_log_unlock(sdp); | 296 | gfs2_log_unlock(sdp); |
286 | gfs2_ail1_empty(sdp, 0); | 297 | gfs2_ail1_empty(sdp, 0); |
287 | gfs2_log_flush(sdp, NULL); | 298 | gfs2_log_flush(sdp, NULL); |
@@ -357,6 +368,58 @@ static inline unsigned int log_distance(struct gfs2_sbd *sdp, unsigned int newer | |||
357 | return dist; | 368 | return dist; |
358 | } | 369 | } |
359 | 370 | ||
371 | /** | ||
372 | * calc_reserved - Calculate the number of blocks to reserve when | ||
373 | * refunding a transaction's unused buffers. | ||
374 | * @sdp: The GFS2 superblock | ||
375 | * | ||
376 | * This is complex. We need to reserve room for all our currently used | ||
377 | * metadata buffers (e.g. normal file I/O rewriting file time stamps) and | ||
378 | * all our journaled data buffers for journaled files (e.g. files in the | ||
379 | * meta_fs like rindex, or files for which chattr +j was done.) | ||
380 | * If we don't reserve enough space, gfs2_log_refund and gfs2_log_flush | ||
381 | * will count it as free space (sd_log_blks_free) and corruption will follow. | ||
382 | * | ||
383 | * We can have metadata bufs and jdata bufs in the same journal. So each | ||
384 | * type gets its own log header, for which we need to reserve a block. | ||
385 | * In fact, each type has the potential for needing more than one header | ||
386 | * in cases where we have more buffers than will fit on a journal page. | ||
387 | * Metadata journal entries take up half the space of journaled buffer entries. | ||
388 | * Thus, metadata entries have buf_limit (502) and journaled buffers have | ||
389 | * databuf_limit (251) before they cause a wrap around. | ||
390 | * | ||
391 | * Also, we need to reserve blocks for revoke journal entries and one for an | ||
392 | * overall header for the lot. | ||
393 | * | ||
394 | * Returns: the number of blocks reserved | ||
395 | */ | ||
396 | static unsigned int calc_reserved(struct gfs2_sbd *sdp) | ||
397 | { | ||
398 | unsigned int reserved = 0; | ||
399 | unsigned int mbuf_limit, metabufhdrs_needed; | ||
400 | unsigned int dbuf_limit, databufhdrs_needed; | ||
401 | unsigned int revokes = 0; | ||
402 | |||
403 | mbuf_limit = buf_limit(sdp); | ||
404 | metabufhdrs_needed = (sdp->sd_log_commited_buf + | ||
405 | (mbuf_limit - 1)) / mbuf_limit; | ||
406 | dbuf_limit = databuf_limit(sdp); | ||
407 | databufhdrs_needed = (sdp->sd_log_commited_databuf + | ||
408 | (dbuf_limit - 1)) / dbuf_limit; | ||
409 | |||
410 | if (sdp->sd_log_commited_revoke) | ||
411 | revokes = gfs2_struct2blk(sdp, sdp->sd_log_commited_revoke, | ||
412 | sizeof(u64)); | ||
413 | |||
414 | reserved = sdp->sd_log_commited_buf + metabufhdrs_needed + | ||
415 | sdp->sd_log_commited_databuf + databufhdrs_needed + | ||
416 | revokes; | ||
417 | /* One for the overall header */ | ||
418 | if (reserved) | ||
419 | reserved++; | ||
420 | return reserved; | ||
421 | } | ||
422 | |||
360 | static unsigned int current_tail(struct gfs2_sbd *sdp) | 423 | static unsigned int current_tail(struct gfs2_sbd *sdp) |
361 | { | 424 | { |
362 | struct gfs2_ail *ai; | 425 | struct gfs2_ail *ai; |
@@ -447,14 +510,14 @@ struct buffer_head *gfs2_log_fake_buf(struct gfs2_sbd *sdp, | |||
447 | return bh; | 510 | return bh; |
448 | } | 511 | } |
449 | 512 | ||
450 | static void log_pull_tail(struct gfs2_sbd *sdp, unsigned int new_tail, int pull) | 513 | static void log_pull_tail(struct gfs2_sbd *sdp, unsigned int new_tail) |
451 | { | 514 | { |
452 | unsigned int dist = log_distance(sdp, new_tail, sdp->sd_log_tail); | 515 | unsigned int dist = log_distance(sdp, new_tail, sdp->sd_log_tail); |
453 | 516 | ||
454 | ail2_empty(sdp, new_tail); | 517 | ail2_empty(sdp, new_tail); |
455 | 518 | ||
456 | gfs2_log_lock(sdp); | 519 | gfs2_log_lock(sdp); |
457 | sdp->sd_log_blks_free += dist - (pull ? 1 : 0); | 520 | sdp->sd_log_blks_free += dist; |
458 | gfs2_assert_withdraw(sdp, sdp->sd_log_blks_free <= sdp->sd_jdesc->jd_blocks); | 521 | gfs2_assert_withdraw(sdp, sdp->sd_log_blks_free <= sdp->sd_jdesc->jd_blocks); |
459 | gfs2_log_unlock(sdp); | 522 | gfs2_log_unlock(sdp); |
460 | 523 | ||
@@ -504,7 +567,7 @@ static void log_write_header(struct gfs2_sbd *sdp, u32 flags, int pull) | |||
504 | brelse(bh); | 567 | brelse(bh); |
505 | 568 | ||
506 | if (sdp->sd_log_tail != tail) | 569 | if (sdp->sd_log_tail != tail) |
507 | log_pull_tail(sdp, tail, pull); | 570 | log_pull_tail(sdp, tail); |
508 | else | 571 | else |
509 | gfs2_assert_withdraw(sdp, !pull); | 572 | gfs2_assert_withdraw(sdp, !pull); |
510 | 573 | ||
@@ -517,6 +580,7 @@ static void log_flush_commit(struct gfs2_sbd *sdp) | |||
517 | struct list_head *head = &sdp->sd_log_flush_list; | 580 | struct list_head *head = &sdp->sd_log_flush_list; |
518 | struct gfs2_log_buf *lb; | 581 | struct gfs2_log_buf *lb; |
519 | struct buffer_head *bh; | 582 | struct buffer_head *bh; |
583 | int flushcount = 0; | ||
520 | 584 | ||
521 | while (!list_empty(head)) { | 585 | while (!list_empty(head)) { |
522 | lb = list_entry(head->next, struct gfs2_log_buf, lb_list); | 586 | lb = list_entry(head->next, struct gfs2_log_buf, lb_list); |
@@ -533,9 +597,20 @@ static void log_flush_commit(struct gfs2_sbd *sdp) | |||
533 | } else | 597 | } else |
534 | brelse(bh); | 598 | brelse(bh); |
535 | kfree(lb); | 599 | kfree(lb); |
600 | flushcount++; | ||
536 | } | 601 | } |
537 | 602 | ||
538 | log_write_header(sdp, 0, 0); | 603 | /* If nothing was journaled, the header is unplanned and unwanted. */ |
604 | if (flushcount) { | ||
605 | log_write_header(sdp, 0, 0); | ||
606 | } else { | ||
607 | unsigned int tail; | ||
608 | tail = current_tail(sdp); | ||
609 | |||
610 | gfs2_ail1_empty(sdp, 0); | ||
611 | if (sdp->sd_log_tail != tail) | ||
612 | log_pull_tail(sdp, tail); | ||
613 | } | ||
539 | } | 614 | } |
540 | 615 | ||
541 | /** | 616 | /** |
@@ -565,7 +640,10 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl) | |||
565 | INIT_LIST_HEAD(&ai->ai_ail1_list); | 640 | INIT_LIST_HEAD(&ai->ai_ail1_list); |
566 | INIT_LIST_HEAD(&ai->ai_ail2_list); | 641 | INIT_LIST_HEAD(&ai->ai_ail2_list); |
567 | 642 | ||
568 | gfs2_assert_withdraw(sdp, sdp->sd_log_num_buf == sdp->sd_log_commited_buf); | 643 | gfs2_assert_withdraw(sdp, |
644 | sdp->sd_log_num_buf + sdp->sd_log_num_jdata == | ||
645 | sdp->sd_log_commited_buf + | ||
646 | sdp->sd_log_commited_databuf); | ||
569 | gfs2_assert_withdraw(sdp, | 647 | gfs2_assert_withdraw(sdp, |
570 | sdp->sd_log_num_revoke == sdp->sd_log_commited_revoke); | 648 | sdp->sd_log_num_revoke == sdp->sd_log_commited_revoke); |
571 | 649 | ||
@@ -576,16 +654,19 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl) | |||
576 | lops_before_commit(sdp); | 654 | lops_before_commit(sdp); |
577 | if (!list_empty(&sdp->sd_log_flush_list)) | 655 | if (!list_empty(&sdp->sd_log_flush_list)) |
578 | log_flush_commit(sdp); | 656 | log_flush_commit(sdp); |
579 | else if (sdp->sd_log_tail != current_tail(sdp) && !sdp->sd_log_idle) | 657 | else if (sdp->sd_log_tail != current_tail(sdp) && !sdp->sd_log_idle){ |
658 | gfs2_log_lock(sdp); | ||
659 | sdp->sd_log_blks_free--; /* Adjust for unreserved buffer */ | ||
660 | gfs2_log_unlock(sdp); | ||
580 | log_write_header(sdp, 0, PULL); | 661 | log_write_header(sdp, 0, PULL); |
662 | } | ||
581 | lops_after_commit(sdp, ai); | 663 | lops_after_commit(sdp, ai); |
582 | 664 | ||
583 | gfs2_log_lock(sdp); | 665 | gfs2_log_lock(sdp); |
584 | sdp->sd_log_head = sdp->sd_log_flush_head; | 666 | sdp->sd_log_head = sdp->sd_log_flush_head; |
585 | sdp->sd_log_blks_free -= sdp->sd_log_num_hdrs; | ||
586 | sdp->sd_log_blks_reserved = 0; | 667 | sdp->sd_log_blks_reserved = 0; |
587 | sdp->sd_log_commited_buf = 0; | 668 | sdp->sd_log_commited_buf = 0; |
588 | sdp->sd_log_num_hdrs = 0; | 669 | sdp->sd_log_commited_databuf = 0; |
589 | sdp->sd_log_commited_revoke = 0; | 670 | sdp->sd_log_commited_revoke = 0; |
590 | 671 | ||
591 | if (!list_empty(&ai->ai_ail1_list)) { | 672 | if (!list_empty(&ai->ai_ail1_list)) { |
@@ -602,32 +683,26 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl) | |||
602 | 683 | ||
603 | static void log_refund(struct gfs2_sbd *sdp, struct gfs2_trans *tr) | 684 | static void log_refund(struct gfs2_sbd *sdp, struct gfs2_trans *tr) |
604 | { | 685 | { |
605 | unsigned int reserved = 0; | 686 | unsigned int reserved; |
606 | unsigned int old; | 687 | unsigned int old; |
607 | 688 | ||
608 | gfs2_log_lock(sdp); | 689 | gfs2_log_lock(sdp); |
609 | 690 | ||
610 | sdp->sd_log_commited_buf += tr->tr_num_buf_new - tr->tr_num_buf_rm; | 691 | sdp->sd_log_commited_buf += tr->tr_num_buf_new - tr->tr_num_buf_rm; |
611 | gfs2_assert_withdraw(sdp, ((int)sdp->sd_log_commited_buf) >= 0); | 692 | sdp->sd_log_commited_databuf += tr->tr_num_databuf_new - |
693 | tr->tr_num_databuf_rm; | ||
694 | gfs2_assert_withdraw(sdp, (((int)sdp->sd_log_commited_buf) >= 0) || | ||
695 | (((int)sdp->sd_log_commited_databuf) >= 0)); | ||
612 | sdp->sd_log_commited_revoke += tr->tr_num_revoke - tr->tr_num_revoke_rm; | 696 | sdp->sd_log_commited_revoke += tr->tr_num_revoke - tr->tr_num_revoke_rm; |
613 | gfs2_assert_withdraw(sdp, ((int)sdp->sd_log_commited_revoke) >= 0); | 697 | gfs2_assert_withdraw(sdp, ((int)sdp->sd_log_commited_revoke) >= 0); |
614 | 698 | reserved = calc_reserved(sdp); | |
615 | if (sdp->sd_log_commited_buf) | ||
616 | reserved += sdp->sd_log_commited_buf; | ||
617 | if (sdp->sd_log_commited_revoke) | ||
618 | reserved += gfs2_struct2blk(sdp, sdp->sd_log_commited_revoke, | ||
619 | sizeof(u64)); | ||
620 | if (reserved) | ||
621 | reserved++; | ||
622 | |||
623 | old = sdp->sd_log_blks_free; | 699 | old = sdp->sd_log_blks_free; |
624 | sdp->sd_log_blks_free += tr->tr_reserved - | 700 | sdp->sd_log_blks_free += tr->tr_reserved - |
625 | (reserved - sdp->sd_log_blks_reserved); | 701 | (reserved - sdp->sd_log_blks_reserved); |
626 | 702 | ||
627 | gfs2_assert_withdraw(sdp, sdp->sd_log_blks_free >= old); | 703 | gfs2_assert_withdraw(sdp, sdp->sd_log_blks_free >= old); |
628 | gfs2_assert_withdraw(sdp, | 704 | gfs2_assert_withdraw(sdp, sdp->sd_log_blks_free <= |
629 | sdp->sd_log_blks_free <= sdp->sd_jdesc->jd_blocks + | 705 | sdp->sd_jdesc->jd_blocks); |
630 | sdp->sd_log_num_hdrs); | ||
631 | 706 | ||
632 | sdp->sd_log_blks_reserved = reserved; | 707 | sdp->sd_log_blks_reserved = reserved; |
633 | 708 | ||
@@ -673,13 +748,13 @@ void gfs2_log_shutdown(struct gfs2_sbd *sdp) | |||
673 | gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke); | 748 | gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke); |
674 | gfs2_assert_withdraw(sdp, !sdp->sd_log_num_rg); | 749 | gfs2_assert_withdraw(sdp, !sdp->sd_log_num_rg); |
675 | gfs2_assert_withdraw(sdp, !sdp->sd_log_num_databuf); | 750 | gfs2_assert_withdraw(sdp, !sdp->sd_log_num_databuf); |
676 | gfs2_assert_withdraw(sdp, !sdp->sd_log_num_hdrs); | ||
677 | gfs2_assert_withdraw(sdp, list_empty(&sdp->sd_ail1_list)); | 751 | gfs2_assert_withdraw(sdp, list_empty(&sdp->sd_ail1_list)); |
678 | 752 | ||
679 | sdp->sd_log_flush_head = sdp->sd_log_head; | 753 | sdp->sd_log_flush_head = sdp->sd_log_head; |
680 | sdp->sd_log_flush_wrapped = 0; | 754 | sdp->sd_log_flush_wrapped = 0; |
681 | 755 | ||
682 | log_write_header(sdp, GFS2_LOG_HEAD_UNMOUNT, 0); | 756 | log_write_header(sdp, GFS2_LOG_HEAD_UNMOUNT, |
757 | (sdp->sd_log_tail == current_tail(sdp)) ? 0 : PULL); | ||
683 | 758 | ||
684 | gfs2_assert_warn(sdp, sdp->sd_log_blks_free == sdp->sd_jdesc->jd_blocks); | 759 | gfs2_assert_warn(sdp, sdp->sd_log_blks_free == sdp->sd_jdesc->jd_blocks); |
685 | gfs2_assert_warn(sdp, sdp->sd_log_head == sdp->sd_log_tail); | 760 | gfs2_assert_warn(sdp, sdp->sd_log_head == sdp->sd_log_tail); |
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c index f82d84d05d23..aff70f0698fd 100644 --- a/fs/gfs2/lops.c +++ b/fs/gfs2/lops.c | |||
@@ -17,6 +17,7 @@ | |||
17 | 17 | ||
18 | #include "gfs2.h" | 18 | #include "gfs2.h" |
19 | #include "incore.h" | 19 | #include "incore.h" |
20 | #include "inode.h" | ||
20 | #include "glock.h" | 21 | #include "glock.h" |
21 | #include "log.h" | 22 | #include "log.h" |
22 | #include "lops.h" | 23 | #include "lops.h" |
@@ -117,15 +118,13 @@ static void buf_lo_before_commit(struct gfs2_sbd *sdp) | |||
117 | struct gfs2_log_descriptor *ld; | 118 | struct gfs2_log_descriptor *ld; |
118 | struct gfs2_bufdata *bd1 = NULL, *bd2; | 119 | struct gfs2_bufdata *bd1 = NULL, *bd2; |
119 | unsigned int total = sdp->sd_log_num_buf; | 120 | unsigned int total = sdp->sd_log_num_buf; |
120 | unsigned int offset = sizeof(struct gfs2_log_descriptor); | 121 | unsigned int offset = BUF_OFFSET; |
121 | unsigned int limit; | 122 | unsigned int limit; |
122 | unsigned int num; | 123 | unsigned int num; |
123 | unsigned n; | 124 | unsigned n; |
124 | __be64 *ptr; | 125 | __be64 *ptr; |
125 | 126 | ||
126 | offset += sizeof(__be64) - 1; | 127 | limit = buf_limit(sdp); |
127 | offset &= ~(sizeof(__be64) - 1); | ||
128 | limit = (sdp->sd_sb.sb_bsize - offset)/sizeof(__be64); | ||
129 | /* for 4k blocks, limit = 503 */ | 128 | /* for 4k blocks, limit = 503 */ |
130 | 129 | ||
131 | bd1 = bd2 = list_prepare_entry(bd1, &sdp->sd_log_le_buf, bd_le.le_list); | 130 | bd1 = bd2 = list_prepare_entry(bd1, &sdp->sd_log_le_buf, bd_le.le_list); |
@@ -134,7 +133,6 @@ static void buf_lo_before_commit(struct gfs2_sbd *sdp) | |||
134 | if (total > limit) | 133 | if (total > limit) |
135 | num = limit; | 134 | num = limit; |
136 | bh = gfs2_log_get_buf(sdp); | 135 | bh = gfs2_log_get_buf(sdp); |
137 | sdp->sd_log_num_hdrs++; | ||
138 | ld = (struct gfs2_log_descriptor *)bh->b_data; | 136 | ld = (struct gfs2_log_descriptor *)bh->b_data; |
139 | ptr = (__be64 *)(bh->b_data + offset); | 137 | ptr = (__be64 *)(bh->b_data + offset); |
140 | ld->ld_header.mh_magic = cpu_to_be32(GFS2_MAGIC); | 138 | ld->ld_header.mh_magic = cpu_to_be32(GFS2_MAGIC); |
@@ -469,25 +467,28 @@ static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le) | |||
469 | struct gfs2_inode *ip = GFS2_I(mapping->host); | 467 | struct gfs2_inode *ip = GFS2_I(mapping->host); |
470 | 468 | ||
471 | gfs2_log_lock(sdp); | 469 | gfs2_log_lock(sdp); |
470 | if (!list_empty(&bd->bd_list_tr)) { | ||
471 | gfs2_log_unlock(sdp); | ||
472 | return; | ||
473 | } | ||
472 | tr->tr_touched = 1; | 474 | tr->tr_touched = 1; |
473 | if (list_empty(&bd->bd_list_tr) && | 475 | if (gfs2_is_jdata(ip)) { |
474 | (ip->i_di.di_flags & GFS2_DIF_JDATA)) { | ||
475 | tr->tr_num_buf++; | 476 | tr->tr_num_buf++; |
476 | list_add(&bd->bd_list_tr, &tr->tr_list_buf); | 477 | list_add(&bd->bd_list_tr, &tr->tr_list_buf); |
477 | gfs2_log_unlock(sdp); | ||
478 | gfs2_pin(sdp, bd->bd_bh); | ||
479 | tr->tr_num_buf_new++; | ||
480 | } else { | ||
481 | gfs2_log_unlock(sdp); | ||
482 | } | 478 | } |
479 | gfs2_log_unlock(sdp); | ||
480 | if (!list_empty(&le->le_list)) | ||
481 | return; | ||
482 | |||
483 | gfs2_trans_add_gl(bd->bd_gl); | 483 | gfs2_trans_add_gl(bd->bd_gl); |
484 | gfs2_log_lock(sdp); | 484 | if (gfs2_is_jdata(ip)) { |
485 | if (list_empty(&le->le_list)) { | 485 | sdp->sd_log_num_jdata++; |
486 | if (ip->i_di.di_flags & GFS2_DIF_JDATA) | 486 | gfs2_pin(sdp, bd->bd_bh); |
487 | sdp->sd_log_num_jdata++; | 487 | tr->tr_num_databuf_new++; |
488 | sdp->sd_log_num_databuf++; | ||
489 | list_add(&le->le_list, &sdp->sd_log_le_databuf); | ||
490 | } | 488 | } |
489 | sdp->sd_log_num_databuf++; | ||
490 | gfs2_log_lock(sdp); | ||
491 | list_add(&le->le_list, &sdp->sd_log_le_databuf); | ||
491 | gfs2_log_unlock(sdp); | 492 | gfs2_log_unlock(sdp); |
492 | } | 493 | } |
493 | 494 | ||
@@ -520,7 +521,6 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp) | |||
520 | LIST_HEAD(started); | 521 | LIST_HEAD(started); |
521 | struct gfs2_bufdata *bd1 = NULL, *bd2, *bdt; | 522 | struct gfs2_bufdata *bd1 = NULL, *bd2, *bdt; |
522 | struct buffer_head *bh = NULL,*bh1 = NULL; | 523 | struct buffer_head *bh = NULL,*bh1 = NULL; |
523 | unsigned int offset = sizeof(struct gfs2_log_descriptor); | ||
524 | struct gfs2_log_descriptor *ld; | 524 | struct gfs2_log_descriptor *ld; |
525 | unsigned int limit; | 525 | unsigned int limit; |
526 | unsigned int total_dbuf = sdp->sd_log_num_databuf; | 526 | unsigned int total_dbuf = sdp->sd_log_num_databuf; |
@@ -528,9 +528,7 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp) | |||
528 | unsigned int num, n; | 528 | unsigned int num, n; |
529 | __be64 *ptr = NULL; | 529 | __be64 *ptr = NULL; |
530 | 530 | ||
531 | offset += 2*sizeof(__be64) - 1; | 531 | limit = databuf_limit(sdp); |
532 | offset &= ~(2*sizeof(__be64) - 1); | ||
533 | limit = (sdp->sd_sb.sb_bsize - offset)/sizeof(__be64); | ||
534 | 532 | ||
535 | /* | 533 | /* |
536 | * Start writing ordered buffers, write journaled buffers | 534 | * Start writing ordered buffers, write journaled buffers |
@@ -581,10 +579,10 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp) | |||
581 | gfs2_log_unlock(sdp); | 579 | gfs2_log_unlock(sdp); |
582 | if (!bh) { | 580 | if (!bh) { |
583 | bh = gfs2_log_get_buf(sdp); | 581 | bh = gfs2_log_get_buf(sdp); |
584 | sdp->sd_log_num_hdrs++; | ||
585 | ld = (struct gfs2_log_descriptor *) | 582 | ld = (struct gfs2_log_descriptor *) |
586 | bh->b_data; | 583 | bh->b_data; |
587 | ptr = (__be64 *)(bh->b_data + offset); | 584 | ptr = (__be64 *)(bh->b_data + |
585 | DATABUF_OFFSET); | ||
588 | ld->ld_header.mh_magic = | 586 | ld->ld_header.mh_magic = |
589 | cpu_to_be32(GFS2_MAGIC); | 587 | cpu_to_be32(GFS2_MAGIC); |
590 | ld->ld_header.mh_type = | 588 | ld->ld_header.mh_type = |
@@ -605,7 +603,7 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp) | |||
605 | if (unlikely(magic != 0)) | 603 | if (unlikely(magic != 0)) |
606 | set_buffer_escaped(bh1); | 604 | set_buffer_escaped(bh1); |
607 | gfs2_log_lock(sdp); | 605 | gfs2_log_lock(sdp); |
608 | if (n++ > num) | 606 | if (++n >= num) |
609 | break; | 607 | break; |
610 | } else if (!bh1) { | 608 | } else if (!bh1) { |
611 | total_dbuf--; | 609 | total_dbuf--; |
@@ -622,6 +620,7 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp) | |||
622 | } | 620 | } |
623 | gfs2_log_unlock(sdp); | 621 | gfs2_log_unlock(sdp); |
624 | if (bh) { | 622 | if (bh) { |
623 | set_buffer_mapped(bh); | ||
625 | set_buffer_dirty(bh); | 624 | set_buffer_dirty(bh); |
626 | ll_rw_block(WRITE, 1, &bh); | 625 | ll_rw_block(WRITE, 1, &bh); |
627 | bh = NULL; | 626 | bh = NULL; |
diff --git a/fs/gfs2/lops.h b/fs/gfs2/lops.h index 965bc65c7c64..41a00df75587 100644 --- a/fs/gfs2/lops.h +++ b/fs/gfs2/lops.h | |||
@@ -13,6 +13,13 @@ | |||
13 | #include <linux/list.h> | 13 | #include <linux/list.h> |
14 | #include "incore.h" | 14 | #include "incore.h" |
15 | 15 | ||
16 | #define BUF_OFFSET \ | ||
17 | ((sizeof(struct gfs2_log_descriptor) + sizeof(__be64) - 1) & \ | ||
18 | ~(sizeof(__be64) - 1)) | ||
19 | #define DATABUF_OFFSET \ | ||
20 | ((sizeof(struct gfs2_log_descriptor) + (2 * sizeof(__be64) - 1)) & \ | ||
21 | ~(2 * sizeof(__be64) - 1)) | ||
22 | |||
16 | extern const struct gfs2_log_operations gfs2_glock_lops; | 23 | extern const struct gfs2_log_operations gfs2_glock_lops; |
17 | extern const struct gfs2_log_operations gfs2_buf_lops; | 24 | extern const struct gfs2_log_operations gfs2_buf_lops; |
18 | extern const struct gfs2_log_operations gfs2_revoke_lops; | 25 | extern const struct gfs2_log_operations gfs2_revoke_lops; |
@@ -21,6 +28,22 @@ extern const struct gfs2_log_operations gfs2_databuf_lops; | |||
21 | 28 | ||
22 | extern const struct gfs2_log_operations *gfs2_log_ops[]; | 29 | extern const struct gfs2_log_operations *gfs2_log_ops[]; |
23 | 30 | ||
31 | static inline unsigned int buf_limit(struct gfs2_sbd *sdp) | ||
32 | { | ||
33 | unsigned int limit; | ||
34 | |||
35 | limit = (sdp->sd_sb.sb_bsize - BUF_OFFSET) / sizeof(__be64); | ||
36 | return limit; | ||
37 | } | ||
38 | |||
39 | static inline unsigned int databuf_limit(struct gfs2_sbd *sdp) | ||
40 | { | ||
41 | unsigned int limit; | ||
42 | |||
43 | limit = (sdp->sd_sb.sb_bsize - DATABUF_OFFSET) / (2 * sizeof(__be64)); | ||
44 | return limit; | ||
45 | } | ||
46 | |||
24 | static inline void lops_init_le(struct gfs2_log_element *le, | 47 | static inline void lops_init_le(struct gfs2_log_element *le, |
25 | const struct gfs2_log_operations *lops) | 48 | const struct gfs2_log_operations *lops) |
26 | { | 49 | { |
diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c index e62d4f620c58..8da343b34ae7 100644 --- a/fs/gfs2/meta_io.c +++ b/fs/gfs2/meta_io.c | |||
@@ -387,12 +387,18 @@ void gfs2_meta_wipe(struct gfs2_inode *ip, u64 bstart, u32 blen) | |||
387 | 387 | ||
388 | if (test_clear_buffer_pinned(bh)) { | 388 | if (test_clear_buffer_pinned(bh)) { |
389 | struct gfs2_trans *tr = current->journal_info; | 389 | struct gfs2_trans *tr = current->journal_info; |
390 | struct gfs2_inode *bh_ip = | ||
391 | GFS2_I(bh->b_page->mapping->host); | ||
392 | |||
390 | gfs2_log_lock(sdp); | 393 | gfs2_log_lock(sdp); |
391 | list_del_init(&bd->bd_le.le_list); | 394 | list_del_init(&bd->bd_le.le_list); |
392 | gfs2_assert_warn(sdp, sdp->sd_log_num_buf); | 395 | gfs2_assert_warn(sdp, sdp->sd_log_num_buf); |
393 | sdp->sd_log_num_buf--; | 396 | sdp->sd_log_num_buf--; |
394 | gfs2_log_unlock(sdp); | 397 | gfs2_log_unlock(sdp); |
395 | tr->tr_num_buf_rm++; | 398 | if (bh_ip->i_inode.i_private != NULL) |
399 | tr->tr_num_databuf_rm++; | ||
400 | else | ||
401 | tr->tr_num_buf_rm++; | ||
396 | brelse(bh); | 402 | brelse(bh); |
397 | } | 403 | } |
398 | if (bd) { | 404 | if (bd) { |
diff --git a/fs/gfs2/meta_io.h b/fs/gfs2/meta_io.h index e037425bc042..527bf19d9690 100644 --- a/fs/gfs2/meta_io.h +++ b/fs/gfs2/meta_io.h | |||
@@ -63,7 +63,7 @@ int gfs2_meta_indirect_buffer(struct gfs2_inode *ip, int height, u64 num, | |||
63 | static inline int gfs2_meta_inode_buffer(struct gfs2_inode *ip, | 63 | static inline int gfs2_meta_inode_buffer(struct gfs2_inode *ip, |
64 | struct buffer_head **bhp) | 64 | struct buffer_head **bhp) |
65 | { | 65 | { |
66 | return gfs2_meta_indirect_buffer(ip, 0, ip->i_num.no_addr, 0, bhp); | 66 | return gfs2_meta_indirect_buffer(ip, 0, ip->i_no_addr, 0, bhp); |
67 | } | 67 | } |
68 | 68 | ||
69 | struct buffer_head *gfs2_meta_ra(struct gfs2_glock *gl, u64 dblock, u32 extlen); | 69 | struct buffer_head *gfs2_meta_ra(struct gfs2_glock *gl, u64 dblock, u32 extlen); |
diff --git a/fs/gfs2/mount.c b/fs/gfs2/mount.c index 4864659555d4..6f006a804db3 100644 --- a/fs/gfs2/mount.c +++ b/fs/gfs2/mount.c | |||
@@ -82,20 +82,19 @@ int gfs2_mount_args(struct gfs2_sbd *sdp, char *data_arg, int remount) | |||
82 | char *options, *o, *v; | 82 | char *options, *o, *v; |
83 | int error = 0; | 83 | int error = 0; |
84 | 84 | ||
85 | if (!remount) { | 85 | /* If someone preloaded options, use those instead */ |
86 | /* If someone preloaded options, use those instead */ | 86 | spin_lock(&gfs2_sys_margs_lock); |
87 | spin_lock(&gfs2_sys_margs_lock); | 87 | if (!remount && gfs2_sys_margs) { |
88 | if (gfs2_sys_margs) { | 88 | data = gfs2_sys_margs; |
89 | data = gfs2_sys_margs; | 89 | gfs2_sys_margs = NULL; |
90 | gfs2_sys_margs = NULL; | ||
91 | } | ||
92 | spin_unlock(&gfs2_sys_margs_lock); | ||
93 | |||
94 | /* Set some defaults */ | ||
95 | args->ar_num_glockd = GFS2_GLOCKD_DEFAULT; | ||
96 | args->ar_quota = GFS2_QUOTA_DEFAULT; | ||
97 | args->ar_data = GFS2_DATA_DEFAULT; | ||
98 | } | 90 | } |
91 | spin_unlock(&gfs2_sys_margs_lock); | ||
92 | |||
93 | /* Set some defaults */ | ||
94 | memset(args, 0, sizeof(struct gfs2_args)); | ||
95 | args->ar_num_glockd = GFS2_GLOCKD_DEFAULT; | ||
96 | args->ar_quota = GFS2_QUOTA_DEFAULT; | ||
97 | args->ar_data = GFS2_DATA_DEFAULT; | ||
99 | 98 | ||
100 | /* Split the options into tokens with the "," character and | 99 | /* Split the options into tokens with the "," character and |
101 | process them */ | 100 | process them */ |
diff --git a/fs/gfs2/ondisk.c b/fs/gfs2/ondisk.c deleted file mode 100644 index d9ecfd23a49e..000000000000 --- a/fs/gfs2/ondisk.c +++ /dev/null | |||
@@ -1,251 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | ||
3 | * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. | ||
4 | * | ||
5 | * This copyrighted material is made available to anyone wishing to use, | ||
6 | * modify, copy, or redistribute it subject to the terms and conditions | ||
7 | * of the GNU General Public License version 2. | ||
8 | */ | ||
9 | |||
10 | #include <linux/slab.h> | ||
11 | #include <linux/spinlock.h> | ||
12 | #include <linux/completion.h> | ||
13 | #include <linux/buffer_head.h> | ||
14 | |||
15 | #include "gfs2.h" | ||
16 | #include <linux/gfs2_ondisk.h> | ||
17 | #include <linux/lm_interface.h> | ||
18 | #include "incore.h" | ||
19 | |||
20 | #define pv(struct, member, fmt) printk(KERN_INFO " "#member" = "fmt"\n", \ | ||
21 | struct->member); | ||
22 | |||
23 | /* | ||
24 | * gfs2_xxx_in - read in an xxx struct | ||
25 | * first arg: the cpu-order structure | ||
26 | * buf: the disk-order buffer | ||
27 | * | ||
28 | * gfs2_xxx_out - write out an xxx struct | ||
29 | * first arg: the cpu-order structure | ||
30 | * buf: the disk-order buffer | ||
31 | * | ||
32 | * gfs2_xxx_print - print out an xxx struct | ||
33 | * first arg: the cpu-order structure | ||
34 | */ | ||
35 | |||
36 | void gfs2_inum_in(struct gfs2_inum_host *no, const void *buf) | ||
37 | { | ||
38 | const struct gfs2_inum *str = buf; | ||
39 | |||
40 | no->no_formal_ino = be64_to_cpu(str->no_formal_ino); | ||
41 | no->no_addr = be64_to_cpu(str->no_addr); | ||
42 | } | ||
43 | |||
44 | void gfs2_inum_out(const struct gfs2_inum_host *no, void *buf) | ||
45 | { | ||
46 | struct gfs2_inum *str = buf; | ||
47 | |||
48 | str->no_formal_ino = cpu_to_be64(no->no_formal_ino); | ||
49 | str->no_addr = cpu_to_be64(no->no_addr); | ||
50 | } | ||
51 | |||
52 | static void gfs2_inum_print(const struct gfs2_inum_host *no) | ||
53 | { | ||
54 | printk(KERN_INFO " no_formal_ino = %llu\n", (unsigned long long)no->no_formal_ino); | ||
55 | printk(KERN_INFO " no_addr = %llu\n", (unsigned long long)no->no_addr); | ||
56 | } | ||
57 | |||
58 | static void gfs2_meta_header_in(struct gfs2_meta_header_host *mh, const void *buf) | ||
59 | { | ||
60 | const struct gfs2_meta_header *str = buf; | ||
61 | |||
62 | mh->mh_magic = be32_to_cpu(str->mh_magic); | ||
63 | mh->mh_type = be32_to_cpu(str->mh_type); | ||
64 | mh->mh_format = be32_to_cpu(str->mh_format); | ||
65 | } | ||
66 | |||
67 | void gfs2_sb_in(struct gfs2_sb_host *sb, const void *buf) | ||
68 | { | ||
69 | const struct gfs2_sb *str = buf; | ||
70 | |||
71 | gfs2_meta_header_in(&sb->sb_header, buf); | ||
72 | |||
73 | sb->sb_fs_format = be32_to_cpu(str->sb_fs_format); | ||
74 | sb->sb_multihost_format = be32_to_cpu(str->sb_multihost_format); | ||
75 | sb->sb_bsize = be32_to_cpu(str->sb_bsize); | ||
76 | sb->sb_bsize_shift = be32_to_cpu(str->sb_bsize_shift); | ||
77 | |||
78 | gfs2_inum_in(&sb->sb_master_dir, (char *)&str->sb_master_dir); | ||
79 | gfs2_inum_in(&sb->sb_root_dir, (char *)&str->sb_root_dir); | ||
80 | |||
81 | memcpy(sb->sb_lockproto, str->sb_lockproto, GFS2_LOCKNAME_LEN); | ||
82 | memcpy(sb->sb_locktable, str->sb_locktable, GFS2_LOCKNAME_LEN); | ||
83 | } | ||
84 | |||
85 | void gfs2_rindex_in(struct gfs2_rindex_host *ri, const void *buf) | ||
86 | { | ||
87 | const struct gfs2_rindex *str = buf; | ||
88 | |||
89 | ri->ri_addr = be64_to_cpu(str->ri_addr); | ||
90 | ri->ri_length = be32_to_cpu(str->ri_length); | ||
91 | ri->ri_data0 = be64_to_cpu(str->ri_data0); | ||
92 | ri->ri_data = be32_to_cpu(str->ri_data); | ||
93 | ri->ri_bitbytes = be32_to_cpu(str->ri_bitbytes); | ||
94 | |||
95 | } | ||
96 | |||
97 | void gfs2_rindex_print(const struct gfs2_rindex_host *ri) | ||
98 | { | ||
99 | printk(KERN_INFO " ri_addr = %llu\n", (unsigned long long)ri->ri_addr); | ||
100 | pv(ri, ri_length, "%u"); | ||
101 | |||
102 | printk(KERN_INFO " ri_data0 = %llu\n", (unsigned long long)ri->ri_data0); | ||
103 | pv(ri, ri_data, "%u"); | ||
104 | |||
105 | pv(ri, ri_bitbytes, "%u"); | ||
106 | } | ||
107 | |||
108 | void gfs2_rgrp_in(struct gfs2_rgrp_host *rg, const void *buf) | ||
109 | { | ||
110 | const struct gfs2_rgrp *str = buf; | ||
111 | |||
112 | rg->rg_flags = be32_to_cpu(str->rg_flags); | ||
113 | rg->rg_free = be32_to_cpu(str->rg_free); | ||
114 | rg->rg_dinodes = be32_to_cpu(str->rg_dinodes); | ||
115 | rg->rg_igeneration = be64_to_cpu(str->rg_igeneration); | ||
116 | } | ||
117 | |||
118 | void gfs2_rgrp_out(const struct gfs2_rgrp_host *rg, void *buf) | ||
119 | { | ||
120 | struct gfs2_rgrp *str = buf; | ||
121 | |||
122 | str->rg_flags = cpu_to_be32(rg->rg_flags); | ||
123 | str->rg_free = cpu_to_be32(rg->rg_free); | ||
124 | str->rg_dinodes = cpu_to_be32(rg->rg_dinodes); | ||
125 | str->__pad = cpu_to_be32(0); | ||
126 | str->rg_igeneration = cpu_to_be64(rg->rg_igeneration); | ||
127 | memset(&str->rg_reserved, 0, sizeof(str->rg_reserved)); | ||
128 | } | ||
129 | |||
130 | void gfs2_quota_in(struct gfs2_quota_host *qu, const void *buf) | ||
131 | { | ||
132 | const struct gfs2_quota *str = buf; | ||
133 | |||
134 | qu->qu_limit = be64_to_cpu(str->qu_limit); | ||
135 | qu->qu_warn = be64_to_cpu(str->qu_warn); | ||
136 | qu->qu_value = be64_to_cpu(str->qu_value); | ||
137 | } | ||
138 | |||
139 | void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf) | ||
140 | { | ||
141 | const struct gfs2_dinode_host *di = &ip->i_di; | ||
142 | struct gfs2_dinode *str = buf; | ||
143 | |||
144 | str->di_header.mh_magic = cpu_to_be32(GFS2_MAGIC); | ||
145 | str->di_header.mh_type = cpu_to_be32(GFS2_METATYPE_DI); | ||
146 | str->di_header.__pad0 = 0; | ||
147 | str->di_header.mh_format = cpu_to_be32(GFS2_FORMAT_DI); | ||
148 | str->di_header.__pad1 = 0; | ||
149 | |||
150 | gfs2_inum_out(&ip->i_num, &str->di_num); | ||
151 | |||
152 | str->di_mode = cpu_to_be32(ip->i_inode.i_mode); | ||
153 | str->di_uid = cpu_to_be32(ip->i_inode.i_uid); | ||
154 | str->di_gid = cpu_to_be32(ip->i_inode.i_gid); | ||
155 | str->di_nlink = cpu_to_be32(ip->i_inode.i_nlink); | ||
156 | str->di_size = cpu_to_be64(di->di_size); | ||
157 | str->di_blocks = cpu_to_be64(di->di_blocks); | ||
158 | str->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec); | ||
159 | str->di_mtime = cpu_to_be64(ip->i_inode.i_mtime.tv_sec); | ||
160 | str->di_ctime = cpu_to_be64(ip->i_inode.i_ctime.tv_sec); | ||
161 | |||
162 | str->di_goal_meta = cpu_to_be64(di->di_goal_meta); | ||
163 | str->di_goal_data = cpu_to_be64(di->di_goal_data); | ||
164 | str->di_generation = cpu_to_be64(di->di_generation); | ||
165 | |||
166 | str->di_flags = cpu_to_be32(di->di_flags); | ||
167 | str->di_height = cpu_to_be16(di->di_height); | ||
168 | str->di_payload_format = cpu_to_be32(S_ISDIR(ip->i_inode.i_mode) && | ||
169 | !(ip->i_di.di_flags & GFS2_DIF_EXHASH) ? | ||
170 | GFS2_FORMAT_DE : 0); | ||
171 | str->di_depth = cpu_to_be16(di->di_depth); | ||
172 | str->di_entries = cpu_to_be32(di->di_entries); | ||
173 | |||
174 | str->di_eattr = cpu_to_be64(di->di_eattr); | ||
175 | } | ||
176 | |||
177 | void gfs2_dinode_print(const struct gfs2_inode *ip) | ||
178 | { | ||
179 | const struct gfs2_dinode_host *di = &ip->i_di; | ||
180 | |||
181 | gfs2_inum_print(&ip->i_num); | ||
182 | |||
183 | printk(KERN_INFO " di_size = %llu\n", (unsigned long long)di->di_size); | ||
184 | printk(KERN_INFO " di_blocks = %llu\n", (unsigned long long)di->di_blocks); | ||
185 | printk(KERN_INFO " di_goal_meta = %llu\n", (unsigned long long)di->di_goal_meta); | ||
186 | printk(KERN_INFO " di_goal_data = %llu\n", (unsigned long long)di->di_goal_data); | ||
187 | |||
188 | pv(di, di_flags, "0x%.8X"); | ||
189 | pv(di, di_height, "%u"); | ||
190 | |||
191 | pv(di, di_depth, "%u"); | ||
192 | pv(di, di_entries, "%u"); | ||
193 | |||
194 | printk(KERN_INFO " di_eattr = %llu\n", (unsigned long long)di->di_eattr); | ||
195 | } | ||
196 | |||
197 | void gfs2_log_header_in(struct gfs2_log_header_host *lh, const void *buf) | ||
198 | { | ||
199 | const struct gfs2_log_header *str = buf; | ||
200 | |||
201 | gfs2_meta_header_in(&lh->lh_header, buf); | ||
202 | lh->lh_sequence = be64_to_cpu(str->lh_sequence); | ||
203 | lh->lh_flags = be32_to_cpu(str->lh_flags); | ||
204 | lh->lh_tail = be32_to_cpu(str->lh_tail); | ||
205 | lh->lh_blkno = be32_to_cpu(str->lh_blkno); | ||
206 | lh->lh_hash = be32_to_cpu(str->lh_hash); | ||
207 | } | ||
208 | |||
209 | void gfs2_inum_range_in(struct gfs2_inum_range_host *ir, const void *buf) | ||
210 | { | ||
211 | const struct gfs2_inum_range *str = buf; | ||
212 | |||
213 | ir->ir_start = be64_to_cpu(str->ir_start); | ||
214 | ir->ir_length = be64_to_cpu(str->ir_length); | ||
215 | } | ||
216 | |||
217 | void gfs2_inum_range_out(const struct gfs2_inum_range_host *ir, void *buf) | ||
218 | { | ||
219 | struct gfs2_inum_range *str = buf; | ||
220 | |||
221 | str->ir_start = cpu_to_be64(ir->ir_start); | ||
222 | str->ir_length = cpu_to_be64(ir->ir_length); | ||
223 | } | ||
224 | |||
225 | void gfs2_statfs_change_in(struct gfs2_statfs_change_host *sc, const void *buf) | ||
226 | { | ||
227 | const struct gfs2_statfs_change *str = buf; | ||
228 | |||
229 | sc->sc_total = be64_to_cpu(str->sc_total); | ||
230 | sc->sc_free = be64_to_cpu(str->sc_free); | ||
231 | sc->sc_dinodes = be64_to_cpu(str->sc_dinodes); | ||
232 | } | ||
233 | |||
234 | void gfs2_statfs_change_out(const struct gfs2_statfs_change_host *sc, void *buf) | ||
235 | { | ||
236 | struct gfs2_statfs_change *str = buf; | ||
237 | |||
238 | str->sc_total = cpu_to_be64(sc->sc_total); | ||
239 | str->sc_free = cpu_to_be64(sc->sc_free); | ||
240 | str->sc_dinodes = cpu_to_be64(sc->sc_dinodes); | ||
241 | } | ||
242 | |||
243 | void gfs2_quota_change_in(struct gfs2_quota_change_host *qc, const void *buf) | ||
244 | { | ||
245 | const struct gfs2_quota_change *str = buf; | ||
246 | |||
247 | qc->qc_change = be64_to_cpu(str->qc_change); | ||
248 | qc->qc_flags = be32_to_cpu(str->qc_flags); | ||
249 | qc->qc_id = be32_to_cpu(str->qc_id); | ||
250 | } | ||
251 | |||
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c index 30c15622174f..26c888890c24 100644 --- a/fs/gfs2/ops_address.c +++ b/fs/gfs2/ops_address.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | 2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. |
3 | * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. | 3 | * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This copyrighted material is made available to anyone wishing to use, | 5 | * This copyrighted material is made available to anyone wishing to use, |
6 | * modify, copy, or redistribute it subject to the terms and conditions | 6 | * modify, copy, or redistribute it subject to the terms and conditions |
@@ -32,6 +32,7 @@ | |||
32 | #include "trans.h" | 32 | #include "trans.h" |
33 | #include "rgrp.h" | 33 | #include "rgrp.h" |
34 | #include "ops_file.h" | 34 | #include "ops_file.h" |
35 | #include "super.h" | ||
35 | #include "util.h" | 36 | #include "util.h" |
36 | #include "glops.h" | 37 | #include "glops.h" |
37 | 38 | ||
@@ -49,6 +50,8 @@ static void gfs2_page_add_databufs(struct gfs2_inode *ip, struct page *page, | |||
49 | end = start + bsize; | 50 | end = start + bsize; |
50 | if (end <= from || start >= to) | 51 | if (end <= from || start >= to) |
51 | continue; | 52 | continue; |
53 | if (gfs2_is_jdata(ip)) | ||
54 | set_buffer_uptodate(bh); | ||
52 | gfs2_trans_add_bh(ip->i_gl, bh, 0); | 55 | gfs2_trans_add_bh(ip->i_gl, bh, 0); |
53 | } | 56 | } |
54 | } | 57 | } |
@@ -134,7 +137,9 @@ static int gfs2_writepage(struct page *page, struct writeback_control *wbc) | |||
134 | return 0; /* don't care */ | 137 | return 0; /* don't care */ |
135 | } | 138 | } |
136 | 139 | ||
137 | if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED || gfs2_is_jdata(ip)) { | 140 | if ((sdp->sd_args.ar_data == GFS2_DATA_ORDERED || gfs2_is_jdata(ip)) && |
141 | PageChecked(page)) { | ||
142 | ClearPageChecked(page); | ||
138 | error = gfs2_trans_begin(sdp, RES_DINODE + 1, 0); | 143 | error = gfs2_trans_begin(sdp, RES_DINODE + 1, 0); |
139 | if (error) | 144 | if (error) |
140 | goto out_ignore; | 145 | goto out_ignore; |
@@ -203,11 +208,7 @@ static int stuffed_readpage(struct gfs2_inode *ip, struct page *page) | |||
203 | * so we need to supply one here. It doesn't happen often. | 208 | * so we need to supply one here. It doesn't happen often. |
204 | */ | 209 | */ |
205 | if (unlikely(page->index)) { | 210 | if (unlikely(page->index)) { |
206 | kaddr = kmap_atomic(page, KM_USER0); | 211 | zero_user_page(page, 0, PAGE_CACHE_SIZE, KM_USER0); |
207 | memset(kaddr, 0, PAGE_CACHE_SIZE); | ||
208 | kunmap_atomic(kaddr, KM_USER0); | ||
209 | flush_dcache_page(page); | ||
210 | SetPageUptodate(page); | ||
211 | return 0; | 212 | return 0; |
212 | } | 213 | } |
213 | 214 | ||
@@ -450,6 +451,31 @@ out_uninit: | |||
450 | } | 451 | } |
451 | 452 | ||
452 | /** | 453 | /** |
454 | * adjust_fs_space - Adjusts the free space available due to gfs2_grow | ||
455 | * @inode: the rindex inode | ||
456 | */ | ||
457 | static void adjust_fs_space(struct inode *inode) | ||
458 | { | ||
459 | struct gfs2_sbd *sdp = inode->i_sb->s_fs_info; | ||
460 | struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master; | ||
461 | struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; | ||
462 | u64 fs_total, new_free; | ||
463 | |||
464 | /* Total up the file system space, according to the latest rindex. */ | ||
465 | fs_total = gfs2_ri_total(sdp); | ||
466 | |||
467 | spin_lock(&sdp->sd_statfs_spin); | ||
468 | if (fs_total > (m_sc->sc_total + l_sc->sc_total)) | ||
469 | new_free = fs_total - (m_sc->sc_total + l_sc->sc_total); | ||
470 | else | ||
471 | new_free = 0; | ||
472 | spin_unlock(&sdp->sd_statfs_spin); | ||
473 | fs_warn(sdp, "File system extended by %llu blocks.\n", | ||
474 | (unsigned long long)new_free); | ||
475 | gfs2_statfs_change(sdp, new_free, new_free, 0); | ||
476 | } | ||
477 | |||
478 | /** | ||
453 | * gfs2_commit_write - Commit write to a file | 479 | * gfs2_commit_write - Commit write to a file |
454 | * @file: The file to write to | 480 | * @file: The file to write to |
455 | * @page: The page containing the data | 481 | * @page: The page containing the data |
@@ -511,6 +537,9 @@ static int gfs2_commit_write(struct file *file, struct page *page, | |||
511 | di->di_size = cpu_to_be64(inode->i_size); | 537 | di->di_size = cpu_to_be64(inode->i_size); |
512 | } | 538 | } |
513 | 539 | ||
540 | if (inode == sdp->sd_rindex) | ||
541 | adjust_fs_space(inode); | ||
542 | |||
514 | brelse(dibh); | 543 | brelse(dibh); |
515 | gfs2_trans_end(sdp); | 544 | gfs2_trans_end(sdp); |
516 | if (al->al_requested) { | 545 | if (al->al_requested) { |
@@ -543,6 +572,23 @@ fail_nounlock: | |||
543 | } | 572 | } |
544 | 573 | ||
545 | /** | 574 | /** |
575 | * gfs2_set_page_dirty - Page dirtying function | ||
576 | * @page: The page to dirty | ||
577 | * | ||
578 | * Returns: 1 if it dirtyed the page, or 0 otherwise | ||
579 | */ | ||
580 | |||
581 | static int gfs2_set_page_dirty(struct page *page) | ||
582 | { | ||
583 | struct gfs2_inode *ip = GFS2_I(page->mapping->host); | ||
584 | struct gfs2_sbd *sdp = GFS2_SB(page->mapping->host); | ||
585 | |||
586 | if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED || gfs2_is_jdata(ip)) | ||
587 | SetPageChecked(page); | ||
588 | return __set_page_dirty_buffers(page); | ||
589 | } | ||
590 | |||
591 | /** | ||
546 | * gfs2_bmap - Block map function | 592 | * gfs2_bmap - Block map function |
547 | * @mapping: Address space info | 593 | * @mapping: Address space info |
548 | * @lblock: The block to map | 594 | * @lblock: The block to map |
@@ -578,6 +624,8 @@ static void discard_buffer(struct gfs2_sbd *sdp, struct buffer_head *bh) | |||
578 | if (bd) { | 624 | if (bd) { |
579 | bd->bd_bh = NULL; | 625 | bd->bd_bh = NULL; |
580 | bh->b_private = NULL; | 626 | bh->b_private = NULL; |
627 | if (!bd->bd_ail && list_empty(&bd->bd_le.le_list)) | ||
628 | kmem_cache_free(gfs2_bufdata_cachep, bd); | ||
581 | } | 629 | } |
582 | gfs2_log_unlock(sdp); | 630 | gfs2_log_unlock(sdp); |
583 | 631 | ||
@@ -598,6 +646,8 @@ static void gfs2_invalidatepage(struct page *page, unsigned long offset) | |||
598 | unsigned int curr_off = 0; | 646 | unsigned int curr_off = 0; |
599 | 647 | ||
600 | BUG_ON(!PageLocked(page)); | 648 | BUG_ON(!PageLocked(page)); |
649 | if (offset == 0) | ||
650 | ClearPageChecked(page); | ||
601 | if (!page_has_buffers(page)) | 651 | if (!page_has_buffers(page)) |
602 | return; | 652 | return; |
603 | 653 | ||
@@ -728,8 +778,8 @@ static unsigned limit = 0; | |||
728 | return; | 778 | return; |
729 | 779 | ||
730 | fs_warn(sdp, "ip = %llu %llu\n", | 780 | fs_warn(sdp, "ip = %llu %llu\n", |
731 | (unsigned long long)ip->i_num.no_formal_ino, | 781 | (unsigned long long)ip->i_no_formal_ino, |
732 | (unsigned long long)ip->i_num.no_addr); | 782 | (unsigned long long)ip->i_no_addr); |
733 | 783 | ||
734 | for (x = 0; x < GFS2_MAX_META_HEIGHT; x++) | 784 | for (x = 0; x < GFS2_MAX_META_HEIGHT; x++) |
735 | fs_warn(sdp, "ip->i_cache[%u] = %s\n", | 785 | fs_warn(sdp, "ip->i_cache[%u] = %s\n", |
@@ -810,6 +860,7 @@ const struct address_space_operations gfs2_file_aops = { | |||
810 | .sync_page = block_sync_page, | 860 | .sync_page = block_sync_page, |
811 | .prepare_write = gfs2_prepare_write, | 861 | .prepare_write = gfs2_prepare_write, |
812 | .commit_write = gfs2_commit_write, | 862 | .commit_write = gfs2_commit_write, |
863 | .set_page_dirty = gfs2_set_page_dirty, | ||
813 | .bmap = gfs2_bmap, | 864 | .bmap = gfs2_bmap, |
814 | .invalidatepage = gfs2_invalidatepage, | 865 | .invalidatepage = gfs2_invalidatepage, |
815 | .releasepage = gfs2_releasepage, | 866 | .releasepage = gfs2_releasepage, |
diff --git a/fs/gfs2/ops_address.h b/fs/gfs2/ops_address.h index 35aaee4aa7e1..fa1b5b3d28b9 100644 --- a/fs/gfs2/ops_address.h +++ b/fs/gfs2/ops_address.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | 2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. |
3 | * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. | 3 | * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This copyrighted material is made available to anyone wishing to use, | 5 | * This copyrighted material is made available to anyone wishing to use, |
6 | * modify, copy, or redistribute it subject to the terms and conditions | 6 | * modify, copy, or redistribute it subject to the terms and conditions |
diff --git a/fs/gfs2/ops_dentry.c b/fs/gfs2/ops_dentry.c index a6fdc52f554a..793e334d098e 100644 --- a/fs/gfs2/ops_dentry.c +++ b/fs/gfs2/ops_dentry.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include "glock.h" | 21 | #include "glock.h" |
22 | #include "ops_dentry.h" | 22 | #include "ops_dentry.h" |
23 | #include "util.h" | 23 | #include "util.h" |
24 | #include "inode.h" | ||
24 | 25 | ||
25 | /** | 26 | /** |
26 | * gfs2_drevalidate - Check directory lookup consistency | 27 | * gfs2_drevalidate - Check directory lookup consistency |
@@ -40,14 +41,15 @@ static int gfs2_drevalidate(struct dentry *dentry, struct nameidata *nd) | |||
40 | struct gfs2_inode *dip = GFS2_I(parent->d_inode); | 41 | struct gfs2_inode *dip = GFS2_I(parent->d_inode); |
41 | struct inode *inode = dentry->d_inode; | 42 | struct inode *inode = dentry->d_inode; |
42 | struct gfs2_holder d_gh; | 43 | struct gfs2_holder d_gh; |
43 | struct gfs2_inode *ip; | 44 | struct gfs2_inode *ip = NULL; |
44 | struct gfs2_inum_host inum; | ||
45 | unsigned int type; | ||
46 | int error; | 45 | int error; |
47 | int had_lock=0; | 46 | int had_lock=0; |
48 | 47 | ||
49 | if (inode && is_bad_inode(inode)) | 48 | if (inode) { |
50 | goto invalid; | 49 | if (is_bad_inode(inode)) |
50 | goto invalid; | ||
51 | ip = GFS2_I(inode); | ||
52 | } | ||
51 | 53 | ||
52 | if (sdp->sd_args.ar_localcaching) | 54 | if (sdp->sd_args.ar_localcaching) |
53 | goto valid; | 55 | goto valid; |
@@ -59,7 +61,7 @@ static int gfs2_drevalidate(struct dentry *dentry, struct nameidata *nd) | |||
59 | goto fail; | 61 | goto fail; |
60 | } | 62 | } |
61 | 63 | ||
62 | error = gfs2_dir_search(parent->d_inode, &dentry->d_name, &inum, &type); | 64 | error = gfs2_dir_check(parent->d_inode, &dentry->d_name, ip); |
63 | switch (error) { | 65 | switch (error) { |
64 | case 0: | 66 | case 0: |
65 | if (!inode) | 67 | if (!inode) |
@@ -73,16 +75,6 @@ static int gfs2_drevalidate(struct dentry *dentry, struct nameidata *nd) | |||
73 | goto fail_gunlock; | 75 | goto fail_gunlock; |
74 | } | 76 | } |
75 | 77 | ||
76 | ip = GFS2_I(inode); | ||
77 | |||
78 | if (!gfs2_inum_equal(&ip->i_num, &inum)) | ||
79 | goto invalid_gunlock; | ||
80 | |||
81 | if (IF2DT(ip->i_inode.i_mode) != type) { | ||
82 | gfs2_consist_inode(dip); | ||
83 | goto fail_gunlock; | ||
84 | } | ||
85 | |||
86 | valid_gunlock: | 78 | valid_gunlock: |
87 | if (!had_lock) | 79 | if (!had_lock) |
88 | gfs2_glock_dq_uninit(&d_gh); | 80 | gfs2_glock_dq_uninit(&d_gh); |
diff --git a/fs/gfs2/ops_export.c b/fs/gfs2/ops_export.c index aad918337a46..b8312edee0e4 100644 --- a/fs/gfs2/ops_export.c +++ b/fs/gfs2/ops_export.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/spinlock.h> | 11 | #include <linux/spinlock.h> |
12 | #include <linux/completion.h> | 12 | #include <linux/completion.h> |
13 | #include <linux/buffer_head.h> | 13 | #include <linux/buffer_head.h> |
14 | #include <linux/exportfs.h> | ||
14 | #include <linux/gfs2_ondisk.h> | 15 | #include <linux/gfs2_ondisk.h> |
15 | #include <linux/crc32.h> | 16 | #include <linux/crc32.h> |
16 | #include <linux/lm_interface.h> | 17 | #include <linux/lm_interface.h> |
@@ -22,10 +23,14 @@ | |||
22 | #include "glops.h" | 23 | #include "glops.h" |
23 | #include "inode.h" | 24 | #include "inode.h" |
24 | #include "ops_dentry.h" | 25 | #include "ops_dentry.h" |
25 | #include "ops_export.h" | 26 | #include "ops_fstype.h" |
26 | #include "rgrp.h" | 27 | #include "rgrp.h" |
27 | #include "util.h" | 28 | #include "util.h" |
28 | 29 | ||
30 | #define GFS2_SMALL_FH_SIZE 4 | ||
31 | #define GFS2_LARGE_FH_SIZE 8 | ||
32 | #define GFS2_OLD_FH_SIZE 10 | ||
33 | |||
29 | static struct dentry *gfs2_decode_fh(struct super_block *sb, | 34 | static struct dentry *gfs2_decode_fh(struct super_block *sb, |
30 | __u32 *p, | 35 | __u32 *p, |
31 | int fh_len, | 36 | int fh_len, |
@@ -35,31 +40,28 @@ static struct dentry *gfs2_decode_fh(struct super_block *sb, | |||
35 | void *context) | 40 | void *context) |
36 | { | 41 | { |
37 | __be32 *fh = (__force __be32 *)p; | 42 | __be32 *fh = (__force __be32 *)p; |
38 | struct gfs2_fh_obj fh_obj; | 43 | struct gfs2_inum_host inum, parent; |
39 | struct gfs2_inum_host *this, parent; | ||
40 | 44 | ||
41 | this = &fh_obj.this; | ||
42 | fh_obj.imode = DT_UNKNOWN; | ||
43 | memset(&parent, 0, sizeof(struct gfs2_inum)); | 45 | memset(&parent, 0, sizeof(struct gfs2_inum)); |
44 | 46 | ||
45 | switch (fh_len) { | 47 | switch (fh_len) { |
46 | case GFS2_LARGE_FH_SIZE: | 48 | case GFS2_LARGE_FH_SIZE: |
49 | case GFS2_OLD_FH_SIZE: | ||
47 | parent.no_formal_ino = ((u64)be32_to_cpu(fh[4])) << 32; | 50 | parent.no_formal_ino = ((u64)be32_to_cpu(fh[4])) << 32; |
48 | parent.no_formal_ino |= be32_to_cpu(fh[5]); | 51 | parent.no_formal_ino |= be32_to_cpu(fh[5]); |
49 | parent.no_addr = ((u64)be32_to_cpu(fh[6])) << 32; | 52 | parent.no_addr = ((u64)be32_to_cpu(fh[6])) << 32; |
50 | parent.no_addr |= be32_to_cpu(fh[7]); | 53 | parent.no_addr |= be32_to_cpu(fh[7]); |
51 | fh_obj.imode = be32_to_cpu(fh[8]); | ||
52 | case GFS2_SMALL_FH_SIZE: | 54 | case GFS2_SMALL_FH_SIZE: |
53 | this->no_formal_ino = ((u64)be32_to_cpu(fh[0])) << 32; | 55 | inum.no_formal_ino = ((u64)be32_to_cpu(fh[0])) << 32; |
54 | this->no_formal_ino |= be32_to_cpu(fh[1]); | 56 | inum.no_formal_ino |= be32_to_cpu(fh[1]); |
55 | this->no_addr = ((u64)be32_to_cpu(fh[2])) << 32; | 57 | inum.no_addr = ((u64)be32_to_cpu(fh[2])) << 32; |
56 | this->no_addr |= be32_to_cpu(fh[3]); | 58 | inum.no_addr |= be32_to_cpu(fh[3]); |
57 | break; | 59 | break; |
58 | default: | 60 | default: |
59 | return NULL; | 61 | return NULL; |
60 | } | 62 | } |
61 | 63 | ||
62 | return gfs2_export_ops.find_exported_dentry(sb, &fh_obj, &parent, | 64 | return gfs2_export_ops.find_exported_dentry(sb, &inum, &parent, |
63 | acceptable, context); | 65 | acceptable, context); |
64 | } | 66 | } |
65 | 67 | ||
@@ -75,10 +77,10 @@ static int gfs2_encode_fh(struct dentry *dentry, __u32 *p, int *len, | |||
75 | (connectable && *len < GFS2_LARGE_FH_SIZE)) | 77 | (connectable && *len < GFS2_LARGE_FH_SIZE)) |
76 | return 255; | 78 | return 255; |
77 | 79 | ||
78 | fh[0] = cpu_to_be32(ip->i_num.no_formal_ino >> 32); | 80 | fh[0] = cpu_to_be32(ip->i_no_formal_ino >> 32); |
79 | fh[1] = cpu_to_be32(ip->i_num.no_formal_ino & 0xFFFFFFFF); | 81 | fh[1] = cpu_to_be32(ip->i_no_formal_ino & 0xFFFFFFFF); |
80 | fh[2] = cpu_to_be32(ip->i_num.no_addr >> 32); | 82 | fh[2] = cpu_to_be32(ip->i_no_addr >> 32); |
81 | fh[3] = cpu_to_be32(ip->i_num.no_addr & 0xFFFFFFFF); | 83 | fh[3] = cpu_to_be32(ip->i_no_addr & 0xFFFFFFFF); |
82 | *len = GFS2_SMALL_FH_SIZE; | 84 | *len = GFS2_SMALL_FH_SIZE; |
83 | 85 | ||
84 | if (!connectable || inode == sb->s_root->d_inode) | 86 | if (!connectable || inode == sb->s_root->d_inode) |
@@ -90,13 +92,10 @@ static int gfs2_encode_fh(struct dentry *dentry, __u32 *p, int *len, | |||
90 | igrab(inode); | 92 | igrab(inode); |
91 | spin_unlock(&dentry->d_lock); | 93 | spin_unlock(&dentry->d_lock); |
92 | 94 | ||
93 | fh[4] = cpu_to_be32(ip->i_num.no_formal_ino >> 32); | 95 | fh[4] = cpu_to_be32(ip->i_no_formal_ino >> 32); |
94 | fh[5] = cpu_to_be32(ip->i_num.no_formal_ino & 0xFFFFFFFF); | 96 | fh[5] = cpu_to_be32(ip->i_no_formal_ino & 0xFFFFFFFF); |
95 | fh[6] = cpu_to_be32(ip->i_num.no_addr >> 32); | 97 | fh[6] = cpu_to_be32(ip->i_no_addr >> 32); |
96 | fh[7] = cpu_to_be32(ip->i_num.no_addr & 0xFFFFFFFF); | 98 | fh[7] = cpu_to_be32(ip->i_no_addr & 0xFFFFFFFF); |
97 | |||
98 | fh[8] = cpu_to_be32(inode->i_mode); | ||
99 | fh[9] = 0; /* pad to double word */ | ||
100 | *len = GFS2_LARGE_FH_SIZE; | 99 | *len = GFS2_LARGE_FH_SIZE; |
101 | 100 | ||
102 | iput(inode); | 101 | iput(inode); |
@@ -144,7 +143,8 @@ static int gfs2_get_name(struct dentry *parent, char *name, | |||
144 | ip = GFS2_I(inode); | 143 | ip = GFS2_I(inode); |
145 | 144 | ||
146 | *name = 0; | 145 | *name = 0; |
147 | gnfd.inum = ip->i_num; | 146 | gnfd.inum.no_addr = ip->i_no_addr; |
147 | gnfd.inum.no_formal_ino = ip->i_no_formal_ino; | ||
148 | gnfd.name = name; | 148 | gnfd.name = name; |
149 | 149 | ||
150 | error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &gh); | 150 | error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &gh); |
@@ -192,8 +192,7 @@ static struct dentry *gfs2_get_parent(struct dentry *child) | |||
192 | static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_obj) | 192 | static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_obj) |
193 | { | 193 | { |
194 | struct gfs2_sbd *sdp = sb->s_fs_info; | 194 | struct gfs2_sbd *sdp = sb->s_fs_info; |
195 | struct gfs2_fh_obj *fh_obj = (struct gfs2_fh_obj *)inum_obj; | 195 | struct gfs2_inum_host *inum = inum_obj; |
196 | struct gfs2_inum_host *inum = &fh_obj->this; | ||
197 | struct gfs2_holder i_gh, ri_gh, rgd_gh; | 196 | struct gfs2_holder i_gh, ri_gh, rgd_gh; |
198 | struct gfs2_rgrpd *rgd; | 197 | struct gfs2_rgrpd *rgd; |
199 | struct inode *inode; | 198 | struct inode *inode; |
@@ -202,9 +201,9 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_obj) | |||
202 | 201 | ||
203 | /* System files? */ | 202 | /* System files? */ |
204 | 203 | ||
205 | inode = gfs2_ilookup(sb, inum); | 204 | inode = gfs2_ilookup(sb, inum->no_addr); |
206 | if (inode) { | 205 | if (inode) { |
207 | if (GFS2_I(inode)->i_num.no_formal_ino != inum->no_formal_ino) { | 206 | if (GFS2_I(inode)->i_no_formal_ino != inum->no_formal_ino) { |
208 | iput(inode); | 207 | iput(inode); |
209 | return ERR_PTR(-ESTALE); | 208 | return ERR_PTR(-ESTALE); |
210 | } | 209 | } |
@@ -236,7 +235,9 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_obj) | |||
236 | gfs2_glock_dq_uninit(&rgd_gh); | 235 | gfs2_glock_dq_uninit(&rgd_gh); |
237 | gfs2_glock_dq_uninit(&ri_gh); | 236 | gfs2_glock_dq_uninit(&ri_gh); |
238 | 237 | ||
239 | inode = gfs2_inode_lookup(sb, inum, fh_obj->imode); | 238 | inode = gfs2_inode_lookup(sb, DT_UNKNOWN, |
239 | inum->no_addr, | ||
240 | 0); | ||
240 | if (!inode) | 241 | if (!inode) |
241 | goto fail; | 242 | goto fail; |
242 | if (IS_ERR(inode)) { | 243 | if (IS_ERR(inode)) { |
@@ -250,6 +251,15 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_obj) | |||
250 | goto fail; | 251 | goto fail; |
251 | } | 252 | } |
252 | 253 | ||
254 | /* Pick up the works we bypass in gfs2_inode_lookup */ | ||
255 | if (inode->i_state & I_NEW) | ||
256 | gfs2_set_iop(inode); | ||
257 | |||
258 | if (GFS2_I(inode)->i_no_formal_ino != inum->no_formal_ino) { | ||
259 | iput(inode); | ||
260 | goto fail; | ||
261 | } | ||
262 | |||
253 | error = -EIO; | 263 | error = -EIO; |
254 | if (GFS2_I(inode)->i_di.di_flags & GFS2_DIF_SYSTEM) { | 264 | if (GFS2_I(inode)->i_di.di_flags & GFS2_DIF_SYSTEM) { |
255 | iput(inode); | 265 | iput(inode); |
diff --git a/fs/gfs2/ops_export.h b/fs/gfs2/ops_export.h deleted file mode 100644 index f925a955b3b8..000000000000 --- a/fs/gfs2/ops_export.h +++ /dev/null | |||
@@ -1,22 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | ||
3 | * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. | ||
4 | * | ||
5 | * This copyrighted material is made available to anyone wishing to use, | ||
6 | * modify, copy, or redistribute it subject to the terms and conditions | ||
7 | * of the GNU General Public License version 2. | ||
8 | */ | ||
9 | |||
10 | #ifndef __OPS_EXPORT_DOT_H__ | ||
11 | #define __OPS_EXPORT_DOT_H__ | ||
12 | |||
13 | #define GFS2_SMALL_FH_SIZE 4 | ||
14 | #define GFS2_LARGE_FH_SIZE 10 | ||
15 | |||
16 | extern struct export_operations gfs2_export_ops; | ||
17 | struct gfs2_fh_obj { | ||
18 | struct gfs2_inum_host this; | ||
19 | __u32 imode; | ||
20 | }; | ||
21 | |||
22 | #endif /* __OPS_EXPORT_DOT_H__ */ | ||
diff --git a/fs/gfs2/ops_file.c b/fs/gfs2/ops_file.c index 064df8804582..196d83266e34 100644 --- a/fs/gfs2/ops_file.c +++ b/fs/gfs2/ops_file.c | |||
@@ -502,7 +502,7 @@ static int gfs2_lock(struct file *file, int cmd, struct file_lock *fl) | |||
502 | struct gfs2_inode *ip = GFS2_I(file->f_mapping->host); | 502 | struct gfs2_inode *ip = GFS2_I(file->f_mapping->host); |
503 | struct gfs2_sbd *sdp = GFS2_SB(file->f_mapping->host); | 503 | struct gfs2_sbd *sdp = GFS2_SB(file->f_mapping->host); |
504 | struct lm_lockname name = | 504 | struct lm_lockname name = |
505 | { .ln_number = ip->i_num.no_addr, | 505 | { .ln_number = ip->i_no_addr, |
506 | .ln_type = LM_TYPE_PLOCK }; | 506 | .ln_type = LM_TYPE_PLOCK }; |
507 | 507 | ||
508 | if (!(fl->fl_flags & FL_POSIX)) | 508 | if (!(fl->fl_flags & FL_POSIX)) |
@@ -557,7 +557,7 @@ static int do_flock(struct file *file, int cmd, struct file_lock *fl) | |||
557 | gfs2_glock_dq_uninit(fl_gh); | 557 | gfs2_glock_dq_uninit(fl_gh); |
558 | } else { | 558 | } else { |
559 | error = gfs2_glock_get(GFS2_SB(&ip->i_inode), | 559 | error = gfs2_glock_get(GFS2_SB(&ip->i_inode), |
560 | ip->i_num.no_addr, &gfs2_flock_glops, | 560 | ip->i_no_addr, &gfs2_flock_glops, |
561 | CREATE, &gl); | 561 | CREATE, &gl); |
562 | if (error) | 562 | if (error) |
563 | goto out; | 563 | goto out; |
@@ -635,7 +635,6 @@ const struct file_operations gfs2_file_fops = { | |||
635 | .release = gfs2_close, | 635 | .release = gfs2_close, |
636 | .fsync = gfs2_fsync, | 636 | .fsync = gfs2_fsync, |
637 | .lock = gfs2_lock, | 637 | .lock = gfs2_lock, |
638 | .sendfile = generic_file_sendfile, | ||
639 | .flock = gfs2_flock, | 638 | .flock = gfs2_flock, |
640 | .splice_read = generic_file_splice_read, | 639 | .splice_read = generic_file_splice_read, |
641 | .splice_write = generic_file_splice_write, | 640 | .splice_write = generic_file_splice_write, |
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index 2c5f8e7def0d..cf5aa5050548 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include "inode.h" | 27 | #include "inode.h" |
28 | #include "lm.h" | 28 | #include "lm.h" |
29 | #include "mount.h" | 29 | #include "mount.h" |
30 | #include "ops_export.h" | ||
31 | #include "ops_fstype.h" | 30 | #include "ops_fstype.h" |
32 | #include "ops_super.h" | 31 | #include "ops_super.h" |
33 | #include "recovery.h" | 32 | #include "recovery.h" |
@@ -105,6 +104,7 @@ static void init_vfs(struct super_block *sb, unsigned noatime) | |||
105 | sb->s_magic = GFS2_MAGIC; | 104 | sb->s_magic = GFS2_MAGIC; |
106 | sb->s_op = &gfs2_super_ops; | 105 | sb->s_op = &gfs2_super_ops; |
107 | sb->s_export_op = &gfs2_export_ops; | 106 | sb->s_export_op = &gfs2_export_ops; |
107 | sb->s_time_gran = 1; | ||
108 | sb->s_maxbytes = MAX_LFS_FILESIZE; | 108 | sb->s_maxbytes = MAX_LFS_FILESIZE; |
109 | 109 | ||
110 | if (sb->s_flags & (MS_NOATIME | MS_NODIRATIME)) | 110 | if (sb->s_flags & (MS_NOATIME | MS_NODIRATIME)) |
@@ -116,7 +116,6 @@ static void init_vfs(struct super_block *sb, unsigned noatime) | |||
116 | 116 | ||
117 | static int init_names(struct gfs2_sbd *sdp, int silent) | 117 | static int init_names(struct gfs2_sbd *sdp, int silent) |
118 | { | 118 | { |
119 | struct page *page; | ||
120 | char *proto, *table; | 119 | char *proto, *table; |
121 | int error = 0; | 120 | int error = 0; |
122 | 121 | ||
@@ -126,14 +125,9 @@ static int init_names(struct gfs2_sbd *sdp, int silent) | |||
126 | /* Try to autodetect */ | 125 | /* Try to autodetect */ |
127 | 126 | ||
128 | if (!proto[0] || !table[0]) { | 127 | if (!proto[0] || !table[0]) { |
129 | struct gfs2_sb *sb; | 128 | error = gfs2_read_super(sdp, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift); |
130 | page = gfs2_read_super(sdp->sd_vfs, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift); | 129 | if (error) |
131 | if (!page) | 130 | return error; |
132 | return -ENOBUFS; | ||
133 | sb = kmap(page); | ||
134 | gfs2_sb_in(&sdp->sd_sb, sb); | ||
135 | kunmap(page); | ||
136 | __free_page(page); | ||
137 | 131 | ||
138 | error = gfs2_check_sb(sdp, &sdp->sd_sb, silent); | 132 | error = gfs2_check_sb(sdp, &sdp->sd_sb, silent); |
139 | if (error) | 133 | if (error) |
@@ -151,6 +145,9 @@ static int init_names(struct gfs2_sbd *sdp, int silent) | |||
151 | snprintf(sdp->sd_proto_name, GFS2_FSNAME_LEN, "%s", proto); | 145 | snprintf(sdp->sd_proto_name, GFS2_FSNAME_LEN, "%s", proto); |
152 | snprintf(sdp->sd_table_name, GFS2_FSNAME_LEN, "%s", table); | 146 | snprintf(sdp->sd_table_name, GFS2_FSNAME_LEN, "%s", table); |
153 | 147 | ||
148 | while ((table = strchr(sdp->sd_table_name, '/'))) | ||
149 | *table = '_'; | ||
150 | |||
154 | out: | 151 | out: |
155 | return error; | 152 | return error; |
156 | } | 153 | } |
@@ -236,17 +233,17 @@ fail: | |||
236 | return error; | 233 | return error; |
237 | } | 234 | } |
238 | 235 | ||
239 | static struct inode *gfs2_lookup_root(struct super_block *sb, | 236 | static inline struct inode *gfs2_lookup_root(struct super_block *sb, |
240 | struct gfs2_inum_host *inum) | 237 | u64 no_addr) |
241 | { | 238 | { |
242 | return gfs2_inode_lookup(sb, inum, DT_DIR); | 239 | return gfs2_inode_lookup(sb, DT_DIR, no_addr, 0); |
243 | } | 240 | } |
244 | 241 | ||
245 | static int init_sb(struct gfs2_sbd *sdp, int silent, int undo) | 242 | static int init_sb(struct gfs2_sbd *sdp, int silent, int undo) |
246 | { | 243 | { |
247 | struct super_block *sb = sdp->sd_vfs; | 244 | struct super_block *sb = sdp->sd_vfs; |
248 | struct gfs2_holder sb_gh; | 245 | struct gfs2_holder sb_gh; |
249 | struct gfs2_inum_host *inum; | 246 | u64 no_addr; |
250 | struct inode *inode; | 247 | struct inode *inode; |
251 | int error = 0; | 248 | int error = 0; |
252 | 249 | ||
@@ -289,10 +286,10 @@ static int init_sb(struct gfs2_sbd *sdp, int silent, int undo) | |||
289 | sb_set_blocksize(sb, sdp->sd_sb.sb_bsize); | 286 | sb_set_blocksize(sb, sdp->sd_sb.sb_bsize); |
290 | 287 | ||
291 | /* Get the root inode */ | 288 | /* Get the root inode */ |
292 | inum = &sdp->sd_sb.sb_root_dir; | 289 | no_addr = sdp->sd_sb.sb_root_dir.no_addr; |
293 | if (sb->s_type == &gfs2meta_fs_type) | 290 | if (sb->s_type == &gfs2meta_fs_type) |
294 | inum = &sdp->sd_sb.sb_master_dir; | 291 | no_addr = sdp->sd_sb.sb_master_dir.no_addr; |
295 | inode = gfs2_lookup_root(sb, inum); | 292 | inode = gfs2_lookup_root(sb, no_addr); |
296 | if (IS_ERR(inode)) { | 293 | if (IS_ERR(inode)) { |
297 | error = PTR_ERR(inode); | 294 | error = PTR_ERR(inode); |
298 | fs_err(sdp, "can't read in root inode: %d\n", error); | 295 | fs_err(sdp, "can't read in root inode: %d\n", error); |
@@ -449,7 +446,7 @@ static int init_inodes(struct gfs2_sbd *sdp, int undo) | |||
449 | if (undo) | 446 | if (undo) |
450 | goto fail_qinode; | 447 | goto fail_qinode; |
451 | 448 | ||
452 | inode = gfs2_lookup_root(sdp->sd_vfs, &sdp->sd_sb.sb_master_dir); | 449 | inode = gfs2_lookup_root(sdp->sd_vfs, sdp->sd_sb.sb_master_dir.no_addr); |
453 | if (IS_ERR(inode)) { | 450 | if (IS_ERR(inode)) { |
454 | error = PTR_ERR(inode); | 451 | error = PTR_ERR(inode); |
455 | fs_err(sdp, "can't read in master directory: %d\n", error); | 452 | fs_err(sdp, "can't read in master directory: %d\n", error); |
diff --git a/fs/gfs2/ops_fstype.h b/fs/gfs2/ops_fstype.h index 7cc2c296271b..407029b3b2b3 100644 --- a/fs/gfs2/ops_fstype.h +++ b/fs/gfs2/ops_fstype.h | |||
@@ -14,5 +14,6 @@ | |||
14 | 14 | ||
15 | extern struct file_system_type gfs2_fs_type; | 15 | extern struct file_system_type gfs2_fs_type; |
16 | extern struct file_system_type gfs2meta_fs_type; | 16 | extern struct file_system_type gfs2meta_fs_type; |
17 | extern struct export_operations gfs2_export_ops; | ||
17 | 18 | ||
18 | #endif /* __OPS_FSTYPE_DOT_H__ */ | 19 | #endif /* __OPS_FSTYPE_DOT_H__ */ |
diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c index d85f6e05cb95..911c115b5c6c 100644 --- a/fs/gfs2/ops_inode.c +++ b/fs/gfs2/ops_inode.c | |||
@@ -157,7 +157,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir, | |||
157 | if (error) | 157 | if (error) |
158 | goto out_gunlock; | 158 | goto out_gunlock; |
159 | 159 | ||
160 | error = gfs2_dir_search(dir, &dentry->d_name, NULL, NULL); | 160 | error = gfs2_dir_check(dir, &dentry->d_name, NULL); |
161 | switch (error) { | 161 | switch (error) { |
162 | case -ENOENT: | 162 | case -ENOENT: |
163 | break; | 163 | break; |
@@ -206,7 +206,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir, | |||
206 | goto out_gunlock_q; | 206 | goto out_gunlock_q; |
207 | 207 | ||
208 | error = gfs2_trans_begin(sdp, sdp->sd_max_dirres + | 208 | error = gfs2_trans_begin(sdp, sdp->sd_max_dirres + |
209 | al->al_rgd->rd_ri.ri_length + | 209 | al->al_rgd->rd_length + |
210 | 2 * RES_DINODE + RES_STATFS + | 210 | 2 * RES_DINODE + RES_STATFS + |
211 | RES_QUOTA, 0); | 211 | RES_QUOTA, 0); |
212 | if (error) | 212 | if (error) |
@@ -217,8 +217,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir, | |||
217 | goto out_ipres; | 217 | goto out_ipres; |
218 | } | 218 | } |
219 | 219 | ||
220 | error = gfs2_dir_add(dir, &dentry->d_name, &ip->i_num, | 220 | error = gfs2_dir_add(dir, &dentry->d_name, ip, IF2DT(inode->i_mode)); |
221 | IF2DT(inode->i_mode)); | ||
222 | if (error) | 221 | if (error) |
223 | goto out_end_trans; | 222 | goto out_end_trans; |
224 | 223 | ||
@@ -275,7 +274,7 @@ static int gfs2_unlink(struct inode *dir, struct dentry *dentry) | |||
275 | gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); | 274 | gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); |
276 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1); | 275 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1); |
277 | 276 | ||
278 | rgd = gfs2_blk2rgrpd(sdp, ip->i_num.no_addr); | 277 | rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr); |
279 | gfs2_holder_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + 2); | 278 | gfs2_holder_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + 2); |
280 | 279 | ||
281 | 280 | ||
@@ -420,7 +419,7 @@ static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
420 | dent = (struct gfs2_dirent *)((char*)dent + GFS2_DIRENT_SIZE(1)); | 419 | dent = (struct gfs2_dirent *)((char*)dent + GFS2_DIRENT_SIZE(1)); |
421 | gfs2_qstr2dirent(&str, dibh->b_size - GFS2_DIRENT_SIZE(1) - sizeof(struct gfs2_dinode), dent); | 420 | gfs2_qstr2dirent(&str, dibh->b_size - GFS2_DIRENT_SIZE(1) - sizeof(struct gfs2_dinode), dent); |
422 | 421 | ||
423 | gfs2_inum_out(&dip->i_num, &dent->de_inum); | 422 | gfs2_inum_out(dip, dent); |
424 | dent->de_type = cpu_to_be16(DT_DIR); | 423 | dent->de_type = cpu_to_be16(DT_DIR); |
425 | 424 | ||
426 | gfs2_dinode_out(ip, di); | 425 | gfs2_dinode_out(ip, di); |
@@ -472,7 +471,7 @@ static int gfs2_rmdir(struct inode *dir, struct dentry *dentry) | |||
472 | gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); | 471 | gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); |
473 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1); | 472 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1); |
474 | 473 | ||
475 | rgd = gfs2_blk2rgrpd(sdp, ip->i_num.no_addr); | 474 | rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr); |
476 | gfs2_holder_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + 2); | 475 | gfs2_holder_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + 2); |
477 | 476 | ||
478 | error = gfs2_glock_nq_m(3, ghs); | 477 | error = gfs2_glock_nq_m(3, ghs); |
@@ -614,7 +613,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
614 | * this is the case of the target file already existing | 613 | * this is the case of the target file already existing |
615 | * so we unlink before doing the rename | 614 | * so we unlink before doing the rename |
616 | */ | 615 | */ |
617 | nrgd = gfs2_blk2rgrpd(sdp, nip->i_num.no_addr); | 616 | nrgd = gfs2_blk2rgrpd(sdp, nip->i_no_addr); |
618 | if (nrgd) | 617 | if (nrgd) |
619 | gfs2_holder_init(nrgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh++); | 618 | gfs2_holder_init(nrgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh++); |
620 | } | 619 | } |
@@ -653,7 +652,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
653 | if (error) | 652 | if (error) |
654 | goto out_gunlock; | 653 | goto out_gunlock; |
655 | 654 | ||
656 | error = gfs2_dir_search(ndir, &ndentry->d_name, NULL, NULL); | 655 | error = gfs2_dir_check(ndir, &ndentry->d_name, NULL); |
657 | switch (error) { | 656 | switch (error) { |
658 | case -ENOENT: | 657 | case -ENOENT: |
659 | error = 0; | 658 | error = 0; |
@@ -712,7 +711,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
712 | goto out_gunlock_q; | 711 | goto out_gunlock_q; |
713 | 712 | ||
714 | error = gfs2_trans_begin(sdp, sdp->sd_max_dirres + | 713 | error = gfs2_trans_begin(sdp, sdp->sd_max_dirres + |
715 | al->al_rgd->rd_ri.ri_length + | 714 | al->al_rgd->rd_length + |
716 | 4 * RES_DINODE + 4 * RES_LEAF + | 715 | 4 * RES_DINODE + 4 * RES_LEAF + |
717 | RES_STATFS + RES_QUOTA + 4, 0); | 716 | RES_STATFS + RES_QUOTA + 4, 0); |
718 | if (error) | 717 | if (error) |
@@ -750,7 +749,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
750 | if (error) | 749 | if (error) |
751 | goto out_end_trans; | 750 | goto out_end_trans; |
752 | 751 | ||
753 | error = gfs2_dir_mvino(ip, &name, &ndip->i_num, DT_DIR); | 752 | error = gfs2_dir_mvino(ip, &name, ndip, DT_DIR); |
754 | if (error) | 753 | if (error) |
755 | goto out_end_trans; | 754 | goto out_end_trans; |
756 | } else { | 755 | } else { |
@@ -758,7 +757,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
758 | error = gfs2_meta_inode_buffer(ip, &dibh); | 757 | error = gfs2_meta_inode_buffer(ip, &dibh); |
759 | if (error) | 758 | if (error) |
760 | goto out_end_trans; | 759 | goto out_end_trans; |
761 | ip->i_inode.i_ctime = CURRENT_TIME_SEC; | 760 | ip->i_inode.i_ctime = CURRENT_TIME; |
762 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 761 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
763 | gfs2_dinode_out(ip, dibh->b_data); | 762 | gfs2_dinode_out(ip, dibh->b_data); |
764 | brelse(dibh); | 763 | brelse(dibh); |
@@ -768,8 +767,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
768 | if (error) | 767 | if (error) |
769 | goto out_end_trans; | 768 | goto out_end_trans; |
770 | 769 | ||
771 | error = gfs2_dir_add(ndir, &ndentry->d_name, &ip->i_num, | 770 | error = gfs2_dir_add(ndir, &ndentry->d_name, ip, IF2DT(ip->i_inode.i_mode)); |
772 | IF2DT(ip->i_inode.i_mode)); | ||
773 | if (error) | 771 | if (error) |
774 | goto out_end_trans; | 772 | goto out_end_trans; |
775 | 773 | ||
@@ -905,8 +903,8 @@ static int setattr_size(struct inode *inode, struct iattr *attr) | |||
905 | } | 903 | } |
906 | 904 | ||
907 | error = gfs2_truncatei(ip, attr->ia_size); | 905 | error = gfs2_truncatei(ip, attr->ia_size); |
908 | if (error) | 906 | if (error && (inode->i_size != ip->i_di.di_size)) |
909 | return error; | 907 | i_size_write(inode, ip->i_di.di_size); |
910 | 908 | ||
911 | return error; | 909 | return error; |
912 | } | 910 | } |
diff --git a/fs/gfs2/ops_super.c b/fs/gfs2/ops_super.c index 485ce3d49923..603d940f1159 100644 --- a/fs/gfs2/ops_super.c +++ b/fs/gfs2/ops_super.c | |||
@@ -326,8 +326,10 @@ static void gfs2_clear_inode(struct inode *inode) | |||
326 | gfs2_glock_schedule_for_reclaim(ip->i_gl); | 326 | gfs2_glock_schedule_for_reclaim(ip->i_gl); |
327 | gfs2_glock_put(ip->i_gl); | 327 | gfs2_glock_put(ip->i_gl); |
328 | ip->i_gl = NULL; | 328 | ip->i_gl = NULL; |
329 | if (ip->i_iopen_gh.gh_gl) | 329 | if (ip->i_iopen_gh.gh_gl) { |
330 | ip->i_iopen_gh.gh_gl->gl_object = NULL; | ||
330 | gfs2_glock_dq_uninit(&ip->i_iopen_gh); | 331 | gfs2_glock_dq_uninit(&ip->i_iopen_gh); |
332 | } | ||
331 | } | 333 | } |
332 | } | 334 | } |
333 | 335 | ||
@@ -422,13 +424,13 @@ static void gfs2_delete_inode(struct inode *inode) | |||
422 | if (!inode->i_private) | 424 | if (!inode->i_private) |
423 | goto out; | 425 | goto out; |
424 | 426 | ||
425 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB, &gh); | 427 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); |
426 | if (unlikely(error)) { | 428 | if (unlikely(error)) { |
427 | gfs2_glock_dq_uninit(&ip->i_iopen_gh); | 429 | gfs2_glock_dq_uninit(&ip->i_iopen_gh); |
428 | goto out; | 430 | goto out; |
429 | } | 431 | } |
430 | 432 | ||
431 | gfs2_glock_dq(&ip->i_iopen_gh); | 433 | gfs2_glock_dq_wait(&ip->i_iopen_gh); |
432 | gfs2_holder_reinit(LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB | GL_NOCACHE, &ip->i_iopen_gh); | 434 | gfs2_holder_reinit(LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB | GL_NOCACHE, &ip->i_iopen_gh); |
433 | error = gfs2_glock_nq(&ip->i_iopen_gh); | 435 | error = gfs2_glock_nq(&ip->i_iopen_gh); |
434 | if (error) | 436 | if (error) |
diff --git a/fs/gfs2/ops_vm.c b/fs/gfs2/ops_vm.c index aa0dbd2aac1b..404b7cc9f8c4 100644 --- a/fs/gfs2/ops_vm.c +++ b/fs/gfs2/ops_vm.c | |||
@@ -66,7 +66,7 @@ static int alloc_page_backing(struct gfs2_inode *ip, struct page *page) | |||
66 | if (error) | 66 | if (error) |
67 | goto out_gunlock_q; | 67 | goto out_gunlock_q; |
68 | 68 | ||
69 | error = gfs2_trans_begin(sdp, al->al_rgd->rd_ri.ri_length + | 69 | error = gfs2_trans_begin(sdp, al->al_rgd->rd_length + |
70 | ind_blocks + RES_DINODE + | 70 | ind_blocks + RES_DINODE + |
71 | RES_STATFS + RES_QUOTA, 0); | 71 | RES_STATFS + RES_QUOTA, 0); |
72 | if (error) | 72 | if (error) |
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index c186857e48a8..6e546ee8f3d4 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c | |||
@@ -66,6 +66,18 @@ | |||
66 | #define QUOTA_USER 1 | 66 | #define QUOTA_USER 1 |
67 | #define QUOTA_GROUP 0 | 67 | #define QUOTA_GROUP 0 |
68 | 68 | ||
69 | struct gfs2_quota_host { | ||
70 | u64 qu_limit; | ||
71 | u64 qu_warn; | ||
72 | s64 qu_value; | ||
73 | }; | ||
74 | |||
75 | struct gfs2_quota_change_host { | ||
76 | u64 qc_change; | ||
77 | u32 qc_flags; /* GFS2_QCF_... */ | ||
78 | u32 qc_id; | ||
79 | }; | ||
80 | |||
69 | static u64 qd2offset(struct gfs2_quota_data *qd) | 81 | static u64 qd2offset(struct gfs2_quota_data *qd) |
70 | { | 82 | { |
71 | u64 offset; | 83 | u64 offset; |
@@ -561,6 +573,25 @@ static void do_qc(struct gfs2_quota_data *qd, s64 change) | |||
561 | mutex_unlock(&sdp->sd_quota_mutex); | 573 | mutex_unlock(&sdp->sd_quota_mutex); |
562 | } | 574 | } |
563 | 575 | ||
576 | static void gfs2_quota_in(struct gfs2_quota_host *qu, const void *buf) | ||
577 | { | ||
578 | const struct gfs2_quota *str = buf; | ||
579 | |||
580 | qu->qu_limit = be64_to_cpu(str->qu_limit); | ||
581 | qu->qu_warn = be64_to_cpu(str->qu_warn); | ||
582 | qu->qu_value = be64_to_cpu(str->qu_value); | ||
583 | } | ||
584 | |||
585 | static void gfs2_quota_out(const struct gfs2_quota_host *qu, void *buf) | ||
586 | { | ||
587 | struct gfs2_quota *str = buf; | ||
588 | |||
589 | str->qu_limit = cpu_to_be64(qu->qu_limit); | ||
590 | str->qu_warn = cpu_to_be64(qu->qu_warn); | ||
591 | str->qu_value = cpu_to_be64(qu->qu_value); | ||
592 | memset(&str->qu_reserved, 0, sizeof(str->qu_reserved)); | ||
593 | } | ||
594 | |||
564 | /** | 595 | /** |
565 | * gfs2_adjust_quota | 596 | * gfs2_adjust_quota |
566 | * | 597 | * |
@@ -573,12 +604,13 @@ static int gfs2_adjust_quota(struct gfs2_inode *ip, loff_t loc, | |||
573 | struct inode *inode = &ip->i_inode; | 604 | struct inode *inode = &ip->i_inode; |
574 | struct address_space *mapping = inode->i_mapping; | 605 | struct address_space *mapping = inode->i_mapping; |
575 | unsigned long index = loc >> PAGE_CACHE_SHIFT; | 606 | unsigned long index = loc >> PAGE_CACHE_SHIFT; |
576 | unsigned offset = loc & (PAGE_CACHE_SHIFT - 1); | 607 | unsigned offset = loc & (PAGE_CACHE_SIZE - 1); |
577 | unsigned blocksize, iblock, pos; | 608 | unsigned blocksize, iblock, pos; |
578 | struct buffer_head *bh; | 609 | struct buffer_head *bh; |
579 | struct page *page; | 610 | struct page *page; |
580 | void *kaddr; | 611 | void *kaddr; |
581 | __be64 *ptr; | 612 | char *ptr; |
613 | struct gfs2_quota_host qp; | ||
582 | s64 value; | 614 | s64 value; |
583 | int err = -EIO; | 615 | int err = -EIO; |
584 | 616 | ||
@@ -620,13 +652,17 @@ static int gfs2_adjust_quota(struct gfs2_inode *ip, loff_t loc, | |||
620 | 652 | ||
621 | kaddr = kmap_atomic(page, KM_USER0); | 653 | kaddr = kmap_atomic(page, KM_USER0); |
622 | ptr = kaddr + offset; | 654 | ptr = kaddr + offset; |
623 | value = (s64)be64_to_cpu(*ptr) + change; | 655 | gfs2_quota_in(&qp, ptr); |
624 | *ptr = cpu_to_be64(value); | 656 | qp.qu_value += change; |
657 | value = qp.qu_value; | ||
658 | gfs2_quota_out(&qp, ptr); | ||
625 | flush_dcache_page(page); | 659 | flush_dcache_page(page); |
626 | kunmap_atomic(kaddr, KM_USER0); | 660 | kunmap_atomic(kaddr, KM_USER0); |
627 | err = 0; | 661 | err = 0; |
628 | qd->qd_qb.qb_magic = cpu_to_be32(GFS2_MAGIC); | 662 | qd->qd_qb.qb_magic = cpu_to_be32(GFS2_MAGIC); |
629 | qd->qd_qb.qb_value = cpu_to_be64(value); | 663 | qd->qd_qb.qb_value = cpu_to_be64(value); |
664 | ((struct gfs2_quota_lvb*)(qd->qd_gl->gl_lvb))->qb_magic = cpu_to_be32(GFS2_MAGIC); | ||
665 | ((struct gfs2_quota_lvb*)(qd->qd_gl->gl_lvb))->qb_value = cpu_to_be64(value); | ||
630 | unlock: | 666 | unlock: |
631 | unlock_page(page); | 667 | unlock_page(page); |
632 | page_cache_release(page); | 668 | page_cache_release(page); |
@@ -689,7 +725,7 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda) | |||
689 | goto out_alloc; | 725 | goto out_alloc; |
690 | 726 | ||
691 | error = gfs2_trans_begin(sdp, | 727 | error = gfs2_trans_begin(sdp, |
692 | al->al_rgd->rd_ri.ri_length + | 728 | al->al_rgd->rd_length + |
693 | num_qd * data_blocks + | 729 | num_qd * data_blocks + |
694 | nalloc * ind_blocks + | 730 | nalloc * ind_blocks + |
695 | RES_DINODE + num_qd + | 731 | RES_DINODE + num_qd + |
@@ -709,7 +745,7 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda) | |||
709 | offset = qd2offset(qd); | 745 | offset = qd2offset(qd); |
710 | error = gfs2_adjust_quota(ip, offset, qd->qd_change_sync, | 746 | error = gfs2_adjust_quota(ip, offset, qd->qd_change_sync, |
711 | (struct gfs2_quota_data *) | 747 | (struct gfs2_quota_data *) |
712 | qd->qd_gl->gl_lvb); | 748 | qd); |
713 | if (error) | 749 | if (error) |
714 | goto out_end_trans; | 750 | goto out_end_trans; |
715 | 751 | ||
@@ -1050,6 +1086,15 @@ int gfs2_quota_refresh(struct gfs2_sbd *sdp, int user, u32 id) | |||
1050 | return error; | 1086 | return error; |
1051 | } | 1087 | } |
1052 | 1088 | ||
1089 | static void gfs2_quota_change_in(struct gfs2_quota_change_host *qc, const void *buf) | ||
1090 | { | ||
1091 | const struct gfs2_quota_change *str = buf; | ||
1092 | |||
1093 | qc->qc_change = be64_to_cpu(str->qc_change); | ||
1094 | qc->qc_flags = be32_to_cpu(str->qc_flags); | ||
1095 | qc->qc_id = be32_to_cpu(str->qc_id); | ||
1096 | } | ||
1097 | |||
1053 | int gfs2_quota_init(struct gfs2_sbd *sdp) | 1098 | int gfs2_quota_init(struct gfs2_sbd *sdp) |
1054 | { | 1099 | { |
1055 | struct gfs2_inode *ip = GFS2_I(sdp->sd_qc_inode); | 1100 | struct gfs2_inode *ip = GFS2_I(sdp->sd_qc_inode); |
diff --git a/fs/gfs2/recovery.c b/fs/gfs2/recovery.c index 8bc182c7e2ef..5ada38c99a2c 100644 --- a/fs/gfs2/recovery.c +++ b/fs/gfs2/recovery.c | |||
@@ -116,6 +116,22 @@ void gfs2_revoke_clean(struct gfs2_sbd *sdp) | |||
116 | } | 116 | } |
117 | } | 117 | } |
118 | 118 | ||
119 | static int gfs2_log_header_in(struct gfs2_log_header_host *lh, const void *buf) | ||
120 | { | ||
121 | const struct gfs2_log_header *str = buf; | ||
122 | |||
123 | if (str->lh_header.mh_magic != cpu_to_be32(GFS2_MAGIC) || | ||
124 | str->lh_header.mh_type != cpu_to_be32(GFS2_METATYPE_LH)) | ||
125 | return 1; | ||
126 | |||
127 | lh->lh_sequence = be64_to_cpu(str->lh_sequence); | ||
128 | lh->lh_flags = be32_to_cpu(str->lh_flags); | ||
129 | lh->lh_tail = be32_to_cpu(str->lh_tail); | ||
130 | lh->lh_blkno = be32_to_cpu(str->lh_blkno); | ||
131 | lh->lh_hash = be32_to_cpu(str->lh_hash); | ||
132 | return 0; | ||
133 | } | ||
134 | |||
119 | /** | 135 | /** |
120 | * get_log_header - read the log header for a given segment | 136 | * get_log_header - read the log header for a given segment |
121 | * @jd: the journal | 137 | * @jd: the journal |
@@ -147,12 +163,10 @@ static int get_log_header(struct gfs2_jdesc *jd, unsigned int blk, | |||
147 | sizeof(u32)); | 163 | sizeof(u32)); |
148 | hash = crc32_le(hash, (unsigned char const *)¬hing, sizeof(nothing)); | 164 | hash = crc32_le(hash, (unsigned char const *)¬hing, sizeof(nothing)); |
149 | hash ^= (u32)~0; | 165 | hash ^= (u32)~0; |
150 | gfs2_log_header_in(&lh, bh->b_data); | 166 | error = gfs2_log_header_in(&lh, bh->b_data); |
151 | brelse(bh); | 167 | brelse(bh); |
152 | 168 | ||
153 | if (lh.lh_header.mh_magic != GFS2_MAGIC || | 169 | if (error || lh.lh_blkno != blk || lh.lh_hash != hash) |
154 | lh.lh_header.mh_type != GFS2_METATYPE_LH || | ||
155 | lh.lh_blkno != blk || lh.lh_hash != hash) | ||
156 | return 1; | 170 | return 1; |
157 | 171 | ||
158 | *head = lh; | 172 | *head = lh; |
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 1727f5012efe..e4e040625153 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | 2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. |
3 | * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. | 3 | * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This copyrighted material is made available to anyone wishing to use, | 5 | * This copyrighted material is made available to anyone wishing to use, |
6 | * modify, copy, or redistribute it subject to the terms and conditions | 6 | * modify, copy, or redistribute it subject to the terms and conditions |
@@ -28,6 +28,7 @@ | |||
28 | #include "ops_file.h" | 28 | #include "ops_file.h" |
29 | #include "util.h" | 29 | #include "util.h" |
30 | #include "log.h" | 30 | #include "log.h" |
31 | #include "inode.h" | ||
31 | 32 | ||
32 | #define BFITNOENT ((u32)~0) | 33 | #define BFITNOENT ((u32)~0) |
33 | 34 | ||
@@ -50,6 +51,9 @@ static const char valid_change[16] = { | |||
50 | 1, 0, 0, 0 | 51 | 1, 0, 0, 0 |
51 | }; | 52 | }; |
52 | 53 | ||
54 | static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal, | ||
55 | unsigned char old_state, unsigned char new_state); | ||
56 | |||
53 | /** | 57 | /** |
54 | * gfs2_setbit - Set a bit in the bitmaps | 58 | * gfs2_setbit - Set a bit in the bitmaps |
55 | * @buffer: the buffer that holds the bitmaps | 59 | * @buffer: the buffer that holds the bitmaps |
@@ -204,7 +208,7 @@ void gfs2_rgrp_verify(struct gfs2_rgrpd *rgd) | |||
204 | { | 208 | { |
205 | struct gfs2_sbd *sdp = rgd->rd_sbd; | 209 | struct gfs2_sbd *sdp = rgd->rd_sbd; |
206 | struct gfs2_bitmap *bi = NULL; | 210 | struct gfs2_bitmap *bi = NULL; |
207 | u32 length = rgd->rd_ri.ri_length; | 211 | u32 length = rgd->rd_length; |
208 | u32 count[4], tmp; | 212 | u32 count[4], tmp; |
209 | int buf, x; | 213 | int buf, x; |
210 | 214 | ||
@@ -227,7 +231,7 @@ void gfs2_rgrp_verify(struct gfs2_rgrpd *rgd) | |||
227 | return; | 231 | return; |
228 | } | 232 | } |
229 | 233 | ||
230 | tmp = rgd->rd_ri.ri_data - | 234 | tmp = rgd->rd_data - |
231 | rgd->rd_rg.rg_free - | 235 | rgd->rd_rg.rg_free - |
232 | rgd->rd_rg.rg_dinodes; | 236 | rgd->rd_rg.rg_dinodes; |
233 | if (count[1] + count[2] != tmp) { | 237 | if (count[1] + count[2] != tmp) { |
@@ -253,10 +257,10 @@ void gfs2_rgrp_verify(struct gfs2_rgrpd *rgd) | |||
253 | 257 | ||
254 | } | 258 | } |
255 | 259 | ||
256 | static inline int rgrp_contains_block(struct gfs2_rindex_host *ri, u64 block) | 260 | static inline int rgrp_contains_block(struct gfs2_rgrpd *rgd, u64 block) |
257 | { | 261 | { |
258 | u64 first = ri->ri_data0; | 262 | u64 first = rgd->rd_data0; |
259 | u64 last = first + ri->ri_data; | 263 | u64 last = first + rgd->rd_data; |
260 | return first <= block && block < last; | 264 | return first <= block && block < last; |
261 | } | 265 | } |
262 | 266 | ||
@@ -275,7 +279,7 @@ struct gfs2_rgrpd *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, u64 blk) | |||
275 | spin_lock(&sdp->sd_rindex_spin); | 279 | spin_lock(&sdp->sd_rindex_spin); |
276 | 280 | ||
277 | list_for_each_entry(rgd, &sdp->sd_rindex_mru_list, rd_list_mru) { | 281 | list_for_each_entry(rgd, &sdp->sd_rindex_mru_list, rd_list_mru) { |
278 | if (rgrp_contains_block(&rgd->rd_ri, blk)) { | 282 | if (rgrp_contains_block(rgd, blk)) { |
279 | list_move(&rgd->rd_list_mru, &sdp->sd_rindex_mru_list); | 283 | list_move(&rgd->rd_list_mru, &sdp->sd_rindex_mru_list); |
280 | spin_unlock(&sdp->sd_rindex_spin); | 284 | spin_unlock(&sdp->sd_rindex_spin); |
281 | return rgd; | 285 | return rgd; |
@@ -354,6 +358,15 @@ void gfs2_clear_rgrpd(struct gfs2_sbd *sdp) | |||
354 | mutex_unlock(&sdp->sd_rindex_mutex); | 358 | mutex_unlock(&sdp->sd_rindex_mutex); |
355 | } | 359 | } |
356 | 360 | ||
361 | static void gfs2_rindex_print(const struct gfs2_rgrpd *rgd) | ||
362 | { | ||
363 | printk(KERN_INFO " ri_addr = %llu\n", (unsigned long long)rgd->rd_addr); | ||
364 | printk(KERN_INFO " ri_length = %u\n", rgd->rd_length); | ||
365 | printk(KERN_INFO " ri_data0 = %llu\n", (unsigned long long)rgd->rd_data0); | ||
366 | printk(KERN_INFO " ri_data = %u\n", rgd->rd_data); | ||
367 | printk(KERN_INFO " ri_bitbytes = %u\n", rgd->rd_bitbytes); | ||
368 | } | ||
369 | |||
357 | /** | 370 | /** |
358 | * gfs2_compute_bitstructs - Compute the bitmap sizes | 371 | * gfs2_compute_bitstructs - Compute the bitmap sizes |
359 | * @rgd: The resource group descriptor | 372 | * @rgd: The resource group descriptor |
@@ -367,7 +380,7 @@ static int compute_bitstructs(struct gfs2_rgrpd *rgd) | |||
367 | { | 380 | { |
368 | struct gfs2_sbd *sdp = rgd->rd_sbd; | 381 | struct gfs2_sbd *sdp = rgd->rd_sbd; |
369 | struct gfs2_bitmap *bi; | 382 | struct gfs2_bitmap *bi; |
370 | u32 length = rgd->rd_ri.ri_length; /* # blocks in hdr & bitmap */ | 383 | u32 length = rgd->rd_length; /* # blocks in hdr & bitmap */ |
371 | u32 bytes_left, bytes; | 384 | u32 bytes_left, bytes; |
372 | int x; | 385 | int x; |
373 | 386 | ||
@@ -378,7 +391,7 @@ static int compute_bitstructs(struct gfs2_rgrpd *rgd) | |||
378 | if (!rgd->rd_bits) | 391 | if (!rgd->rd_bits) |
379 | return -ENOMEM; | 392 | return -ENOMEM; |
380 | 393 | ||
381 | bytes_left = rgd->rd_ri.ri_bitbytes; | 394 | bytes_left = rgd->rd_bitbytes; |
382 | 395 | ||
383 | for (x = 0; x < length; x++) { | 396 | for (x = 0; x < length; x++) { |
384 | bi = rgd->rd_bits + x; | 397 | bi = rgd->rd_bits + x; |
@@ -399,14 +412,14 @@ static int compute_bitstructs(struct gfs2_rgrpd *rgd) | |||
399 | } else if (x + 1 == length) { | 412 | } else if (x + 1 == length) { |
400 | bytes = bytes_left; | 413 | bytes = bytes_left; |
401 | bi->bi_offset = sizeof(struct gfs2_meta_header); | 414 | bi->bi_offset = sizeof(struct gfs2_meta_header); |
402 | bi->bi_start = rgd->rd_ri.ri_bitbytes - bytes_left; | 415 | bi->bi_start = rgd->rd_bitbytes - bytes_left; |
403 | bi->bi_len = bytes; | 416 | bi->bi_len = bytes; |
404 | /* other blocks */ | 417 | /* other blocks */ |
405 | } else { | 418 | } else { |
406 | bytes = sdp->sd_sb.sb_bsize - | 419 | bytes = sdp->sd_sb.sb_bsize - |
407 | sizeof(struct gfs2_meta_header); | 420 | sizeof(struct gfs2_meta_header); |
408 | bi->bi_offset = sizeof(struct gfs2_meta_header); | 421 | bi->bi_offset = sizeof(struct gfs2_meta_header); |
409 | bi->bi_start = rgd->rd_ri.ri_bitbytes - bytes_left; | 422 | bi->bi_start = rgd->rd_bitbytes - bytes_left; |
410 | bi->bi_len = bytes; | 423 | bi->bi_len = bytes; |
411 | } | 424 | } |
412 | 425 | ||
@@ -418,9 +431,9 @@ static int compute_bitstructs(struct gfs2_rgrpd *rgd) | |||
418 | return -EIO; | 431 | return -EIO; |
419 | } | 432 | } |
420 | bi = rgd->rd_bits + (length - 1); | 433 | bi = rgd->rd_bits + (length - 1); |
421 | if ((bi->bi_start + bi->bi_len) * GFS2_NBBY != rgd->rd_ri.ri_data) { | 434 | if ((bi->bi_start + bi->bi_len) * GFS2_NBBY != rgd->rd_data) { |
422 | if (gfs2_consist_rgrpd(rgd)) { | 435 | if (gfs2_consist_rgrpd(rgd)) { |
423 | gfs2_rindex_print(&rgd->rd_ri); | 436 | gfs2_rindex_print(rgd); |
424 | fs_err(sdp, "start=%u len=%u offset=%u\n", | 437 | fs_err(sdp, "start=%u len=%u offset=%u\n", |
425 | bi->bi_start, bi->bi_len, bi->bi_offset); | 438 | bi->bi_start, bi->bi_len, bi->bi_offset); |
426 | } | 439 | } |
@@ -431,9 +444,104 @@ static int compute_bitstructs(struct gfs2_rgrpd *rgd) | |||
431 | } | 444 | } |
432 | 445 | ||
433 | /** | 446 | /** |
434 | * gfs2_ri_update - Pull in a new resource index from the disk | 447 | * gfs2_ri_total - Total up the file system space, according to the rindex. |
448 | * | ||
449 | */ | ||
450 | u64 gfs2_ri_total(struct gfs2_sbd *sdp) | ||
451 | { | ||
452 | u64 total_data = 0; | ||
453 | struct inode *inode = sdp->sd_rindex; | ||
454 | struct gfs2_inode *ip = GFS2_I(inode); | ||
455 | char buf[sizeof(struct gfs2_rindex)]; | ||
456 | struct file_ra_state ra_state; | ||
457 | int error, rgrps; | ||
458 | |||
459 | mutex_lock(&sdp->sd_rindex_mutex); | ||
460 | file_ra_state_init(&ra_state, inode->i_mapping); | ||
461 | for (rgrps = 0;; rgrps++) { | ||
462 | loff_t pos = rgrps * sizeof(struct gfs2_rindex); | ||
463 | |||
464 | if (pos + sizeof(struct gfs2_rindex) >= ip->i_di.di_size) | ||
465 | break; | ||
466 | error = gfs2_internal_read(ip, &ra_state, buf, &pos, | ||
467 | sizeof(struct gfs2_rindex)); | ||
468 | if (error != sizeof(struct gfs2_rindex)) | ||
469 | break; | ||
470 | total_data += be32_to_cpu(((struct gfs2_rindex *)buf)->ri_data); | ||
471 | } | ||
472 | mutex_unlock(&sdp->sd_rindex_mutex); | ||
473 | return total_data; | ||
474 | } | ||
475 | |||
476 | static void gfs2_rindex_in(struct gfs2_rgrpd *rgd, const void *buf) | ||
477 | { | ||
478 | const struct gfs2_rindex *str = buf; | ||
479 | |||
480 | rgd->rd_addr = be64_to_cpu(str->ri_addr); | ||
481 | rgd->rd_length = be32_to_cpu(str->ri_length); | ||
482 | rgd->rd_data0 = be64_to_cpu(str->ri_data0); | ||
483 | rgd->rd_data = be32_to_cpu(str->ri_data); | ||
484 | rgd->rd_bitbytes = be32_to_cpu(str->ri_bitbytes); | ||
485 | } | ||
486 | |||
487 | /** | ||
488 | * read_rindex_entry - Pull in a new resource index entry from the disk | ||
435 | * @gl: The glock covering the rindex inode | 489 | * @gl: The glock covering the rindex inode |
436 | * | 490 | * |
491 | * Returns: 0 on success, error code otherwise | ||
492 | */ | ||
493 | |||
494 | static int read_rindex_entry(struct gfs2_inode *ip, | ||
495 | struct file_ra_state *ra_state) | ||
496 | { | ||
497 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | ||
498 | loff_t pos = sdp->sd_rgrps * sizeof(struct gfs2_rindex); | ||
499 | char buf[sizeof(struct gfs2_rindex)]; | ||
500 | int error; | ||
501 | struct gfs2_rgrpd *rgd; | ||
502 | |||
503 | error = gfs2_internal_read(ip, ra_state, buf, &pos, | ||
504 | sizeof(struct gfs2_rindex)); | ||
505 | if (!error) | ||
506 | return 0; | ||
507 | if (error != sizeof(struct gfs2_rindex)) { | ||
508 | if (error > 0) | ||
509 | error = -EIO; | ||
510 | return error; | ||
511 | } | ||
512 | |||
513 | rgd = kzalloc(sizeof(struct gfs2_rgrpd), GFP_NOFS); | ||
514 | error = -ENOMEM; | ||
515 | if (!rgd) | ||
516 | return error; | ||
517 | |||
518 | mutex_init(&rgd->rd_mutex); | ||
519 | lops_init_le(&rgd->rd_le, &gfs2_rg_lops); | ||
520 | rgd->rd_sbd = sdp; | ||
521 | |||
522 | list_add_tail(&rgd->rd_list, &sdp->sd_rindex_list); | ||
523 | list_add_tail(&rgd->rd_list_mru, &sdp->sd_rindex_mru_list); | ||
524 | |||
525 | gfs2_rindex_in(rgd, buf); | ||
526 | error = compute_bitstructs(rgd); | ||
527 | if (error) | ||
528 | return error; | ||
529 | |||
530 | error = gfs2_glock_get(sdp, rgd->rd_addr, | ||
531 | &gfs2_rgrp_glops, CREATE, &rgd->rd_gl); | ||
532 | if (error) | ||
533 | return error; | ||
534 | |||
535 | rgd->rd_gl->gl_object = rgd; | ||
536 | rgd->rd_rg_vn = rgd->rd_gl->gl_vn - 1; | ||
537 | rgd->rd_flags |= GFS2_RDF_CHECK; | ||
538 | return error; | ||
539 | } | ||
540 | |||
541 | /** | ||
542 | * gfs2_ri_update - Pull in a new resource index from the disk | ||
543 | * @ip: pointer to the rindex inode | ||
544 | * | ||
437 | * Returns: 0 on successful update, error code otherwise | 545 | * Returns: 0 on successful update, error code otherwise |
438 | */ | 546 | */ |
439 | 547 | ||
@@ -441,13 +549,11 @@ static int gfs2_ri_update(struct gfs2_inode *ip) | |||
441 | { | 549 | { |
442 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 550 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
443 | struct inode *inode = &ip->i_inode; | 551 | struct inode *inode = &ip->i_inode; |
444 | struct gfs2_rgrpd *rgd; | ||
445 | char buf[sizeof(struct gfs2_rindex)]; | ||
446 | struct file_ra_state ra_state; | 552 | struct file_ra_state ra_state; |
447 | u64 junk = ip->i_di.di_size; | 553 | u64 rgrp_count = ip->i_di.di_size; |
448 | int error; | 554 | int error; |
449 | 555 | ||
450 | if (do_div(junk, sizeof(struct gfs2_rindex))) { | 556 | if (do_div(rgrp_count, sizeof(struct gfs2_rindex))) { |
451 | gfs2_consist_inode(ip); | 557 | gfs2_consist_inode(ip); |
452 | return -EIO; | 558 | return -EIO; |
453 | } | 559 | } |
@@ -455,50 +561,50 @@ static int gfs2_ri_update(struct gfs2_inode *ip) | |||
455 | clear_rgrpdi(sdp); | 561 | clear_rgrpdi(sdp); |
456 | 562 | ||
457 | file_ra_state_init(&ra_state, inode->i_mapping); | 563 | file_ra_state_init(&ra_state, inode->i_mapping); |
458 | for (sdp->sd_rgrps = 0;; sdp->sd_rgrps++) { | 564 | for (sdp->sd_rgrps = 0; sdp->sd_rgrps < rgrp_count; sdp->sd_rgrps++) { |
459 | loff_t pos = sdp->sd_rgrps * sizeof(struct gfs2_rindex); | 565 | error = read_rindex_entry(ip, &ra_state); |
460 | error = gfs2_internal_read(ip, &ra_state, buf, &pos, | 566 | if (error) { |
461 | sizeof(struct gfs2_rindex)); | 567 | clear_rgrpdi(sdp); |
462 | if (!error) | 568 | return error; |
463 | break; | ||
464 | if (error != sizeof(struct gfs2_rindex)) { | ||
465 | if (error > 0) | ||
466 | error = -EIO; | ||
467 | goto fail; | ||
468 | } | 569 | } |
570 | } | ||
469 | 571 | ||
470 | rgd = kzalloc(sizeof(struct gfs2_rgrpd), GFP_NOFS); | 572 | sdp->sd_rindex_vn = ip->i_gl->gl_vn; |
471 | error = -ENOMEM; | 573 | return 0; |
472 | if (!rgd) | 574 | } |
473 | goto fail; | ||
474 | |||
475 | mutex_init(&rgd->rd_mutex); | ||
476 | lops_init_le(&rgd->rd_le, &gfs2_rg_lops); | ||
477 | rgd->rd_sbd = sdp; | ||
478 | |||
479 | list_add_tail(&rgd->rd_list, &sdp->sd_rindex_list); | ||
480 | list_add_tail(&rgd->rd_list_mru, &sdp->sd_rindex_mru_list); | ||
481 | |||
482 | gfs2_rindex_in(&rgd->rd_ri, buf); | ||
483 | error = compute_bitstructs(rgd); | ||
484 | if (error) | ||
485 | goto fail; | ||
486 | 575 | ||
487 | error = gfs2_glock_get(sdp, rgd->rd_ri.ri_addr, | 576 | /** |
488 | &gfs2_rgrp_glops, CREATE, &rgd->rd_gl); | 577 | * gfs2_ri_update_special - Pull in a new resource index from the disk |
489 | if (error) | 578 | * |
490 | goto fail; | 579 | * This is a special version that's safe to call from gfs2_inplace_reserve_i. |
580 | * In this case we know that we don't have any resource groups in memory yet. | ||
581 | * | ||
582 | * @ip: pointer to the rindex inode | ||
583 | * | ||
584 | * Returns: 0 on successful update, error code otherwise | ||
585 | */ | ||
586 | static int gfs2_ri_update_special(struct gfs2_inode *ip) | ||
587 | { | ||
588 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | ||
589 | struct inode *inode = &ip->i_inode; | ||
590 | struct file_ra_state ra_state; | ||
591 | int error; | ||
491 | 592 | ||
492 | rgd->rd_gl->gl_object = rgd; | 593 | file_ra_state_init(&ra_state, inode->i_mapping); |
493 | rgd->rd_rg_vn = rgd->rd_gl->gl_vn - 1; | 594 | for (sdp->sd_rgrps = 0;; sdp->sd_rgrps++) { |
595 | /* Ignore partials */ | ||
596 | if ((sdp->sd_rgrps + 1) * sizeof(struct gfs2_rindex) > | ||
597 | ip->i_di.di_size) | ||
598 | break; | ||
599 | error = read_rindex_entry(ip, &ra_state); | ||
600 | if (error) { | ||
601 | clear_rgrpdi(sdp); | ||
602 | return error; | ||
603 | } | ||
494 | } | 604 | } |
495 | 605 | ||
496 | sdp->sd_rindex_vn = ip->i_gl->gl_vn; | 606 | sdp->sd_rindex_vn = ip->i_gl->gl_vn; |
497 | return 0; | 607 | return 0; |
498 | |||
499 | fail: | ||
500 | clear_rgrpdi(sdp); | ||
501 | return error; | ||
502 | } | 608 | } |
503 | 609 | ||
504 | /** | 610 | /** |
@@ -543,6 +649,28 @@ int gfs2_rindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ri_gh) | |||
543 | return error; | 649 | return error; |
544 | } | 650 | } |
545 | 651 | ||
652 | static void gfs2_rgrp_in(struct gfs2_rgrp_host *rg, const void *buf) | ||
653 | { | ||
654 | const struct gfs2_rgrp *str = buf; | ||
655 | |||
656 | rg->rg_flags = be32_to_cpu(str->rg_flags); | ||
657 | rg->rg_free = be32_to_cpu(str->rg_free); | ||
658 | rg->rg_dinodes = be32_to_cpu(str->rg_dinodes); | ||
659 | rg->rg_igeneration = be64_to_cpu(str->rg_igeneration); | ||
660 | } | ||
661 | |||
662 | static void gfs2_rgrp_out(const struct gfs2_rgrp_host *rg, void *buf) | ||
663 | { | ||
664 | struct gfs2_rgrp *str = buf; | ||
665 | |||
666 | str->rg_flags = cpu_to_be32(rg->rg_flags); | ||
667 | str->rg_free = cpu_to_be32(rg->rg_free); | ||
668 | str->rg_dinodes = cpu_to_be32(rg->rg_dinodes); | ||
669 | str->__pad = cpu_to_be32(0); | ||
670 | str->rg_igeneration = cpu_to_be64(rg->rg_igeneration); | ||
671 | memset(&str->rg_reserved, 0, sizeof(str->rg_reserved)); | ||
672 | } | ||
673 | |||
546 | /** | 674 | /** |
547 | * gfs2_rgrp_bh_get - Read in a RG's header and bitmaps | 675 | * gfs2_rgrp_bh_get - Read in a RG's header and bitmaps |
548 | * @rgd: the struct gfs2_rgrpd describing the RG to read in | 676 | * @rgd: the struct gfs2_rgrpd describing the RG to read in |
@@ -557,7 +685,7 @@ int gfs2_rgrp_bh_get(struct gfs2_rgrpd *rgd) | |||
557 | { | 685 | { |
558 | struct gfs2_sbd *sdp = rgd->rd_sbd; | 686 | struct gfs2_sbd *sdp = rgd->rd_sbd; |
559 | struct gfs2_glock *gl = rgd->rd_gl; | 687 | struct gfs2_glock *gl = rgd->rd_gl; |
560 | unsigned int length = rgd->rd_ri.ri_length; | 688 | unsigned int length = rgd->rd_length; |
561 | struct gfs2_bitmap *bi; | 689 | struct gfs2_bitmap *bi; |
562 | unsigned int x, y; | 690 | unsigned int x, y; |
563 | int error; | 691 | int error; |
@@ -575,7 +703,7 @@ int gfs2_rgrp_bh_get(struct gfs2_rgrpd *rgd) | |||
575 | 703 | ||
576 | for (x = 0; x < length; x++) { | 704 | for (x = 0; x < length; x++) { |
577 | bi = rgd->rd_bits + x; | 705 | bi = rgd->rd_bits + x; |
578 | error = gfs2_meta_read(gl, rgd->rd_ri.ri_addr + x, 0, &bi->bi_bh); | 706 | error = gfs2_meta_read(gl, rgd->rd_addr + x, 0, &bi->bi_bh); |
579 | if (error) | 707 | if (error) |
580 | goto fail; | 708 | goto fail; |
581 | } | 709 | } |
@@ -637,7 +765,7 @@ void gfs2_rgrp_bh_hold(struct gfs2_rgrpd *rgd) | |||
637 | void gfs2_rgrp_bh_put(struct gfs2_rgrpd *rgd) | 765 | void gfs2_rgrp_bh_put(struct gfs2_rgrpd *rgd) |
638 | { | 766 | { |
639 | struct gfs2_sbd *sdp = rgd->rd_sbd; | 767 | struct gfs2_sbd *sdp = rgd->rd_sbd; |
640 | int x, length = rgd->rd_ri.ri_length; | 768 | int x, length = rgd->rd_length; |
641 | 769 | ||
642 | spin_lock(&sdp->sd_rindex_spin); | 770 | spin_lock(&sdp->sd_rindex_spin); |
643 | gfs2_assert_warn(rgd->rd_sbd, rgd->rd_bh_count); | 771 | gfs2_assert_warn(rgd->rd_sbd, rgd->rd_bh_count); |
@@ -660,7 +788,7 @@ void gfs2_rgrp_bh_put(struct gfs2_rgrpd *rgd) | |||
660 | void gfs2_rgrp_repolish_clones(struct gfs2_rgrpd *rgd) | 788 | void gfs2_rgrp_repolish_clones(struct gfs2_rgrpd *rgd) |
661 | { | 789 | { |
662 | struct gfs2_sbd *sdp = rgd->rd_sbd; | 790 | struct gfs2_sbd *sdp = rgd->rd_sbd; |
663 | unsigned int length = rgd->rd_ri.ri_length; | 791 | unsigned int length = rgd->rd_length; |
664 | unsigned int x; | 792 | unsigned int x; |
665 | 793 | ||
666 | for (x = 0; x < length; x++) { | 794 | for (x = 0; x < length; x++) { |
@@ -722,6 +850,38 @@ static int try_rgrp_fit(struct gfs2_rgrpd *rgd, struct gfs2_alloc *al) | |||
722 | } | 850 | } |
723 | 851 | ||
724 | /** | 852 | /** |
853 | * try_rgrp_unlink - Look for any unlinked, allocated, but unused inodes | ||
854 | * @rgd: The rgrp | ||
855 | * | ||
856 | * Returns: The inode, if one has been found | ||
857 | */ | ||
858 | |||
859 | static struct inode *try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked) | ||
860 | { | ||
861 | struct inode *inode; | ||
862 | u32 goal = 0; | ||
863 | u64 no_addr; | ||
864 | |||
865 | for(;;) { | ||
866 | goal = rgblk_search(rgd, goal, GFS2_BLKST_UNLINKED, | ||
867 | GFS2_BLKST_UNLINKED); | ||
868 | if (goal == 0) | ||
869 | return 0; | ||
870 | no_addr = goal + rgd->rd_data0; | ||
871 | if (no_addr <= *last_unlinked) | ||
872 | continue; | ||
873 | *last_unlinked = no_addr; | ||
874 | inode = gfs2_inode_lookup(rgd->rd_sbd->sd_vfs, DT_UNKNOWN, | ||
875 | no_addr, -1); | ||
876 | if (!IS_ERR(inode)) | ||
877 | return inode; | ||
878 | } | ||
879 | |||
880 | rgd->rd_flags &= ~GFS2_RDF_CHECK; | ||
881 | return NULL; | ||
882 | } | ||
883 | |||
884 | /** | ||
725 | * recent_rgrp_first - get first RG from "recent" list | 885 | * recent_rgrp_first - get first RG from "recent" list |
726 | * @sdp: The GFS2 superblock | 886 | * @sdp: The GFS2 superblock |
727 | * @rglast: address of the rgrp used last | 887 | * @rglast: address of the rgrp used last |
@@ -743,7 +903,7 @@ static struct gfs2_rgrpd *recent_rgrp_first(struct gfs2_sbd *sdp, | |||
743 | goto first; | 903 | goto first; |
744 | 904 | ||
745 | list_for_each_entry(rgd, &sdp->sd_rindex_recent_list, rd_recent) { | 905 | list_for_each_entry(rgd, &sdp->sd_rindex_recent_list, rd_recent) { |
746 | if (rgd->rd_ri.ri_addr == rglast) | 906 | if (rgd->rd_addr == rglast) |
747 | goto out; | 907 | goto out; |
748 | } | 908 | } |
749 | 909 | ||
@@ -882,8 +1042,9 @@ static void forward_rgrp_set(struct gfs2_sbd *sdp, struct gfs2_rgrpd *rgd) | |||
882 | * Returns: errno | 1042 | * Returns: errno |
883 | */ | 1043 | */ |
884 | 1044 | ||
885 | static int get_local_rgrp(struct gfs2_inode *ip) | 1045 | static struct inode *get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked) |
886 | { | 1046 | { |
1047 | struct inode *inode = NULL; | ||
887 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 1048 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
888 | struct gfs2_rgrpd *rgd, *begin = NULL; | 1049 | struct gfs2_rgrpd *rgd, *begin = NULL; |
889 | struct gfs2_alloc *al = &ip->i_alloc; | 1050 | struct gfs2_alloc *al = &ip->i_alloc; |
@@ -903,7 +1064,11 @@ static int get_local_rgrp(struct gfs2_inode *ip) | |||
903 | case 0: | 1064 | case 0: |
904 | if (try_rgrp_fit(rgd, al)) | 1065 | if (try_rgrp_fit(rgd, al)) |
905 | goto out; | 1066 | goto out; |
1067 | if (rgd->rd_flags & GFS2_RDF_CHECK) | ||
1068 | inode = try_rgrp_unlink(rgd, last_unlinked); | ||
906 | gfs2_glock_dq_uninit(&al->al_rgd_gh); | 1069 | gfs2_glock_dq_uninit(&al->al_rgd_gh); |
1070 | if (inode) | ||
1071 | return inode; | ||
907 | rgd = recent_rgrp_next(rgd, 1); | 1072 | rgd = recent_rgrp_next(rgd, 1); |
908 | break; | 1073 | break; |
909 | 1074 | ||
@@ -912,7 +1077,7 @@ static int get_local_rgrp(struct gfs2_inode *ip) | |||
912 | break; | 1077 | break; |
913 | 1078 | ||
914 | default: | 1079 | default: |
915 | return error; | 1080 | return ERR_PTR(error); |
916 | } | 1081 | } |
917 | } | 1082 | } |
918 | 1083 | ||
@@ -927,7 +1092,11 @@ static int get_local_rgrp(struct gfs2_inode *ip) | |||
927 | case 0: | 1092 | case 0: |
928 | if (try_rgrp_fit(rgd, al)) | 1093 | if (try_rgrp_fit(rgd, al)) |
929 | goto out; | 1094 | goto out; |
1095 | if (rgd->rd_flags & GFS2_RDF_CHECK) | ||
1096 | inode = try_rgrp_unlink(rgd, last_unlinked); | ||
930 | gfs2_glock_dq_uninit(&al->al_rgd_gh); | 1097 | gfs2_glock_dq_uninit(&al->al_rgd_gh); |
1098 | if (inode) | ||
1099 | return inode; | ||
931 | break; | 1100 | break; |
932 | 1101 | ||
933 | case GLR_TRYFAILED: | 1102 | case GLR_TRYFAILED: |
@@ -935,7 +1104,7 @@ static int get_local_rgrp(struct gfs2_inode *ip) | |||
935 | break; | 1104 | break; |
936 | 1105 | ||
937 | default: | 1106 | default: |
938 | return error; | 1107 | return ERR_PTR(error); |
939 | } | 1108 | } |
940 | 1109 | ||
941 | rgd = gfs2_rgrpd_get_next(rgd); | 1110 | rgd = gfs2_rgrpd_get_next(rgd); |
@@ -944,7 +1113,7 @@ static int get_local_rgrp(struct gfs2_inode *ip) | |||
944 | 1113 | ||
945 | if (rgd == begin) { | 1114 | if (rgd == begin) { |
946 | if (++loops >= 3) | 1115 | if (++loops >= 3) |
947 | return -ENOSPC; | 1116 | return ERR_PTR(-ENOSPC); |
948 | if (!skipped) | 1117 | if (!skipped) |
949 | loops++; | 1118 | loops++; |
950 | flags = 0; | 1119 | flags = 0; |
@@ -954,7 +1123,7 @@ static int get_local_rgrp(struct gfs2_inode *ip) | |||
954 | } | 1123 | } |
955 | 1124 | ||
956 | out: | 1125 | out: |
957 | ip->i_last_rg_alloc = rgd->rd_ri.ri_addr; | 1126 | ip->i_last_rg_alloc = rgd->rd_addr; |
958 | 1127 | ||
959 | if (begin) { | 1128 | if (begin) { |
960 | recent_rgrp_add(rgd); | 1129 | recent_rgrp_add(rgd); |
@@ -964,7 +1133,7 @@ out: | |||
964 | forward_rgrp_set(sdp, rgd); | 1133 | forward_rgrp_set(sdp, rgd); |
965 | } | 1134 | } |
966 | 1135 | ||
967 | return 0; | 1136 | return NULL; |
968 | } | 1137 | } |
969 | 1138 | ||
970 | /** | 1139 | /** |
@@ -978,19 +1147,33 @@ int gfs2_inplace_reserve_i(struct gfs2_inode *ip, char *file, unsigned int line) | |||
978 | { | 1147 | { |
979 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 1148 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
980 | struct gfs2_alloc *al = &ip->i_alloc; | 1149 | struct gfs2_alloc *al = &ip->i_alloc; |
981 | int error; | 1150 | struct inode *inode; |
1151 | int error = 0; | ||
1152 | u64 last_unlinked = 0; | ||
982 | 1153 | ||
983 | if (gfs2_assert_warn(sdp, al->al_requested)) | 1154 | if (gfs2_assert_warn(sdp, al->al_requested)) |
984 | return -EINVAL; | 1155 | return -EINVAL; |
985 | 1156 | ||
986 | error = gfs2_rindex_hold(sdp, &al->al_ri_gh); | 1157 | try_again: |
1158 | /* We need to hold the rindex unless the inode we're using is | ||
1159 | the rindex itself, in which case it's already held. */ | ||
1160 | if (ip != GFS2_I(sdp->sd_rindex)) | ||
1161 | error = gfs2_rindex_hold(sdp, &al->al_ri_gh); | ||
1162 | else if (!sdp->sd_rgrps) /* We may not have the rindex read in, so: */ | ||
1163 | error = gfs2_ri_update_special(ip); | ||
1164 | |||
987 | if (error) | 1165 | if (error) |
988 | return error; | 1166 | return error; |
989 | 1167 | ||
990 | error = get_local_rgrp(ip); | 1168 | inode = get_local_rgrp(ip, &last_unlinked); |
991 | if (error) { | 1169 | if (inode) { |
992 | gfs2_glock_dq_uninit(&al->al_ri_gh); | 1170 | if (ip != GFS2_I(sdp->sd_rindex)) |
993 | return error; | 1171 | gfs2_glock_dq_uninit(&al->al_ri_gh); |
1172 | if (IS_ERR(inode)) | ||
1173 | return PTR_ERR(inode); | ||
1174 | iput(inode); | ||
1175 | gfs2_log_flush(sdp, NULL); | ||
1176 | goto try_again; | ||
994 | } | 1177 | } |
995 | 1178 | ||
996 | al->al_file = file; | 1179 | al->al_file = file; |
@@ -1019,7 +1202,8 @@ void gfs2_inplace_release(struct gfs2_inode *ip) | |||
1019 | 1202 | ||
1020 | al->al_rgd = NULL; | 1203 | al->al_rgd = NULL; |
1021 | gfs2_glock_dq_uninit(&al->al_rgd_gh); | 1204 | gfs2_glock_dq_uninit(&al->al_rgd_gh); |
1022 | gfs2_glock_dq_uninit(&al->al_ri_gh); | 1205 | if (ip != GFS2_I(sdp->sd_rindex)) |
1206 | gfs2_glock_dq_uninit(&al->al_ri_gh); | ||
1023 | } | 1207 | } |
1024 | 1208 | ||
1025 | /** | 1209 | /** |
@@ -1037,8 +1221,8 @@ unsigned char gfs2_get_block_type(struct gfs2_rgrpd *rgd, u64 block) | |||
1037 | unsigned int buf; | 1221 | unsigned int buf; |
1038 | unsigned char type; | 1222 | unsigned char type; |
1039 | 1223 | ||
1040 | length = rgd->rd_ri.ri_length; | 1224 | length = rgd->rd_length; |
1041 | rgrp_block = block - rgd->rd_ri.ri_data0; | 1225 | rgrp_block = block - rgd->rd_data0; |
1042 | 1226 | ||
1043 | for (buf = 0; buf < length; buf++) { | 1227 | for (buf = 0; buf < length; buf++) { |
1044 | bi = rgd->rd_bits + buf; | 1228 | bi = rgd->rd_bits + buf; |
@@ -1077,10 +1261,10 @@ unsigned char gfs2_get_block_type(struct gfs2_rgrpd *rgd, u64 block) | |||
1077 | */ | 1261 | */ |
1078 | 1262 | ||
1079 | static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal, | 1263 | static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal, |
1080 | unsigned char old_state, unsigned char new_state) | 1264 | unsigned char old_state, unsigned char new_state) |
1081 | { | 1265 | { |
1082 | struct gfs2_bitmap *bi = NULL; | 1266 | struct gfs2_bitmap *bi = NULL; |
1083 | u32 length = rgd->rd_ri.ri_length; | 1267 | u32 length = rgd->rd_length; |
1084 | u32 blk = 0; | 1268 | u32 blk = 0; |
1085 | unsigned int buf, x; | 1269 | unsigned int buf, x; |
1086 | 1270 | ||
@@ -1118,17 +1302,18 @@ static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal, | |||
1118 | goal = 0; | 1302 | goal = 0; |
1119 | } | 1303 | } |
1120 | 1304 | ||
1121 | if (gfs2_assert_withdraw(rgd->rd_sbd, x <= length)) | 1305 | if (old_state != new_state) { |
1122 | blk = 0; | 1306 | gfs2_assert_withdraw(rgd->rd_sbd, blk != BFITNOENT); |
1123 | 1307 | ||
1124 | gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1); | 1308 | gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1); |
1125 | gfs2_setbit(rgd, bi->bi_bh->b_data + bi->bi_offset, | 1309 | gfs2_setbit(rgd, bi->bi_bh->b_data + bi->bi_offset, |
1126 | bi->bi_len, blk, new_state); | ||
1127 | if (bi->bi_clone) | ||
1128 | gfs2_setbit(rgd, bi->bi_clone + bi->bi_offset, | ||
1129 | bi->bi_len, blk, new_state); | 1310 | bi->bi_len, blk, new_state); |
1311 | if (bi->bi_clone) | ||
1312 | gfs2_setbit(rgd, bi->bi_clone + bi->bi_offset, | ||
1313 | bi->bi_len, blk, new_state); | ||
1314 | } | ||
1130 | 1315 | ||
1131 | return bi->bi_start * GFS2_NBBY + blk; | 1316 | return (blk == BFITNOENT) ? 0 : (bi->bi_start * GFS2_NBBY) + blk; |
1132 | } | 1317 | } |
1133 | 1318 | ||
1134 | /** | 1319 | /** |
@@ -1156,9 +1341,9 @@ static struct gfs2_rgrpd *rgblk_free(struct gfs2_sbd *sdp, u64 bstart, | |||
1156 | return NULL; | 1341 | return NULL; |
1157 | } | 1342 | } |
1158 | 1343 | ||
1159 | length = rgd->rd_ri.ri_length; | 1344 | length = rgd->rd_length; |
1160 | 1345 | ||
1161 | rgrp_blk = bstart - rgd->rd_ri.ri_data0; | 1346 | rgrp_blk = bstart - rgd->rd_data0; |
1162 | 1347 | ||
1163 | while (blen--) { | 1348 | while (blen--) { |
1164 | for (buf = 0; buf < length; buf++) { | 1349 | for (buf = 0; buf < length; buf++) { |
@@ -1202,15 +1387,15 @@ u64 gfs2_alloc_data(struct gfs2_inode *ip) | |||
1202 | u32 goal, blk; | 1387 | u32 goal, blk; |
1203 | u64 block; | 1388 | u64 block; |
1204 | 1389 | ||
1205 | if (rgrp_contains_block(&rgd->rd_ri, ip->i_di.di_goal_data)) | 1390 | if (rgrp_contains_block(rgd, ip->i_di.di_goal_data)) |
1206 | goal = ip->i_di.di_goal_data - rgd->rd_ri.ri_data0; | 1391 | goal = ip->i_di.di_goal_data - rgd->rd_data0; |
1207 | else | 1392 | else |
1208 | goal = rgd->rd_last_alloc_data; | 1393 | goal = rgd->rd_last_alloc_data; |
1209 | 1394 | ||
1210 | blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, GFS2_BLKST_USED); | 1395 | blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, GFS2_BLKST_USED); |
1211 | rgd->rd_last_alloc_data = blk; | 1396 | rgd->rd_last_alloc_data = blk; |
1212 | 1397 | ||
1213 | block = rgd->rd_ri.ri_data0 + blk; | 1398 | block = rgd->rd_data0 + blk; |
1214 | ip->i_di.di_goal_data = block; | 1399 | ip->i_di.di_goal_data = block; |
1215 | 1400 | ||
1216 | gfs2_assert_withdraw(sdp, rgd->rd_rg.rg_free); | 1401 | gfs2_assert_withdraw(sdp, rgd->rd_rg.rg_free); |
@@ -1246,15 +1431,15 @@ u64 gfs2_alloc_meta(struct gfs2_inode *ip) | |||
1246 | u32 goal, blk; | 1431 | u32 goal, blk; |
1247 | u64 block; | 1432 | u64 block; |
1248 | 1433 | ||
1249 | if (rgrp_contains_block(&rgd->rd_ri, ip->i_di.di_goal_meta)) | 1434 | if (rgrp_contains_block(rgd, ip->i_di.di_goal_meta)) |
1250 | goal = ip->i_di.di_goal_meta - rgd->rd_ri.ri_data0; | 1435 | goal = ip->i_di.di_goal_meta - rgd->rd_data0; |
1251 | else | 1436 | else |
1252 | goal = rgd->rd_last_alloc_meta; | 1437 | goal = rgd->rd_last_alloc_meta; |
1253 | 1438 | ||
1254 | blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, GFS2_BLKST_USED); | 1439 | blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, GFS2_BLKST_USED); |
1255 | rgd->rd_last_alloc_meta = blk; | 1440 | rgd->rd_last_alloc_meta = blk; |
1256 | 1441 | ||
1257 | block = rgd->rd_ri.ri_data0 + blk; | 1442 | block = rgd->rd_data0 + blk; |
1258 | ip->i_di.di_goal_meta = block; | 1443 | ip->i_di.di_goal_meta = block; |
1259 | 1444 | ||
1260 | gfs2_assert_withdraw(sdp, rgd->rd_rg.rg_free); | 1445 | gfs2_assert_withdraw(sdp, rgd->rd_rg.rg_free); |
@@ -1296,7 +1481,7 @@ u64 gfs2_alloc_di(struct gfs2_inode *dip, u64 *generation) | |||
1296 | 1481 | ||
1297 | rgd->rd_last_alloc_meta = blk; | 1482 | rgd->rd_last_alloc_meta = blk; |
1298 | 1483 | ||
1299 | block = rgd->rd_ri.ri_data0 + blk; | 1484 | block = rgd->rd_data0 + blk; |
1300 | 1485 | ||
1301 | gfs2_assert_withdraw(sdp, rgd->rd_rg.rg_free); | 1486 | gfs2_assert_withdraw(sdp, rgd->rd_rg.rg_free); |
1302 | rgd->rd_rg.rg_free--; | 1487 | rgd->rd_rg.rg_free--; |
@@ -1379,7 +1564,7 @@ void gfs2_unlink_di(struct inode *inode) | |||
1379 | struct gfs2_inode *ip = GFS2_I(inode); | 1564 | struct gfs2_inode *ip = GFS2_I(inode); |
1380 | struct gfs2_sbd *sdp = GFS2_SB(inode); | 1565 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
1381 | struct gfs2_rgrpd *rgd; | 1566 | struct gfs2_rgrpd *rgd; |
1382 | u64 blkno = ip->i_num.no_addr; | 1567 | u64 blkno = ip->i_no_addr; |
1383 | 1568 | ||
1384 | rgd = rgblk_free(sdp, blkno, 1, GFS2_BLKST_UNLINKED); | 1569 | rgd = rgblk_free(sdp, blkno, 1, GFS2_BLKST_UNLINKED); |
1385 | if (!rgd) | 1570 | if (!rgd) |
@@ -1414,9 +1599,9 @@ static void gfs2_free_uninit_di(struct gfs2_rgrpd *rgd, u64 blkno) | |||
1414 | 1599 | ||
1415 | void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip) | 1600 | void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip) |
1416 | { | 1601 | { |
1417 | gfs2_free_uninit_di(rgd, ip->i_num.no_addr); | 1602 | gfs2_free_uninit_di(rgd, ip->i_no_addr); |
1418 | gfs2_quota_change(ip, -1, ip->i_inode.i_uid, ip->i_inode.i_gid); | 1603 | gfs2_quota_change(ip, -1, ip->i_inode.i_uid, ip->i_inode.i_gid); |
1419 | gfs2_meta_wipe(ip, ip->i_num.no_addr, 1); | 1604 | gfs2_meta_wipe(ip, ip->i_no_addr, 1); |
1420 | } | 1605 | } |
1421 | 1606 | ||
1422 | /** | 1607 | /** |
diff --git a/fs/gfs2/rgrp.h b/fs/gfs2/rgrp.h index b01e0cfc99b5..b4c6adfc6f2e 100644 --- a/fs/gfs2/rgrp.h +++ b/fs/gfs2/rgrp.h | |||
@@ -65,5 +65,6 @@ void gfs2_rlist_add(struct gfs2_sbd *sdp, struct gfs2_rgrp_list *rlist, | |||
65 | void gfs2_rlist_alloc(struct gfs2_rgrp_list *rlist, unsigned int state, | 65 | void gfs2_rlist_alloc(struct gfs2_rgrp_list *rlist, unsigned int state, |
66 | int flags); | 66 | int flags); |
67 | void gfs2_rlist_free(struct gfs2_rgrp_list *rlist); | 67 | void gfs2_rlist_free(struct gfs2_rgrp_list *rlist); |
68 | u64 gfs2_ri_total(struct gfs2_sbd *sdp); | ||
68 | 69 | ||
69 | #endif /* __RGRP_DOT_H__ */ | 70 | #endif /* __RGRP_DOT_H__ */ |
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index 4fdda974dc83..f916b9740c75 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c | |||
@@ -95,8 +95,8 @@ int gfs2_check_sb(struct gfs2_sbd *sdp, struct gfs2_sb_host *sb, int silent) | |||
95 | { | 95 | { |
96 | unsigned int x; | 96 | unsigned int x; |
97 | 97 | ||
98 | if (sb->sb_header.mh_magic != GFS2_MAGIC || | 98 | if (sb->sb_magic != GFS2_MAGIC || |
99 | sb->sb_header.mh_type != GFS2_METATYPE_SB) { | 99 | sb->sb_type != GFS2_METATYPE_SB) { |
100 | if (!silent) | 100 | if (!silent) |
101 | printk(KERN_WARNING "GFS2: not a GFS2 filesystem\n"); | 101 | printk(KERN_WARNING "GFS2: not a GFS2 filesystem\n"); |
102 | return -EINVAL; | 102 | return -EINVAL; |
@@ -174,10 +174,31 @@ static int end_bio_io_page(struct bio *bio, unsigned int bytes_done, int error) | |||
174 | return 0; | 174 | return 0; |
175 | } | 175 | } |
176 | 176 | ||
177 | static void gfs2_sb_in(struct gfs2_sb_host *sb, const void *buf) | ||
178 | { | ||
179 | const struct gfs2_sb *str = buf; | ||
180 | |||
181 | sb->sb_magic = be32_to_cpu(str->sb_header.mh_magic); | ||
182 | sb->sb_type = be32_to_cpu(str->sb_header.mh_type); | ||
183 | sb->sb_format = be32_to_cpu(str->sb_header.mh_format); | ||
184 | sb->sb_fs_format = be32_to_cpu(str->sb_fs_format); | ||
185 | sb->sb_multihost_format = be32_to_cpu(str->sb_multihost_format); | ||
186 | sb->sb_bsize = be32_to_cpu(str->sb_bsize); | ||
187 | sb->sb_bsize_shift = be32_to_cpu(str->sb_bsize_shift); | ||
188 | sb->sb_master_dir.no_addr = be64_to_cpu(str->sb_master_dir.no_addr); | ||
189 | sb->sb_master_dir.no_formal_ino = be64_to_cpu(str->sb_master_dir.no_formal_ino); | ||
190 | sb->sb_root_dir.no_addr = be64_to_cpu(str->sb_root_dir.no_addr); | ||
191 | sb->sb_root_dir.no_formal_ino = be64_to_cpu(str->sb_root_dir.no_formal_ino); | ||
192 | |||
193 | memcpy(sb->sb_lockproto, str->sb_lockproto, GFS2_LOCKNAME_LEN); | ||
194 | memcpy(sb->sb_locktable, str->sb_locktable, GFS2_LOCKNAME_LEN); | ||
195 | } | ||
196 | |||
177 | /** | 197 | /** |
178 | * gfs2_read_super - Read the gfs2 super block from disk | 198 | * gfs2_read_super - Read the gfs2 super block from disk |
179 | * @sb: The VFS super block | 199 | * @sdp: The GFS2 super block |
180 | * @sector: The location of the super block | 200 | * @sector: The location of the super block |
201 | * @error: The error code to return | ||
181 | * | 202 | * |
182 | * This uses the bio functions to read the super block from disk | 203 | * This uses the bio functions to read the super block from disk |
183 | * because we want to be 100% sure that we never read cached data. | 204 | * because we want to be 100% sure that we never read cached data. |
@@ -189,17 +210,19 @@ static int end_bio_io_page(struct bio *bio, unsigned int bytes_done, int error) | |||
189 | * the master directory (contains pointers to journals etc) and the | 210 | * the master directory (contains pointers to journals etc) and the |
190 | * root directory. | 211 | * root directory. |
191 | * | 212 | * |
192 | * Returns: A page containing the sb or NULL | 213 | * Returns: 0 on success or error |
193 | */ | 214 | */ |
194 | 215 | ||
195 | struct page *gfs2_read_super(struct super_block *sb, sector_t sector) | 216 | int gfs2_read_super(struct gfs2_sbd *sdp, sector_t sector) |
196 | { | 217 | { |
218 | struct super_block *sb = sdp->sd_vfs; | ||
219 | struct gfs2_sb *p; | ||
197 | struct page *page; | 220 | struct page *page; |
198 | struct bio *bio; | 221 | struct bio *bio; |
199 | 222 | ||
200 | page = alloc_page(GFP_KERNEL); | 223 | page = alloc_page(GFP_KERNEL); |
201 | if (unlikely(!page)) | 224 | if (unlikely(!page)) |
202 | return NULL; | 225 | return -ENOBUFS; |
203 | 226 | ||
204 | ClearPageUptodate(page); | 227 | ClearPageUptodate(page); |
205 | ClearPageDirty(page); | 228 | ClearPageDirty(page); |
@@ -208,7 +231,7 @@ struct page *gfs2_read_super(struct super_block *sb, sector_t sector) | |||
208 | bio = bio_alloc(GFP_KERNEL, 1); | 231 | bio = bio_alloc(GFP_KERNEL, 1); |
209 | if (unlikely(!bio)) { | 232 | if (unlikely(!bio)) { |
210 | __free_page(page); | 233 | __free_page(page); |
211 | return NULL; | 234 | return -ENOBUFS; |
212 | } | 235 | } |
213 | 236 | ||
214 | bio->bi_sector = sector * (sb->s_blocksize >> 9); | 237 | bio->bi_sector = sector * (sb->s_blocksize >> 9); |
@@ -222,9 +245,13 @@ struct page *gfs2_read_super(struct super_block *sb, sector_t sector) | |||
222 | bio_put(bio); | 245 | bio_put(bio); |
223 | if (!PageUptodate(page)) { | 246 | if (!PageUptodate(page)) { |
224 | __free_page(page); | 247 | __free_page(page); |
225 | return NULL; | 248 | return -EIO; |
226 | } | 249 | } |
227 | return page; | 250 | p = kmap(page); |
251 | gfs2_sb_in(&sdp->sd_sb, p); | ||
252 | kunmap(page); | ||
253 | __free_page(page); | ||
254 | return 0; | ||
228 | } | 255 | } |
229 | 256 | ||
230 | /** | 257 | /** |
@@ -241,19 +268,13 @@ int gfs2_read_sb(struct gfs2_sbd *sdp, struct gfs2_glock *gl, int silent) | |||
241 | u32 tmp_blocks; | 268 | u32 tmp_blocks; |
242 | unsigned int x; | 269 | unsigned int x; |
243 | int error; | 270 | int error; |
244 | struct page *page; | ||
245 | char *sb; | ||
246 | 271 | ||
247 | page = gfs2_read_super(sdp->sd_vfs, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift); | 272 | error = gfs2_read_super(sdp, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift); |
248 | if (!page) { | 273 | if (error) { |
249 | if (!silent) | 274 | if (!silent) |
250 | fs_err(sdp, "can't read superblock\n"); | 275 | fs_err(sdp, "can't read superblock\n"); |
251 | return -EIO; | 276 | return error; |
252 | } | 277 | } |
253 | sb = kmap(page); | ||
254 | gfs2_sb_in(&sdp->sd_sb, sb); | ||
255 | kunmap(page); | ||
256 | __free_page(page); | ||
257 | 278 | ||
258 | error = gfs2_check_sb(sdp, &sdp->sd_sb, silent); | 279 | error = gfs2_check_sb(sdp, &sdp->sd_sb, silent); |
259 | if (error) | 280 | if (error) |
@@ -360,7 +381,7 @@ int gfs2_jindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ji_gh) | |||
360 | name.len = sprintf(buf, "journal%u", sdp->sd_journals); | 381 | name.len = sprintf(buf, "journal%u", sdp->sd_journals); |
361 | name.hash = gfs2_disk_hash(name.name, name.len); | 382 | name.hash = gfs2_disk_hash(name.name, name.len); |
362 | 383 | ||
363 | error = gfs2_dir_search(sdp->sd_jindex, &name, NULL, NULL); | 384 | error = gfs2_dir_check(sdp->sd_jindex, &name, NULL); |
364 | if (error == -ENOENT) { | 385 | if (error == -ENOENT) { |
365 | error = 0; | 386 | error = 0; |
366 | break; | 387 | break; |
@@ -593,6 +614,24 @@ int gfs2_make_fs_ro(struct gfs2_sbd *sdp) | |||
593 | return error; | 614 | return error; |
594 | } | 615 | } |
595 | 616 | ||
617 | static void gfs2_statfs_change_in(struct gfs2_statfs_change_host *sc, const void *buf) | ||
618 | { | ||
619 | const struct gfs2_statfs_change *str = buf; | ||
620 | |||
621 | sc->sc_total = be64_to_cpu(str->sc_total); | ||
622 | sc->sc_free = be64_to_cpu(str->sc_free); | ||
623 | sc->sc_dinodes = be64_to_cpu(str->sc_dinodes); | ||
624 | } | ||
625 | |||
626 | static void gfs2_statfs_change_out(const struct gfs2_statfs_change_host *sc, void *buf) | ||
627 | { | ||
628 | struct gfs2_statfs_change *str = buf; | ||
629 | |||
630 | str->sc_total = cpu_to_be64(sc->sc_total); | ||
631 | str->sc_free = cpu_to_be64(sc->sc_free); | ||
632 | str->sc_dinodes = cpu_to_be64(sc->sc_dinodes); | ||
633 | } | ||
634 | |||
596 | int gfs2_statfs_init(struct gfs2_sbd *sdp) | 635 | int gfs2_statfs_init(struct gfs2_sbd *sdp) |
597 | { | 636 | { |
598 | struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode); | 637 | struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode); |
@@ -772,7 +811,7 @@ static int statfs_slow_fill(struct gfs2_rgrpd *rgd, | |||
772 | struct gfs2_statfs_change_host *sc) | 811 | struct gfs2_statfs_change_host *sc) |
773 | { | 812 | { |
774 | gfs2_rgrp_verify(rgd); | 813 | gfs2_rgrp_verify(rgd); |
775 | sc->sc_total += rgd->rd_ri.ri_data; | 814 | sc->sc_total += rgd->rd_data; |
776 | sc->sc_free += rgd->rd_rg.rg_free; | 815 | sc->sc_free += rgd->rd_rg.rg_free; |
777 | sc->sc_dinodes += rgd->rd_rg.rg_dinodes; | 816 | sc->sc_dinodes += rgd->rd_rg.rg_dinodes; |
778 | return 0; | 817 | return 0; |
diff --git a/fs/gfs2/super.h b/fs/gfs2/super.h index e590b2df11dc..60a870e430be 100644 --- a/fs/gfs2/super.h +++ b/fs/gfs2/super.h | |||
@@ -16,7 +16,7 @@ void gfs2_tune_init(struct gfs2_tune *gt); | |||
16 | 16 | ||
17 | int gfs2_check_sb(struct gfs2_sbd *sdp, struct gfs2_sb_host *sb, int silent); | 17 | int gfs2_check_sb(struct gfs2_sbd *sdp, struct gfs2_sb_host *sb, int silent); |
18 | int gfs2_read_sb(struct gfs2_sbd *sdp, struct gfs2_glock *gl, int silent); | 18 | int gfs2_read_sb(struct gfs2_sbd *sdp, struct gfs2_glock *gl, int silent); |
19 | struct page *gfs2_read_super(struct super_block *sb, sector_t sector); | 19 | int gfs2_read_super(struct gfs2_sbd *sdp, sector_t sector); |
20 | 20 | ||
21 | static inline unsigned int gfs2_jindex_size(struct gfs2_sbd *sdp) | 21 | static inline unsigned int gfs2_jindex_size(struct gfs2_sbd *sdp) |
22 | { | 22 | { |
diff --git a/fs/gfs2/util.c b/fs/gfs2/util.c index 601eaa1b9ed6..424a0774eda8 100644 --- a/fs/gfs2/util.c +++ b/fs/gfs2/util.c | |||
@@ -115,8 +115,8 @@ int gfs2_consist_inode_i(struct gfs2_inode *ip, int cluster_wide, | |||
115 | "GFS2: fsid=%s: inode = %llu %llu\n" | 115 | "GFS2: fsid=%s: inode = %llu %llu\n" |
116 | "GFS2: fsid=%s: function = %s, file = %s, line = %u\n", | 116 | "GFS2: fsid=%s: function = %s, file = %s, line = %u\n", |
117 | sdp->sd_fsname, | 117 | sdp->sd_fsname, |
118 | sdp->sd_fsname, (unsigned long long)ip->i_num.no_formal_ino, | 118 | sdp->sd_fsname, (unsigned long long)ip->i_no_formal_ino, |
119 | (unsigned long long)ip->i_num.no_addr, | 119 | (unsigned long long)ip->i_no_addr, |
120 | sdp->sd_fsname, function, file, line); | 120 | sdp->sd_fsname, function, file, line); |
121 | return rv; | 121 | return rv; |
122 | } | 122 | } |
@@ -137,7 +137,7 @@ int gfs2_consist_rgrpd_i(struct gfs2_rgrpd *rgd, int cluster_wide, | |||
137 | "GFS2: fsid=%s: RG = %llu\n" | 137 | "GFS2: fsid=%s: RG = %llu\n" |
138 | "GFS2: fsid=%s: function = %s, file = %s, line = %u\n", | 138 | "GFS2: fsid=%s: function = %s, file = %s, line = %u\n", |
139 | sdp->sd_fsname, | 139 | sdp->sd_fsname, |
140 | sdp->sd_fsname, (unsigned long long)rgd->rd_ri.ri_addr, | 140 | sdp->sd_fsname, (unsigned long long)rgd->rd_addr, |
141 | sdp->sd_fsname, function, file, line); | 141 | sdp->sd_fsname, function, file, line); |
142 | return rv; | 142 | return rv; |
143 | } | 143 | } |