From 0a305e496059a113f93bdd3ad27a5aaa917fe34d Mon Sep 17 00:00:00 2001 From: Bob Peterson Date: Wed, 6 Jun 2012 11:17:59 +0100 Subject: GFS2: Extend the life of the reservations This patch lengthens the lifespan of the reservations structure for inodes. Before, they were allocated and deallocated for every write operation. With this patch, they are allocated when the first write occurs, and deallocated when the last process closes the file. It's more efficient to do it this way because it saves GFS2 a lot of unnecessary allocates and frees. It also gives us more flexibility for the future: (1) we can now fold the qadata structure back into the structure and save those alloc/frees, (2) we can use this for multi-block reservations. Signed-off-by: Bob Peterson Signed-off-by: Steven Whitehouse --- fs/gfs2/super.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'fs/gfs2/super.c') diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index 713e621c240b..65578df29446 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c @@ -1554,6 +1554,7 @@ out_unlock: out: /* Case 3 starts here */ truncate_inode_pages(&inode->i_data, 0); + gfs2_rs_delete(ip); clear_inode(inode); gfs2_dir_hash_inval(ip); ip->i_gl->gl_object = NULL; @@ -1576,6 +1577,7 @@ static struct inode *gfs2_alloc_inode(struct super_block *sb) ip->i_flags = 0; ip->i_gl = NULL; ip->i_rgd = NULL; + ip->i_res = NULL; } return &ip->i_inode; } -- cgit From 5407e24229408d7586ee451a384fc13e4a2332be Mon Sep 17 00:00:00 2001 From: Bob Peterson Date: Fri, 18 May 2012 09:28:23 -0400 Subject: GFS2: Fold quota data into the reservations struct This patch moves the ancillary quota data structures into the block reservations structure. This saves GFS2 some time and effort in allocating and deallocating the qadata structure. Signed-off-by: Bob Peterson Signed-off-by: Steven Whitehouse --- fs/gfs2/super.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'fs/gfs2/super.c') diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index 65578df29446..81fc76264ed4 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c @@ -1399,7 +1399,6 @@ static void gfs2_final_release_pages(struct gfs2_inode *ip) static int gfs2_dinode_dealloc(struct gfs2_inode *ip) { struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); - struct gfs2_qadata *qa; struct gfs2_rgrpd *rgd; struct gfs2_holder gh; int error; @@ -1409,13 +1408,9 @@ static int gfs2_dinode_dealloc(struct gfs2_inode *ip) return -EIO; } - qa = gfs2_qadata_get(ip); - if (!qa) - return -ENOMEM; - error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); if (error) - goto out; + return error; rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr, 1); if (!rgd) { @@ -1443,8 +1438,6 @@ out_rg_gunlock: gfs2_glock_dq_uninit(&gh); out_qs: gfs2_quota_unhold(ip); -out: - gfs2_qadata_put(ip); return error; } -- cgit From 90306c41dc3d8e5f12ecd0193dae99e0e7f6e896 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Tue, 29 May 2012 23:01:09 -0500 Subject: GFS2: Use lvbs for storing rgrp information with mount option Instead of reading in the resource groups when gfs2 is checking for free space to allocate from, gfs2 can store the necessary infromation in the resource group's lvb. Also, instead of searching for unlinked inodes in every resource group that's checked for free space, gfs2 can store the number of unlinked but inodes in the lvb, and only check for unlinked inodes if it will find some. The first time a resource group is locked, the lvb must initialized. Since this involves counting the unlinked inodes in the resource group, this takes a little extra time. But after that, if the resource group is locked with GL_SKIP, the buffer head won't be read in unless it's actually needed. Enabling the resource groups lvbs is done via the rgrplvb mount option. If this option isn't set, the lvbs will still be set and updated, but they won't be verfied or used by the filesystem. To safely turn on this option, all of the nodes mounting the filesystem must be running code with this patch, and the filesystem must have been completely unmounted since they were updated. Signed-off-by: Benjamin Marzinski Signed-off-by: Steven Whitehouse --- fs/gfs2/super.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'fs/gfs2/super.c') diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index 81fc76264ed4..788068758f3a 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c @@ -78,6 +78,8 @@ enum { Opt_quota_quantum, Opt_barrier, Opt_nobarrier, + Opt_rgrplvb, + Opt_norgrplvb, Opt_error, }; @@ -115,6 +117,8 @@ static const match_table_t tokens = { {Opt_quota_quantum, "quota_quantum=%d"}, {Opt_barrier, "barrier"}, {Opt_nobarrier, "nobarrier"}, + {Opt_rgrplvb, "rgrplvb"}, + {Opt_norgrplvb, "norgrplvb"}, {Opt_error, NULL} }; @@ -267,6 +271,12 @@ int gfs2_mount_args(struct gfs2_args *args, char *options) case Opt_nobarrier: args->ar_nobarrier = 1; break; + case Opt_rgrplvb: + args->ar_rgrplvb = 1; + break; + case Opt_norgrplvb: + args->ar_rgrplvb = 0; + break; case Opt_error: default: printk(KERN_WARNING "GFS2: invalid mount option: %s\n", o); @@ -1379,6 +1389,8 @@ static int gfs2_show_options(struct seq_file *s, struct dentry *root) seq_printf(s, ",nobarrier"); if (test_bit(SDF_DEMOTE, &sdp->sd_flags)) seq_printf(s, ",demote_interface_used"); + if (args->ar_rgrplvb) + seq_printf(s, ",rgrplvb"); return 0; } -- cgit From 8e2e00473598dd5379d8408cb974dade000acafc Mon Sep 17 00:00:00 2001 From: Bob Peterson Date: Thu, 19 Jul 2012 08:12:40 -0400 Subject: GFS2: Reduce file fragmentation This patch reduces GFS2 file fragmentation by pre-reserving blocks. The resulting improved on disk layout greatly speeds up operations in cases which would have resulted in interlaced allocation of blocks previously. A typical example of this is 10 parallel dd processes, each writing to a file in a common dirctory. The implementation uses an rbtree of reservations attached to each resource group (and each inode). Signed-off-by: Bob Peterson Signed-off-by: Steven Whitehouse --- fs/gfs2/super.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'fs/gfs2/super.c') diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index 788068758f3a..b1502c4bc60d 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c @@ -1420,6 +1420,10 @@ static int gfs2_dinode_dealloc(struct gfs2_inode *ip) return -EIO; } + error = gfs2_rindex_update(sdp); + if (error) + return error; + error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); if (error) return error; @@ -1550,6 +1554,9 @@ out_truncate: out_unlock: /* Error path for case 1 */ + if (gfs2_rs_active(ip->i_res)) + gfs2_rs_deltree(ip->i_res); + if (test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags)) gfs2_glock_dq(&ip->i_iopen_gh); gfs2_holder_uninit(&ip->i_iopen_gh); -- cgit