aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/rgrp.c
diff options
context:
space:
mode:
authorBob Peterson <rpeterso@redhat.com>2012-06-06 06:17:59 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2012-06-06 06:17:59 -0400
commit0a305e496059a113f93bdd3ad27a5aaa917fe34d (patch)
treeb0b6ce3997fef4c4e28f598a98e2e08c939414a6 /fs/gfs2/rgrp.c
parenteea5b5510fc5545d15b69da8e485a7424ae388cf (diff)
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 <rpeterso@redhat.com> Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/rgrp.c')
-rw-r--r--fs/gfs2/rgrp.c68
1 files changed, 37 insertions, 31 deletions
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index f74fb9bd1973..e944fefbc9a8 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -417,6 +417,39 @@ void gfs2_free_clones(struct gfs2_rgrpd *rgd)
417 } 417 }
418} 418}
419 419
420/**
421 * gfs2_rs_alloc - make sure we have a reservation assigned to the inode
422 * @ip: the inode for this reservation
423 */
424int gfs2_rs_alloc(struct gfs2_inode *ip)
425{
426 int error = 0;
427
428 down_write(&ip->i_rw_mutex);
429 if (!ip->i_res) {
430 ip->i_res = kmem_cache_zalloc(gfs2_rsrv_cachep, GFP_NOFS);
431 if (!ip->i_res)
432 error = -ENOMEM;
433 }
434 up_write(&ip->i_rw_mutex);
435 return error;
436}
437
438/**
439 * gfs2_rs_delete - delete a reservation
440 * @ip: The inode for this reservation
441 *
442 */
443void gfs2_rs_delete(struct gfs2_inode *ip)
444{
445 down_write(&ip->i_rw_mutex);
446 if (ip->i_res) {
447 kmem_cache_free(gfs2_rsrv_cachep, ip->i_res);
448 ip->i_res = NULL;
449 }
450 up_write(&ip->i_rw_mutex);
451}
452
420void gfs2_clear_rgrpd(struct gfs2_sbd *sdp) 453void gfs2_clear_rgrpd(struct gfs2_sbd *sdp)
421{ 454{
422 struct rb_node *n; 455 struct rb_node *n;
@@ -993,22 +1026,6 @@ struct gfs2_qadata *gfs2_qadata_get(struct gfs2_inode *ip)
993} 1026}
994 1027
995/** 1028/**
996 * gfs2_blkrsv_get - get the struct gfs2_blkreserv structure for an inode
997 * @ip: the incore GFS2 inode structure
998 *
999 * Returns: the struct gfs2_qadata
1000 */
1001
1002static int gfs2_blkrsv_get(struct gfs2_inode *ip)
1003{
1004 BUG_ON(ip->i_res != NULL);
1005 ip->i_res = kmem_cache_zalloc(gfs2_rsrv_cachep, GFP_NOFS);
1006 if (!ip->i_res)
1007 return -ENOMEM;
1008 return 0;
1009}
1010
1011/**
1012 * try_rgrp_fit - See if a given reservation will fit in a given RG 1029 * try_rgrp_fit - See if a given reservation will fit in a given RG
1013 * @rgd: the RG data 1030 * @rgd: the RG data
1014 * @ip: the inode 1031 * @ip: the inode
@@ -1162,13 +1179,6 @@ static int get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked)
1162 return -ENOSPC; 1179 return -ENOSPC;
1163} 1180}
1164 1181
1165static void gfs2_blkrsv_put(struct gfs2_inode *ip)
1166{
1167 BUG_ON(ip->i_res == NULL);
1168 kmem_cache_free(gfs2_rsrv_cachep, ip->i_res);
1169 ip->i_res = NULL;
1170}
1171
1172/** 1182/**
1173 * gfs2_inplace_reserve - Reserve space in the filesystem 1183 * gfs2_inplace_reserve - Reserve space in the filesystem
1174 * @ip: the inode to reserve space for 1184 * @ip: the inode to reserve space for
@@ -1181,14 +1191,10 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested)
1181{ 1191{
1182 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); 1192 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
1183 struct gfs2_blkreserv *rs; 1193 struct gfs2_blkreserv *rs;
1184 int error; 1194 int error = 0;
1185 u64 last_unlinked = NO_BLOCK; 1195 u64 last_unlinked = NO_BLOCK;
1186 int tries = 0; 1196 int tries = 0;
1187 1197
1188 error = gfs2_blkrsv_get(ip);
1189 if (error)
1190 return error;
1191
1192 rs = ip->i_res; 1198 rs = ip->i_res;
1193 rs->rs_requested = requested; 1199 rs->rs_requested = requested;
1194 if (gfs2_assert_warn(sdp, requested)) { 1200 if (gfs2_assert_warn(sdp, requested)) {
@@ -1213,7 +1219,7 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested)
1213 1219
1214out: 1220out:
1215 if (error) 1221 if (error)
1216 gfs2_blkrsv_put(ip); 1222 rs->rs_requested = 0;
1217 return error; 1223 return error;
1218} 1224}
1219 1225
@@ -1230,7 +1236,7 @@ void gfs2_inplace_release(struct gfs2_inode *ip)
1230 1236
1231 if (rs->rs_rgd_gh.gh_gl) 1237 if (rs->rs_rgd_gh.gh_gl)
1232 gfs2_glock_dq_uninit(&rs->rs_rgd_gh); 1238 gfs2_glock_dq_uninit(&rs->rs_rgd_gh);
1233 gfs2_blkrsv_put(ip); 1239 rs->rs_requested = 0;
1234} 1240}
1235 1241
1236/** 1242/**
@@ -1496,7 +1502,7 @@ int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *nblocks,
1496 /* Only happens if there is a bug in gfs2, return something distinctive 1502 /* Only happens if there is a bug in gfs2, return something distinctive
1497 * to ensure that it is noticed. 1503 * to ensure that it is noticed.
1498 */ 1504 */
1499 if (ip->i_res == NULL) 1505 if (ip->i_res->rs_requested == 0)
1500 return -ECANCELED; 1506 return -ECANCELED;
1501 1507
1502 rgd = ip->i_rgd; 1508 rgd = ip->i_rgd;