aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/gfs2/aops.c14
-rw-r--r--fs/gfs2/bmap.c88
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 */
650void adjust_fs_space(struct inode *inode) 650void 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);
681out: 684out2:
682 brelse(m_bh); 685 brelse(m_bh);
686out:
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
994static 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
994static void gfs2_iomap_page_done(struct inode *inode, loff_t pos, 1002static 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
1004static const struct iomap_page_ops gfs2_iomap_page_ops = { 1014static 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
1177out: 1187out:
1178 if (dibh)
1179 brelse(dibh);
1180 return 0; 1188 return 0;
1181} 1189}
1182 1190