aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/gfs2/glock.c41
-rw-r--r--fs/gfs2/incore.h1
-rw-r--r--fs/gfs2/inode.c59
-rw-r--r--fs/gfs2/inode.h1
-rw-r--r--fs/gfs2/lops.c27
-rw-r--r--fs/gfs2/main.c1
-rw-r--r--fs/gfs2/super.c78
7 files changed, 119 insertions, 89 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 0c6c69090140..cb8776f0102e 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -145,14 +145,9 @@ static int demote_ok(const struct gfs2_glock *gl)
145{ 145{
146 const struct gfs2_glock_operations *glops = gl->gl_ops; 146 const struct gfs2_glock_operations *glops = gl->gl_ops;
147 147
148 /* assert_spin_locked(&gl->gl_spin); */
149
150 if (gl->gl_state == LM_ST_UNLOCKED) 148 if (gl->gl_state == LM_ST_UNLOCKED)
151 return 0; 149 return 0;
152 if (test_bit(GLF_LFLUSH, &gl->gl_flags)) 150 if (!list_empty(&gl->gl_holders))
153 return 0;
154 if ((gl->gl_name.ln_type != LM_TYPE_INODE) &&
155 !list_empty(&gl->gl_holders))
156 return 0; 151 return 0;
157 if (glops->go_demote_ok) 152 if (glops->go_demote_ok)
158 return glops->go_demote_ok(gl); 153 return glops->go_demote_ok(gl);
@@ -174,6 +169,17 @@ void gfs2_glock_add_to_lru(struct gfs2_glock *gl)
174 spin_unlock(&lru_lock); 169 spin_unlock(&lru_lock);
175} 170}
176 171
172static void gfs2_glock_remove_from_lru(struct gfs2_glock *gl)
173{
174 spin_lock(&lru_lock);
175 if (!list_empty(&gl->gl_lru)) {
176 list_del_init(&gl->gl_lru);
177 atomic_dec(&lru_count);
178 clear_bit(GLF_LRU, &gl->gl_flags);
179 }
180 spin_unlock(&lru_lock);
181}
182
177/** 183/**
178 * __gfs2_glock_schedule_for_reclaim - Add a glock to the reclaim list 184 * __gfs2_glock_schedule_for_reclaim - Add a glock to the reclaim list
179 * @gl: the glock 185 * @gl: the glock
@@ -217,12 +223,7 @@ void gfs2_glock_put(struct gfs2_glock *gl)
217 spin_lock_bucket(gl->gl_hash); 223 spin_lock_bucket(gl->gl_hash);
218 hlist_bl_del_rcu(&gl->gl_list); 224 hlist_bl_del_rcu(&gl->gl_list);
219 spin_unlock_bucket(gl->gl_hash); 225 spin_unlock_bucket(gl->gl_hash);
220 spin_lock(&lru_lock); 226 gfs2_glock_remove_from_lru(gl);
221 if (!list_empty(&gl->gl_lru)) {
222 list_del_init(&gl->gl_lru);
223 atomic_dec(&lru_count);
224 }
225 spin_unlock(&lru_lock);
226 GLOCK_BUG_ON(gl, !list_empty(&gl->gl_holders)); 227 GLOCK_BUG_ON(gl, !list_empty(&gl->gl_holders));
227 GLOCK_BUG_ON(gl, mapping && mapping->nrpages); 228 GLOCK_BUG_ON(gl, mapping && mapping->nrpages);
228 trace_gfs2_glock_put(gl); 229 trace_gfs2_glock_put(gl);
@@ -1025,6 +1026,9 @@ int gfs2_glock_nq(struct gfs2_holder *gh)
1025 if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) 1026 if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags)))
1026 return -EIO; 1027 return -EIO;
1027 1028
1029 if (test_bit(GLF_LRU, &gl->gl_flags))
1030 gfs2_glock_remove_from_lru(gl);
1031
1028 spin_lock(&gl->gl_spin); 1032 spin_lock(&gl->gl_spin);
1029 add_to_queue(gh); 1033 add_to_queue(gh);
1030 if ((LM_FLAG_NOEXP & gh->gh_flags) && 1034 if ((LM_FLAG_NOEXP & gh->gh_flags) &&
@@ -1082,7 +1086,8 @@ void gfs2_glock_dq(struct gfs2_holder *gh)
1082 !test_bit(GLF_DEMOTE, &gl->gl_flags)) 1086 !test_bit(GLF_DEMOTE, &gl->gl_flags))
1083 fast_path = 1; 1087 fast_path = 1;
1084 } 1088 }
1085 __gfs2_glock_schedule_for_reclaim(gl); 1089 if (!test_bit(GLF_LFLUSH, &gl->gl_flags))
1090 __gfs2_glock_schedule_for_reclaim(gl);
1086 trace_gfs2_glock_queue(gh, 0); 1091 trace_gfs2_glock_queue(gh, 0);
1087 spin_unlock(&gl->gl_spin); 1092 spin_unlock(&gl->gl_spin);
1088 if (likely(fast_path)) 1093 if (likely(fast_path))
@@ -1461,12 +1466,7 @@ static void thaw_glock(struct gfs2_glock *gl)
1461 1466
1462static void clear_glock(struct gfs2_glock *gl) 1467static void clear_glock(struct gfs2_glock *gl)
1463{ 1468{
1464 spin_lock(&lru_lock); 1469 gfs2_glock_remove_from_lru(gl);
1465 if (!list_empty(&gl->gl_lru)) {
1466 list_del_init(&gl->gl_lru);
1467 atomic_dec(&lru_count);
1468 }
1469 spin_unlock(&lru_lock);
1470 1470
1471 spin_lock(&gl->gl_spin); 1471 spin_lock(&gl->gl_spin);
1472 if (gl->gl_state != LM_ST_UNLOCKED) 1472 if (gl->gl_state != LM_ST_UNLOCKED)
@@ -1666,7 +1666,7 @@ static int __dump_glock(struct seq_file *seq, const struct gfs2_glock *gl)
1666 dtime *= 1000000/HZ; /* demote time in uSec */ 1666 dtime *= 1000000/HZ; /* demote time in uSec */
1667 if (!test_bit(GLF_DEMOTE, &gl->gl_flags)) 1667 if (!test_bit(GLF_DEMOTE, &gl->gl_flags))
1668 dtime = 0; 1668 dtime = 0;
1669 gfs2_print_dbg(seq, "G: s:%s n:%u/%llx f:%s t:%s d:%s/%llu a:%d r:%d\n", 1669 gfs2_print_dbg(seq, "G: s:%s n:%u/%llx f:%s t:%s d:%s/%llu a:%d v:%d r:%d\n",
1670 state2str(gl->gl_state), 1670 state2str(gl->gl_state),
1671 gl->gl_name.ln_type, 1671 gl->gl_name.ln_type,
1672 (unsigned long long)gl->gl_name.ln_number, 1672 (unsigned long long)gl->gl_name.ln_number,
@@ -1674,6 +1674,7 @@ static int __dump_glock(struct seq_file *seq, const struct gfs2_glock *gl)
1674 state2str(gl->gl_target), 1674 state2str(gl->gl_target),
1675 state2str(gl->gl_demote_state), dtime, 1675 state2str(gl->gl_demote_state), dtime,
1676 atomic_read(&gl->gl_ail_count), 1676 atomic_read(&gl->gl_ail_count),
1677 atomic_read(&gl->gl_revokes),
1677 atomic_read(&gl->gl_ref)); 1678 atomic_read(&gl->gl_ref));
1678 1679
1679 list_for_each_entry(gh, &gl->gl_holders, gh_list) { 1680 list_for_each_entry(gh, &gl->gl_holders, gh_list) {
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index 48eb1eed51b5..5067beaffa68 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -236,6 +236,7 @@ struct gfs2_glock {
236 236
237 struct list_head gl_ail_list; 237 struct list_head gl_ail_list;
238 atomic_t gl_ail_count; 238 atomic_t gl_ail_count;
239 atomic_t gl_revokes;
239 struct delayed_work gl_work; 240 struct delayed_work gl_work;
240 struct work_struct gl_delete; 241 struct work_struct gl_delete;
241 struct rcu_head gl_rcu; 242 struct rcu_head gl_rcu;
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 9134dcb89479..9b7b9e40073b 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -341,65 +341,6 @@ int gfs2_inode_refresh(struct gfs2_inode *ip)
341 return error; 341 return error;
342} 342}
343 343
344int gfs2_dinode_dealloc(struct gfs2_inode *ip)
345{
346 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
347 struct gfs2_alloc *al;
348 struct gfs2_rgrpd *rgd;
349 int error;
350
351 if (gfs2_get_inode_blocks(&ip->i_inode) != 1) {
352 if (gfs2_consist_inode(ip))
353 gfs2_dinode_print(ip);
354 return -EIO;
355 }
356
357 al = gfs2_alloc_get(ip);
358 if (!al)
359 return -ENOMEM;
360
361 error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE);
362 if (error)
363 goto out;
364
365 error = gfs2_rindex_hold(sdp, &al->al_ri_gh);
366 if (error)
367 goto out_qs;
368
369 rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr);
370 if (!rgd) {
371 gfs2_consist_inode(ip);
372 error = -EIO;
373 goto out_rindex_relse;
374 }
375
376 error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0,
377 &al->al_rgd_gh);
378 if (error)
379 goto out_rindex_relse;
380
381 error = gfs2_trans_begin(sdp, RES_RG_BIT + RES_STATFS + RES_QUOTA, 1);
382 if (error)
383 goto out_rg_gunlock;
384
385 set_bit(GLF_DIRTY, &ip->i_gl->gl_flags);
386 set_bit(GLF_LFLUSH, &ip->i_gl->gl_flags);
387
388 gfs2_free_di(rgd, ip);
389
390 gfs2_trans_end(sdp);
391
392out_rg_gunlock:
393 gfs2_glock_dq_uninit(&al->al_rgd_gh);
394out_rindex_relse:
395 gfs2_glock_dq_uninit(&al->al_ri_gh);
396out_qs:
397 gfs2_quota_unhold(ip);
398out:
399 gfs2_alloc_put(ip);
400 return error;
401}
402
403/** 344/**
404 * gfs2_change_nlink - Change nlink count on inode 345 * gfs2_change_nlink - Change nlink count on inode
405 * @ip: The GFS2 inode 346 * @ip: The GFS2 inode
diff --git a/fs/gfs2/inode.h b/fs/gfs2/inode.h
index 099ca305e518..842346eae836 100644
--- a/fs/gfs2/inode.h
+++ b/fs/gfs2/inode.h
@@ -106,7 +106,6 @@ extern struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr);
106 106
107extern int gfs2_inode_refresh(struct gfs2_inode *ip); 107extern int gfs2_inode_refresh(struct gfs2_inode *ip);
108 108
109extern int gfs2_dinode_dealloc(struct gfs2_inode *inode);
110extern int gfs2_change_nlink(struct gfs2_inode *ip, int diff); 109extern int gfs2_change_nlink(struct gfs2_inode *ip, int diff);
111extern struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name, 110extern struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name,
112 int is_root); 111 int is_root);
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c
index 611a51d476b2..05bbb124699f 100644
--- a/fs/gfs2/lops.c
+++ b/fs/gfs2/lops.c
@@ -320,12 +320,16 @@ static void buf_lo_after_scan(struct gfs2_jdesc *jd, int error, int pass)
320 320
321static void revoke_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le) 321static void revoke_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le)
322{ 322{
323 struct gfs2_bufdata *bd = container_of(le, struct gfs2_bufdata, bd_le);
324 struct gfs2_glock *gl = bd->bd_gl;
323 struct gfs2_trans *tr; 325 struct gfs2_trans *tr;
324 326
325 tr = current->journal_info; 327 tr = current->journal_info;
326 tr->tr_touched = 1; 328 tr->tr_touched = 1;
327 tr->tr_num_revoke++; 329 tr->tr_num_revoke++;
328 sdp->sd_log_num_revoke++; 330 sdp->sd_log_num_revoke++;
331 atomic_inc(&gl->gl_revokes);
332 set_bit(GLF_LFLUSH, &gl->gl_flags);
329 list_add(&le->le_list, &sdp->sd_log_le_revoke); 333 list_add(&le->le_list, &sdp->sd_log_le_revoke);
330} 334}
331 335
@@ -348,9 +352,7 @@ static void revoke_lo_before_commit(struct gfs2_sbd *sdp)
348 ld->ld_data1 = cpu_to_be32(sdp->sd_log_num_revoke); 352 ld->ld_data1 = cpu_to_be32(sdp->sd_log_num_revoke);
349 offset = sizeof(struct gfs2_log_descriptor); 353 offset = sizeof(struct gfs2_log_descriptor);
350 354
351 while (!list_empty(head)) { 355 list_for_each_entry(bd, head, bd_le.le_list) {
352 bd = list_entry(head->next, struct gfs2_bufdata, bd_le.le_list);
353 list_del_init(&bd->bd_le.le_list);
354 sdp->sd_log_num_revoke--; 356 sdp->sd_log_num_revoke--;
355 357
356 if (offset + sizeof(u64) > sdp->sd_sb.sb_bsize) { 358 if (offset + sizeof(u64) > sdp->sd_sb.sb_bsize) {
@@ -365,8 +367,6 @@ static void revoke_lo_before_commit(struct gfs2_sbd *sdp)
365 } 367 }
366 368
367 *(__be64 *)(bh->b_data + offset) = cpu_to_be64(bd->bd_blkno); 369 *(__be64 *)(bh->b_data + offset) = cpu_to_be64(bd->bd_blkno);
368 kmem_cache_free(gfs2_bufdata_cachep, bd);
369
370 offset += sizeof(u64); 370 offset += sizeof(u64);
371 } 371 }
372 gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke); 372 gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke);
@@ -374,6 +374,22 @@ static void revoke_lo_before_commit(struct gfs2_sbd *sdp)
374 submit_bh(WRITE_SYNC, bh); 374 submit_bh(WRITE_SYNC, bh);
375} 375}
376 376
377static void revoke_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_ail *ai)
378{
379 struct list_head *head = &sdp->sd_log_le_revoke;
380 struct gfs2_bufdata *bd;
381 struct gfs2_glock *gl;
382
383 while (!list_empty(head)) {
384 bd = list_entry(head->next, struct gfs2_bufdata, bd_le.le_list);
385 list_del_init(&bd->bd_le.le_list);
386 gl = bd->bd_gl;
387 atomic_dec(&gl->gl_revokes);
388 clear_bit(GLF_LFLUSH, &gl->gl_flags);
389 kmem_cache_free(gfs2_bufdata_cachep, bd);
390 }
391}
392
377static void revoke_lo_before_scan(struct gfs2_jdesc *jd, 393static void revoke_lo_before_scan(struct gfs2_jdesc *jd,
378 struct gfs2_log_header_host *head, int pass) 394 struct gfs2_log_header_host *head, int pass)
379{ 395{
@@ -747,6 +763,7 @@ const struct gfs2_log_operations gfs2_buf_lops = {
747const struct gfs2_log_operations gfs2_revoke_lops = { 763const struct gfs2_log_operations gfs2_revoke_lops = {
748 .lo_add = revoke_lo_add, 764 .lo_add = revoke_lo_add,
749 .lo_before_commit = revoke_lo_before_commit, 765 .lo_before_commit = revoke_lo_before_commit,
766 .lo_after_commit = revoke_lo_after_commit,
750 .lo_before_scan = revoke_lo_before_scan, 767 .lo_before_scan = revoke_lo_before_scan,
751 .lo_scan_elements = revoke_lo_scan_elements, 768 .lo_scan_elements = revoke_lo_scan_elements,
752 .lo_after_scan = revoke_lo_after_scan, 769 .lo_after_scan = revoke_lo_after_scan,
diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c
index 888a5f5a1a58..cfa327d33194 100644
--- a/fs/gfs2/main.c
+++ b/fs/gfs2/main.c
@@ -53,6 +53,7 @@ static void gfs2_init_glock_once(void *foo)
53 INIT_LIST_HEAD(&gl->gl_lru); 53 INIT_LIST_HEAD(&gl->gl_lru);
54 INIT_LIST_HEAD(&gl->gl_ail_list); 54 INIT_LIST_HEAD(&gl->gl_ail_list);
55 atomic_set(&gl->gl_ail_count, 0); 55 atomic_set(&gl->gl_ail_count, 0);
56 atomic_set(&gl->gl_revokes, 0);
56} 57}
57 58
58static void gfs2_init_gl_aspace_once(void *foo) 59static void gfs2_init_gl_aspace_once(void *foo)
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: