diff options
| -rw-r--r-- | fs/gfs2/aops.c | 14 | ||||
| -rw-r--r-- | fs/gfs2/bmap.c | 88 |
2 files changed, 58 insertions, 44 deletions
diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c index 05dd78f4b2b3..6210d4429d84 100644 --- a/fs/gfs2/aops.c +++ b/fs/gfs2/aops.c | |||
| @@ -649,7 +649,7 @@ out_uninit: | |||
| 649 | */ | 649 | */ |
| 650 | void adjust_fs_space(struct inode *inode) | 650 | void adjust_fs_space(struct inode *inode) |
| 651 | { | 651 | { |
| 652 | struct gfs2_sbd *sdp = inode->i_sb->s_fs_info; | 652 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
| 653 | struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode); | 653 | struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode); |
| 654 | struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode); | 654 | struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode); |
| 655 | struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master; | 655 | struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master; |
| @@ -657,10 +657,13 @@ void adjust_fs_space(struct inode *inode) | |||
| 657 | struct buffer_head *m_bh, *l_bh; | 657 | struct buffer_head *m_bh, *l_bh; |
| 658 | u64 fs_total, new_free; | 658 | u64 fs_total, new_free; |
| 659 | 659 | ||
| 660 | if (gfs2_trans_begin(sdp, 2 * RES_STATFS, 0) != 0) | ||
| 661 | return; | ||
| 662 | |||
| 660 | /* Total up the file system space, according to the latest rindex. */ | 663 | /* Total up the file system space, according to the latest rindex. */ |
| 661 | fs_total = gfs2_ri_total(sdp); | 664 | fs_total = gfs2_ri_total(sdp); |
| 662 | if (gfs2_meta_inode_buffer(m_ip, &m_bh) != 0) | 665 | if (gfs2_meta_inode_buffer(m_ip, &m_bh) != 0) |
| 663 | return; | 666 | goto out; |
| 664 | 667 | ||
| 665 | spin_lock(&sdp->sd_statfs_spin); | 668 | spin_lock(&sdp->sd_statfs_spin); |
| 666 | gfs2_statfs_change_in(m_sc, m_bh->b_data + | 669 | gfs2_statfs_change_in(m_sc, m_bh->b_data + |
| @@ -675,11 +678,14 @@ void adjust_fs_space(struct inode *inode) | |||
| 675 | gfs2_statfs_change(sdp, new_free, new_free, 0); | 678 | gfs2_statfs_change(sdp, new_free, new_free, 0); |
| 676 | 679 | ||
| 677 | if (gfs2_meta_inode_buffer(l_ip, &l_bh) != 0) | 680 | if (gfs2_meta_inode_buffer(l_ip, &l_bh) != 0) |
| 678 | goto out; | 681 | goto out2; |
| 679 | update_statfs(sdp, m_bh, l_bh); | 682 | update_statfs(sdp, m_bh, l_bh); |
| 680 | brelse(l_bh); | 683 | brelse(l_bh); |
| 681 | out: | 684 | out2: |
| 682 | brelse(m_bh); | 685 | brelse(m_bh); |
| 686 | out: | ||
| 687 | sdp->sd_rindex_uptodate = 0; | ||
| 688 | gfs2_trans_end(sdp); | ||
| 683 | } | 689 | } |
| 684 | 690 | ||
| 685 | /** | 691 | /** |
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index 6f1f0d30fe29..f42718dd292f 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c | |||
| @@ -991,17 +991,28 @@ static void gfs2_write_unlock(struct inode *inode) | |||
| 991 | gfs2_glock_dq_uninit(&ip->i_gh); | 991 | gfs2_glock_dq_uninit(&ip->i_gh); |
| 992 | } | 992 | } |
| 993 | 993 | ||
| 994 | static int gfs2_iomap_page_prepare(struct inode *inode, loff_t pos, | ||
| 995 | unsigned len, struct iomap *iomap) | ||
| 996 | { | ||
| 997 | struct gfs2_sbd *sdp = GFS2_SB(inode); | ||
| 998 | |||
| 999 | return gfs2_trans_begin(sdp, RES_DINODE + (len >> inode->i_blkbits), 0); | ||
| 1000 | } | ||
| 1001 | |||
| 994 | static void gfs2_iomap_page_done(struct inode *inode, loff_t pos, | 1002 | static void gfs2_iomap_page_done(struct inode *inode, loff_t pos, |
| 995 | unsigned copied, struct page *page, | 1003 | unsigned copied, struct page *page, |
| 996 | struct iomap *iomap) | 1004 | struct iomap *iomap) |
| 997 | { | 1005 | { |
| 998 | struct gfs2_inode *ip = GFS2_I(inode); | 1006 | struct gfs2_inode *ip = GFS2_I(inode); |
| 1007 | struct gfs2_sbd *sdp = GFS2_SB(inode); | ||
| 999 | 1008 | ||
| 1000 | if (page) | 1009 | if (page && !gfs2_is_stuffed(ip)) |
| 1001 | gfs2_page_add_databufs(ip, page, offset_in_page(pos), copied); | 1010 | gfs2_page_add_databufs(ip, page, offset_in_page(pos), copied); |
| 1011 | gfs2_trans_end(sdp); | ||
| 1002 | } | 1012 | } |
| 1003 | 1013 | ||
| 1004 | static const struct iomap_page_ops gfs2_iomap_page_ops = { | 1014 | static const struct iomap_page_ops gfs2_iomap_page_ops = { |
| 1015 | .page_prepare = gfs2_iomap_page_prepare, | ||
| 1005 | .page_done = gfs2_iomap_page_done, | 1016 | .page_done = gfs2_iomap_page_done, |
| 1006 | }; | 1017 | }; |
| 1007 | 1018 | ||
| @@ -1057,31 +1068,45 @@ static int gfs2_iomap_begin_write(struct inode *inode, loff_t pos, | |||
| 1057 | if (alloc_required) | 1068 | if (alloc_required) |
| 1058 | rblocks += gfs2_rg_blocks(ip, data_blocks + ind_blocks); | 1069 | rblocks += gfs2_rg_blocks(ip, data_blocks + ind_blocks); |
| 1059 | 1070 | ||
| 1060 | ret = gfs2_trans_begin(sdp, rblocks, iomap->length >> inode->i_blkbits); | 1071 | if (unstuff || iomap->type == IOMAP_HOLE) { |
| 1061 | if (ret) | 1072 | struct gfs2_trans *tr; |
| 1062 | goto out_trans_fail; | ||
| 1063 | 1073 | ||
| 1064 | if (unstuff) { | 1074 | ret = gfs2_trans_begin(sdp, rblocks, |
| 1065 | ret = gfs2_unstuff_dinode(ip, NULL); | 1075 | iomap->length >> inode->i_blkbits); |
| 1066 | if (ret) | 1076 | if (ret) |
| 1067 | goto out_trans_end; | 1077 | goto out_trans_fail; |
| 1068 | release_metapath(mp); | ||
| 1069 | ret = gfs2_iomap_get(inode, iomap->offset, iomap->length, | ||
| 1070 | flags, iomap, mp); | ||
| 1071 | if (ret) | ||
| 1072 | goto out_trans_end; | ||
| 1073 | } | ||
| 1074 | 1078 | ||
| 1075 | if (iomap->type == IOMAP_HOLE) { | 1079 | if (unstuff) { |
| 1076 | ret = gfs2_iomap_alloc(inode, iomap, flags, mp); | 1080 | ret = gfs2_unstuff_dinode(ip, NULL); |
| 1077 | if (ret) { | 1081 | if (ret) |
| 1078 | gfs2_trans_end(sdp); | 1082 | goto out_trans_end; |
| 1079 | gfs2_inplace_release(ip); | 1083 | release_metapath(mp); |
| 1080 | punch_hole(ip, iomap->offset, iomap->length); | 1084 | ret = gfs2_iomap_get(inode, iomap->offset, |
| 1081 | goto out_qunlock; | 1085 | iomap->length, flags, iomap, mp); |
| 1086 | if (ret) | ||
| 1087 | goto out_trans_end; | ||
| 1088 | } | ||
| 1089 | |||
| 1090 | if (iomap->type == IOMAP_HOLE) { | ||
| 1091 | ret = gfs2_iomap_alloc(inode, iomap, flags, mp); | ||
| 1092 | if (ret) { | ||
| 1093 | gfs2_trans_end(sdp); | ||
| 1094 | gfs2_inplace_release(ip); | ||
| 1095 | punch_hole(ip, iomap->offset, iomap->length); | ||
| 1096 | goto out_qunlock; | ||
| 1097 | } | ||
| 1082 | } | 1098 | } |
| 1099 | |||
| 1100 | tr = current->journal_info; | ||
| 1101 | if (tr->tr_num_buf_new) | ||
| 1102 | __mark_inode_dirty(inode, I_DIRTY_DATASYNC); | ||
| 1103 | else | ||
| 1104 | gfs2_trans_add_meta(ip->i_gl, mp->mp_bh[0]); | ||
| 1105 | |||
| 1106 | gfs2_trans_end(sdp); | ||
| 1083 | } | 1107 | } |
| 1084 | if (!gfs2_is_stuffed(ip) && gfs2_is_jdata(ip)) | 1108 | |
| 1109 | if (gfs2_is_stuffed(ip) || gfs2_is_jdata(ip)) | ||
| 1085 | iomap->page_ops = &gfs2_iomap_page_ops; | 1110 | iomap->page_ops = &gfs2_iomap_page_ops; |
| 1086 | return 0; | 1111 | return 0; |
| 1087 | 1112 | ||
| @@ -1121,10 +1146,6 @@ static int gfs2_iomap_begin(struct inode *inode, loff_t pos, loff_t length, | |||
| 1121 | iomap->type != IOMAP_MAPPED) | 1146 | iomap->type != IOMAP_MAPPED) |
| 1122 | ret = -ENOTBLK; | 1147 | ret = -ENOTBLK; |
| 1123 | } | 1148 | } |
| 1124 | if (!ret) { | ||
| 1125 | get_bh(mp.mp_bh[0]); | ||
| 1126 | iomap->private = mp.mp_bh[0]; | ||
| 1127 | } | ||
| 1128 | release_metapath(&mp); | 1149 | release_metapath(&mp); |
| 1129 | trace_gfs2_iomap_end(ip, iomap, ret); | 1150 | trace_gfs2_iomap_end(ip, iomap, ret); |
| 1130 | return ret; | 1151 | return ret; |
| @@ -1135,27 +1156,16 @@ static int gfs2_iomap_end(struct inode *inode, loff_t pos, loff_t length, | |||
| 1135 | { | 1156 | { |
| 1136 | struct gfs2_inode *ip = GFS2_I(inode); | 1157 | struct gfs2_inode *ip = GFS2_I(inode); |
| 1137 | struct gfs2_sbd *sdp = GFS2_SB(inode); | 1158 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
| 1138 | struct gfs2_trans *tr = current->journal_info; | ||
| 1139 | struct buffer_head *dibh = iomap->private; | ||
| 1140 | 1159 | ||
| 1141 | if ((flags & (IOMAP_WRITE | IOMAP_DIRECT)) != IOMAP_WRITE) | 1160 | if ((flags & (IOMAP_WRITE | IOMAP_DIRECT)) != IOMAP_WRITE) |
| 1142 | goto out; | 1161 | goto out; |
| 1143 | 1162 | ||
| 1144 | if (iomap->type != IOMAP_INLINE) { | 1163 | if (!gfs2_is_stuffed(ip)) |
| 1145 | gfs2_ordered_add_inode(ip); | 1164 | gfs2_ordered_add_inode(ip); |
| 1146 | 1165 | ||
| 1147 | if (tr->tr_num_buf_new) | 1166 | if (inode == sdp->sd_rindex) |
| 1148 | __mark_inode_dirty(inode, I_DIRTY_DATASYNC); | ||
| 1149 | else | ||
| 1150 | gfs2_trans_add_meta(ip->i_gl, dibh); | ||
| 1151 | } | ||
| 1152 | |||
| 1153 | if (inode == sdp->sd_rindex) { | ||
| 1154 | adjust_fs_space(inode); | 1167 | adjust_fs_space(inode); |
| 1155 | sdp->sd_rindex_uptodate = 0; | ||
| 1156 | } | ||
| 1157 | 1168 | ||
| 1158 | gfs2_trans_end(sdp); | ||
| 1159 | gfs2_inplace_release(ip); | 1169 | gfs2_inplace_release(ip); |
| 1160 | 1170 | ||
| 1161 | if (length != written && (iomap->flags & IOMAP_F_NEW)) { | 1171 | if (length != written && (iomap->flags & IOMAP_F_NEW)) { |
| @@ -1175,8 +1185,6 @@ static int gfs2_iomap_end(struct inode *inode, loff_t pos, loff_t length, | |||
| 1175 | gfs2_write_unlock(inode); | 1185 | gfs2_write_unlock(inode); |
| 1176 | 1186 | ||
| 1177 | out: | 1187 | out: |
| 1178 | if (dibh) | ||
| 1179 | brelse(dibh); | ||
| 1180 | return 0; | 1188 | return 0; |
| 1181 | } | 1189 | } |
| 1182 | 1190 | ||
