aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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