Commit 7ed122e4 authored by Steven Whitehouse's avatar Steven Whitehouse

GFS2: Streamline alloc calculations for writes

This patch removes some unused code, and make the calculation
of the number of blocks required conditional in order to reduce
the number of times this (potentially expensive) calculation
is done.
Signed-off-by: default avatarSteven Whitehouse <swhiteho@redhat.com>
parent 9a776db7
...@@ -1230,35 +1230,6 @@ int gfs2_file_dealloc(struct gfs2_inode *ip) ...@@ -1230,35 +1230,6 @@ int gfs2_file_dealloc(struct gfs2_inode *ip)
return trunc_dealloc(ip, 0); return trunc_dealloc(ip, 0);
} }
/**
* gfs2_write_calc_reserv - calculate number of blocks needed to write to a file
* @ip: the file
* @len: the number of bytes to be written to the file
* @data_blocks: returns the number of data blocks required
* @ind_blocks: returns the number of indirect blocks required
*
*/
void gfs2_write_calc_reserv(struct gfs2_inode *ip, unsigned int len,
unsigned int *data_blocks, unsigned int *ind_blocks)
{
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
unsigned int tmp;
if (gfs2_is_dir(ip)) {
*data_blocks = DIV_ROUND_UP(len, sdp->sd_jbsize) + 2;
*ind_blocks = 3 * (sdp->sd_max_jheight - 1);
} else {
*data_blocks = (len >> sdp->sd_sb.sb_bsize_shift) + 3;
*ind_blocks = 3 * (sdp->sd_max_height - 1);
}
for (tmp = *data_blocks; tmp > sdp->sd_diptrs;) {
tmp = DIV_ROUND_UP(tmp, sdp->sd_inptrs);
*ind_blocks += tmp;
}
}
/** /**
* gfs2_write_alloc_required - figure out if a write will require an allocation * gfs2_write_alloc_required - figure out if a write will require an allocation
* @ip: the file being written to * @ip: the file being written to
...@@ -1276,6 +1247,7 @@ int gfs2_write_alloc_required(struct gfs2_inode *ip, u64 offset, ...@@ -1276,6 +1247,7 @@ int gfs2_write_alloc_required(struct gfs2_inode *ip, u64 offset,
struct buffer_head bh; struct buffer_head bh;
unsigned int shift; unsigned int shift;
u64 lblock, lblock_stop, size; u64 lblock, lblock_stop, size;
u64 end_of_file;
*alloc_required = 0; *alloc_required = 0;
...@@ -1291,19 +1263,12 @@ int gfs2_write_alloc_required(struct gfs2_inode *ip, u64 offset, ...@@ -1291,19 +1263,12 @@ int gfs2_write_alloc_required(struct gfs2_inode *ip, u64 offset,
*alloc_required = 1; *alloc_required = 1;
shift = sdp->sd_sb.sb_bsize_shift; shift = sdp->sd_sb.sb_bsize_shift;
if (gfs2_is_dir(ip)) { BUG_ON(gfs2_is_dir(ip));
unsigned int bsize = sdp->sd_jbsize; end_of_file = (ip->i_disksize + sdp->sd_sb.sb_bsize - 1) >> shift;
lblock = offset; lblock = offset >> shift;
do_div(lblock, bsize); lblock_stop = (offset + len + sdp->sd_sb.sb_bsize - 1) >> shift;
lblock_stop = offset + len + bsize - 1; if (lblock_stop > end_of_file)
do_div(lblock_stop, bsize); return 0;
} else {
u64 end_of_file = (ip->i_disksize + sdp->sd_sb.sb_bsize - 1) >> shift;
lblock = offset >> shift;
lblock_stop = (offset + len + sdp->sd_sb.sb_bsize - 1) >> shift;
if (lblock_stop > end_of_file)
return 0;
}
size = (lblock_stop - lblock) << shift; size = (lblock_stop - lblock) << shift;
do { do {
......
...@@ -10,10 +10,40 @@ ...@@ -10,10 +10,40 @@
#ifndef __BMAP_DOT_H__ #ifndef __BMAP_DOT_H__
#define __BMAP_DOT_H__ #define __BMAP_DOT_H__
#include "inode.h"
struct inode; struct inode;
struct gfs2_inode; struct gfs2_inode;
struct page; struct page;
/**
* gfs2_write_calc_reserv - calculate number of blocks needed to write to a file
* @ip: the file
* @len: the number of bytes to be written to the file
* @data_blocks: returns the number of data blocks required
* @ind_blocks: returns the number of indirect blocks required
*
*/
static inline void gfs2_write_calc_reserv(const struct gfs2_inode *ip,
unsigned int len,
unsigned int *data_blocks,
unsigned int *ind_blocks)
{
const struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
unsigned int tmp;
BUG_ON(gfs2_is_dir(ip));
*data_blocks = (len >> sdp->sd_sb.sb_bsize_shift) + 3;
*ind_blocks = 3 * (sdp->sd_max_height - 1);
for (tmp = *data_blocks; tmp > sdp->sd_diptrs;) {
tmp = DIV_ROUND_UP(tmp, sdp->sd_inptrs);
*ind_blocks += tmp;
}
}
int gfs2_unstuff_dinode(struct gfs2_inode *ip, struct page *page); int gfs2_unstuff_dinode(struct gfs2_inode *ip, struct page *page);
int gfs2_block_map(struct inode *inode, sector_t lblock, struct buffer_head *bh, int create); int gfs2_block_map(struct inode *inode, sector_t lblock, struct buffer_head *bh, int create);
int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsigned *extlen); int 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 ...@@ -21,10 +51,6 @@ int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsi
int gfs2_truncatei(struct gfs2_inode *ip, u64 size); int gfs2_truncatei(struct gfs2_inode *ip, u64 size);
int gfs2_truncatei_resume(struct gfs2_inode *ip); int gfs2_truncatei_resume(struct gfs2_inode *ip);
int gfs2_file_dealloc(struct gfs2_inode *ip); int gfs2_file_dealloc(struct gfs2_inode *ip);
void gfs2_write_calc_reserv(struct gfs2_inode *ip, unsigned int len,
unsigned int *data_blocks,
unsigned int *ind_blocks);
int gfs2_write_alloc_required(struct gfs2_inode *ip, u64 offset, int gfs2_write_alloc_required(struct gfs2_inode *ip, u64 offset,
unsigned int len, int *alloc_required); unsigned int len, int *alloc_required);
......
...@@ -625,7 +625,7 @@ static int gfs2_write_begin(struct file *file, struct address_space *mapping, ...@@ -625,7 +625,7 @@ static int gfs2_write_begin(struct file *file, struct address_space *mapping,
{ {
struct gfs2_inode *ip = GFS2_I(mapping->host); struct gfs2_inode *ip = GFS2_I(mapping->host);
struct gfs2_sbd *sdp = GFS2_SB(mapping->host); struct gfs2_sbd *sdp = GFS2_SB(mapping->host);
unsigned int data_blocks, ind_blocks, rblocks; unsigned int data_blocks = 0, ind_blocks = 0, rblocks;
int alloc_required; int alloc_required;
int error = 0; int error = 0;
struct gfs2_alloc *al; struct gfs2_alloc *al;
...@@ -639,11 +639,13 @@ static int gfs2_write_begin(struct file *file, struct address_space *mapping, ...@@ -639,11 +639,13 @@ static int gfs2_write_begin(struct file *file, struct address_space *mapping,
if (unlikely(error)) if (unlikely(error))
goto out_uninit; goto out_uninit;
gfs2_write_calc_reserv(ip, len, &data_blocks, &ind_blocks);
error = gfs2_write_alloc_required(ip, pos, len, &alloc_required); error = gfs2_write_alloc_required(ip, pos, len, &alloc_required);
if (error) if (error)
goto out_unlock; goto out_unlock;
if (alloc_required || gfs2_is_jdata(ip))
gfs2_write_calc_reserv(ip, len, &data_blocks, &ind_blocks);
if (alloc_required) { if (alloc_required) {
al = gfs2_alloc_get(ip); al = gfs2_alloc_get(ip);
if (!al) { if (!al) {
......
...@@ -355,7 +355,6 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct page *page) ...@@ -355,7 +355,6 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct page *page)
goto out; goto out;
set_bit(GIF_SW_PAGED, &ip->i_flags); set_bit(GIF_SW_PAGED, &ip->i_flags);
gfs2_write_calc_reserv(ip, PAGE_CACHE_SIZE, &data_blocks, &ind_blocks);
ret = gfs2_write_alloc_required(ip, pos, PAGE_CACHE_SIZE, &alloc_required); ret = gfs2_write_alloc_required(ip, pos, PAGE_CACHE_SIZE, &alloc_required);
if (ret || !alloc_required) if (ret || !alloc_required)
goto out_unlock; goto out_unlock;
...@@ -367,6 +366,7 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct page *page) ...@@ -367,6 +366,7 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct page *page)
ret = gfs2_quota_lock_check(ip); ret = gfs2_quota_lock_check(ip);
if (ret) if (ret)
goto out_alloc_put; goto out_alloc_put;
gfs2_write_calc_reserv(ip, PAGE_CACHE_SIZE, &data_blocks, &ind_blocks);
al->al_requested = data_blocks + ind_blocks; al->al_requested = data_blocks + ind_blocks;
ret = gfs2_inplace_reserve(ip); ret = gfs2_inplace_reserve(ip);
if (ret) if (ret)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment