GFS2: Add allocation parameters structure
This patch adds a structure to contain allocation parameters with the intention of future expansion of this structure. The idea is that we should be able to add more information about the allocation in the future in order to allow the allocator to make a better job of placing the requests on-disk. There is no functional difference from applying this patch. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
This commit is contained in:
parent
af5c269799
commit
7b9cff4671
|
@ -611,12 +611,14 @@ static int gfs2_write_begin(struct file *file, struct address_space *mapping,
|
||||||
gfs2_write_calc_reserv(ip, len, &data_blocks, &ind_blocks);
|
gfs2_write_calc_reserv(ip, len, &data_blocks, &ind_blocks);
|
||||||
|
|
||||||
if (alloc_required) {
|
if (alloc_required) {
|
||||||
|
struct gfs2_alloc_parms ap = { .aflags = 0, };
|
||||||
error = gfs2_quota_lock_check(ip);
|
error = gfs2_quota_lock_check(ip);
|
||||||
if (error)
|
if (error)
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
|
|
||||||
requested = data_blocks + ind_blocks;
|
requested = data_blocks + ind_blocks;
|
||||||
error = gfs2_inplace_reserve(ip, requested, 0);
|
ap.target = requested;
|
||||||
|
error = gfs2_inplace_reserve(ip, &ap);
|
||||||
if (error)
|
if (error)
|
||||||
goto out_qunlock;
|
goto out_qunlock;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1216,6 +1216,7 @@ static int do_grow(struct inode *inode, u64 size)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = GFS2_I(inode);
|
struct gfs2_inode *ip = GFS2_I(inode);
|
||||||
struct gfs2_sbd *sdp = GFS2_SB(inode);
|
struct gfs2_sbd *sdp = GFS2_SB(inode);
|
||||||
|
struct gfs2_alloc_parms ap = { .target = 1, };
|
||||||
struct buffer_head *dibh;
|
struct buffer_head *dibh;
|
||||||
int error;
|
int error;
|
||||||
int unstuff = 0;
|
int unstuff = 0;
|
||||||
|
@ -1226,7 +1227,7 @@ static int do_grow(struct inode *inode, u64 size)
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
error = gfs2_inplace_reserve(ip, 1, 0);
|
error = gfs2_inplace_reserve(ip, &ap);
|
||||||
if (error)
|
if (error)
|
||||||
goto do_grow_qunlock;
|
goto do_grow_qunlock;
|
||||||
unstuff = 1;
|
unstuff = 1;
|
||||||
|
|
|
@ -383,6 +383,7 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
|
||||||
struct inode *inode = file_inode(vma->vm_file);
|
struct inode *inode = file_inode(vma->vm_file);
|
||||||
struct gfs2_inode *ip = GFS2_I(inode);
|
struct gfs2_inode *ip = GFS2_I(inode);
|
||||||
struct gfs2_sbd *sdp = GFS2_SB(inode);
|
struct gfs2_sbd *sdp = GFS2_SB(inode);
|
||||||
|
struct gfs2_alloc_parms ap = { .aflags = 0, };
|
||||||
unsigned long last_index;
|
unsigned long last_index;
|
||||||
u64 pos = page->index << PAGE_CACHE_SHIFT;
|
u64 pos = page->index << PAGE_CACHE_SHIFT;
|
||||||
unsigned int data_blocks, ind_blocks, rblocks;
|
unsigned int data_blocks, ind_blocks, rblocks;
|
||||||
|
@ -430,7 +431,8 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
gfs2_write_calc_reserv(ip, PAGE_CACHE_SIZE, &data_blocks, &ind_blocks);
|
gfs2_write_calc_reserv(ip, PAGE_CACHE_SIZE, &data_blocks, &ind_blocks);
|
||||||
ret = gfs2_inplace_reserve(ip, data_blocks + ind_blocks, 0);
|
ap.target = data_blocks + ind_blocks;
|
||||||
|
ret = gfs2_inplace_reserve(ip, &ap);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out_quota_unlock;
|
goto out_quota_unlock;
|
||||||
|
|
||||||
|
@ -800,6 +802,7 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset,
|
||||||
struct inode *inode = file_inode(file);
|
struct inode *inode = file_inode(file);
|
||||||
struct gfs2_sbd *sdp = GFS2_SB(inode);
|
struct gfs2_sbd *sdp = GFS2_SB(inode);
|
||||||
struct gfs2_inode *ip = GFS2_I(inode);
|
struct gfs2_inode *ip = GFS2_I(inode);
|
||||||
|
struct gfs2_alloc_parms ap = { .aflags = 0, };
|
||||||
unsigned int data_blocks = 0, ind_blocks = 0, rblocks;
|
unsigned int data_blocks = 0, ind_blocks = 0, rblocks;
|
||||||
loff_t bytes, max_bytes;
|
loff_t bytes, max_bytes;
|
||||||
int error;
|
int error;
|
||||||
|
@ -850,7 +853,8 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset,
|
||||||
retry:
|
retry:
|
||||||
gfs2_write_calc_reserv(ip, bytes, &data_blocks, &ind_blocks);
|
gfs2_write_calc_reserv(ip, bytes, &data_blocks, &ind_blocks);
|
||||||
|
|
||||||
error = gfs2_inplace_reserve(ip, data_blocks + ind_blocks, 0);
|
ap.target = data_blocks + ind_blocks;
|
||||||
|
error = gfs2_inplace_reserve(ip, &ap);
|
||||||
if (error) {
|
if (error) {
|
||||||
if (error == -ENOSPC && bytes > sdp->sd_sb.sb_bsize) {
|
if (error == -ENOSPC && bytes > sdp->sd_sb.sb_bsize) {
|
||||||
bytes >>= 1;
|
bytes >>= 1;
|
||||||
|
|
|
@ -285,6 +285,20 @@ struct gfs2_blkreserv {
|
||||||
unsigned int rs_qa_qd_num;
|
unsigned int rs_qa_qd_num;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allocation parameters
|
||||||
|
* @target: The number of blocks we'd ideally like to allocate
|
||||||
|
* @aflags: The flags (e.g. Orlov flag)
|
||||||
|
*
|
||||||
|
* The intent is to gradually expand this structure over time in
|
||||||
|
* order to give more information, e.g. alignment, min extent size
|
||||||
|
* to the allocation code.
|
||||||
|
*/
|
||||||
|
struct gfs2_alloc_parms {
|
||||||
|
u32 target;
|
||||||
|
u32 aflags;
|
||||||
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
GLF_LOCK = 1,
|
GLF_LOCK = 1,
|
||||||
GLF_DEMOTE = 3,
|
GLF_DEMOTE = 3,
|
||||||
|
|
|
@ -379,6 +379,7 @@ static void munge_mode_uid_gid(const struct gfs2_inode *dip,
|
||||||
static int alloc_dinode(struct gfs2_inode *ip, u32 flags)
|
static int alloc_dinode(struct gfs2_inode *ip, u32 flags)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
||||||
|
struct gfs2_alloc_parms ap = { .target = RES_DINODE, .aflags = flags, };
|
||||||
int error;
|
int error;
|
||||||
int dblocks = 1;
|
int dblocks = 1;
|
||||||
|
|
||||||
|
@ -386,7 +387,7 @@ static int alloc_dinode(struct gfs2_inode *ip, u32 flags)
|
||||||
if (error)
|
if (error)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
error = gfs2_inplace_reserve(ip, RES_DINODE, flags);
|
error = gfs2_inplace_reserve(ip, &ap);
|
||||||
if (error)
|
if (error)
|
||||||
goto out_quota;
|
goto out_quota;
|
||||||
|
|
||||||
|
@ -472,6 +473,7 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name,
|
||||||
struct gfs2_inode *ip, int arq)
|
struct gfs2_inode *ip, int arq)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
|
struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
|
||||||
|
struct gfs2_alloc_parms ap = { .target = sdp->sd_max_dirres, };
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
if (arq) {
|
if (arq) {
|
||||||
|
@ -479,7 +481,7 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name,
|
||||||
if (error)
|
if (error)
|
||||||
goto fail_quota_locks;
|
goto fail_quota_locks;
|
||||||
|
|
||||||
error = gfs2_inplace_reserve(dip, sdp->sd_max_dirres, 0);
|
error = gfs2_inplace_reserve(dip, &ap);
|
||||||
if (error)
|
if (error)
|
||||||
goto fail_quota_locks;
|
goto fail_quota_locks;
|
||||||
|
|
||||||
|
@ -874,11 +876,12 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
|
||||||
error = 0;
|
error = 0;
|
||||||
|
|
||||||
if (alloc_required) {
|
if (alloc_required) {
|
||||||
|
struct gfs2_alloc_parms ap = { .target = sdp->sd_max_dirres, };
|
||||||
error = gfs2_quota_lock_check(dip);
|
error = gfs2_quota_lock_check(dip);
|
||||||
if (error)
|
if (error)
|
||||||
goto out_gunlock;
|
goto out_gunlock;
|
||||||
|
|
||||||
error = gfs2_inplace_reserve(dip, sdp->sd_max_dirres, 0);
|
error = gfs2_inplace_reserve(dip, &ap);
|
||||||
if (error)
|
if (error)
|
||||||
goto out_gunlock_q;
|
goto out_gunlock_q;
|
||||||
|
|
||||||
|
@ -1387,11 +1390,12 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
|
||||||
goto out_gunlock;
|
goto out_gunlock;
|
||||||
|
|
||||||
if (alloc_required) {
|
if (alloc_required) {
|
||||||
|
struct gfs2_alloc_parms ap = { .target = sdp->sd_max_dirres, };
|
||||||
error = gfs2_quota_lock_check(ndip);
|
error = gfs2_quota_lock_check(ndip);
|
||||||
if (error)
|
if (error)
|
||||||
goto out_gunlock;
|
goto out_gunlock;
|
||||||
|
|
||||||
error = gfs2_inplace_reserve(ndip, sdp->sd_max_dirres, 0);
|
error = gfs2_inplace_reserve(ndip, &ap);
|
||||||
if (error)
|
if (error)
|
||||||
goto out_gunlock_q;
|
goto out_gunlock_q;
|
||||||
|
|
||||||
|
|
|
@ -763,6 +763,7 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = (*qda)->qd_gl->gl_sbd;
|
struct gfs2_sbd *sdp = (*qda)->qd_gl->gl_sbd;
|
||||||
struct gfs2_inode *ip = GFS2_I(sdp->sd_quota_inode);
|
struct gfs2_inode *ip = GFS2_I(sdp->sd_quota_inode);
|
||||||
|
struct gfs2_alloc_parms ap = { .aflags = 0, };
|
||||||
unsigned int data_blocks, ind_blocks;
|
unsigned int data_blocks, ind_blocks;
|
||||||
struct gfs2_holder *ghs, i_gh;
|
struct gfs2_holder *ghs, i_gh;
|
||||||
unsigned int qx, x;
|
unsigned int qx, x;
|
||||||
|
@ -815,7 +816,8 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda)
|
||||||
blocks = num_qd * data_blocks + RES_DINODE + num_qd + 3;
|
blocks = num_qd * data_blocks + RES_DINODE + num_qd + 3;
|
||||||
|
|
||||||
reserved = 1 + (nalloc * (data_blocks + ind_blocks));
|
reserved = 1 + (nalloc * (data_blocks + ind_blocks));
|
||||||
error = gfs2_inplace_reserve(ip, reserved, 0);
|
ap.target = reserved;
|
||||||
|
error = gfs2_inplace_reserve(ip, &ap);
|
||||||
if (error)
|
if (error)
|
||||||
goto out_alloc;
|
goto out_alloc;
|
||||||
|
|
||||||
|
@ -1573,10 +1575,12 @@ static int gfs2_set_dqblk(struct super_block *sb, struct kqid qid,
|
||||||
if (gfs2_is_stuffed(ip))
|
if (gfs2_is_stuffed(ip))
|
||||||
alloc_required = 1;
|
alloc_required = 1;
|
||||||
if (alloc_required) {
|
if (alloc_required) {
|
||||||
|
struct gfs2_alloc_parms ap = { .aflags = 0, };
|
||||||
gfs2_write_calc_reserv(ip, sizeof(struct gfs2_quota),
|
gfs2_write_calc_reserv(ip, sizeof(struct gfs2_quota),
|
||||||
&data_blocks, &ind_blocks);
|
&data_blocks, &ind_blocks);
|
||||||
blocks = 1 + data_blocks + ind_blocks;
|
blocks = 1 + data_blocks + ind_blocks;
|
||||||
error = gfs2_inplace_reserve(ip, blocks, 0);
|
ap.target = blocks;
|
||||||
|
error = gfs2_inplace_reserve(ip, &ap);
|
||||||
if (error)
|
if (error)
|
||||||
goto out_i;
|
goto out_i;
|
||||||
blocks += gfs2_rg_blocks(ip, blocks);
|
blocks += gfs2_rg_blocks(ip, blocks);
|
||||||
|
|
|
@ -1422,12 +1422,12 @@ static void rs_insert(struct gfs2_inode *ip)
|
||||||
* rg_mblk_search - find a group of multiple free blocks to form a reservation
|
* rg_mblk_search - find a group of multiple free blocks to form a reservation
|
||||||
* @rgd: the resource group descriptor
|
* @rgd: the resource group descriptor
|
||||||
* @ip: pointer to the inode for which we're reserving blocks
|
* @ip: pointer to the inode for which we're reserving blocks
|
||||||
* @requested: number of blocks required for this allocation
|
* @ap: the allocation parameters
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void rg_mblk_search(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip,
|
static void rg_mblk_search(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip,
|
||||||
unsigned requested)
|
const struct gfs2_alloc_parms *ap)
|
||||||
{
|
{
|
||||||
struct gfs2_rbm rbm = { .rgd = rgd, };
|
struct gfs2_rbm rbm = { .rgd = rgd, };
|
||||||
u64 goal;
|
u64 goal;
|
||||||
|
@ -1440,7 +1440,7 @@ static void rg_mblk_search(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip,
|
||||||
if (S_ISDIR(inode->i_mode))
|
if (S_ISDIR(inode->i_mode))
|
||||||
extlen = 1;
|
extlen = 1;
|
||||||
else {
|
else {
|
||||||
extlen = max_t(u32, atomic_read(&rs->rs_sizehint), requested);
|
extlen = max_t(u32, atomic_read(&rs->rs_sizehint), ap->target);
|
||||||
extlen = clamp(extlen, RGRP_RSRV_MINBLKS, free_blocks);
|
extlen = clamp(extlen, RGRP_RSRV_MINBLKS, free_blocks);
|
||||||
}
|
}
|
||||||
if ((rgd->rd_free_clone < rgd->rd_reserved) || (free_blocks < extlen))
|
if ((rgd->rd_free_clone < rgd->rd_reserved) || (free_blocks < extlen))
|
||||||
|
@ -1831,12 +1831,12 @@ static bool gfs2_select_rgrp(struct gfs2_rgrpd **pos, const struct gfs2_rgrpd *b
|
||||||
/**
|
/**
|
||||||
* gfs2_inplace_reserve - Reserve space in the filesystem
|
* gfs2_inplace_reserve - Reserve space in the filesystem
|
||||||
* @ip: the inode to reserve space for
|
* @ip: the inode to reserve space for
|
||||||
* @requested: the number of blocks to be reserved
|
* @ap: the allocation parameters
|
||||||
*
|
*
|
||||||
* Returns: errno
|
* Returns: errno
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested, u32 aflags)
|
int gfs2_inplace_reserve(struct gfs2_inode *ip, const struct gfs2_alloc_parms *ap)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
||||||
struct gfs2_rgrpd *begin = NULL;
|
struct gfs2_rgrpd *begin = NULL;
|
||||||
|
@ -1848,7 +1848,7 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested, u32 aflags)
|
||||||
|
|
||||||
if (sdp->sd_args.ar_rgrplvb)
|
if (sdp->sd_args.ar_rgrplvb)
|
||||||
flags |= GL_SKIP;
|
flags |= GL_SKIP;
|
||||||
if (gfs2_assert_warn(sdp, requested))
|
if (gfs2_assert_warn(sdp, ap->target))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (gfs2_rs_active(rs)) {
|
if (gfs2_rs_active(rs)) {
|
||||||
begin = rs->rs_rbm.rgd;
|
begin = rs->rs_rbm.rgd;
|
||||||
|
@ -1857,7 +1857,7 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested, u32 aflags)
|
||||||
} else {
|
} else {
|
||||||
rs->rs_rbm.rgd = begin = gfs2_blk2rgrpd(sdp, ip->i_goal, 1);
|
rs->rs_rbm.rgd = begin = gfs2_blk2rgrpd(sdp, ip->i_goal, 1);
|
||||||
}
|
}
|
||||||
if (S_ISDIR(ip->i_inode.i_mode) && (aflags & GFS2_AF_ORLOV))
|
if (S_ISDIR(ip->i_inode.i_mode) && (ap->aflags & GFS2_AF_ORLOV))
|
||||||
skip = gfs2_orlov_skip(ip);
|
skip = gfs2_orlov_skip(ip);
|
||||||
if (rs->rs_rbm.rgd == NULL)
|
if (rs->rs_rbm.rgd == NULL)
|
||||||
return -EBADSLT;
|
return -EBADSLT;
|
||||||
|
@ -1899,14 +1899,14 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested, u32 aflags)
|
||||||
|
|
||||||
/* Get a reservation if we don't already have one */
|
/* Get a reservation if we don't already have one */
|
||||||
if (!gfs2_rs_active(rs))
|
if (!gfs2_rs_active(rs))
|
||||||
rg_mblk_search(rs->rs_rbm.rgd, ip, requested);
|
rg_mblk_search(rs->rs_rbm.rgd, ip, ap);
|
||||||
|
|
||||||
/* Skip rgrps when we can't get a reservation on first pass */
|
/* Skip rgrps when we can't get a reservation on first pass */
|
||||||
if (!gfs2_rs_active(rs) && (loops < 1))
|
if (!gfs2_rs_active(rs) && (loops < 1))
|
||||||
goto check_rgrp;
|
goto check_rgrp;
|
||||||
|
|
||||||
/* If rgrp has enough free space, use it */
|
/* If rgrp has enough free space, use it */
|
||||||
if (rs->rs_rbm.rgd->rd_free_clone >= requested) {
|
if (rs->rs_rbm.rgd->rd_free_clone >= ap->target) {
|
||||||
ip->i_rgd = rs->rs_rbm.rgd;
|
ip->i_rgd = rs->rs_rbm.rgd;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ extern void gfs2_rgrp_go_unlock(struct gfs2_holder *gh);
|
||||||
extern struct gfs2_alloc *gfs2_alloc_get(struct gfs2_inode *ip);
|
extern struct gfs2_alloc *gfs2_alloc_get(struct gfs2_inode *ip);
|
||||||
|
|
||||||
#define GFS2_AF_ORLOV 1
|
#define GFS2_AF_ORLOV 1
|
||||||
extern int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested, u32 flags);
|
extern int gfs2_inplace_reserve(struct gfs2_inode *ip, const struct gfs2_alloc_parms *ap);
|
||||||
extern void gfs2_inplace_release(struct gfs2_inode *ip);
|
extern void gfs2_inplace_release(struct gfs2_inode *ip);
|
||||||
|
|
||||||
extern int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *n,
|
extern int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *n,
|
||||||
|
|
|
@ -723,6 +723,7 @@ static int ea_alloc_skeleton(struct gfs2_inode *ip, struct gfs2_ea_request *er,
|
||||||
unsigned int blks,
|
unsigned int blks,
|
||||||
ea_skeleton_call_t skeleton_call, void *private)
|
ea_skeleton_call_t skeleton_call, void *private)
|
||||||
{
|
{
|
||||||
|
struct gfs2_alloc_parms ap = { .target = blks };
|
||||||
struct buffer_head *dibh;
|
struct buffer_head *dibh;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
@ -734,7 +735,7 @@ static int ea_alloc_skeleton(struct gfs2_inode *ip, struct gfs2_ea_request *er,
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
error = gfs2_inplace_reserve(ip, blks, 0);
|
error = gfs2_inplace_reserve(ip, &ap);
|
||||||
if (error)
|
if (error)
|
||||||
goto out_gunlock_q;
|
goto out_gunlock_q;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue