diff options
Diffstat (limited to 'fs/gfs2/bmap.c')
-rw-r--r-- | fs/gfs2/bmap.c | 77 |
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) | |||
1219 | int gfs2_truncatei_resume(struct gfs2_inode *ip) | 1219 | int 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 | |||
1242 | void 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 { |