aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2
diff options
context:
space:
mode:
authorBenjamin Marzinski <bmarzins@redhat.com>2014-11-13 21:42:04 -0500
committerSteven Whitehouse <swhiteho@redhat.com>2014-11-17 05:36:39 -0500
commit2e60d7683c8d2ea21317f6d9f4cd3bf5428ce162 (patch)
treefc7900ad18814d1ea46879f93eab063ff5754d1e /fs/gfs2
parent48b6bca6b7b8309697fc8a101793befe92d249d9 (diff)
GFS2: update freeze code to use freeze/thaw_super on all nodes
The current gfs2 freezing code is considerably more complicated than it should be because it doesn't use the vfs freezing code on any node except the one that begins the freeze. This is because it needs to acquire a cluster glock before calling the vfs code to prevent a deadlock, and without the new freeze_super and thaw_super hooks, that was impossible. To deal with the issue, gfs2 had to do some hacky locking tricks to make sure that a frozen node couldn't be holding on a lock it needed to do the unfreeze ioctl. This patch makes use of the new hooks to simply the gfs2 locking code. Now, all the nodes in the cluster freeze and thaw in exactly the same way. Every node in the cluster caches the freeze glock in the shared state. The new freeze_super hook allows the freezing node to grab this freeze glock in the exclusive state without first calling the vfs freeze_super function. All the nodes in the cluster see this lock change, and call the vfs freeze_super function. The vfs locking code guarantees that the nodes can't get stuck holding the glocks necessary to unfreeze the system. To unfreeze, the freezing node uses the new thaw_super hook to drop the freeze glock. Again, all the nodes notice this, reacquire the glock in shared mode and call the vfs thaw_super function. Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com> Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2')
-rw-r--r--fs/gfs2/glops.c26
-rw-r--r--fs/gfs2/glops.h2
-rw-r--r--fs/gfs2/incore.h18
-rw-r--r--fs/gfs2/inode.c40
-rw-r--r--fs/gfs2/log.c42
-rw-r--r--fs/gfs2/main.c11
-rw-r--r--fs/gfs2/ops_fstype.c18
-rw-r--r--fs/gfs2/super.c112
-rw-r--r--fs/gfs2/super.h1
-rw-r--r--fs/gfs2/trans.c17
10 files changed, 161 insertions, 126 deletions
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
index 1cc0bba6313f..fe91951c3361 100644
--- a/fs/gfs2/glops.c
+++ b/fs/gfs2/glops.c
@@ -28,6 +28,8 @@
28#include "trans.h" 28#include "trans.h"
29#include "dir.h" 29#include "dir.h"
30 30
31struct workqueue_struct *gfs2_freeze_wq;
32
31static void gfs2_ail_error(struct gfs2_glock *gl, const struct buffer_head *bh) 33static void gfs2_ail_error(struct gfs2_glock *gl, const struct buffer_head *bh)
32{ 34{
33 fs_err(gl->gl_sbd, "AIL buffer %p: blocknr %llu state 0x%08lx mapping %p page state 0x%lx\n", 35 fs_err(gl->gl_sbd, "AIL buffer %p: blocknr %llu state 0x%08lx mapping %p page state 0x%lx\n",
@@ -94,11 +96,8 @@ static void gfs2_ail_empty_gl(struct gfs2_glock *gl)
94 * on the stack */ 96 * on the stack */
95 tr.tr_reserved = 1 + gfs2_struct2blk(sdp, tr.tr_revokes, sizeof(u64)); 97 tr.tr_reserved = 1 + gfs2_struct2blk(sdp, tr.tr_revokes, sizeof(u64));
96 tr.tr_ip = _RET_IP_; 98 tr.tr_ip = _RET_IP_;
97 sb_start_intwrite(sdp->sd_vfs); 99 if (gfs2_log_reserve(sdp, tr.tr_reserved) < 0)
98 if (gfs2_log_reserve(sdp, tr.tr_reserved) < 0) {
99 sb_end_intwrite(sdp->sd_vfs);
100 return; 100 return;
101 }
102 WARN_ON_ONCE(current->journal_info); 101 WARN_ON_ONCE(current->journal_info);
103 current->journal_info = &tr; 102 current->journal_info = &tr;
104 103
@@ -469,20 +468,19 @@ static void inode_go_dump(struct seq_file *seq, const struct gfs2_glock *gl)
469 468
470static void freeze_go_sync(struct gfs2_glock *gl) 469static void freeze_go_sync(struct gfs2_glock *gl)
471{ 470{
471 int error = 0;
472 struct gfs2_sbd *sdp = gl->gl_sbd; 472 struct gfs2_sbd *sdp = gl->gl_sbd;
473 DEFINE_WAIT(wait);
474 473
475 if (gl->gl_state == LM_ST_SHARED && 474 if (gl->gl_state == LM_ST_SHARED &&
476 test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) { 475 test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) {
477 atomic_set(&sdp->sd_log_freeze, 1); 476 atomic_set(&sdp->sd_freeze_state, SFS_STARTING_FREEZE);
478 wake_up(&sdp->sd_logd_waitq); 477 error = freeze_super(sdp->sd_vfs);
479 do { 478 if (error) {
480 prepare_to_wait(&sdp->sd_log_frozen_wait, &wait, 479 printk(KERN_INFO "GFS2: couldn't freeze filesystem: %d\n", error);
481 TASK_UNINTERRUPTIBLE); 480 gfs2_assert_withdraw(sdp, 0);
482 if (atomic_read(&sdp->sd_log_freeze)) 481 }
483 io_schedule(); 482 queue_work(gfs2_freeze_wq, &sdp->sd_freeze_work);
484 } while(atomic_read(&sdp->sd_log_freeze)); 483 gfs2_log_flush(sdp, NULL, FREEZE_FLUSH);
485 finish_wait(&sdp->sd_log_frozen_wait, &wait);
486 } 484 }
487} 485}
488 486
diff --git a/fs/gfs2/glops.h b/fs/gfs2/glops.h
index 7455d2629bcb..8ed1857c1a8d 100644
--- a/fs/gfs2/glops.h
+++ b/fs/gfs2/glops.h
@@ -12,6 +12,8 @@
12 12
13#include "incore.h" 13#include "incore.h"
14 14
15extern struct workqueue_struct *gfs2_freeze_wq;
16
15extern const struct gfs2_glock_operations gfs2_meta_glops; 17extern const struct gfs2_glock_operations gfs2_meta_glops;
16extern const struct gfs2_glock_operations gfs2_inode_glops; 18extern const struct gfs2_glock_operations gfs2_inode_glops;
17extern const struct gfs2_glock_operations gfs2_rgrp_glops; 19extern const struct gfs2_glock_operations gfs2_rgrp_glops;
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index 1b899187be5a..7a2dbbc0d634 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -588,6 +588,12 @@ enum {
588 SDF_SKIP_DLM_UNLOCK = 8, 588 SDF_SKIP_DLM_UNLOCK = 8,
589}; 589};
590 590
591enum gfs2_freeze_state {
592 SFS_UNFROZEN = 0,
593 SFS_STARTING_FREEZE = 1,
594 SFS_FROZEN = 2,
595};
596
591#define GFS2_FSNAME_LEN 256 597#define GFS2_FSNAME_LEN 256
592 598
593struct gfs2_inum_host { 599struct gfs2_inum_host {
@@ -685,6 +691,7 @@ struct gfs2_sbd {
685 struct gfs2_holder sd_live_gh; 691 struct gfs2_holder sd_live_gh;
686 struct gfs2_glock *sd_rename_gl; 692 struct gfs2_glock *sd_rename_gl;
687 struct gfs2_glock *sd_freeze_gl; 693 struct gfs2_glock *sd_freeze_gl;
694 struct work_struct sd_freeze_work;
688 wait_queue_head_t sd_glock_wait; 695 wait_queue_head_t sd_glock_wait;
689 atomic_t sd_glock_disposal; 696 atomic_t sd_glock_disposal;
690 struct completion sd_locking_init; 697 struct completion sd_locking_init;
@@ -789,6 +796,9 @@ struct gfs2_sbd {
789 wait_queue_head_t sd_log_flush_wait; 796 wait_queue_head_t sd_log_flush_wait;
790 int sd_log_error; 797 int sd_log_error;
791 798
799 atomic_t sd_reserving_log;
800 wait_queue_head_t sd_reserving_log_wait;
801
792 unsigned int sd_log_flush_head; 802 unsigned int sd_log_flush_head;
793 u64 sd_log_flush_wrapped; 803 u64 sd_log_flush_wrapped;
794 804
@@ -798,12 +808,8 @@ struct gfs2_sbd {
798 808
799 /* For quiescing the filesystem */ 809 /* For quiescing the filesystem */
800 struct gfs2_holder sd_freeze_gh; 810 struct gfs2_holder sd_freeze_gh;
801 struct gfs2_holder sd_freeze_root_gh; 811 atomic_t sd_freeze_state;
802 struct gfs2_holder sd_thaw_gh; 812 struct mutex sd_freeze_mutex;
803 atomic_t sd_log_freeze;
804 atomic_t sd_frozen_root;
805 wait_queue_head_t sd_frozen_root_wait;
806 wait_queue_head_t sd_log_frozen_wait;
807 813
808 char sd_fsname[GFS2_FSNAME_LEN]; 814 char sd_fsname[GFS2_FSNAME_LEN];
809 char sd_table_name[GFS2_FSNAME_LEN]; 815 char sd_table_name[GFS2_FSNAME_LEN];
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index b41b5c7898da..04065e5af4b6 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -1618,26 +1618,18 @@ int gfs2_permission(struct inode *inode, int mask)
1618{ 1618{
1619 struct gfs2_inode *ip; 1619 struct gfs2_inode *ip;
1620 struct gfs2_holder i_gh; 1620 struct gfs2_holder i_gh;
1621 struct gfs2_sbd *sdp = GFS2_SB(inode);
1622 int error; 1621 int error;
1623 int unlock = 0; 1622 int unlock = 0;
1624 int frozen_root = 0;
1625 1623
1626 1624
1627 ip = GFS2_I(inode); 1625 ip = GFS2_I(inode);
1628 if (gfs2_glock_is_locked_by_me(ip->i_gl) == NULL) { 1626 if (gfs2_glock_is_locked_by_me(ip->i_gl) == NULL) {
1629 if (unlikely(gfs2_glock_is_held_excl(sdp->sd_freeze_gl) && 1627 if (mask & MAY_NOT_BLOCK)
1630 inode == sdp->sd_root_dir->d_inode && 1628 return -ECHILD;
1631 atomic_inc_not_zero(&sdp->sd_frozen_root))) 1629 error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh);
1632 frozen_root = 1; 1630 if (error)
1633 else { 1631 return error;
1634 if (mask & MAY_NOT_BLOCK) 1632 unlock = 1;
1635 return -ECHILD;
1636 error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh);
1637 if (error)
1638 return error;
1639 unlock = 1;
1640 }
1641 } 1633 }
1642 1634
1643 if ((mask & MAY_WRITE) && IS_IMMUTABLE(inode)) 1635 if ((mask & MAY_WRITE) && IS_IMMUTABLE(inode))
@@ -1646,8 +1638,6 @@ int gfs2_permission(struct inode *inode, int mask)
1646 error = generic_permission(inode, mask); 1638 error = generic_permission(inode, mask);
1647 if (unlock) 1639 if (unlock)
1648 gfs2_glock_dq_uninit(&i_gh); 1640 gfs2_glock_dq_uninit(&i_gh);
1649 else if (frozen_root && atomic_dec_and_test(&sdp->sd_frozen_root))
1650 wake_up(&sdp->sd_frozen_root_wait);
1651 1641
1652 return error; 1642 return error;
1653} 1643}
@@ -1820,29 +1810,19 @@ static int gfs2_getattr(struct vfsmount *mnt, struct dentry *dentry,
1820 struct inode *inode = dentry->d_inode; 1810 struct inode *inode = dentry->d_inode;
1821 struct gfs2_inode *ip = GFS2_I(inode); 1811 struct gfs2_inode *ip = GFS2_I(inode);
1822 struct gfs2_holder gh; 1812 struct gfs2_holder gh;
1823 struct gfs2_sbd *sdp = GFS2_SB(inode);
1824 int error; 1813 int error;
1825 int unlock = 0; 1814 int unlock = 0;
1826 int frozen_root = 0;
1827 1815
1828 if (gfs2_glock_is_locked_by_me(ip->i_gl) == NULL) { 1816 if (gfs2_glock_is_locked_by_me(ip->i_gl) == NULL) {
1829 if (unlikely(gfs2_glock_is_held_excl(sdp->sd_freeze_gl) && 1817 error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &gh);
1830 inode == sdp->sd_root_dir->d_inode && 1818 if (error)
1831 atomic_inc_not_zero(&sdp->sd_frozen_root))) 1819 return error;
1832 frozen_root = 1; 1820 unlock = 1;
1833 else {
1834 error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &gh);
1835 if (error)
1836 return error;
1837 unlock = 1;
1838 }
1839 } 1821 }
1840 1822
1841 generic_fillattr(inode, stat); 1823 generic_fillattr(inode, stat);
1842 if (unlock) 1824 if (unlock)
1843 gfs2_glock_dq_uninit(&gh); 1825 gfs2_glock_dq_uninit(&gh);
1844 else if (frozen_root && atomic_dec_and_test(&sdp->sd_frozen_root))
1845 wake_up(&sdp->sd_frozen_root_wait);
1846 1826
1847 return 0; 1827 return 0;
1848} 1828}
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
index 3966fadbcebd..536e7a6252cd 100644
--- a/fs/gfs2/log.c
+++ b/fs/gfs2/log.c
@@ -339,6 +339,7 @@ void gfs2_log_release(struct gfs2_sbd *sdp, unsigned int blks)
339 339
340int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks) 340int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks)
341{ 341{
342 int ret = 0;
342 unsigned reserved_blks = 7 * (4096 / sdp->sd_vfs->s_blocksize); 343 unsigned reserved_blks = 7 * (4096 / sdp->sd_vfs->s_blocksize);
343 unsigned wanted = blks + reserved_blks; 344 unsigned wanted = blks + reserved_blks;
344 DEFINE_WAIT(wait); 345 DEFINE_WAIT(wait);
@@ -362,9 +363,13 @@ retry:
362 } while(free_blocks <= wanted); 363 } while(free_blocks <= wanted);
363 finish_wait(&sdp->sd_log_waitq, &wait); 364 finish_wait(&sdp->sd_log_waitq, &wait);
364 } 365 }
366 atomic_inc(&sdp->sd_reserving_log);
365 if (atomic_cmpxchg(&sdp->sd_log_blks_free, free_blocks, 367 if (atomic_cmpxchg(&sdp->sd_log_blks_free, free_blocks,
366 free_blocks - blks) != free_blocks) 368 free_blocks - blks) != free_blocks) {
369 if (atomic_dec_and_test(&sdp->sd_reserving_log))
370 wake_up(&sdp->sd_reserving_log_wait);
367 goto retry; 371 goto retry;
372 }
368 trace_gfs2_log_blocks(sdp, -blks); 373 trace_gfs2_log_blocks(sdp, -blks);
369 374
370 /* 375 /*
@@ -377,9 +382,11 @@ retry:
377 down_read(&sdp->sd_log_flush_lock); 382 down_read(&sdp->sd_log_flush_lock);
378 if (unlikely(!test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags))) { 383 if (unlikely(!test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags))) {
379 gfs2_log_release(sdp, blks); 384 gfs2_log_release(sdp, blks);
380 return -EROFS; 385 ret = -EROFS;
381 } 386 }
382 return 0; 387 if (atomic_dec_and_test(&sdp->sd_reserving_log))
388 wake_up(&sdp->sd_reserving_log_wait);
389 return ret;
383} 390}
384 391
385/** 392/**
@@ -652,9 +659,12 @@ static void log_write_header(struct gfs2_sbd *sdp, u32 flags)
652 u32 hash; 659 u32 hash;
653 int rw = WRITE_FLUSH_FUA | REQ_META; 660 int rw = WRITE_FLUSH_FUA | REQ_META;
654 struct page *page = mempool_alloc(gfs2_page_pool, GFP_NOIO); 661 struct page *page = mempool_alloc(gfs2_page_pool, GFP_NOIO);
662 enum gfs2_freeze_state state = atomic_read(&sdp->sd_freeze_state);
655 lh = page_address(page); 663 lh = page_address(page);
656 clear_page(lh); 664 clear_page(lh);
657 665
666 gfs2_assert_withdraw(sdp, (state != SFS_FROZEN));
667
658 tail = current_tail(sdp); 668 tail = current_tail(sdp);
659 669
660 lh->lh_header.mh_magic = cpu_to_be32(GFS2_MAGIC); 670 lh->lh_header.mh_magic = cpu_to_be32(GFS2_MAGIC);
@@ -695,6 +705,7 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl,
695 enum gfs2_flush_type type) 705 enum gfs2_flush_type type)
696{ 706{
697 struct gfs2_trans *tr; 707 struct gfs2_trans *tr;
708 enum gfs2_freeze_state state = atomic_read(&sdp->sd_freeze_state);
698 709
699 down_write(&sdp->sd_log_flush_lock); 710 down_write(&sdp->sd_log_flush_lock);
700 711
@@ -713,8 +724,12 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl,
713 INIT_LIST_HEAD(&tr->tr_ail1_list); 724 INIT_LIST_HEAD(&tr->tr_ail1_list);
714 INIT_LIST_HEAD(&tr->tr_ail2_list); 725 INIT_LIST_HEAD(&tr->tr_ail2_list);
715 tr->tr_first = sdp->sd_log_flush_head; 726 tr->tr_first = sdp->sd_log_flush_head;
727 if (unlikely (state == SFS_FROZEN))
728 gfs2_assert_withdraw(sdp, !tr->tr_num_buf_new && !tr->tr_num_databuf_new);
716 } 729 }
717 730
731 if (unlikely(state == SFS_FROZEN))
732 gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke);
718 gfs2_assert_withdraw(sdp, 733 gfs2_assert_withdraw(sdp,
719 sdp->sd_log_num_revoke == sdp->sd_log_commited_revoke); 734 sdp->sd_log_num_revoke == sdp->sd_log_commited_revoke);
720 735
@@ -745,8 +760,6 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl,
745 spin_unlock(&sdp->sd_ail_lock); 760 spin_unlock(&sdp->sd_ail_lock);
746 gfs2_log_unlock(sdp); 761 gfs2_log_unlock(sdp);
747 762
748 if (atomic_read(&sdp->sd_log_freeze))
749 type = FREEZE_FLUSH;
750 if (type != NORMAL_FLUSH) { 763 if (type != NORMAL_FLUSH) {
751 if (!sdp->sd_log_idle) { 764 if (!sdp->sd_log_idle) {
752 for (;;) { 765 for (;;) {
@@ -763,21 +776,8 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl,
763 } 776 }
764 if (type == SHUTDOWN_FLUSH || type == FREEZE_FLUSH) 777 if (type == SHUTDOWN_FLUSH || type == FREEZE_FLUSH)
765 gfs2_log_shutdown(sdp); 778 gfs2_log_shutdown(sdp);
766 if (type == FREEZE_FLUSH) { 779 if (type == FREEZE_FLUSH)
767 int error; 780 atomic_set(&sdp->sd_freeze_state, SFS_FROZEN);
768
769 atomic_set(&sdp->sd_log_freeze, 0);
770 wake_up(&sdp->sd_log_frozen_wait);
771 error = gfs2_glock_nq_init(sdp->sd_freeze_gl,
772 LM_ST_SHARED, 0,
773 &sdp->sd_thaw_gh);
774 if (error) {
775 printk(KERN_INFO "GFS2: couln't get freeze lock : %d\n", error);
776 gfs2_assert_withdraw(sdp, 0);
777 }
778 else
779 gfs2_glock_dq_uninit(&sdp->sd_thaw_gh);
780 }
781 } 781 }
782 782
783 trace_gfs2_log_flush(sdp, 0); 783 trace_gfs2_log_flush(sdp, 0);
@@ -888,7 +888,7 @@ void gfs2_log_shutdown(struct gfs2_sbd *sdp)
888 888
889static inline int gfs2_jrnl_flush_reqd(struct gfs2_sbd *sdp) 889static inline int gfs2_jrnl_flush_reqd(struct gfs2_sbd *sdp)
890{ 890{
891 return (atomic_read(&sdp->sd_log_pinned) >= atomic_read(&sdp->sd_log_thresh1) || atomic_read(&sdp->sd_log_freeze)); 891 return (atomic_read(&sdp->sd_log_pinned) >= atomic_read(&sdp->sd_log_thresh1));
892} 892}
893 893
894static inline int gfs2_ail_flush_reqd(struct gfs2_sbd *sdp) 894static inline int gfs2_ail_flush_reqd(struct gfs2_sbd *sdp)
diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c
index 82b6ac829656..241a399bf83d 100644
--- a/fs/gfs2/main.c
+++ b/fs/gfs2/main.c
@@ -30,6 +30,7 @@
30#include "quota.h" 30#include "quota.h"
31#include "recovery.h" 31#include "recovery.h"
32#include "dir.h" 32#include "dir.h"
33#include "glops.h"
33 34
34struct workqueue_struct *gfs2_control_wq; 35struct workqueue_struct *gfs2_control_wq;
35 36
@@ -161,9 +162,14 @@ static int __init init_gfs2_fs(void)
161 if (!gfs2_control_wq) 162 if (!gfs2_control_wq)
162 goto fail_recovery; 163 goto fail_recovery;
163 164
165 gfs2_freeze_wq = alloc_workqueue("freeze_workqueue", 0, 0);
166
167 if (!gfs2_freeze_wq)
168 goto fail_control;
169
164 gfs2_page_pool = mempool_create_page_pool(64, 0); 170 gfs2_page_pool = mempool_create_page_pool(64, 0);
165 if (!gfs2_page_pool) 171 if (!gfs2_page_pool)
166 goto fail_control; 172 goto fail_freeze;
167 173
168 gfs2_register_debugfs(); 174 gfs2_register_debugfs();
169 175
@@ -171,6 +177,8 @@ static int __init init_gfs2_fs(void)
171 177
172 return 0; 178 return 0;
173 179
180fail_freeze:
181 destroy_workqueue(gfs2_freeze_wq);
174fail_control: 182fail_control:
175 destroy_workqueue(gfs2_control_wq); 183 destroy_workqueue(gfs2_control_wq);
176fail_recovery: 184fail_recovery:
@@ -224,6 +232,7 @@ static void __exit exit_gfs2_fs(void)
224 unregister_filesystem(&gfs2meta_fs_type); 232 unregister_filesystem(&gfs2meta_fs_type);
225 destroy_workqueue(gfs_recovery_wq); 233 destroy_workqueue(gfs_recovery_wq);
226 destroy_workqueue(gfs2_control_wq); 234 destroy_workqueue(gfs2_control_wq);
235 destroy_workqueue(gfs2_freeze_wq);
227 list_lru_destroy(&gfs2_qd_lru); 236 list_lru_destroy(&gfs2_qd_lru);
228 237
229 rcu_barrier(); 238 rcu_barrier();
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index d3eae244076e..b5803acb8818 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -129,11 +129,11 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb)
129 129
130 init_rwsem(&sdp->sd_log_flush_lock); 130 init_rwsem(&sdp->sd_log_flush_lock);
131 atomic_set(&sdp->sd_log_in_flight, 0); 131 atomic_set(&sdp->sd_log_in_flight, 0);
132 atomic_set(&sdp->sd_reserving_log, 0);
133 init_waitqueue_head(&sdp->sd_reserving_log_wait);
132 init_waitqueue_head(&sdp->sd_log_flush_wait); 134 init_waitqueue_head(&sdp->sd_log_flush_wait);
133 init_waitqueue_head(&sdp->sd_log_frozen_wait); 135 atomic_set(&sdp->sd_freeze_state, SFS_UNFROZEN);
134 atomic_set(&sdp->sd_log_freeze, 0); 136 mutex_init(&sdp->sd_freeze_mutex);
135 atomic_set(&sdp->sd_frozen_root, 0);
136 init_waitqueue_head(&sdp->sd_frozen_root_wait);
137 137
138 return sdp; 138 return sdp;
139} 139}
@@ -760,15 +760,7 @@ static int init_journal(struct gfs2_sbd *sdp, int undo)
760 set_bit(SDF_JOURNAL_CHECKED, &sdp->sd_flags); 760 set_bit(SDF_JOURNAL_CHECKED, &sdp->sd_flags);
761 gfs2_glock_dq_uninit(&ji_gh); 761 gfs2_glock_dq_uninit(&ji_gh);
762 jindex = 0; 762 jindex = 0;
763 if (!sdp->sd_args.ar_spectator) { 763 INIT_WORK(&sdp->sd_freeze_work, gfs2_freeze_func);
764 error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED, 0,
765 &sdp->sd_thaw_gh);
766 if (error) {
767 fs_err(sdp, "can't acquire freeze glock: %d\n", error);
768 goto fail_jinode_gh;
769 }
770 }
771 gfs2_glock_dq_uninit(&sdp->sd_thaw_gh);
772 return 0; 764 return 0;
773 765
774fail_jinode_gh: 766fail_jinode_gh:
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index a346f56c4c6d..5b327f837de7 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -26,6 +26,7 @@
26#include <linux/wait.h> 26#include <linux/wait.h>
27#include <linux/writeback.h> 27#include <linux/writeback.h>
28#include <linux/backing-dev.h> 28#include <linux/backing-dev.h>
29#include <linux/kernel.h>
29 30
30#include "gfs2.h" 31#include "gfs2.h"
31#include "incore.h" 32#include "incore.h"
@@ -399,7 +400,7 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp)
399{ 400{
400 struct gfs2_inode *ip = GFS2_I(sdp->sd_jdesc->jd_inode); 401 struct gfs2_inode *ip = GFS2_I(sdp->sd_jdesc->jd_inode);
401 struct gfs2_glock *j_gl = ip->i_gl; 402 struct gfs2_glock *j_gl = ip->i_gl;
402 struct gfs2_holder thaw_gh; 403 struct gfs2_holder freeze_gh;
403 struct gfs2_log_header_host head; 404 struct gfs2_log_header_host head;
404 int error; 405 int error;
405 406
@@ -408,7 +409,7 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp)
408 return error; 409 return error;
409 410
410 error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED, 0, 411 error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED, 0,
411 &thaw_gh); 412 &freeze_gh);
412 if (error) 413 if (error)
413 goto fail_threads; 414 goto fail_threads;
414 415
@@ -434,13 +435,13 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp)
434 435
435 set_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags); 436 set_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags);
436 437
437 gfs2_glock_dq_uninit(&thaw_gh); 438 gfs2_glock_dq_uninit(&freeze_gh);
438 439
439 return 0; 440 return 0;
440 441
441fail: 442fail:
442 thaw_gh.gh_flags |= GL_NOCACHE; 443 freeze_gh.gh_flags |= GL_NOCACHE;
443 gfs2_glock_dq_uninit(&thaw_gh); 444 gfs2_glock_dq_uninit(&freeze_gh);
444fail_threads: 445fail_threads:
445 kthread_stop(sdp->sd_quotad_process); 446 kthread_stop(sdp->sd_quotad_process);
446 kthread_stop(sdp->sd_logd_process); 447 kthread_stop(sdp->sd_logd_process);
@@ -580,14 +581,15 @@ int gfs2_statfs_sync(struct super_block *sb, int type)
580 struct buffer_head *m_bh, *l_bh; 581 struct buffer_head *m_bh, *l_bh;
581 int error; 582 int error;
582 583
584 sb_start_write(sb);
583 error = gfs2_glock_nq_init(m_ip->i_gl, LM_ST_EXCLUSIVE, GL_NOCACHE, 585 error = gfs2_glock_nq_init(m_ip->i_gl, LM_ST_EXCLUSIVE, GL_NOCACHE,
584 &gh); 586 &gh);
585 if (error) 587 if (error)
586 return error; 588 goto out;
587 589
588 error = gfs2_meta_inode_buffer(m_ip, &m_bh); 590 error = gfs2_meta_inode_buffer(m_ip, &m_bh);
589 if (error) 591 if (error)
590 goto out; 592 goto out_unlock;
591 593
592 spin_lock(&sdp->sd_statfs_spin); 594 spin_lock(&sdp->sd_statfs_spin);
593 gfs2_statfs_change_in(m_sc, m_bh->b_data + 595 gfs2_statfs_change_in(m_sc, m_bh->b_data +
@@ -615,8 +617,10 @@ out_bh2:
615 brelse(l_bh); 617 brelse(l_bh);
616out_bh: 618out_bh:
617 brelse(m_bh); 619 brelse(m_bh);
618out: 620out_unlock:
619 gfs2_glock_dq_uninit(&gh); 621 gfs2_glock_dq_uninit(&gh);
622out:
623 sb_end_write(sb);
620 return error; 624 return error;
621} 625}
622 626
@@ -643,14 +647,8 @@ static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp,
643 struct lfcc *lfcc; 647 struct lfcc *lfcc;
644 LIST_HEAD(list); 648 LIST_HEAD(list);
645 struct gfs2_log_header_host lh; 649 struct gfs2_log_header_host lh;
646 struct gfs2_inode *dip = GFS2_I(sdp->sd_root_dir->d_inode);
647 int error; 650 int error;
648 651
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);
654 list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) { 652 list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) {
655 lfcc = kmalloc(sizeof(struct lfcc), GFP_KERNEL); 653 lfcc = kmalloc(sizeof(struct lfcc), GFP_KERNEL);
656 if (!lfcc) { 654 if (!lfcc) {
@@ -692,11 +690,6 @@ out:
692 gfs2_glock_dq_uninit(&lfcc->gh); 690 gfs2_glock_dq_uninit(&lfcc->gh);
693 kfree(lfcc); 691 kfree(lfcc);
694 } 692 }
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 }
700 return error; 693 return error;
701} 694}
702 695
@@ -834,18 +827,14 @@ out:
834 827
835static int gfs2_make_fs_ro(struct gfs2_sbd *sdp) 828static int gfs2_make_fs_ro(struct gfs2_sbd *sdp)
836{ 829{
837 struct gfs2_holder thaw_gh; 830 struct gfs2_holder freeze_gh;
838 int error; 831 int error;
839 832
840 error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED, GL_NOCACHE, 833 error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED, GL_NOCACHE,
841 &thaw_gh); 834 &freeze_gh);
842 if (error && !test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) 835 if (error && !test_bit(SDF_SHUTDOWN, &sdp->sd_flags))
843 return error; 836 return error;
844 837
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
849 kthread_stop(sdp->sd_quotad_process); 838 kthread_stop(sdp->sd_quotad_process);
850 kthread_stop(sdp->sd_logd_process); 839 kthread_stop(sdp->sd_logd_process);
851 840
@@ -853,11 +842,16 @@ static int gfs2_make_fs_ro(struct gfs2_sbd *sdp)
853 gfs2_quota_sync(sdp->sd_vfs, 0); 842 gfs2_quota_sync(sdp->sd_vfs, 0);
854 gfs2_statfs_sync(sdp->sd_vfs, 0); 843 gfs2_statfs_sync(sdp->sd_vfs, 0);
855 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
856 gfs2_log_flush(sdp, NULL, SHUTDOWN_FLUSH); 849 gfs2_log_flush(sdp, NULL, SHUTDOWN_FLUSH);
850 wait_event(sdp->sd_reserving_log_wait, atomic_read(&sdp->sd_reserving_log) == 0);
857 gfs2_assert_warn(sdp, atomic_read(&sdp->sd_log_blks_free) == sdp->sd_jdesc->jd_blocks); 851 gfs2_assert_warn(sdp, atomic_read(&sdp->sd_log_blks_free) == sdp->sd_jdesc->jd_blocks);
858 852
859 if (thaw_gh.gh_gl) 853 if (freeze_gh.gh_gl)
860 gfs2_glock_dq_uninit(&thaw_gh); 854 gfs2_glock_dq_uninit(&freeze_gh);
861 855
862 gfs2_quota_cleanup(sdp); 856 gfs2_quota_cleanup(sdp);
863 857
@@ -943,11 +937,41 @@ static int gfs2_sync_fs(struct super_block *sb, int wait)
943 struct gfs2_sbd *sdp = sb->s_fs_info; 937 struct gfs2_sbd *sdp = sb->s_fs_info;
944 938
945 gfs2_quota_sync(sb, -1); 939 gfs2_quota_sync(sb, -1);
946 if (wait && sdp && !atomic_read(&sdp->sd_log_freeze)) 940 if (wait && sdp)
947 gfs2_log_flush(sdp, NULL, NORMAL_FLUSH); 941 gfs2_log_flush(sdp, NULL, NORMAL_FLUSH);
948 return 0; 942 return 0;
949} 943}
950 944
945void gfs2_freeze_func(struct work_struct *work)
946{
947 int error;
948 struct gfs2_holder freeze_gh;
949 struct gfs2_sbd *sdp = container_of(work, struct gfs2_sbd, sd_freeze_work);
950 struct super_block *sb = sdp->sd_vfs;
951
952 atomic_inc(&sb->s_active);
953 error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED, 0,
954 &freeze_gh);
955 if (error) {
956 printk(KERN_INFO "GFS2: couln't get freeze lock : %d\n", error);
957 gfs2_assert_withdraw(sdp, 0);
958 }
959 else {
960 atomic_set(&sdp->sd_freeze_state, SFS_UNFROZEN);
961 error = thaw_super(sb);
962 if (error) {
963 printk(KERN_INFO "GFS2: couldn't thaw filesystem: %d\n",
964 error);
965 gfs2_assert_withdraw(sdp, 0);
966 }
967 if (!test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags))
968 freeze_gh.gh_flags |= GL_NOCACHE;
969 gfs2_glock_dq_uninit(&freeze_gh);
970 }
971 deactivate_super(sb);
972 return;
973}
974
951/** 975/**
952 * gfs2_freeze - prevent further writes to the filesystem 976 * gfs2_freeze - prevent further writes to the filesystem
953 * @sb: the VFS structure for the filesystem 977 * @sb: the VFS structure for the filesystem
@@ -957,10 +981,16 @@ static int gfs2_sync_fs(struct super_block *sb, int wait)
957static int gfs2_freeze(struct super_block *sb) 981static int gfs2_freeze(struct super_block *sb)
958{ 982{
959 struct gfs2_sbd *sdp = sb->s_fs_info; 983 struct gfs2_sbd *sdp = sb->s_fs_info;
960 int error; 984 int error = 0;
961 985
962 if (test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) 986 mutex_lock(&sdp->sd_freeze_mutex);
963 return -EINVAL; 987 if (atomic_read(&sdp->sd_freeze_state) != SFS_UNFROZEN)
988 goto out;
989
990 if (test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) {
991 error = -EINVAL;
992 goto out;
993 }
964 994
965 for (;;) { 995 for (;;) {
966 error = gfs2_lock_fs_check_clean(sdp, &sdp->sd_freeze_gh); 996 error = gfs2_lock_fs_check_clean(sdp, &sdp->sd_freeze_gh);
@@ -980,7 +1010,10 @@ static int gfs2_freeze(struct super_block *sb)
980 fs_err(sdp, "retrying...\n"); 1010 fs_err(sdp, "retrying...\n");
981 msleep(1000); 1011 msleep(1000);
982 } 1012 }
983 return 0; 1013 error = 0;
1014out:
1015 mutex_unlock(&sdp->sd_freeze_mutex);
1016 return error;
984} 1017}
985 1018
986/** 1019/**
@@ -993,10 +1026,15 @@ static int gfs2_unfreeze(struct super_block *sb)
993{ 1026{
994 struct gfs2_sbd *sdp = sb->s_fs_info; 1027 struct gfs2_sbd *sdp = sb->s_fs_info;
995 1028
1029 mutex_lock(&sdp->sd_freeze_mutex);
1030 if (atomic_read(&sdp->sd_freeze_state) != SFS_FROZEN ||
1031 sdp->sd_freeze_gh.gh_gl == NULL) {
1032 mutex_unlock(&sdp->sd_freeze_mutex);
1033 return 0;
1034 }
1035
996 gfs2_glock_dq_uninit(&sdp->sd_freeze_gh); 1036 gfs2_glock_dq_uninit(&sdp->sd_freeze_gh);
997 atomic_dec(&sdp->sd_frozen_root); 1037 mutex_unlock(&sdp->sd_freeze_mutex);
998 wait_event(sdp->sd_frozen_root_wait, atomic_read(&sdp->sd_frozen_root) == 0);
999 gfs2_glock_dq_uninit(&sdp->sd_freeze_root_gh);
1000 return 0; 1038 return 0;
1001} 1039}
1002 1040
@@ -1618,8 +1656,8 @@ const struct super_operations gfs2_super_ops = {
1618 .evict_inode = gfs2_evict_inode, 1656 .evict_inode = gfs2_evict_inode,
1619 .put_super = gfs2_put_super, 1657 .put_super = gfs2_put_super,
1620 .sync_fs = gfs2_sync_fs, 1658 .sync_fs = gfs2_sync_fs,
1621 .freeze_fs = gfs2_freeze, 1659 .freeze_super = gfs2_freeze,
1622 .unfreeze_fs = gfs2_unfreeze, 1660 .thaw_super = gfs2_unfreeze,
1623 .statfs = gfs2_statfs, 1661 .statfs = gfs2_statfs,
1624 .remount_fs = gfs2_remount_fs, 1662 .remount_fs = gfs2_remount_fs,
1625 .drop_inode = gfs2_drop_inode, 1663 .drop_inode = gfs2_drop_inode,
diff --git a/fs/gfs2/super.h b/fs/gfs2/super.h
index 90e3322ffa10..73c97dccae21 100644
--- a/fs/gfs2/super.h
+++ b/fs/gfs2/super.h
@@ -45,6 +45,7 @@ extern void gfs2_statfs_change_in(struct gfs2_statfs_change_host *sc,
45extern void update_statfs(struct gfs2_sbd *sdp, struct buffer_head *m_bh, 45extern void update_statfs(struct gfs2_sbd *sdp, struct buffer_head *m_bh,
46 struct buffer_head *l_bh); 46 struct buffer_head *l_bh);
47extern int gfs2_statfs_sync(struct super_block *sb, int type); 47extern int gfs2_statfs_sync(struct super_block *sb, int type);
48extern void gfs2_freeze_func(struct work_struct *work);
48 49
49extern struct file_system_type gfs2_fs_type; 50extern struct file_system_type gfs2_fs_type;
50extern struct file_system_type gfs2meta_fs_type; 51extern struct file_system_type gfs2meta_fs_type;
diff --git a/fs/gfs2/trans.c b/fs/gfs2/trans.c
index 42bfd3361979..88bff2430669 100644
--- a/fs/gfs2/trans.c
+++ b/fs/gfs2/trans.c
@@ -89,14 +89,17 @@ void gfs2_trans_end(struct gfs2_sbd *sdp)
89{ 89{
90 struct gfs2_trans *tr = current->journal_info; 90 struct gfs2_trans *tr = current->journal_info;
91 s64 nbuf; 91 s64 nbuf;
92 int alloced = tr->tr_alloced;
93
92 BUG_ON(!tr); 94 BUG_ON(!tr);
93 current->journal_info = NULL; 95 current->journal_info = NULL;
94 96
95 if (!tr->tr_touched) { 97 if (!tr->tr_touched) {
96 gfs2_log_release(sdp, tr->tr_reserved); 98 gfs2_log_release(sdp, tr->tr_reserved);
97 if (tr->tr_alloced) 99 if (alloced) {
98 kfree(tr); 100 kfree(tr);
99 sb_end_intwrite(sdp->sd_vfs); 101 sb_end_intwrite(sdp->sd_vfs);
102 }
100 return; 103 return;
101 } 104 }
102 105
@@ -109,13 +112,14 @@ void gfs2_trans_end(struct gfs2_sbd *sdp)
109 gfs2_print_trans(tr); 112 gfs2_print_trans(tr);
110 113
111 gfs2_log_commit(sdp, tr); 114 gfs2_log_commit(sdp, tr);
112 if (tr->tr_alloced && !tr->tr_attached) 115 if (alloced && !tr->tr_attached)
113 kfree(tr); 116 kfree(tr);
114 up_read(&sdp->sd_log_flush_lock); 117 up_read(&sdp->sd_log_flush_lock);
115 118
116 if (sdp->sd_vfs->s_flags & MS_SYNCHRONOUS) 119 if (sdp->sd_vfs->s_flags & MS_SYNCHRONOUS)
117 gfs2_log_flush(sdp, NULL, NORMAL_FLUSH); 120 gfs2_log_flush(sdp, NULL, NORMAL_FLUSH);
118 sb_end_intwrite(sdp->sd_vfs); 121 if (alloced)
122 sb_end_intwrite(sdp->sd_vfs);
119} 123}
120 124
121static struct gfs2_bufdata *gfs2_alloc_bufdata(struct gfs2_glock *gl, 125static struct gfs2_bufdata *gfs2_alloc_bufdata(struct gfs2_glock *gl,
@@ -192,6 +196,7 @@ static void meta_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd)
192{ 196{
193 struct gfs2_meta_header *mh; 197 struct gfs2_meta_header *mh;
194 struct gfs2_trans *tr; 198 struct gfs2_trans *tr;
199 enum gfs2_freeze_state state = atomic_read(&sdp->sd_freeze_state);
195 200
196 tr = current->journal_info; 201 tr = current->journal_info;
197 tr->tr_touched = 1; 202 tr->tr_touched = 1;
@@ -205,6 +210,10 @@ static void meta_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd)
205 (unsigned long long)bd->bd_bh->b_blocknr); 210 (unsigned long long)bd->bd_bh->b_blocknr);
206 BUG(); 211 BUG();
207 } 212 }
213 if (unlikely(state == SFS_FROZEN)) {
214 printk(KERN_INFO "GFS2:adding buf while frozen\n");
215 gfs2_assert_withdraw(sdp, 0);
216 }
208 gfs2_pin(sdp, bd->bd_bh); 217 gfs2_pin(sdp, bd->bd_bh);
209 mh->__pad0 = cpu_to_be64(0); 218 mh->__pad0 = cpu_to_be64(0);
210 mh->mh_jid = cpu_to_be32(sdp->sd_jdesc->jd_jid); 219 mh->mh_jid = cpu_to_be32(sdp->sd_jdesc->jd_jid);