aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/gfs2/bmap.c49
-rw-r--r--fs/gfs2/bmap.h34
-rw-r--r--fs/gfs2/ops_address.c6
-rw-r--r--fs/gfs2/ops_file.c2
4 files changed, 42 insertions, 49 deletions
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
index 789f28cfdc20..11ffc56f1f81 100644
--- a/fs/gfs2/bmap.c
+++ b/fs/gfs2/bmap.c
@@ -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_disksize + 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 {
diff --git a/fs/gfs2/bmap.h b/fs/gfs2/bmap.h
index 4e6cde2943bd..c983177e05ac 100644
--- a/fs/gfs2/bmap.h
+++ b/fs/gfs2/bmap.h
@@ -10,10 +10,40 @@
10#ifndef __BMAP_DOT_H__ 10#ifndef __BMAP_DOT_H__
11#define __BMAP_DOT_H__ 11#define __BMAP_DOT_H__
12 12
13#include "inode.h"
14
13struct inode; 15struct inode;
14struct gfs2_inode; 16struct gfs2_inode;
15struct page; 17struct page;
16 18
19
20/**
21 * gfs2_write_calc_reserv - calculate number of blocks needed to write to a file
22 * @ip: the file
23 * @len: the number of bytes to be written to the file
24 * @data_blocks: returns the number of data blocks required
25 * @ind_blocks: returns the number of indirect blocks required
26 *
27 */
28
29static inline void gfs2_write_calc_reserv(const struct gfs2_inode *ip,
30 unsigned int len,
31 unsigned int *data_blocks,
32 unsigned int *ind_blocks)
33{
34 const struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
35 unsigned int tmp;
36
37 BUG_ON(gfs2_is_dir(ip));
38 *data_blocks = (len >> sdp->sd_sb.sb_bsize_shift) + 3;
39 *ind_blocks = 3 * (sdp->sd_max_height - 1);
40
41 for (tmp = *data_blocks; tmp > sdp->sd_diptrs;) {
42 tmp = DIV_ROUND_UP(tmp, sdp->sd_inptrs);
43 *ind_blocks += tmp;
44 }
45}
46
17int gfs2_unstuff_dinode(struct gfs2_inode *ip, struct page *page); 47int gfs2_unstuff_dinode(struct gfs2_inode *ip, struct page *page);
18int gfs2_block_map(struct inode *inode, sector_t lblock, struct buffer_head *bh, int create); 48int gfs2_block_map(struct inode *inode, sector_t lblock, struct buffer_head *bh, int create);
19int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsigned *extlen); 49int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsigned *extlen);
@@ -21,10 +51,6 @@ int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsi
21int gfs2_truncatei(struct gfs2_inode *ip, u64 size); 51int gfs2_truncatei(struct gfs2_inode *ip, u64 size);
22int gfs2_truncatei_resume(struct gfs2_inode *ip); 52int gfs2_truncatei_resume(struct gfs2_inode *ip);
23int gfs2_file_dealloc(struct gfs2_inode *ip); 53int gfs2_file_dealloc(struct gfs2_inode *ip);
24
25void gfs2_write_calc_reserv(struct gfs2_inode *ip, unsigned int len,
26 unsigned int *data_blocks,
27 unsigned int *ind_blocks);
28int gfs2_write_alloc_required(struct gfs2_inode *ip, u64 offset, 54int gfs2_write_alloc_required(struct gfs2_inode *ip, u64 offset,
29 unsigned int len, int *alloc_required); 55 unsigned int len, int *alloc_required);
30 56
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c
index 0df560f4269a..6e4ea36c6605 100644
--- a/fs/gfs2/ops_address.c
+++ b/fs/gfs2/ops_address.c
@@ -625,7 +625,7 @@ static int gfs2_write_begin(struct file *file, struct address_space *mapping,
625{ 625{
626 struct gfs2_inode *ip = GFS2_I(mapping->host); 626 struct gfs2_inode *ip = GFS2_I(mapping->host);
627 struct gfs2_sbd *sdp = GFS2_SB(mapping->host); 627 struct gfs2_sbd *sdp = GFS2_SB(mapping->host);
628 unsigned int data_blocks, ind_blocks, rblocks; 628 unsigned int data_blocks = 0, ind_blocks = 0, rblocks;
629 int alloc_required; 629 int alloc_required;
630 int error = 0; 630 int error = 0;
631 struct gfs2_alloc *al; 631 struct gfs2_alloc *al;
@@ -639,11 +639,13 @@ static int gfs2_write_begin(struct file *file, struct address_space *mapping,
639 if (unlikely(error)) 639 if (unlikely(error))
640 goto out_uninit; 640 goto out_uninit;
641 641
642 gfs2_write_calc_reserv(ip, len, &data_blocks, &ind_blocks);
643 error = gfs2_write_alloc_required(ip, pos, len, &alloc_required); 642 error = gfs2_write_alloc_required(ip, pos, len, &alloc_required);
644 if (error) 643 if (error)
645 goto out_unlock; 644 goto out_unlock;
646 645
646 if (alloc_required || gfs2_is_jdata(ip))
647 gfs2_write_calc_reserv(ip, len, &data_blocks, &ind_blocks);
648
647 if (alloc_required) { 649 if (alloc_required) {
648 al = gfs2_alloc_get(ip); 650 al = gfs2_alloc_get(ip);
649 if (!al) { 651 if (!al) {
diff --git a/fs/gfs2/ops_file.c b/fs/gfs2/ops_file.c
index a6b7a733fd4d..289c5f54ba53 100644
--- a/fs/gfs2/ops_file.c
+++ b/fs/gfs2/ops_file.c
@@ -355,7 +355,6 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct page *page)
355 goto out; 355 goto out;
356 356
357 set_bit(GIF_SW_PAGED, &ip->i_flags); 357 set_bit(GIF_SW_PAGED, &ip->i_flags);
358 gfs2_write_calc_reserv(ip, PAGE_CACHE_SIZE, &data_blocks, &ind_blocks);
359 ret = gfs2_write_alloc_required(ip, pos, PAGE_CACHE_SIZE, &alloc_required); 358 ret = gfs2_write_alloc_required(ip, pos, PAGE_CACHE_SIZE, &alloc_required);
360 if (ret || !alloc_required) 359 if (ret || !alloc_required)
361 goto out_unlock; 360 goto out_unlock;
@@ -367,6 +366,7 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct page *page)
367 ret = gfs2_quota_lock_check(ip); 366 ret = gfs2_quota_lock_check(ip);
368 if (ret) 367 if (ret)
369 goto out_alloc_put; 368 goto out_alloc_put;
369 gfs2_write_calc_reserv(ip, PAGE_CACHE_SIZE, &data_blocks, &ind_blocks);
370 al->al_requested = data_blocks + ind_blocks; 370 al->al_requested = data_blocks + ind_blocks;
371 ret = gfs2_inplace_reserve(ip); 371 ret = gfs2_inplace_reserve(ip);
372 if (ret) 372 if (ret)