From 75f19a4075dff845fbc1a2940c6aee9cd4891b2e Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Sat, 14 Dec 2002 03:17:26 -0800 Subject: [PATCH] Add a sync_fs super_block operation This is infrastructure for fixing the journalled-data ext3 unmount data loss problem. It was sent for comment to linux-fsdevel a week ago; there was none. Add a `sync_fs' superblock operation whose mandate is to perform filesystem-specific operations to ensure a successful sync. It is called in two places: 1: fsync_super() - for umount. 2: sys_sync() - for global sync. In the sys_sync() case we call all the ->write_super() methods first. write_super() is an async flushing operation. It should not block. After that, we call all the ->sync_fs functions. This is independent of the state of s_dirt! That was all confused up before, and in this patch ->write_super() and ->sync_fs() are quite separate. With ext3 as an example, the initial ->write_super() will start a transaction, but will not wait on it. (But only if s_dirt was set!) The first ->sync_fs() call will get the IO underway. The second ->sync_fs() call will wait on the IO. And we really do need to be this elaborate, because all the testing of s_dirt in there makes ->write_super() an unreliable way of detecting when the VFS is trying to sync the filesystem. --- include/linux/fs.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux/fs.h') diff --git a/include/linux/fs.h b/include/linux/fs.h index f39d21e5bcd9..afbb9474f25b 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -631,6 +631,7 @@ struct super_block { struct semaphore s_lock; int s_count; int s_syncing; + int s_need_sync_fs; atomic_t s_active; void *s_security; @@ -810,6 +811,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 *sb, int wait); void (*write_super_lockfs) (struct super_block *); void (*unlockfs) (struct super_block *); int (*statfs) (struct super_block *, struct statfs *); @@ -1143,6 +1145,7 @@ extern void write_inode_now(struct inode *, int); extern int filemap_fdatawrite(struct address_space *); extern int filemap_fdatawait(struct address_space *); extern void sync_supers(void); +extern void sync_filesystems(int wait); extern sector_t bmap(struct inode *, sector_t); extern int setattr_mask(unsigned int); extern int notify_change(struct dentry *, struct iattr *); -- cgit v1.2.3