aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/bmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2/bmap.c')
-rw-r--r--fs/gfs2/bmap.c77
1 files changed, 21 insertions, 56 deletions
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
index bec76b1c2bb0..11ffc56f1f81 100644
--- a/fs/gfs2/bmap.c
+++ b/fs/gfs2/bmap.c
@@ -75,9 +75,9 @@ static int gfs2_unstuffer_page(struct gfs2_inode *ip, struct buffer_head *dibh,
75 void *kaddr = kmap(page); 75 void *kaddr = kmap(page);
76 76
77 memcpy(kaddr, dibh->b_data + sizeof(struct gfs2_dinode), 77 memcpy(kaddr, dibh->b_data + sizeof(struct gfs2_dinode),
78 ip->i_di.di_size); 78 ip->i_disksize);
79 memset(kaddr + ip->i_di.di_size, 0, 79 memset(kaddr + ip->i_disksize, 0,
80 PAGE_CACHE_SIZE - ip->i_di.di_size); 80 PAGE_CACHE_SIZE - ip->i_disksize);
81 kunmap(page); 81 kunmap(page);
82 82
83 SetPageUptodate(page); 83 SetPageUptodate(page);
@@ -132,7 +132,7 @@ int gfs2_unstuff_dinode(struct gfs2_inode *ip, struct page *page)
132 if (error) 132 if (error)
133 goto out; 133 goto out;
134 134
135 if (ip->i_di.di_size) { 135 if (ip->i_disksize) {
136 /* Get a free block, fill it with the stuffed data, 136 /* Get a free block, fill it with the stuffed data,
137 and write it out to disk */ 137 and write it out to disk */
138 138
@@ -159,7 +159,7 @@ int gfs2_unstuff_dinode(struct gfs2_inode *ip, struct page *page)
159 di = (struct gfs2_dinode *)dibh->b_data; 159 di = (struct gfs2_dinode *)dibh->b_data;
160 gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode)); 160 gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode));
161 161
162 if (ip->i_di.di_size) { 162 if (ip->i_disksize) {
163 *(__be64 *)(di + 1) = cpu_to_be64(block); 163 *(__be64 *)(di + 1) = cpu_to_be64(block);
164 gfs2_add_inode_blocks(&ip->i_inode, 1); 164 gfs2_add_inode_blocks(&ip->i_inode, 1);
165 di->di_blocks = cpu_to_be64(gfs2_get_inode_blocks(&ip->i_inode)); 165 di->di_blocks = cpu_to_be64(gfs2_get_inode_blocks(&ip->i_inode));
@@ -926,7 +926,7 @@ static int do_grow(struct gfs2_inode *ip, u64 size)
926 } 926 }
927 } 927 }
928 928
929 ip->i_di.di_size = size; 929 ip->i_disksize = size;
930 ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; 930 ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
931 gfs2_trans_add_bh(ip->i_gl, dibh, 1); 931 gfs2_trans_add_bh(ip->i_gl, dibh, 1);
932 gfs2_dinode_out(ip, dibh->b_data); 932 gfs2_dinode_out(ip, dibh->b_data);
@@ -1033,7 +1033,7 @@ static int trunc_start(struct gfs2_inode *ip, u64 size)
1033 goto out; 1033 goto out;
1034 1034
1035 if (gfs2_is_stuffed(ip)) { 1035 if (gfs2_is_stuffed(ip)) {
1036 ip->i_di.di_size = size; 1036 ip->i_disksize = size;
1037 ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; 1037 ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
1038 gfs2_trans_add_bh(ip->i_gl, dibh, 1); 1038 gfs2_trans_add_bh(ip->i_gl, dibh, 1);
1039 gfs2_dinode_out(ip, dibh->b_data); 1039 gfs2_dinode_out(ip, dibh->b_data);
@@ -1045,9 +1045,9 @@ static int trunc_start(struct gfs2_inode *ip, u64 size)
1045 error = gfs2_block_truncate_page(ip->i_inode.i_mapping); 1045 error = gfs2_block_truncate_page(ip->i_inode.i_mapping);
1046 1046
1047 if (!error) { 1047 if (!error) {
1048 ip->i_di.di_size = size; 1048 ip->i_disksize = size;
1049 ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; 1049 ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
1050 ip->i_di.di_flags |= GFS2_DIF_TRUNC_IN_PROG; 1050 ip->i_diskflags |= GFS2_DIF_TRUNC_IN_PROG;
1051 gfs2_trans_add_bh(ip->i_gl, dibh, 1); 1051 gfs2_trans_add_bh(ip->i_gl, dibh, 1);
1052 gfs2_dinode_out(ip, dibh->b_data); 1052 gfs2_dinode_out(ip, dibh->b_data);
1053 } 1053 }
@@ -1114,13 +1114,13 @@ static int trunc_end(struct gfs2_inode *ip)
1114 if (error) 1114 if (error)
1115 goto out; 1115 goto out;
1116 1116
1117 if (!ip->i_di.di_size) { 1117 if (!ip->i_disksize) {
1118 ip->i_height = 0; 1118 ip->i_height = 0;
1119 ip->i_goal = ip->i_no_addr; 1119 ip->i_goal = ip->i_no_addr;
1120 gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode)); 1120 gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode));
1121 } 1121 }
1122 ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; 1122 ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
1123 ip->i_di.di_flags &= ~GFS2_DIF_TRUNC_IN_PROG; 1123 ip->i_diskflags &= ~GFS2_DIF_TRUNC_IN_PROG;
1124 1124
1125 gfs2_trans_add_bh(ip->i_gl, dibh, 1); 1125 gfs2_trans_add_bh(ip->i_gl, dibh, 1);
1126 gfs2_dinode_out(ip, dibh->b_data); 1126 gfs2_dinode_out(ip, dibh->b_data);
@@ -1205,9 +1205,9 @@ int gfs2_truncatei(struct gfs2_inode *ip, u64 size)
1205 if (gfs2_assert_warn(GFS2_SB(&ip->i_inode), S_ISREG(ip->i_inode.i_mode))) 1205 if (gfs2_assert_warn(GFS2_SB(&ip->i_inode), S_ISREG(ip->i_inode.i_mode)))
1206 return -EINVAL; 1206 return -EINVAL;
1207 1207
1208 if (size > ip->i_di.di_size) 1208 if (size > ip->i_disksize)
1209 error = do_grow(ip, size); 1209 error = do_grow(ip, size);
1210 else if (size < ip->i_di.di_size) 1210 else if (size < ip->i_disksize)
1211 error = do_shrink(ip, size); 1211 error = do_shrink(ip, size);
1212 else 1212 else
1213 /* update time stamps */ 1213 /* update time stamps */
@@ -1219,7 +1219,7 @@ int gfs2_truncatei(struct gfs2_inode *ip, u64 size)
1219int gfs2_truncatei_resume(struct gfs2_inode *ip) 1219int gfs2_truncatei_resume(struct gfs2_inode *ip)
1220{ 1220{
1221 int error; 1221 int error;
1222 error = trunc_dealloc(ip, ip->i_di.di_size); 1222 error = trunc_dealloc(ip, ip->i_disksize);
1223 if (!error) 1223 if (!error)
1224 error = trunc_end(ip); 1224 error = trunc_end(ip);
1225 return error; 1225 return error;
@@ -1231,35 +1231,6 @@ int gfs2_file_dealloc(struct gfs2_inode *ip)
1231} 1231}
1232 1232
1233/** 1233/**
1234 * gfs2_write_calc_reserv - calculate number of blocks needed to write to a file
1235 * @ip: the file
1236 * @len: the number of bytes to be written to the file
1237 * @data_blocks: returns the number of data blocks required
1238 * @ind_blocks: returns the number of indirect blocks required
1239 *
1240 */
1241
1242void gfs2_write_calc_reserv(struct gfs2_inode *ip, unsigned int len,
1243 unsigned int *data_blocks, unsigned int *ind_blocks)
1244{
1245 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
1246 unsigned int tmp;
1247
1248 if (gfs2_is_dir(ip)) {
1249 *data_blocks = DIV_ROUND_UP(len, sdp->sd_jbsize) + 2;
1250 *ind_blocks = 3 * (sdp->sd_max_jheight - 1);
1251 } else {
1252 *data_blocks = (len >> sdp->sd_sb.sb_bsize_shift) + 3;
1253 *ind_blocks = 3 * (sdp->sd_max_height - 1);
1254 }
1255
1256 for (tmp = *data_blocks; tmp > sdp->sd_diptrs;) {
1257 tmp = DIV_ROUND_UP(tmp, sdp->sd_inptrs);
1258 *ind_blocks += tmp;
1259 }
1260}
1261
1262/**
1263 * gfs2_write_alloc_required - figure out if a write will require an allocation 1234 * gfs2_write_alloc_required - figure out if a write will require an allocation
1264 * @ip: the file being written to 1235 * @ip: the file being written to
1265 * @offset: the offset to write to 1236 * @offset: the offset to write to
@@ -1276,6 +1247,7 @@ int gfs2_write_alloc_required(struct gfs2_inode *ip, u64 offset,
1276 struct buffer_head bh; 1247 struct buffer_head bh;
1277 unsigned int shift; 1248 unsigned int shift;
1278 u64 lblock, lblock_stop, size; 1249 u64 lblock, lblock_stop, size;
1250 u64 end_of_file;
1279 1251
1280 *alloc_required = 0; 1252 *alloc_required = 0;
1281 1253
@@ -1291,19 +1263,12 @@ int gfs2_write_alloc_required(struct gfs2_inode *ip, u64 offset,
1291 1263
1292 *alloc_required = 1; 1264 *alloc_required = 1;
1293 shift = sdp->sd_sb.sb_bsize_shift; 1265 shift = sdp->sd_sb.sb_bsize_shift;
1294 if (gfs2_is_dir(ip)) { 1266 BUG_ON(gfs2_is_dir(ip));
1295 unsigned int bsize = sdp->sd_jbsize; 1267 end_of_file = (ip->i_disksize + sdp->sd_sb.sb_bsize - 1) >> shift;
1296 lblock = offset; 1268 lblock = offset >> shift;
1297 do_div(lblock, bsize); 1269 lblock_stop = (offset + len + sdp->sd_sb.sb_bsize - 1) >> shift;
1298 lblock_stop = offset + len + bsize - 1; 1270 if (lblock_stop > end_of_file)
1299 do_div(lblock_stop, bsize); 1271 return 0;
1300 } else {
1301 u64 end_of_file = (ip->i_di.di_size + sdp->sd_sb.sb_bsize - 1) >> shift;
1302 lblock = offset >> shift;
1303 lblock_stop = (offset + len + sdp->sd_sb.sb_bsize - 1) >> shift;
1304 if (lblock_stop > end_of_file)
1305 return 0;
1306 }
1307 1272
1308 size = (lblock_stop - lblock) << shift; 1273 size = (lblock_stop - lblock) << shift;
1309 do { 1274 do {