aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/super.c
diff options
context:
space:
mode:
authorBenjamin Marzinski <bmarzins@redhat.com>2014-05-01 23:26:55 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2014-05-14 05:04:34 -0400
commit24972557b12ce8fd5b6c6847d0e2ee1837ddc13b (patch)
treefb82edff8bfab9d4d1c4df6dd7784dd3c9f85c1b /fs/gfs2/super.c
parent5a7c6690c2759d686d2c299402327e92ed92ab6c (diff)
GFS2: remove transaction glock
GFS2 has a transaction glock, which must be grabbed for every transaction, whose purpose is to deal with freezing the filesystem. Aside from this involving a large amount of locking, it is very easy to make the current fsfreeze code hang on unfreezing. This patch rewrites how gfs2 handles freezing the filesystem. The transaction glock is removed. In it's place is a freeze glock, which is cached (but not held) in a shared state by every node in the cluster when the filesystem is mounted. This lock only needs to be grabbed on freezing, and actions which need to be safe from freezing, like recovery. When a node wants to freeze the filesystem, it grabs this glock exclusively. When the freeze glock state changes on the nodes (either from shared to unlocked, or shared to exclusive), the filesystem does a special log flush. gfs2_log_flush() does all the work for flushing out the and shutting down the incore log, and then it tries to grab the freeze glock in a shared state again. Since the filesystem is stuck in gfs2_log_flush, no new transaction can start, and nothing can be written to disk. Unfreezing the filesytem simply involes dropping the freeze glock, allowing gfs2_log_flush() to grab and then release the shared lock, so it is cached for next time. However, in order for the unfreezing ioctl to occur, gfs2 needs to get a shared lock on the filesystem root directory inode to check permissions. If that glock has already been grabbed exclusively, fsfreeze will be unable to get the shared lock and unfreeze the filesystem. In order to allow the unfreeze, this patch makes gfs2 grab a shared lock on the filesystem root directory during the freeze, and hold it until it unfreezes the filesystem. The functions which need to grab a shared lock in order to allow the unfreeze ioctl to be issued now use the lock grabbed by the freeze code instead. The freeze and unfreeze code take care to make sure that this shared lock will not be dropped while another process is using it. Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com> Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/super.c')
-rw-r--r--fs/gfs2/super.c69
1 files changed, 43 insertions, 26 deletions
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index de8afad89e51..1319b5c4ec68 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -399,7 +399,7 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp)
399{ 399{
400 struct gfs2_inode *ip = GFS2_I(sdp->sd_jdesc->jd_inode); 400 struct gfs2_inode *ip = GFS2_I(sdp->sd_jdesc->jd_inode);
401 struct gfs2_glock *j_gl = ip->i_gl; 401 struct gfs2_glock *j_gl = ip->i_gl;
402 struct gfs2_holder t_gh; 402 struct gfs2_holder thaw_gh;
403 struct gfs2_log_header_host head; 403 struct gfs2_log_header_host head;
404 int error; 404 int error;
405 405
@@ -407,7 +407,8 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp)
407 if (error) 407 if (error)
408 return error; 408 return error;
409 409
410 error = gfs2_glock_nq_init(sdp->sd_trans_gl, LM_ST_SHARED, 0, &t_gh); 410 error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED, 0,
411 &thaw_gh);
411 if (error) 412 if (error)
412 goto fail_threads; 413 goto fail_threads;
413 414
@@ -433,13 +434,13 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp)
433 434
434 set_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags); 435 set_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags);
435 436
436 gfs2_glock_dq_uninit(&t_gh); 437 gfs2_glock_dq_uninit(&thaw_gh);
437 438
438 return 0; 439 return 0;
439 440
440fail: 441fail:
441 t_gh.gh_flags |= GL_NOCACHE; 442 thaw_gh.gh_flags |= GL_NOCACHE;
442 gfs2_glock_dq_uninit(&t_gh); 443 gfs2_glock_dq_uninit(&thaw_gh);
443fail_threads: 444fail_threads:
444 kthread_stop(sdp->sd_quotad_process); 445 kthread_stop(sdp->sd_quotad_process);
445 kthread_stop(sdp->sd_logd_process); 446 kthread_stop(sdp->sd_logd_process);
@@ -635,15 +636,21 @@ struct lfcc {
635 */ 636 */
636 637
637static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp, 638static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp,
638 struct gfs2_holder *t_gh) 639 struct gfs2_holder *freeze_gh)
639{ 640{
640 struct gfs2_inode *ip; 641 struct gfs2_inode *ip;
641 struct gfs2_jdesc *jd; 642 struct gfs2_jdesc *jd;
642 struct lfcc *lfcc; 643 struct lfcc *lfcc;
643 LIST_HEAD(list); 644 LIST_HEAD(list);
644 struct gfs2_log_header_host lh; 645 struct gfs2_log_header_host lh;
646 struct gfs2_inode *dip = GFS2_I(sdp->sd_root_dir->d_inode);
645 int error; 647 int error;
646 648
649 error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0,
650 &sdp->sd_freeze_root_gh);
651 if (error)
652 return error;
653 atomic_set(&sdp->sd_frozen_root, 1);
647 list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) { 654 list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) {
648 lfcc = kmalloc(sizeof(struct lfcc), GFP_KERNEL); 655 lfcc = kmalloc(sizeof(struct lfcc), GFP_KERNEL);
649 if (!lfcc) { 656 if (!lfcc) {
@@ -659,8 +666,8 @@ static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp,
659 list_add(&lfcc->list, &list); 666 list_add(&lfcc->list, &list);
660 } 667 }
661 668
662 error = gfs2_glock_nq_init(sdp->sd_trans_gl, LM_ST_DEFERRED, 669 error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_EXCLUSIVE,
663 GL_NOCACHE, t_gh); 670 GL_NOCACHE, freeze_gh);
664 671
665 list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) { 672 list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) {
666 error = gfs2_jdesc_check(jd); 673 error = gfs2_jdesc_check(jd);
@@ -676,7 +683,7 @@ static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp,
676 } 683 }
677 684
678 if (error) 685 if (error)
679 gfs2_glock_dq_uninit(t_gh); 686 gfs2_glock_dq_uninit(freeze_gh);
680 687
681out: 688out:
682 while (!list_empty(&list)) { 689 while (!list_empty(&list)) {
@@ -685,6 +692,11 @@ out:
685 gfs2_glock_dq_uninit(&lfcc->gh); 692 gfs2_glock_dq_uninit(&lfcc->gh);
686 kfree(lfcc); 693 kfree(lfcc);
687 } 694 }
695 if (error) {
696 atomic_dec(&sdp->sd_frozen_root);
697 wait_event(sdp->sd_frozen_root_wait, atomic_read(&sdp->sd_frozen_root) == 0);
698 gfs2_glock_dq_uninit(&sdp->sd_freeze_root_gh);
699 }
688 return error; 700 return error;
689} 701}
690 702
@@ -742,7 +754,7 @@ static int gfs2_write_inode(struct inode *inode, struct writeback_control *wbc)
742 int ret = 0; 754 int ret = 0;
743 755
744 if (wbc->sync_mode == WB_SYNC_ALL) 756 if (wbc->sync_mode == WB_SYNC_ALL)
745 gfs2_log_flush(GFS2_SB(inode), ip->i_gl); 757 gfs2_log_flush(GFS2_SB(inode), ip->i_gl, NORMAL_FLUSH);
746 if (bdi->dirty_exceeded) 758 if (bdi->dirty_exceeded)
747 gfs2_ail1_flush(sdp, wbc); 759 gfs2_ail1_flush(sdp, wbc);
748 else 760 else
@@ -822,9 +834,18 @@ out:
822 834
823static int gfs2_make_fs_ro(struct gfs2_sbd *sdp) 835static int gfs2_make_fs_ro(struct gfs2_sbd *sdp)
824{ 836{
825 struct gfs2_holder t_gh; 837 struct gfs2_holder thaw_gh;
826 int error; 838 int error;
827 839
840 error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED, GL_NOCACHE,
841 &thaw_gh);
842 if (error && !test_bit(SDF_SHUTDOWN, &sdp->sd_flags))
843 return error;
844
845 down_write(&sdp->sd_log_flush_lock);
846 clear_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags);
847 up_write(&sdp->sd_log_flush_lock);
848
828 kthread_stop(sdp->sd_quotad_process); 849 kthread_stop(sdp->sd_quotad_process);
829 kthread_stop(sdp->sd_logd_process); 850 kthread_stop(sdp->sd_logd_process);
830 851
@@ -832,18 +853,11 @@ static int gfs2_make_fs_ro(struct gfs2_sbd *sdp)
832 gfs2_quota_sync(sdp->sd_vfs, 0); 853 gfs2_quota_sync(sdp->sd_vfs, 0);
833 gfs2_statfs_sync(sdp->sd_vfs, 0); 854 gfs2_statfs_sync(sdp->sd_vfs, 0);
834 855
835 error = gfs2_glock_nq_init(sdp->sd_trans_gl, LM_ST_SHARED, GL_NOCACHE, 856 gfs2_log_flush(sdp, NULL, SHUTDOWN_FLUSH);
836 &t_gh); 857 gfs2_assert_warn(sdp, atomic_read(&sdp->sd_log_blks_free) == sdp->sd_jdesc->jd_blocks);
837 if (error && !test_bit(SDF_SHUTDOWN, &sdp->sd_flags))
838 return error;
839
840 gfs2_meta_syncfs(sdp);
841 gfs2_log_shutdown(sdp);
842
843 clear_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags);
844 858
845 if (t_gh.gh_gl) 859 if (thaw_gh.gh_gl)
846 gfs2_glock_dq_uninit(&t_gh); 860 gfs2_glock_dq_uninit(&thaw_gh);
847 861
848 gfs2_quota_cleanup(sdp); 862 gfs2_quota_cleanup(sdp);
849 863
@@ -900,7 +914,7 @@ restart:
900 iput(sdp->sd_quota_inode); 914 iput(sdp->sd_quota_inode);
901 915
902 gfs2_glock_put(sdp->sd_rename_gl); 916 gfs2_glock_put(sdp->sd_rename_gl);
903 gfs2_glock_put(sdp->sd_trans_gl); 917 gfs2_glock_put(sdp->sd_freeze_gl);
904 918
905 if (!sdp->sd_args.ar_spectator) { 919 if (!sdp->sd_args.ar_spectator) {
906 gfs2_glock_dq_uninit(&sdp->sd_journal_gh); 920 gfs2_glock_dq_uninit(&sdp->sd_journal_gh);
@@ -935,8 +949,8 @@ static int gfs2_sync_fs(struct super_block *sb, int wait)
935 struct gfs2_sbd *sdp = sb->s_fs_info; 949 struct gfs2_sbd *sdp = sb->s_fs_info;
936 950
937 gfs2_quota_sync(sb, -1); 951 gfs2_quota_sync(sb, -1);
938 if (wait && sdp) 952 if (wait && sdp && !atomic_read(&sdp->sd_log_freeze))
939 gfs2_log_flush(sdp, NULL); 953 gfs2_log_flush(sdp, NULL, NORMAL_FLUSH);
940 return 0; 954 return 0;
941} 955}
942 956
@@ -986,6 +1000,9 @@ static int gfs2_unfreeze(struct super_block *sb)
986 struct gfs2_sbd *sdp = sb->s_fs_info; 1000 struct gfs2_sbd *sdp = sb->s_fs_info;
987 1001
988 gfs2_glock_dq_uninit(&sdp->sd_freeze_gh); 1002 gfs2_glock_dq_uninit(&sdp->sd_freeze_gh);
1003 atomic_dec(&sdp->sd_frozen_root);
1004 wait_event(sdp->sd_frozen_root_wait, atomic_read(&sdp->sd_frozen_root) == 0);
1005 gfs2_glock_dq_uninit(&sdp->sd_freeze_root_gh);
989 return 0; 1006 return 0;
990} 1007}
991 1008
@@ -1525,7 +1542,7 @@ static void gfs2_evict_inode(struct inode *inode)
1525 goto out_unlock; 1542 goto out_unlock;
1526 1543
1527out_truncate: 1544out_truncate:
1528 gfs2_log_flush(sdp, ip->i_gl); 1545 gfs2_log_flush(sdp, ip->i_gl, NORMAL_FLUSH);
1529 if (test_bit(GLF_DIRTY, &ip->i_gl->gl_flags)) { 1546 if (test_bit(GLF_DIRTY, &ip->i_gl->gl_flags)) {
1530 struct address_space *metamapping = gfs2_glock2aspace(ip->i_gl); 1547 struct address_space *metamapping = gfs2_glock2aspace(ip->i_gl);
1531 filemap_fdatawrite(metamapping); 1548 filemap_fdatawrite(metamapping);