aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2013-10-02 06:13:25 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2013-10-02 06:13:25 -0400
commit7b9cff467144c8c62268db1b0948df089caa0999 (patch)
treeabe7408d4cf28502bdbfc91983c02869898ccced /fs/gfs2
parentaf5c269799feaef110e59ce55b497cdd08712b0c (diff)
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>
Diffstat (limited to 'fs/gfs2')
-rw-r--r--fs/gfs2/aops.c4
-rw-r--r--fs/gfs2/bmap.c3
-rw-r--r--fs/gfs2/file.c8
-rw-r--r--fs/gfs2/incore.h14
-rw-r--r--fs/gfs2/inode.c12
-rw-r--r--fs/gfs2/quota.c8
-rw-r--r--fs/gfs2/rgrp.c18
-rw-r--r--fs/gfs2/rgrp.h2
-rw-r--r--fs/gfs2/xattr.c3
9 files changed, 51 insertions, 21 deletions
diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c
index 1f7d8057ea68..b7fc035a6943 100644
--- a/fs/gfs2/aops.c
+++ b/fs/gfs2/aops.c
@@ -611,12 +611,14 @@ static int gfs2_write_begin(struct file *file, struct address_space *mapping,
611 gfs2_write_calc_reserv(ip, len, &data_blocks, &ind_blocks); 611 gfs2_write_calc_reserv(ip, len, &data_blocks, &ind_blocks);
612 612
613 if (alloc_required) { 613 if (alloc_required) {
614 struct gfs2_alloc_parms ap = { .aflags = 0, };
614 error = gfs2_quota_lock_check(ip); 615 error = gfs2_quota_lock_check(ip);
615 if (error) 616 if (error)
616 goto out_unlock; 617 goto out_unlock;
617 618
618 requested = data_blocks + ind_blocks; 619 requested = data_blocks + ind_blocks;
619 error = gfs2_inplace_reserve(ip, requested, 0); 620 ap.target = requested;
621 error = gfs2_inplace_reserve(ip, &ap);
620 if (error) 622 if (error)
621 goto out_qunlock; 623 goto out_qunlock;
622 } 624 }
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
index 21ad0f11cad4..fe0500c0af7a 100644
--- a/fs/gfs2/bmap.c
+++ b/fs/gfs2/bmap.c
@@ -1216,6 +1216,7 @@ static int do_grow(struct inode *inode, u64 size)
1216{ 1216{
1217 struct gfs2_inode *ip = GFS2_I(inode); 1217 struct gfs2_inode *ip = GFS2_I(inode);
1218 struct gfs2_sbd *sdp = GFS2_SB(inode); 1218 struct gfs2_sbd *sdp = GFS2_SB(inode);
1219 struct gfs2_alloc_parms ap = { .target = 1, };
1219 struct buffer_head *dibh; 1220 struct buffer_head *dibh;
1220 int error; 1221 int error;
1221 int unstuff = 0; 1222 int unstuff = 0;
@@ -1226,7 +1227,7 @@ static int do_grow(struct inode *inode, u64 size)
1226 if (error) 1227 if (error)
1227 return error; 1228 return error;
1228 1229
1229 error = gfs2_inplace_reserve(ip, 1, 0); 1230 error = gfs2_inplace_reserve(ip, &ap);
1230 if (error) 1231 if (error)
1231 goto do_grow_qunlock; 1232 goto do_grow_qunlock;
1232 unstuff = 1; 1233 unstuff = 1;
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c
index 9ad20edc9c27..efc078f0ee4e 100644
--- a/fs/gfs2/file.c
+++ b/fs/gfs2/file.c
@@ -383,6 +383,7 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
383 struct inode *inode = file_inode(vma->vm_file); 383 struct inode *inode = file_inode(vma->vm_file);
384 struct gfs2_inode *ip = GFS2_I(inode); 384 struct gfs2_inode *ip = GFS2_I(inode);
385 struct gfs2_sbd *sdp = GFS2_SB(inode); 385 struct gfs2_sbd *sdp = GFS2_SB(inode);
386 struct gfs2_alloc_parms ap = { .aflags = 0, };
386 unsigned long last_index; 387 unsigned long last_index;
387 u64 pos = page->index << PAGE_CACHE_SHIFT; 388 u64 pos = page->index << PAGE_CACHE_SHIFT;
388 unsigned int data_blocks, ind_blocks, rblocks; 389 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)
430 if (ret) 431 if (ret)
431 goto out_unlock; 432 goto out_unlock;
432 gfs2_write_calc_reserv(ip, PAGE_CACHE_SIZE, &data_blocks, &ind_blocks); 433 gfs2_write_calc_reserv(ip, PAGE_CACHE_SIZE, &data_blocks, &ind_blocks);
433 ret = gfs2_inplace_reserve(ip, data_blocks + ind_blocks, 0); 434 ap.target = data_blocks + ind_blocks;
435 ret = gfs2_inplace_reserve(ip, &ap);
434 if (ret) 436 if (ret)
435 goto out_quota_unlock; 437 goto out_quota_unlock;
436 438
@@ -800,6 +802,7 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset,
800 struct inode *inode = file_inode(file); 802 struct inode *inode = file_inode(file);
801 struct gfs2_sbd *sdp = GFS2_SB(inode); 803 struct gfs2_sbd *sdp = GFS2_SB(inode);
802 struct gfs2_inode *ip = GFS2_I(inode); 804 struct gfs2_inode *ip = GFS2_I(inode);
805 struct gfs2_alloc_parms ap = { .aflags = 0, };
803 unsigned int data_blocks = 0, ind_blocks = 0, rblocks; 806 unsigned int data_blocks = 0, ind_blocks = 0, rblocks;
804 loff_t bytes, max_bytes; 807 loff_t bytes, max_bytes;
805 int error; 808 int error;
@@ -850,7 +853,8 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset,
850retry: 853retry:
851 gfs2_write_calc_reserv(ip, bytes, &data_blocks, &ind_blocks); 854 gfs2_write_calc_reserv(ip, bytes, &data_blocks, &ind_blocks);
852 855
853 error = gfs2_inplace_reserve(ip, data_blocks + ind_blocks, 0); 856 ap.target = data_blocks + ind_blocks;
857 error = gfs2_inplace_reserve(ip, &ap);
854 if (error) { 858 if (error) {
855 if (error == -ENOSPC && bytes > sdp->sd_sb.sb_bsize) { 859 if (error == -ENOSPC && bytes > sdp->sd_sb.sb_bsize) {
856 bytes >>= 1; 860 bytes >>= 1;
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index 8c8f110d8e35..082c8fa7fab9 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -285,6 +285,20 @@ struct gfs2_blkreserv {
285 unsigned int rs_qa_qd_num; 285 unsigned int rs_qa_qd_num;
286}; 286};
287 287
288/*
289 * Allocation parameters
290 * @target: The number of blocks we'd ideally like to allocate
291 * @aflags: The flags (e.g. Orlov flag)
292 *
293 * The intent is to gradually expand this structure over time in
294 * order to give more information, e.g. alignment, min extent size
295 * to the allocation code.
296 */
297struct gfs2_alloc_parms {
298 u32 target;
299 u32 aflags;
300};
301
288enum { 302enum {
289 GLF_LOCK = 1, 303 GLF_LOCK = 1,
290 GLF_DEMOTE = 3, 304 GLF_DEMOTE = 3,
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 4b79c19100d2..5a7ca3d1d1cf 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -379,6 +379,7 @@ static void munge_mode_uid_gid(const struct gfs2_inode *dip,
379static int alloc_dinode(struct gfs2_inode *ip, u32 flags) 379static int alloc_dinode(struct gfs2_inode *ip, u32 flags)
380{ 380{
381 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); 381 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
382 struct gfs2_alloc_parms ap = { .target = RES_DINODE, .aflags = flags, };
382 int error; 383 int error;
383 int dblocks = 1; 384 int dblocks = 1;
384 385
@@ -386,7 +387,7 @@ static int alloc_dinode(struct gfs2_inode *ip, u32 flags)
386 if (error) 387 if (error)
387 goto out; 388 goto out;
388 389
389 error = gfs2_inplace_reserve(ip, RES_DINODE, flags); 390 error = gfs2_inplace_reserve(ip, &ap);
390 if (error) 391 if (error)
391 goto out_quota; 392 goto out_quota;
392 393
@@ -472,6 +473,7 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name,
472 struct gfs2_inode *ip, int arq) 473 struct gfs2_inode *ip, int arq)
473{ 474{
474 struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); 475 struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
476 struct gfs2_alloc_parms ap = { .target = sdp->sd_max_dirres, };
475 int error; 477 int error;
476 478
477 if (arq) { 479 if (arq) {
@@ -479,7 +481,7 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name,
479 if (error) 481 if (error)
480 goto fail_quota_locks; 482 goto fail_quota_locks;
481 483
482 error = gfs2_inplace_reserve(dip, sdp->sd_max_dirres, 0); 484 error = gfs2_inplace_reserve(dip, &ap);
483 if (error) 485 if (error)
484 goto fail_quota_locks; 486 goto fail_quota_locks;
485 487
@@ -874,11 +876,12 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
874 error = 0; 876 error = 0;
875 877
876 if (alloc_required) { 878 if (alloc_required) {
879 struct gfs2_alloc_parms ap = { .target = sdp->sd_max_dirres, };
877 error = gfs2_quota_lock_check(dip); 880 error = gfs2_quota_lock_check(dip);
878 if (error) 881 if (error)
879 goto out_gunlock; 882 goto out_gunlock;
880 883
881 error = gfs2_inplace_reserve(dip, sdp->sd_max_dirres, 0); 884 error = gfs2_inplace_reserve(dip, &ap);
882 if (error) 885 if (error)
883 goto out_gunlock_q; 886 goto out_gunlock_q;
884 887
@@ -1387,11 +1390,12 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
1387 goto out_gunlock; 1390 goto out_gunlock;
1388 1391
1389 if (alloc_required) { 1392 if (alloc_required) {
1393 struct gfs2_alloc_parms ap = { .target = sdp->sd_max_dirres, };
1390 error = gfs2_quota_lock_check(ndip); 1394 error = gfs2_quota_lock_check(ndip);
1391 if (error) 1395 if (error)
1392 goto out_gunlock; 1396 goto out_gunlock;
1393 1397
1394 error = gfs2_inplace_reserve(ndip, sdp->sd_max_dirres, 0); 1398 error = gfs2_inplace_reserve(ndip, &ap);
1395 if (error) 1399 if (error)
1396 goto out_gunlock_q; 1400 goto out_gunlock_q;
1397 1401
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index db441359ee8c..8fe7a0a87c80 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -763,6 +763,7 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda)
763{ 763{
764 struct gfs2_sbd *sdp = (*qda)->qd_gl->gl_sbd; 764 struct gfs2_sbd *sdp = (*qda)->qd_gl->gl_sbd;
765 struct gfs2_inode *ip = GFS2_I(sdp->sd_quota_inode); 765 struct gfs2_inode *ip = GFS2_I(sdp->sd_quota_inode);
766 struct gfs2_alloc_parms ap = { .aflags = 0, };
766 unsigned int data_blocks, ind_blocks; 767 unsigned int data_blocks, ind_blocks;
767 struct gfs2_holder *ghs, i_gh; 768 struct gfs2_holder *ghs, i_gh;
768 unsigned int qx, x; 769 unsigned int qx, x;
@@ -815,7 +816,8 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda)
815 blocks = num_qd * data_blocks + RES_DINODE + num_qd + 3; 816 blocks = num_qd * data_blocks + RES_DINODE + num_qd + 3;
816 817
817 reserved = 1 + (nalloc * (data_blocks + ind_blocks)); 818 reserved = 1 + (nalloc * (data_blocks + ind_blocks));
818 error = gfs2_inplace_reserve(ip, reserved, 0); 819 ap.target = reserved;
820 error = gfs2_inplace_reserve(ip, &ap);
819 if (error) 821 if (error)
820 goto out_alloc; 822 goto out_alloc;
821 823
@@ -1573,10 +1575,12 @@ static int gfs2_set_dqblk(struct super_block *sb, struct kqid qid,
1573 if (gfs2_is_stuffed(ip)) 1575 if (gfs2_is_stuffed(ip))
1574 alloc_required = 1; 1576 alloc_required = 1;
1575 if (alloc_required) { 1577 if (alloc_required) {
1578 struct gfs2_alloc_parms ap = { .aflags = 0, };
1576 gfs2_write_calc_reserv(ip, sizeof(struct gfs2_quota), 1579 gfs2_write_calc_reserv(ip, sizeof(struct gfs2_quota),
1577 &data_blocks, &ind_blocks); 1580 &data_blocks, &ind_blocks);
1578 blocks = 1 + data_blocks + ind_blocks; 1581 blocks = 1 + data_blocks + ind_blocks;
1579 error = gfs2_inplace_reserve(ip, blocks, 0); 1582 ap.target = blocks;
1583 error = gfs2_inplace_reserve(ip, &ap);
1580 if (error) 1584 if (error)
1581 goto out_i; 1585 goto out_i;
1582 blocks += gfs2_rg_blocks(ip, blocks); 1586 blocks += gfs2_rg_blocks(ip, blocks);
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index d4d10fadab79..4f0984a607b3 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -1422,12 +1422,12 @@ static void rs_insert(struct gfs2_inode *ip)
1422 * rg_mblk_search - find a group of multiple free blocks to form a reservation 1422 * rg_mblk_search - find a group of multiple free blocks to form a reservation
1423 * @rgd: the resource group descriptor 1423 * @rgd: the resource group descriptor
1424 * @ip: pointer to the inode for which we're reserving blocks 1424 * @ip: pointer to the inode for which we're reserving blocks
1425 * @requested: number of blocks required for this allocation 1425 * @ap: the allocation parameters
1426 * 1426 *
1427 */ 1427 */
1428 1428
1429static void rg_mblk_search(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip, 1429static void rg_mblk_search(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip,
1430 unsigned requested) 1430 const struct gfs2_alloc_parms *ap)
1431{ 1431{
1432 struct gfs2_rbm rbm = { .rgd = rgd, }; 1432 struct gfs2_rbm rbm = { .rgd = rgd, };
1433 u64 goal; 1433 u64 goal;
@@ -1440,7 +1440,7 @@ static void rg_mblk_search(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip,
1440 if (S_ISDIR(inode->i_mode)) 1440 if (S_ISDIR(inode->i_mode))
1441 extlen = 1; 1441 extlen = 1;
1442 else { 1442 else {
1443 extlen = max_t(u32, atomic_read(&rs->rs_sizehint), requested); 1443 extlen = max_t(u32, atomic_read(&rs->rs_sizehint), ap->target);
1444 extlen = clamp(extlen, RGRP_RSRV_MINBLKS, free_blocks); 1444 extlen = clamp(extlen, RGRP_RSRV_MINBLKS, free_blocks);
1445 } 1445 }
1446 if ((rgd->rd_free_clone < rgd->rd_reserved) || (free_blocks < extlen)) 1446 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
1831/** 1831/**
1832 * gfs2_inplace_reserve - Reserve space in the filesystem 1832 * gfs2_inplace_reserve - Reserve space in the filesystem
1833 * @ip: the inode to reserve space for 1833 * @ip: the inode to reserve space for
1834 * @requested: the number of blocks to be reserved 1834 * @ap: the allocation parameters
1835 * 1835 *
1836 * Returns: errno 1836 * Returns: errno
1837 */ 1837 */
1838 1838
1839int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested, u32 aflags) 1839int gfs2_inplace_reserve(struct gfs2_inode *ip, const struct gfs2_alloc_parms *ap)
1840{ 1840{
1841 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); 1841 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
1842 struct gfs2_rgrpd *begin = NULL; 1842 struct gfs2_rgrpd *begin = NULL;
@@ -1848,7 +1848,7 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested, u32 aflags)
1848 1848
1849 if (sdp->sd_args.ar_rgrplvb) 1849 if (sdp->sd_args.ar_rgrplvb)
1850 flags |= GL_SKIP; 1850 flags |= GL_SKIP;
1851 if (gfs2_assert_warn(sdp, requested)) 1851 if (gfs2_assert_warn(sdp, ap->target))
1852 return -EINVAL; 1852 return -EINVAL;
1853 if (gfs2_rs_active(rs)) { 1853 if (gfs2_rs_active(rs)) {
1854 begin = rs->rs_rbm.rgd; 1854 begin = rs->rs_rbm.rgd;
@@ -1857,7 +1857,7 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested, u32 aflags)
1857 } else { 1857 } else {
1858 rs->rs_rbm.rgd = begin = gfs2_blk2rgrpd(sdp, ip->i_goal, 1); 1858 rs->rs_rbm.rgd = begin = gfs2_blk2rgrpd(sdp, ip->i_goal, 1);
1859 } 1859 }
1860 if (S_ISDIR(ip->i_inode.i_mode) && (aflags & GFS2_AF_ORLOV)) 1860 if (S_ISDIR(ip->i_inode.i_mode) && (ap->aflags & GFS2_AF_ORLOV))
1861 skip = gfs2_orlov_skip(ip); 1861 skip = gfs2_orlov_skip(ip);
1862 if (rs->rs_rbm.rgd == NULL) 1862 if (rs->rs_rbm.rgd == NULL)
1863 return -EBADSLT; 1863 return -EBADSLT;
@@ -1899,14 +1899,14 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested, u32 aflags)
1899 1899
1900 /* Get a reservation if we don't already have one */ 1900 /* Get a reservation if we don't already have one */
1901 if (!gfs2_rs_active(rs)) 1901 if (!gfs2_rs_active(rs))
1902 rg_mblk_search(rs->rs_rbm.rgd, ip, requested); 1902 rg_mblk_search(rs->rs_rbm.rgd, ip, ap);
1903 1903
1904 /* Skip rgrps when we can't get a reservation on first pass */ 1904 /* Skip rgrps when we can't get a reservation on first pass */
1905 if (!gfs2_rs_active(rs) && (loops < 1)) 1905 if (!gfs2_rs_active(rs) && (loops < 1))
1906 goto check_rgrp; 1906 goto check_rgrp;
1907 1907
1908 /* If rgrp has enough free space, use it */ 1908 /* If rgrp has enough free space, use it */
1909 if (rs->rs_rbm.rgd->rd_free_clone >= requested) { 1909 if (rs->rs_rbm.rgd->rd_free_clone >= ap->target) {
1910 ip->i_rgd = rs->rs_rbm.rgd; 1910 ip->i_rgd = rs->rs_rbm.rgd;
1911 return 0; 1911 return 0;
1912 } 1912 }
diff --git a/fs/gfs2/rgrp.h b/fs/gfs2/rgrp.h
index 57ea16ba3414..3a10d2ffbbe7 100644
--- a/fs/gfs2/rgrp.h
+++ b/fs/gfs2/rgrp.h
@@ -40,7 +40,7 @@ extern void gfs2_rgrp_go_unlock(struct gfs2_holder *gh);
40extern struct gfs2_alloc *gfs2_alloc_get(struct gfs2_inode *ip); 40extern struct gfs2_alloc *gfs2_alloc_get(struct gfs2_inode *ip);
41 41
42#define GFS2_AF_ORLOV 1 42#define GFS2_AF_ORLOV 1
43extern int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested, u32 flags); 43extern int gfs2_inplace_reserve(struct gfs2_inode *ip, const struct gfs2_alloc_parms *ap);
44extern void gfs2_inplace_release(struct gfs2_inode *ip); 44extern void gfs2_inplace_release(struct gfs2_inode *ip);
45 45
46extern int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *n, 46extern int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *n,
diff --git a/fs/gfs2/xattr.c b/fs/gfs2/xattr.c
index ecd37f30ab91..8c6a6f6bdba9 100644
--- a/fs/gfs2/xattr.c
+++ b/fs/gfs2/xattr.c
@@ -723,6 +723,7 @@ static int ea_alloc_skeleton(struct gfs2_inode *ip, struct gfs2_ea_request *er,
723 unsigned int blks, 723 unsigned int blks,
724 ea_skeleton_call_t skeleton_call, void *private) 724 ea_skeleton_call_t skeleton_call, void *private)
725{ 725{
726 struct gfs2_alloc_parms ap = { .target = blks };
726 struct buffer_head *dibh; 727 struct buffer_head *dibh;
727 int error; 728 int error;
728 729
@@ -734,7 +735,7 @@ static int ea_alloc_skeleton(struct gfs2_inode *ip, struct gfs2_ea_request *er,
734 if (error) 735 if (error)
735 return error; 736 return error;
736 737
737 error = gfs2_inplace_reserve(ip, blks, 0); 738 error = gfs2_inplace_reserve(ip, &ap);
738 if (error) 739 if (error)
739 goto out_gunlock_q; 740 goto out_gunlock_q;
740 741