* fix for the ext3 data=journal unmount problem
@ 2002-12-04 5:27 Andrew Morton
2002-12-05 16:34 ` Stephen C. Tweedie
0 siblings, 1 reply; 3+ messages in thread
From: Andrew Morton @ 2002-12-04 5:27 UTC (permalink / raw)
To: linux-fsdevel, ext2-devel
Well here's what I have, for 2.4.20:
- Add a new super_block operation `sync_fs'. It is called when the
VFS wants to sync the filesystem for "data integrity" purposes.
That's sys_sync and unmount.
- Implement ext3_sync_fs(). It runs a commit and waits on it.
Which is cheating, really - there's still unwritten data. But
we "know" that the VFS will write that.
ext3_write_super() is used on the kupdate path, and is nonblocking.
fs/buffer.c | 6 ++++--
fs/ext3/super.c | 25 +++++++++++++------------
fs/super.c | 6 +++++-
include/linux/fs.h | 3 ++-
4 files changed, 24 insertions(+), 16 deletions(-)
--- linux-akpm/fs/buffer.c~sync_fs Tue Dec 3 12:08:59 2002
+++ linux-akpm-akpm/fs/buffer.c Tue Dec 3 12:09:54 2002
@@ -327,6 +327,8 @@ int fsync_super(struct super_block *sb)
lock_super(sb);
if (sb->s_dirt && sb->s_op && sb->s_op->write_super)
sb->s_op->write_super(sb);
+ if (sb->s_op && sb->s_op->sync_fs)
+ sb->s_op->sync_fs(sb);
unlock_super(sb);
unlock_kernel();
@@ -346,7 +348,7 @@ int fsync_dev(kdev_t dev)
lock_kernel();
sync_inodes(dev);
DQUOT_SYNC(dev);
- sync_supers(dev);
+ sync_supers(dev, 1);
unlock_kernel();
return sync_buffers(dev, 1);
@@ -2833,7 +2835,7 @@ static int sync_old_buffers(void)
{
lock_kernel();
sync_unlocked_inodes();
- sync_supers(0);
+ sync_supers(0, 0);
unlock_kernel();
for (;;) {
--- linux-akpm/include/linux/fs.h~sync_fs Tue Dec 3 12:08:59 2002
+++ linux-akpm-akpm/include/linux/fs.h Tue Dec 3 21:02:03 2002
@@ -894,6 +894,7 @@ struct super_operations {
void (*delete_inode) (struct inode *);
void (*put_super) (struct super_block *);
void (*write_super) (struct super_block *);
+ int (*sync_fs) (struct super_block *);
void (*write_super_lockfs) (struct super_block *);
void (*unlockfs) (struct super_block *);
int (*statfs) (struct super_block *, struct statfs *);
@@ -1240,7 +1241,7 @@ static inline int fsync_inode_data_buffe
extern int inode_has_buffers(struct inode *);
extern int filemap_fdatasync(struct address_space *);
extern int filemap_fdatawait(struct address_space *);
-extern void sync_supers(kdev_t);
+extern void sync_supers(kdev_t dev, int wait);
extern int bmap(struct inode *, int);
extern int notify_change(struct dentry *, struct iattr *);
extern int permission(struct inode *, int);
--- linux-akpm/fs/super.c~sync_fs Tue Dec 3 12:08:59 2002
+++ linux-akpm-akpm/fs/super.c Tue Dec 3 12:10:24 2002
@@ -445,7 +445,7 @@ static inline void write_super(struct su
* hold up the sync while mounting a device. (The newly
* mounted device won't need syncing.)
*/
-void sync_supers(kdev_t dev)
+void sync_supers(kdev_t dev, int wait)
{
struct super_block * sb;
@@ -454,6 +454,8 @@ void sync_supers(kdev_t dev)
if (sb) {
if (sb->s_dirt)
write_super(sb);
+ if (wait && sb->s_op && sb->s_op->sync_fs)
+ sb->s_op->sync_fs(sb);
drop_super(sb);
}
return;
@@ -467,6 +469,8 @@ restart:
spin_unlock(&sb_lock);
down_read(&sb->s_umount);
write_super(sb);
+ if (wait && sb->s_op && sb->s_op->sync_fs)
+ sb->s_op->sync_fs(sb);
drop_super(sb);
goto restart;
} else
--- linux-akpm/fs/ext3/super.c~sync_fs Tue Dec 3 21:12:57 2002
+++ linux-akpm-akpm/fs/ext3/super.c Tue Dec 3 21:13:04 2002
@@ -47,6 +47,8 @@ static void ext3_mark_recovery_complete(
static void ext3_clear_journal_err(struct super_block * sb,
struct ext3_super_block * es);
+static int ext3_sync_fs(struct super_block * sb);
+
#ifdef CONFIG_JBD_DEBUG
int journal_no_write[2];
@@ -454,6 +456,7 @@ static struct super_operations ext3_sops
delete_inode: ext3_delete_inode, /* BKL not held. We take it */
put_super: ext3_put_super, /* BKL held */
write_super: ext3_write_super, /* BKL held */
+ sync_fs: ext3_sync_fs,
write_super_lockfs: ext3_write_super_lockfs, /* BKL not held. Take it */
unlockfs: ext3_unlockfs, /* BKL not held. We take it */
statfs: ext3_statfs, /* BKL held */
@@ -1577,24 +1580,22 @@ int ext3_force_commit(struct super_block
* This implicitly triggers the writebehind on sync().
*/
-static int do_sync_supers = 0;
-MODULE_PARM(do_sync_supers, "i");
-MODULE_PARM_DESC(do_sync_supers, "Write superblocks synchronously");
-
void ext3_write_super (struct super_block * sb)
{
+ if (down_trylock(&sb->s_lock) == 0)
+ BUG();
+ sb->s_dirt = 0;
+ log_start_commit(EXT3_SB(sb)->s_journal, NULL);
+}
+
+static int ext3_sync_fs(struct super_block *sb)
+{
tid_t target;
- if (down_trylock(&sb->s_lock) == 0)
- BUG(); /* aviro detector */
sb->s_dirt = 0;
target = log_start_commit(EXT3_SB(sb)->s_journal, NULL);
-
- if (do_sync_supers) {
- unlock_super(sb);
- log_wait_commit(EXT3_SB(sb)->s_journal, target);
- lock_super(sb);
- }
+ log_wait_commit(EXT3_SB(sb)->s_journal, target);
+ return 0;
}
/*
_
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2002-12-06 18:55 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-12-04 5:27 fix for the ext3 data=journal unmount problem Andrew Morton
2002-12-05 16:34 ` Stephen C. Tweedie
2002-12-06 18:55 ` [Ext2-devel] " Stephen C. Tweedie
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).