aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Sato <t-sato@yk.jp.nec.com>2009-01-09 19:40:58 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-01-09 19:54:42 -0500
commitc4be0c1dc4cdc37b175579be1460f15ac6495e9a (patch)
tree716ea88318211ed27cadcebda0fd85c1f8246edb
parent69347a236b22c3962ea812511495e502dedfd50c (diff)
filesystem freeze: add error handling of write_super_lockfs/unlockfs
Currently, ext3 in mainline Linux doesn't have the freeze feature which suspends write requests. So, we cannot take a backup which keeps the filesystem's consistency with the storage device's features (snapshot and replication) while it is mounted. In many case, a commercial filesystem (e.g. VxFS) has the freeze feature and it would be used to get the consistent backup. If Linux's standard filesystem ext3 has the freeze feature, we can do it without a commercial filesystem. So I have implemented the ioctls of the freeze feature. I think we can take the consistent backup with the following steps. 1. Freeze the filesystem with the freeze ioctl. 2. Separate the replication volume or create the snapshot with the storage device's feature. 3. Unfreeze the filesystem with the unfreeze ioctl. 4. Take the backup from the separated replication volume or the snapshot. This patch: VFS: Changed the type of write_super_lockfs and unlockfs from "void" to "int" so that they can return an error. Rename write_super_lockfs and unlockfs of the super block operation freeze_fs and unfreeze_fs to avoid a confusion. ext3, ext4, xfs, gfs2, jfs: Changed the type of write_super_lockfs and unlockfs from "void" to "int" so that write_super_lockfs returns an error if needed, and unlockfs always returns 0. reiserfs: Changed the type of write_super_lockfs and unlockfs from "void" to "int" so that they always return 0 (success) to keep a current behavior. Signed-off-by: Takashi Sato <t-sato@yk.jp.nec.com> Signed-off-by: Masayuki Hamaguchi <m-hamaguchi@ys.jp.nec.com> Cc: <xfs-masters@oss.sgi.com> Cc: <linux-ext4@vger.kernel.org> Cc: Christoph Hellwig <hch@lst.de> Cc: Dave Kleikamp <shaggy@austin.ibm.com> Cc: Dave Chinner <david@fromorbit.com> Cc: Alasdair G Kergon <agk@redhat.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--Documentation/filesystems/Locking8
-rw-r--r--Documentation/filesystems/vfs.txt8
-rw-r--r--fs/buffer.c8
-rw-r--r--fs/ext3/super.c45
-rw-r--r--fs/ext4/super.c45
-rw-r--r--fs/gfs2/ops_super.c16
-rw-r--r--fs/jfs/super.c10
-rw-r--r--fs/reiserfs/super.c10
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c8
-rw-r--r--fs/xfs/xfs_fsops.c11
-rw-r--r--fs/xfs/xfs_fsops.h2
-rw-r--r--include/linux/fs.h4
12 files changed, 107 insertions, 68 deletions
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
index cfbfa15a46ba..ec6a9392a173 100644
--- a/Documentation/filesystems/Locking
+++ b/Documentation/filesystems/Locking
@@ -97,8 +97,8 @@ prototypes:
97 void (*put_super) (struct super_block *); 97 void (*put_super) (struct super_block *);
98 void (*write_super) (struct super_block *); 98 void (*write_super) (struct super_block *);
99 int (*sync_fs)(struct super_block *sb, int wait); 99 int (*sync_fs)(struct super_block *sb, int wait);
100 void (*write_super_lockfs) (struct super_block *); 100 int (*freeze_fs) (struct super_block *);
101 void (*unlockfs) (struct super_block *); 101 int (*unfreeze_fs) (struct super_block *);
102 int (*statfs) (struct dentry *, struct kstatfs *); 102 int (*statfs) (struct dentry *, struct kstatfs *);
103 int (*remount_fs) (struct super_block *, int *, char *); 103 int (*remount_fs) (struct super_block *, int *, char *);
104 void (*clear_inode) (struct inode *); 104 void (*clear_inode) (struct inode *);
@@ -119,8 +119,8 @@ delete_inode: no
119put_super: yes yes no 119put_super: yes yes no
120write_super: no yes read 120write_super: no yes read
121sync_fs: no no read 121sync_fs: no no read
122write_super_lockfs: ? 122freeze_fs: ?
123unlockfs: ? 123unfreeze_fs: ?
124statfs: no no no 124statfs: no no no
125remount_fs: yes yes maybe (see below) 125remount_fs: yes yes maybe (see below)
126clear_inode: no 126clear_inode: no
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt
index ef19afa186a9..deeeed0faa8f 100644
--- a/Documentation/filesystems/vfs.txt
+++ b/Documentation/filesystems/vfs.txt
@@ -210,8 +210,8 @@ struct super_operations {
210 void (*put_super) (struct super_block *); 210 void (*put_super) (struct super_block *);
211 void (*write_super) (struct super_block *); 211 void (*write_super) (struct super_block *);
212 int (*sync_fs)(struct super_block *sb, int wait); 212 int (*sync_fs)(struct super_block *sb, int wait);
213 void (*write_super_lockfs) (struct super_block *); 213 int (*freeze_fs) (struct super_block *);
214 void (*unlockfs) (struct super_block *); 214 int (*unfreeze_fs) (struct super_block *);
215 int (*statfs) (struct dentry *, struct kstatfs *); 215 int (*statfs) (struct dentry *, struct kstatfs *);
216 int (*remount_fs) (struct super_block *, int *, char *); 216 int (*remount_fs) (struct super_block *, int *, char *);
217 void (*clear_inode) (struct inode *); 217 void (*clear_inode) (struct inode *);
@@ -270,11 +270,11 @@ or bottom half).
270 a superblock. The second parameter indicates whether the method 270 a superblock. The second parameter indicates whether the method
271 should wait until the write out has been completed. Optional. 271 should wait until the write out has been completed. Optional.
272 272
273 write_super_lockfs: called when VFS is locking a filesystem and 273 freeze_fs: called when VFS is locking a filesystem and
274 forcing it into a consistent state. This method is currently 274 forcing it into a consistent state. This method is currently
275 used by the Logical Volume Manager (LVM). 275 used by the Logical Volume Manager (LVM).
276 276
277 unlockfs: called when VFS is unlocking a filesystem and making it writable 277 unfreeze_fs: called when VFS is unlocking a filesystem and making it writable
278 again. 278 again.
279 279
280 statfs: called when the VFS needs to get filesystem statistics. This 280 statfs: called when the VFS needs to get filesystem statistics. This
diff --git a/fs/buffer.c b/fs/buffer.c
index c26da785938a..87f9e537b8c3 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -221,8 +221,8 @@ struct super_block *freeze_bdev(struct block_device *bdev)
221 221
222 sync_blockdev(sb->s_bdev); 222 sync_blockdev(sb->s_bdev);
223 223
224 if (sb->s_op->write_super_lockfs) 224 if (sb->s_op->freeze_fs)
225 sb->s_op->write_super_lockfs(sb); 225 sb->s_op->freeze_fs(sb);
226 } 226 }
227 227
228 sync_blockdev(bdev); 228 sync_blockdev(bdev);
@@ -242,8 +242,8 @@ void thaw_bdev(struct block_device *bdev, struct super_block *sb)
242 if (sb) { 242 if (sb) {
243 BUG_ON(sb->s_bdev != bdev); 243 BUG_ON(sb->s_bdev != bdev);
244 244
245 if (sb->s_op->unlockfs) 245 if (sb->s_op->unfreeze_fs)
246 sb->s_op->unlockfs(sb); 246 sb->s_op->unfreeze_fs(sb);
247 sb->s_frozen = SB_UNFROZEN; 247 sb->s_frozen = SB_UNFROZEN;
248 smp_wmb(); 248 smp_wmb();
249 wake_up(&sb->s_wait_unfrozen); 249 wake_up(&sb->s_wait_unfrozen);
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 5d047a030a73..b70d90e08a3c 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -48,8 +48,8 @@ static int ext3_load_journal(struct super_block *, struct ext3_super_block *,
48 unsigned long journal_devnum); 48 unsigned long journal_devnum);
49static int ext3_create_journal(struct super_block *, struct ext3_super_block *, 49static int ext3_create_journal(struct super_block *, struct ext3_super_block *,
50 unsigned int); 50 unsigned int);
51static void ext3_commit_super (struct super_block * sb, 51static int ext3_commit_super(struct super_block *sb,
52 struct ext3_super_block * es, 52 struct ext3_super_block *es,
53 int sync); 53 int sync);
54static void ext3_mark_recovery_complete(struct super_block * sb, 54static void ext3_mark_recovery_complete(struct super_block * sb,
55 struct ext3_super_block * es); 55 struct ext3_super_block * es);
@@ -60,9 +60,9 @@ static const char *ext3_decode_error(struct super_block * sb, int errno,
60 char nbuf[16]); 60 char nbuf[16]);
61static int ext3_remount (struct super_block * sb, int * flags, char * data); 61static int ext3_remount (struct super_block * sb, int * flags, char * data);
62static int ext3_statfs (struct dentry * dentry, struct kstatfs * buf); 62static int ext3_statfs (struct dentry * dentry, struct kstatfs * buf);
63static void ext3_unlockfs(struct super_block *sb); 63static int ext3_unfreeze(struct super_block *sb);
64static void ext3_write_super (struct super_block * sb); 64static void ext3_write_super (struct super_block * sb);
65static void ext3_write_super_lockfs(struct super_block *sb); 65static int ext3_freeze(struct super_block *sb);
66 66
67/* 67/*
68 * Wrappers for journal_start/end. 68 * Wrappers for journal_start/end.
@@ -759,8 +759,8 @@ static const struct super_operations ext3_sops = {
759 .put_super = ext3_put_super, 759 .put_super = ext3_put_super,
760 .write_super = ext3_write_super, 760 .write_super = ext3_write_super,
761 .sync_fs = ext3_sync_fs, 761 .sync_fs = ext3_sync_fs,
762 .write_super_lockfs = ext3_write_super_lockfs, 762 .freeze_fs = ext3_freeze,
763 .unlockfs = ext3_unlockfs, 763 .unfreeze_fs = ext3_unfreeze,
764 .statfs = ext3_statfs, 764 .statfs = ext3_statfs,
765 .remount_fs = ext3_remount, 765 .remount_fs = ext3_remount,
766 .clear_inode = ext3_clear_inode, 766 .clear_inode = ext3_clear_inode,
@@ -2311,21 +2311,23 @@ static int ext3_create_journal(struct super_block * sb,
2311 return 0; 2311 return 0;
2312} 2312}
2313 2313
2314static void ext3_commit_super (struct super_block * sb, 2314static int ext3_commit_super(struct super_block *sb,
2315 struct ext3_super_block * es, 2315 struct ext3_super_block *es,
2316 int sync) 2316 int sync)
2317{ 2317{
2318 struct buffer_head *sbh = EXT3_SB(sb)->s_sbh; 2318 struct buffer_head *sbh = EXT3_SB(sb)->s_sbh;
2319 int error = 0;
2319 2320
2320 if (!sbh) 2321 if (!sbh)
2321 return; 2322 return error;
2322 es->s_wtime = cpu_to_le32(get_seconds()); 2323 es->s_wtime = cpu_to_le32(get_seconds());
2323 es->s_free_blocks_count = cpu_to_le32(ext3_count_free_blocks(sb)); 2324 es->s_free_blocks_count = cpu_to_le32(ext3_count_free_blocks(sb));
2324 es->s_free_inodes_count = cpu_to_le32(ext3_count_free_inodes(sb)); 2325 es->s_free_inodes_count = cpu_to_le32(ext3_count_free_inodes(sb));
2325 BUFFER_TRACE(sbh, "marking dirty"); 2326 BUFFER_TRACE(sbh, "marking dirty");
2326 mark_buffer_dirty(sbh); 2327 mark_buffer_dirty(sbh);
2327 if (sync) 2328 if (sync)
2328 sync_dirty_buffer(sbh); 2329 error = sync_dirty_buffer(sbh);
2330 return error;
2329} 2331}
2330 2332
2331 2333
@@ -2439,12 +2441,14 @@ static int ext3_sync_fs(struct super_block *sb, int wait)
2439 * LVM calls this function before a (read-only) snapshot is created. This 2441 * LVM calls this function before a (read-only) snapshot is created. This
2440 * gives us a chance to flush the journal completely and mark the fs clean. 2442 * gives us a chance to flush the journal completely and mark the fs clean.
2441 */ 2443 */
2442static void ext3_write_super_lockfs(struct super_block *sb) 2444static int ext3_freeze(struct super_block *sb)
2443{ 2445{
2446 int error = 0;
2447 journal_t *journal;
2444 sb->s_dirt = 0; 2448 sb->s_dirt = 0;
2445 2449
2446 if (!(sb->s_flags & MS_RDONLY)) { 2450 if (!(sb->s_flags & MS_RDONLY)) {
2447 journal_t *journal = EXT3_SB(sb)->s_journal; 2451 journal = EXT3_SB(sb)->s_journal;
2448 2452
2449 /* Now we set up the journal barrier. */ 2453 /* Now we set up the journal barrier. */
2450 journal_lock_updates(journal); 2454 journal_lock_updates(journal);
@@ -2453,20 +2457,28 @@ static void ext3_write_super_lockfs(struct super_block *sb)
2453 * We don't want to clear needs_recovery flag when we failed 2457 * We don't want to clear needs_recovery flag when we failed
2454 * to flush the journal. 2458 * to flush the journal.
2455 */ 2459 */
2456 if (journal_flush(journal) < 0) 2460 error = journal_flush(journal);
2457 return; 2461 if (error < 0)
2462 goto out;
2458 2463
2459 /* Journal blocked and flushed, clear needs_recovery flag. */ 2464 /* Journal blocked and flushed, clear needs_recovery flag. */
2460 EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER); 2465 EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
2461 ext3_commit_super(sb, EXT3_SB(sb)->s_es, 1); 2466 error = ext3_commit_super(sb, EXT3_SB(sb)->s_es, 1);
2467 if (error)
2468 goto out;
2462 } 2469 }
2470 return 0;
2471
2472out:
2473 journal_unlock_updates(journal);
2474 return error;
2463} 2475}
2464 2476
2465/* 2477/*
2466 * Called by LVM after the snapshot is done. We need to reset the RECOVER 2478 * Called by LVM after the snapshot is done. We need to reset the RECOVER
2467 * flag here, even though the filesystem is not technically dirty yet. 2479 * flag here, even though the filesystem is not technically dirty yet.
2468 */ 2480 */
2469static void ext3_unlockfs(struct super_block *sb) 2481static int ext3_unfreeze(struct super_block *sb)
2470{ 2482{
2471 if (!(sb->s_flags & MS_RDONLY)) { 2483 if (!(sb->s_flags & MS_RDONLY)) {
2472 lock_super(sb); 2484 lock_super(sb);
@@ -2476,6 +2488,7 @@ static void ext3_unlockfs(struct super_block *sb)
2476 unlock_super(sb); 2488 unlock_super(sb);
2477 journal_unlock_updates(EXT3_SB(sb)->s_journal); 2489 journal_unlock_updates(EXT3_SB(sb)->s_journal);
2478 } 2490 }
2491 return 0;
2479} 2492}
2480 2493
2481static int ext3_remount (struct super_block * sb, int * flags, char * data) 2494static int ext3_remount (struct super_block * sb, int * flags, char * data)
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 8f7e0be8ab1b..e5f06a5f045e 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -51,7 +51,7 @@ struct proc_dir_entry *ext4_proc_root;
51 51
52static int ext4_load_journal(struct super_block *, struct ext4_super_block *, 52static int ext4_load_journal(struct super_block *, struct ext4_super_block *,
53 unsigned long journal_devnum); 53 unsigned long journal_devnum);
54static void ext4_commit_super(struct super_block *sb, 54static int ext4_commit_super(struct super_block *sb,
55 struct ext4_super_block *es, int sync); 55 struct ext4_super_block *es, int sync);
56static void ext4_mark_recovery_complete(struct super_block *sb, 56static void ext4_mark_recovery_complete(struct super_block *sb,
57 struct ext4_super_block *es); 57 struct ext4_super_block *es);
@@ -62,9 +62,9 @@ static const char *ext4_decode_error(struct super_block *sb, int errno,
62 char nbuf[16]); 62 char nbuf[16]);
63static int ext4_remount(struct super_block *sb, int *flags, char *data); 63static int ext4_remount(struct super_block *sb, int *flags, char *data);
64static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf); 64static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf);
65static void ext4_unlockfs(struct super_block *sb); 65static int ext4_unfreeze(struct super_block *sb);
66static void ext4_write_super(struct super_block *sb); 66static void ext4_write_super(struct super_block *sb);
67static void ext4_write_super_lockfs(struct super_block *sb); 67static int ext4_freeze(struct super_block *sb);
68 68
69 69
70ext4_fsblk_t ext4_block_bitmap(struct super_block *sb, 70ext4_fsblk_t ext4_block_bitmap(struct super_block *sb,
@@ -978,8 +978,8 @@ static const struct super_operations ext4_sops = {
978 .put_super = ext4_put_super, 978 .put_super = ext4_put_super,
979 .write_super = ext4_write_super, 979 .write_super = ext4_write_super,
980 .sync_fs = ext4_sync_fs, 980 .sync_fs = ext4_sync_fs,
981 .write_super_lockfs = ext4_write_super_lockfs, 981 .freeze_fs = ext4_freeze,
982 .unlockfs = ext4_unlockfs, 982 .unfreeze_fs = ext4_unfreeze,
983 .statfs = ext4_statfs, 983 .statfs = ext4_statfs,
984 .remount_fs = ext4_remount, 984 .remount_fs = ext4_remount,
985 .clear_inode = ext4_clear_inode, 985 .clear_inode = ext4_clear_inode,
@@ -2888,13 +2888,14 @@ static int ext4_load_journal(struct super_block *sb,
2888 return 0; 2888 return 0;
2889} 2889}
2890 2890
2891static void ext4_commit_super(struct super_block *sb, 2891static int ext4_commit_super(struct super_block *sb,
2892 struct ext4_super_block *es, int sync) 2892 struct ext4_super_block *es, int sync)
2893{ 2893{
2894 struct buffer_head *sbh = EXT4_SB(sb)->s_sbh; 2894 struct buffer_head *sbh = EXT4_SB(sb)->s_sbh;
2895 int error = 0;
2895 2896
2896 if (!sbh) 2897 if (!sbh)
2897 return; 2898 return error;
2898 if (buffer_write_io_error(sbh)) { 2899 if (buffer_write_io_error(sbh)) {
2899 /* 2900 /*
2900 * Oh, dear. A previous attempt to write the 2901 * Oh, dear. A previous attempt to write the
@@ -2918,14 +2919,19 @@ static void ext4_commit_super(struct super_block *sb,
2918 BUFFER_TRACE(sbh, "marking dirty"); 2919 BUFFER_TRACE(sbh, "marking dirty");
2919 mark_buffer_dirty(sbh); 2920 mark_buffer_dirty(sbh);
2920 if (sync) { 2921 if (sync) {
2921 sync_dirty_buffer(sbh); 2922 error = sync_dirty_buffer(sbh);
2922 if (buffer_write_io_error(sbh)) { 2923 if (error)
2924 return error;
2925
2926 error = buffer_write_io_error(sbh);
2927 if (error) {
2923 printk(KERN_ERR "EXT4-fs: I/O error while writing " 2928 printk(KERN_ERR "EXT4-fs: I/O error while writing "
2924 "superblock for %s.\n", sb->s_id); 2929 "superblock for %s.\n", sb->s_id);
2925 clear_buffer_write_io_error(sbh); 2930 clear_buffer_write_io_error(sbh);
2926 set_buffer_uptodate(sbh); 2931 set_buffer_uptodate(sbh);
2927 } 2932 }
2928 } 2933 }
2934 return error;
2929} 2935}
2930 2936
2931 2937
@@ -3058,12 +3064,14 @@ static int ext4_sync_fs(struct super_block *sb, int wait)
3058 * LVM calls this function before a (read-only) snapshot is created. This 3064 * LVM calls this function before a (read-only) snapshot is created. This
3059 * gives us a chance to flush the journal completely and mark the fs clean. 3065 * gives us a chance to flush the journal completely and mark the fs clean.
3060 */ 3066 */
3061static void ext4_write_super_lockfs(struct super_block *sb) 3067static int ext4_freeze(struct super_block *sb)
3062{ 3068{
3069 int error = 0;
3070 journal_t *journal;
3063 sb->s_dirt = 0; 3071 sb->s_dirt = 0;
3064 3072
3065 if (!(sb->s_flags & MS_RDONLY)) { 3073 if (!(sb->s_flags & MS_RDONLY)) {
3066 journal_t *journal = EXT4_SB(sb)->s_journal; 3074 journal = EXT4_SB(sb)->s_journal;
3067 3075
3068 if (journal) { 3076 if (journal) {
3069 /* Now we set up the journal barrier. */ 3077 /* Now we set up the journal barrier. */
@@ -3073,21 +3081,29 @@ static void ext4_write_super_lockfs(struct super_block *sb)
3073 * We don't want to clear needs_recovery flag when we 3081 * We don't want to clear needs_recovery flag when we
3074 * failed to flush the journal. 3082 * failed to flush the journal.
3075 */ 3083 */
3076 if (jbd2_journal_flush(journal) < 0) 3084 error = jbd2_journal_flush(journal);
3077 return; 3085 if (error < 0)
3086 goto out;
3078 } 3087 }
3079 3088
3080 /* Journal blocked and flushed, clear needs_recovery flag. */ 3089 /* Journal blocked and flushed, clear needs_recovery flag. */
3081 EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); 3090 EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
3082 ext4_commit_super(sb, EXT4_SB(sb)->s_es, 1); 3091 ext4_commit_super(sb, EXT4_SB(sb)->s_es, 1);
3092 error = ext4_commit_super(sb, EXT4_SB(sb)->s_es, 1);
3093 if (error)
3094 goto out;
3083 } 3095 }
3096 return 0;
3097out:
3098 jbd2_journal_unlock_updates(journal);
3099 return error;
3084} 3100}
3085 3101
3086/* 3102/*
3087 * Called by LVM after the snapshot is done. We need to reset the RECOVER 3103 * Called by LVM after the snapshot is done. We need to reset the RECOVER
3088 * flag here, even though the filesystem is not technically dirty yet. 3104 * flag here, even though the filesystem is not technically dirty yet.
3089 */ 3105 */
3090static void ext4_unlockfs(struct super_block *sb) 3106static int ext4_unfreeze(struct super_block *sb)
3091{ 3107{
3092 if (EXT4_SB(sb)->s_journal && !(sb->s_flags & MS_RDONLY)) { 3108 if (EXT4_SB(sb)->s_journal && !(sb->s_flags & MS_RDONLY)) {
3093 lock_super(sb); 3109 lock_super(sb);
@@ -3097,6 +3113,7 @@ static void ext4_unlockfs(struct super_block *sb)
3097 unlock_super(sb); 3113 unlock_super(sb);
3098 jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); 3114 jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal);
3099 } 3115 }
3116 return 0;
3100} 3117}
3101 3118
3102static int ext4_remount(struct super_block *sb, int *flags, char *data) 3119static int ext4_remount(struct super_block *sb, int *flags, char *data)
diff --git a/fs/gfs2/ops_super.c b/fs/gfs2/ops_super.c
index 777783deddcb..320323d03479 100644
--- a/fs/gfs2/ops_super.c
+++ b/fs/gfs2/ops_super.c
@@ -211,18 +211,18 @@ static int gfs2_sync_fs(struct super_block *sb, int wait)
211} 211}
212 212
213/** 213/**
214 * gfs2_write_super_lockfs - prevent further writes to the filesystem 214 * gfs2_freeze - prevent further writes to the filesystem
215 * @sb: the VFS structure for the filesystem 215 * @sb: the VFS structure for the filesystem
216 * 216 *
217 */ 217 */
218 218
219static void gfs2_write_super_lockfs(struct super_block *sb) 219static int gfs2_freeze(struct super_block *sb)
220{ 220{
221 struct gfs2_sbd *sdp = sb->s_fs_info; 221 struct gfs2_sbd *sdp = sb->s_fs_info;
222 int error; 222 int error;
223 223
224 if (test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) 224 if (test_bit(SDF_SHUTDOWN, &sdp->sd_flags))
225 return; 225 return -EINVAL;
226 226
227 for (;;) { 227 for (;;) {
228 error = gfs2_freeze_fs(sdp); 228 error = gfs2_freeze_fs(sdp);
@@ -242,17 +242,19 @@ static void gfs2_write_super_lockfs(struct super_block *sb)
242 fs_err(sdp, "retrying...\n"); 242 fs_err(sdp, "retrying...\n");
243 msleep(1000); 243 msleep(1000);
244 } 244 }
245 return 0;
245} 246}
246 247
247/** 248/**
248 * gfs2_unlockfs - reallow writes to the filesystem 249 * gfs2_unfreeze - reallow writes to the filesystem
249 * @sb: the VFS structure for the filesystem 250 * @sb: the VFS structure for the filesystem
250 * 251 *
251 */ 252 */
252 253
253static void gfs2_unlockfs(struct super_block *sb) 254static int gfs2_unfreeze(struct super_block *sb)
254{ 255{
255 gfs2_unfreeze_fs(sb->s_fs_info); 256 gfs2_unfreeze_fs(sb->s_fs_info);
257 return 0;
256} 258}
257 259
258/** 260/**
@@ -688,8 +690,8 @@ const struct super_operations gfs2_super_ops = {
688 .put_super = gfs2_put_super, 690 .put_super = gfs2_put_super,
689 .write_super = gfs2_write_super, 691 .write_super = gfs2_write_super,
690 .sync_fs = gfs2_sync_fs, 692 .sync_fs = gfs2_sync_fs,
691 .write_super_lockfs = gfs2_write_super_lockfs, 693 .freeze_fs = gfs2_freeze,
692 .unlockfs = gfs2_unlockfs, 694 .unfreeze_fs = gfs2_unfreeze,
693 .statfs = gfs2_statfs, 695 .statfs = gfs2_statfs,
694 .remount_fs = gfs2_remount_fs, 696 .remount_fs = gfs2_remount_fs,
695 .clear_inode = gfs2_clear_inode, 697 .clear_inode = gfs2_clear_inode,
diff --git a/fs/jfs/super.c b/fs/jfs/super.c
index 0dae345e481b..b37d1f78b854 100644
--- a/fs/jfs/super.c
+++ b/fs/jfs/super.c
@@ -543,7 +543,7 @@ out_kfree:
543 return ret; 543 return ret;
544} 544}
545 545
546static void jfs_write_super_lockfs(struct super_block *sb) 546static int jfs_freeze(struct super_block *sb)
547{ 547{
548 struct jfs_sb_info *sbi = JFS_SBI(sb); 548 struct jfs_sb_info *sbi = JFS_SBI(sb);
549 struct jfs_log *log = sbi->log; 549 struct jfs_log *log = sbi->log;
@@ -553,9 +553,10 @@ static void jfs_write_super_lockfs(struct super_block *sb)
553 lmLogShutdown(log); 553 lmLogShutdown(log);
554 updateSuper(sb, FM_CLEAN); 554 updateSuper(sb, FM_CLEAN);
555 } 555 }
556 return 0;
556} 557}
557 558
558static void jfs_unlockfs(struct super_block *sb) 559static int jfs_unfreeze(struct super_block *sb)
559{ 560{
560 struct jfs_sb_info *sbi = JFS_SBI(sb); 561 struct jfs_sb_info *sbi = JFS_SBI(sb);
561 struct jfs_log *log = sbi->log; 562 struct jfs_log *log = sbi->log;
@@ -568,6 +569,7 @@ static void jfs_unlockfs(struct super_block *sb)
568 else 569 else
569 txResume(sb); 570 txResume(sb);
570 } 571 }
572 return 0;
571} 573}
572 574
573static int jfs_get_sb(struct file_system_type *fs_type, 575static int jfs_get_sb(struct file_system_type *fs_type,
@@ -735,8 +737,8 @@ static const struct super_operations jfs_super_operations = {
735 .delete_inode = jfs_delete_inode, 737 .delete_inode = jfs_delete_inode,
736 .put_super = jfs_put_super, 738 .put_super = jfs_put_super,
737 .sync_fs = jfs_sync_fs, 739 .sync_fs = jfs_sync_fs,
738 .write_super_lockfs = jfs_write_super_lockfs, 740 .freeze_fs = jfs_freeze,
739 .unlockfs = jfs_unlockfs, 741 .unfreeze_fs = jfs_unfreeze,
740 .statfs = jfs_statfs, 742 .statfs = jfs_statfs,
741 .remount_fs = jfs_remount, 743 .remount_fs = jfs_remount,
742 .show_options = jfs_show_options, 744 .show_options = jfs_show_options,
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index c55651f1407c..f3c820b75829 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -83,7 +83,7 @@ static void reiserfs_write_super(struct super_block *s)
83 reiserfs_sync_fs(s, 1); 83 reiserfs_sync_fs(s, 1);
84} 84}
85 85
86static void reiserfs_write_super_lockfs(struct super_block *s) 86static int reiserfs_freeze(struct super_block *s)
87{ 87{
88 struct reiserfs_transaction_handle th; 88 struct reiserfs_transaction_handle th;
89 reiserfs_write_lock(s); 89 reiserfs_write_lock(s);
@@ -101,11 +101,13 @@ static void reiserfs_write_super_lockfs(struct super_block *s)
101 } 101 }
102 s->s_dirt = 0; 102 s->s_dirt = 0;
103 reiserfs_write_unlock(s); 103 reiserfs_write_unlock(s);
104 return 0;
104} 105}
105 106
106static void reiserfs_unlockfs(struct super_block *s) 107static int reiserfs_unfreeze(struct super_block *s)
107{ 108{
108 reiserfs_allow_writes(s); 109 reiserfs_allow_writes(s);
110 return 0;
109} 111}
110 112
111extern const struct in_core_key MAX_IN_CORE_KEY; 113extern const struct in_core_key MAX_IN_CORE_KEY;
@@ -613,8 +615,8 @@ static const struct super_operations reiserfs_sops = {
613 .put_super = reiserfs_put_super, 615 .put_super = reiserfs_put_super,
614 .write_super = reiserfs_write_super, 616 .write_super = reiserfs_write_super,
615 .sync_fs = reiserfs_sync_fs, 617 .sync_fs = reiserfs_sync_fs,
616 .write_super_lockfs = reiserfs_write_super_lockfs, 618 .freeze_fs = reiserfs_freeze,
617 .unlockfs = reiserfs_unlockfs, 619 .unfreeze_fs = reiserfs_unfreeze,
618 .statfs = reiserfs_statfs, 620 .statfs = reiserfs_statfs,
619 .remount_fs = reiserfs_remount, 621 .remount_fs = reiserfs_remount,
620 .show_options = generic_show_options, 622 .show_options = generic_show_options,
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index be846d606ae8..95a971080368 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -1269,14 +1269,14 @@ xfs_fs_remount(
1269 * need to take care of the metadata. Once that's done write a dummy 1269 * need to take care of the metadata. Once that's done write a dummy
1270 * record to dirty the log in case of a crash while frozen. 1270 * record to dirty the log in case of a crash while frozen.
1271 */ 1271 */
1272STATIC void 1272STATIC int
1273xfs_fs_lockfs( 1273xfs_fs_freeze(
1274 struct super_block *sb) 1274 struct super_block *sb)
1275{ 1275{
1276 struct xfs_mount *mp = XFS_M(sb); 1276 struct xfs_mount *mp = XFS_M(sb);
1277 1277
1278 xfs_quiesce_attr(mp); 1278 xfs_quiesce_attr(mp);
1279 xfs_fs_log_dummy(mp); 1279 return -xfs_fs_log_dummy(mp);
1280} 1280}
1281 1281
1282STATIC int 1282STATIC int
@@ -1557,7 +1557,7 @@ static struct super_operations xfs_super_operations = {
1557 .put_super = xfs_fs_put_super, 1557 .put_super = xfs_fs_put_super,
1558 .write_super = xfs_fs_write_super, 1558 .write_super = xfs_fs_write_super,
1559 .sync_fs = xfs_fs_sync_super, 1559 .sync_fs = xfs_fs_sync_super,
1560 .write_super_lockfs = xfs_fs_lockfs, 1560 .freeze_fs = xfs_fs_freeze,
1561 .statfs = xfs_fs_statfs, 1561 .statfs = xfs_fs_statfs,
1562 .remount_fs = xfs_fs_remount, 1562 .remount_fs = xfs_fs_remount,
1563 .show_options = xfs_fs_show_options, 1563 .show_options = xfs_fs_show_options,
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
index 852b6d32e8d0..680d0e0ec932 100644
--- a/fs/xfs/xfs_fsops.c
+++ b/fs/xfs/xfs_fsops.c
@@ -595,17 +595,19 @@ out:
595 return 0; 595 return 0;
596} 596}
597 597
598void 598int
599xfs_fs_log_dummy( 599xfs_fs_log_dummy(
600 xfs_mount_t *mp) 600 xfs_mount_t *mp)
601{ 601{
602 xfs_trans_t *tp; 602 xfs_trans_t *tp;
603 xfs_inode_t *ip; 603 xfs_inode_t *ip;
604 int error;
604 605
605 tp = _xfs_trans_alloc(mp, XFS_TRANS_DUMMY1); 606 tp = _xfs_trans_alloc(mp, XFS_TRANS_DUMMY1);
606 if (xfs_trans_reserve(tp, 0, XFS_ICHANGE_LOG_RES(mp), 0, 0, 0)) { 607 error = xfs_trans_reserve(tp, 0, XFS_ICHANGE_LOG_RES(mp), 0, 0, 0);
608 if (error) {
607 xfs_trans_cancel(tp, 0); 609 xfs_trans_cancel(tp, 0);
608 return; 610 return error;
609 } 611 }
610 612
611 ip = mp->m_rootip; 613 ip = mp->m_rootip;
@@ -615,9 +617,10 @@ xfs_fs_log_dummy(
615 xfs_trans_ihold(tp, ip); 617 xfs_trans_ihold(tp, ip);
616 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 618 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
617 xfs_trans_set_sync(tp); 619 xfs_trans_set_sync(tp);
618 xfs_trans_commit(tp, 0); 620 error = xfs_trans_commit(tp, 0);
619 621
620 xfs_iunlock(ip, XFS_ILOCK_EXCL); 622 xfs_iunlock(ip, XFS_ILOCK_EXCL);
623 return error;
621} 624}
622 625
623int 626int
diff --git a/fs/xfs/xfs_fsops.h b/fs/xfs/xfs_fsops.h
index 300d0c9d61ad..88435e0a77c9 100644
--- a/fs/xfs/xfs_fsops.h
+++ b/fs/xfs/xfs_fsops.h
@@ -25,6 +25,6 @@ extern int xfs_fs_counts(xfs_mount_t *mp, xfs_fsop_counts_t *cnt);
25extern int xfs_reserve_blocks(xfs_mount_t *mp, __uint64_t *inval, 25extern int xfs_reserve_blocks(xfs_mount_t *mp, __uint64_t *inval,
26 xfs_fsop_resblks_t *outval); 26 xfs_fsop_resblks_t *outval);
27extern int xfs_fs_goingdown(xfs_mount_t *mp, __uint32_t inflags); 27extern int xfs_fs_goingdown(xfs_mount_t *mp, __uint32_t inflags);
28extern void xfs_fs_log_dummy(xfs_mount_t *mp); 28extern int xfs_fs_log_dummy(xfs_mount_t *mp);
29 29
30#endif /* __XFS_FSOPS_H__ */ 30#endif /* __XFS_FSOPS_H__ */
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 0b87b29f4797..3e59182de9df 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1377,8 +1377,8 @@ struct super_operations {
1377 void (*put_super) (struct super_block *); 1377 void (*put_super) (struct super_block *);
1378 void (*write_super) (struct super_block *); 1378 void (*write_super) (struct super_block *);
1379 int (*sync_fs)(struct super_block *sb, int wait); 1379 int (*sync_fs)(struct super_block *sb, int wait);
1380 void (*write_super_lockfs) (struct super_block *); 1380 int (*freeze_fs) (struct super_block *);
1381 void (*unlockfs) (struct super_block *); 1381 int (*unfreeze_fs) (struct super_block *);
1382 int (*statfs) (struct dentry *, struct kstatfs *); 1382 int (*statfs) (struct dentry *, struct kstatfs *);
1383 int (*remount_fs) (struct super_block *, int *, char *); 1383 int (*remount_fs) (struct super_block *, int *, char *);
1384 void (*clear_inode) (struct inode *); 1384 void (*clear_inode) (struct inode *);