summaryrefslogtreecommitdiffstats
path: root/fs/gfs2/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2/super.c')
-rw-r--r--fs/gfs2/super.c88
1 files changed, 36 insertions, 52 deletions
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index d21c04a22d73..e5f79466340d 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -134,7 +134,7 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp)
int error;
j_gl->gl_ops->go_inval(j_gl, DIO_METADATA);
- if (gfs2_withdrawn(sdp))
+ if (gfs2_withdrawing_or_withdrawn(sdp))
return -EIO;
error = gfs2_find_jhead(sdp->sd_jdesc, &head, false);
@@ -153,7 +153,7 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp)
gfs2_log_pointers_init(sdp, head.lh_blkno);
error = gfs2_quota_init(sdp);
- if (!error && gfs2_withdrawn(sdp))
+ if (!error && gfs2_withdrawing_or_withdrawn(sdp))
error = -EIO;
if (!error)
set_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags);
@@ -499,7 +499,7 @@ static void gfs2_dirty_inode(struct inode *inode, int flags)
return;
}
- if (unlikely(gfs2_withdrawn(sdp)))
+ if (gfs2_withdrawing_or_withdrawn(sdp))
return;
if (!gfs2_glock_is_locked_by_me(ip->i_gl)) {
ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
@@ -605,7 +605,7 @@ restart:
if (!sb_rdonly(sb))
gfs2_make_fs_ro(sdp);
else {
- if (gfs2_withdrawn(sdp))
+ if (gfs2_withdrawing_or_withdrawn(sdp))
gfs2_destroy_threads(sdp);
gfs2_quota_cleanup(sdp);
@@ -673,28 +673,6 @@ static int gfs2_sync_fs(struct super_block *sb, int wait)
return sdp->sd_log_error;
}
-static int gfs2_freeze_locally(struct gfs2_sbd *sdp)
-{
- struct super_block *sb = sdp->sd_vfs;
- int error;
-
- error = freeze_super(sb, FREEZE_HOLDER_USERSPACE);
- if (error)
- return error;
-
- if (test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) {
- gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_FREEZE |
- GFS2_LFC_FREEZE_GO_SYNC);
- if (gfs2_withdrawn(sdp)) {
- error = thaw_super(sb, FREEZE_HOLDER_USERSPACE);
- if (error)
- return error;
- return -EIO;
- }
- }
- return 0;
-}
-
static int gfs2_do_thaw(struct gfs2_sbd *sdp)
{
struct super_block *sb = sdp->sd_vfs;
@@ -724,7 +702,7 @@ void gfs2_freeze_func(struct work_struct *work)
if (test_bit(SDF_FROZEN, &sdp->sd_flags))
goto freeze_failed;
- error = gfs2_freeze_locally(sdp);
+ error = freeze_super(sb, FREEZE_HOLDER_USERSPACE);
if (error)
goto freeze_failed;
@@ -759,12 +737,13 @@ static int gfs2_freeze_super(struct super_block *sb, enum freeze_holder who)
if (!mutex_trylock(&sdp->sd_freeze_mutex))
return -EBUSY;
- error = -EBUSY;
- if (test_bit(SDF_FROZEN, &sdp->sd_flags))
- goto out;
+ if (test_bit(SDF_FROZEN, &sdp->sd_flags)) {
+ mutex_unlock(&sdp->sd_freeze_mutex);
+ return -EBUSY;
+ }
for (;;) {
- error = gfs2_freeze_locally(sdp);
+ error = freeze_super(sb, FREEZE_HOLDER_USERSPACE);
if (error) {
fs_info(sdp, "GFS2: couldn't freeze filesystem: %d\n",
error);
@@ -772,8 +751,11 @@ static int gfs2_freeze_super(struct super_block *sb, enum freeze_holder who)
}
error = gfs2_lock_fs_check_clean(sdp);
- if (!error)
- break; /* success */
+ if (!error) {
+ set_bit(SDF_FREEZE_INITIATOR, &sdp->sd_flags);
+ set_bit(SDF_FROZEN, &sdp->sd_flags);
+ break;
+ }
error = gfs2_do_thaw(sdp);
if (error)
@@ -793,14 +775,23 @@ static int gfs2_freeze_super(struct super_block *sb, enum freeze_holder who)
}
out:
- if (!error) {
- set_bit(SDF_FREEZE_INITIATOR, &sdp->sd_flags);
- set_bit(SDF_FROZEN, &sdp->sd_flags);
- }
mutex_unlock(&sdp->sd_freeze_mutex);
return error;
}
+static int gfs2_freeze_fs(struct super_block *sb)
+{
+ struct gfs2_sbd *sdp = sb->s_fs_info;
+
+ if (test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) {
+ gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_FREEZE |
+ GFS2_LFC_FREEZE_GO_SYNC);
+ if (gfs2_withdrawing_or_withdrawn(sdp))
+ return -EIO;
+ }
+ return 0;
+}
+
/**
* gfs2_thaw_super - reallow writes to the filesystem
* @sb: the VFS structure for the filesystem
@@ -814,10 +805,12 @@ static int gfs2_thaw_super(struct super_block *sb, enum freeze_holder who)
if (!mutex_trylock(&sdp->sd_freeze_mutex))
return -EBUSY;
- error = -EINVAL;
- if (!test_bit(SDF_FREEZE_INITIATOR, &sdp->sd_flags))
- goto out;
+ if (!test_bit(SDF_FREEZE_INITIATOR, &sdp->sd_flags)) {
+ mutex_unlock(&sdp->sd_freeze_mutex);
+ return -EINVAL;
+ }
+ atomic_inc(&sb->s_active);
gfs2_freeze_unlock(&sdp->sd_freeze_gh);
error = gfs2_do_thaw(sdp);
@@ -826,8 +819,8 @@ static int gfs2_thaw_super(struct super_block *sb, enum freeze_holder who)
clear_bit(SDF_FREEZE_INITIATOR, &sdp->sd_flags);
clear_bit(SDF_FROZEN, &sdp->sd_flags);
}
-out:
mutex_unlock(&sdp->sd_freeze_mutex);
+ deactivate_super(sb);
return error;
}
@@ -1065,16 +1058,6 @@ static int gfs2_drop_inode(struct inode *inode)
return generic_drop_inode(inode);
}
-static int is_ancestor(const struct dentry *d1, const struct dentry *d2)
-{
- do {
- if (d1 == d2)
- return 1;
- d1 = d1->d_parent;
- } while (!IS_ROOT(d1));
- return 0;
-}
-
/**
* gfs2_show_options - Show mount options for /proc/mounts
* @s: seq_file structure
@@ -1096,7 +1079,7 @@ static int gfs2_show_options(struct seq_file *s, struct dentry *root)
statfs_slow = sdp->sd_tune.gt_statfs_slow;
spin_unlock(&sdp->sd_tune.gt_spin);
- if (is_ancestor(root, sdp->sd_master_dir))
+ if (is_subdir(root, sdp->sd_master_dir))
seq_puts(s, ",meta");
if (args->ar_lockproto[0])
seq_show_option(s, "lockproto", args->ar_lockproto);
@@ -1607,6 +1590,7 @@ const struct super_operations gfs2_super_ops = {
.put_super = gfs2_put_super,
.sync_fs = gfs2_sync_fs,
.freeze_super = gfs2_freeze_super,
+ .freeze_fs = gfs2_freeze_fs,
.thaw_super = gfs2_thaw_super,
.statfs = gfs2_statfs,
.drop_inode = gfs2_drop_inode,