diff options
| author | Andrew Morton <akpm@digeo.com> | 2002-12-14 03:17:26 -0800 |
|---|---|---|
| committer | Jaroslav Kysela <perex@suse.cz> | 2002-12-14 03:17:26 -0800 |
| commit | 75f19a4075dff845fbc1a2940c6aee9cd4891b2e (patch) | |
| tree | 0d7f53f2781717d031af349742a58094bea98ea8 /include/linux/fs.h | |
| parent | 7404e32c0f2dbd8cbca0126d7a46099ff1c4d57d (diff) | |
[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.
Diffstat (limited to 'include/linux/fs.h')
| -rw-r--r-- | include/linux/fs.h | 3 |
1 files changed, 3 insertions, 0 deletions
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 *); |
