aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/super.c
diff options
context:
space:
mode:
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: