aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/super.c
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2011-04-14 11:50:31 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2011-04-20 04:01:17 -0400
commitf42ab0852946c1fb5103682c5897eb3da908e4b0 (patch)
tree3847b23d2cac6bab422e6e001e0c6d6c66a81f1e /fs/gfs2/super.c
parent627c10b7e471b5dcfb7101d6cc74d219619c9bc4 (diff)
GFS2: Optimise glock lru and end of life inodes
The GLF_LRU flag introduced in the previous patch can be used to check if a glock is on the lru list when a new holder is queued and if so remove it, without having first to get the lru_lock. The main purpose of this patch however is to optimise the glocks left over when an inode at end of life is being evicted. Previously such glocks were left with the GLF_LFLUSH flag set, so that when reclaimed, each one required a log flush. This patch resets the GLF_LFLUSH flag when there is nothing left to flush thus preventing later log flushes as glocks are reused or demoted. In order to do this, we need to keep track of the number of revokes which are outstanding, and also to clear the GLF_LFLUSH bit after a log commit when only revokes have been processed. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/super.c')
-rw-r--r--fs/gfs2/super.c78
1 files changed, 74 insertions, 4 deletions
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index b62c8427672c..215c37bfc2a4 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -1315,6 +1315,78 @@ static int gfs2_show_options(struct seq_file *s, struct vfsmount *mnt)
1315 return 0; 1315 return 0;
1316} 1316}
1317 1317
1318static void gfs2_final_release_pages(struct gfs2_inode *ip)
1319{
1320 struct inode *inode = &ip->i_inode;
1321 struct gfs2_glock *gl = ip->i_gl;
1322
1323 truncate_inode_pages(gfs2_glock2aspace(ip->i_gl), 0);
1324 truncate_inode_pages(&inode->i_data, 0);
1325
1326 if (atomic_read(&gl->gl_revokes) == 0) {
1327 clear_bit(GLF_LFLUSH, &gl->gl_flags);
1328 clear_bit(GLF_DIRTY, &gl->gl_flags);
1329 }
1330}
1331
1332static int gfs2_dinode_dealloc(struct gfs2_inode *ip)
1333{
1334 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
1335 struct gfs2_alloc *al;
1336 struct gfs2_rgrpd *rgd;
1337 int error;
1338
1339 if (gfs2_get_inode_blocks(&ip->i_inode) != 1) {
1340 if (gfs2_consist_inode(ip))
1341 gfs2_dinode_print(ip);
1342 return -EIO;
1343 }
1344
1345 al = gfs2_alloc_get(ip);
1346 if (!al)
1347 return -ENOMEM;
1348
1349 error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE);
1350 if (error)
1351 goto out;
1352
1353 error = gfs2_rindex_hold(sdp, &al->al_ri_gh);
1354 if (error)
1355 goto out_qs;
1356
1357 rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr);
1358 if (!rgd) {
1359 gfs2_consist_inode(ip);
1360 error = -EIO;
1361 goto out_rindex_relse;
1362 }
1363
1364 error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0,
1365 &al->al_rgd_gh);
1366 if (error)
1367 goto out_rindex_relse;
1368
1369 error = gfs2_trans_begin(sdp, RES_RG_BIT + RES_STATFS + RES_QUOTA, 1);
1370 if (error)
1371 goto out_rg_gunlock;
1372
1373 gfs2_free_di(rgd, ip);
1374
1375 gfs2_final_release_pages(ip);
1376
1377 gfs2_trans_end(sdp);
1378
1379out_rg_gunlock:
1380 gfs2_glock_dq_uninit(&al->al_rgd_gh);
1381out_rindex_relse:
1382 gfs2_glock_dq_uninit(&al->al_ri_gh);
1383out_qs:
1384 gfs2_quota_unhold(ip);
1385out:
1386 gfs2_alloc_put(ip);
1387 return error;
1388}
1389
1318/* 1390/*
1319 * We have to (at the moment) hold the inodes main lock to cover 1391 * We have to (at the moment) hold the inodes main lock to cover
1320 * the gap between unlocking the shared lock on the iopen lock and 1392 * the gap between unlocking the shared lock on the iopen lock and
@@ -1378,15 +1450,13 @@ static void gfs2_evict_inode(struct inode *inode)
1378 } 1450 }
1379 1451
1380 error = gfs2_dinode_dealloc(ip); 1452 error = gfs2_dinode_dealloc(ip);
1381 if (error) 1453 goto out_unlock;
1382 goto out_unlock;
1383 1454
1384out_truncate: 1455out_truncate:
1385 error = gfs2_trans_begin(sdp, 0, sdp->sd_jdesc->jd_blocks); 1456 error = gfs2_trans_begin(sdp, 0, sdp->sd_jdesc->jd_blocks);
1386 if (error) 1457 if (error)
1387 goto out_unlock; 1458 goto out_unlock;
1388 /* Needs to be done before glock release & also in a transaction */ 1459 gfs2_final_release_pages(ip);
1389 truncate_inode_pages(&inode->i_data, 0);
1390 gfs2_trans_end(sdp); 1460 gfs2_trans_end(sdp);
1391 1461
1392out_unlock: 1462out_unlock: