linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* sync_fs for 2.5
@ 2002-12-10 20:01 Andrew Morton
  0 siblings, 0 replies; only message in thread
From: Andrew Morton @ 2002-12-10 20:01 UTC (permalink / raw)
  To: linux-fsdevel@vger.kernel.org

Here's my shot at a 2.5 version of the sync_fs() superblock operation.
It is more elaborate than in 2.4 - it is independent of s_dirt, and
does a two pass operation.  The first to get IO underway, the second
to wait on it.

Seeking comments...


 Documentation/filesystems/Locking |    2 +
 fs/buffer.c                       |   11 ++++++--
 fs/super.c                        |   48 +++++++++++++++++++++++++++++++++++---
 include/linux/fs.h                |    3 ++
 4 files changed, 58 insertions(+), 6 deletions(-)

--- 25/fs/buffer.c~sync_fs	Fri Dec  6 12:54:47 2002
+++ 25-akpm/fs/buffer.c	Fri Dec  6 13:23:32 2002
@@ -222,6 +222,9 @@ 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, 1);
+	}
 	unlock_super(sb);
 	sync_blockdev(sb->s_bdev);
 	sync_inodes_sb(sb, 1);
@@ -252,10 +255,12 @@ int fsync_bdev(struct block_device *bdev
 asmlinkage long sys_sync(void)
 {
 	wakeup_bdflush(0);
-	sync_inodes(0);	/* All mappings and inodes, including block devices */
+	sync_inodes(0);		/* All mappings, inodes and their blockdevs */
 	DQUOT_SYNC(NULL);
-	sync_supers();	/* Write the superblocks */
-	sync_inodes(1);	/* All the mappings and inodes, again. */
+	sync_supers();		/* Write the superblocks */
+	sync_filesystems(0);	/* Start syncing the filesystems */
+	sync_filesystems(1);	/* Waitingly sync the filesystems */
+	sync_inodes(1);		/* Mappings, inodes and blockdevs, again. */
 	return 0;
 }
 
--- 25/include/linux/fs.h~sync_fs	Fri Dec  6 12:54:47 2002
+++ 25-akpm/include/linux/fs.h	Fri Dec  6 13:23:56 2002
@@ -632,6 +632,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
 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 *);
--- 25/fs/super.c~sync_fs	Fri Dec  6 12:54:47 2002
+++ 25-akpm/fs/super.c	Fri Dec  6 13:27:10 2002
@@ -189,6 +189,8 @@ void generic_shutdown_super(struct super
 		if (sop) {
 			if (sop->write_super && sb->s_dirt)
 				sop->write_super(sb);
+			if (sop->sync_fs)
+				sop->sync_fs(sb, 1);
 			if (sop->put_super)
 				sop->put_super(sb);
 		}
@@ -266,8 +268,8 @@ void drop_super(struct super_block *sb)
 static inline void write_super(struct super_block *sb)
 {
 	lock_super(sb);
-	if (sb->s_root && sb->s_dirt)
-		if (sb->s_op && sb->s_op->write_super)
+	if (sb->s_op && sb->s_root && sb->s_dirt)
+		if (sb->s_op->write_super)
 			sb->s_op->write_super(sb);
 	unlock_super(sb);
 }
@@ -277,7 +279,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(void)
+void sync_supers()
 {
 	struct super_block * sb;
 restart:
@@ -296,6 +298,46 @@ restart:
 	spin_unlock(&sb_lock);
 }
 
+/*
+ * Call the ->sync_fs super_op against all filesytems which are r/w and
+ * which implement it.
+ */
+void sync_filesystems(int wait)
+{
+	struct super_block * sb;
+
+	spin_lock(&sb_lock);
+	for (sb = sb_entry(super_blocks.next); sb != sb_entry(&super_blocks);
+			sb = sb_entry(sb->s_list.next)) {
+		if (!sb->s_op)
+			continue;
+		if (!sb->s_op->sync_fs);
+			continue;
+		if (sb->s_flags & MS_RDONLY)
+			continue;
+		sb->s_need_sync_fs = 1;
+	}
+	spin_unlock(&sb_lock);
+
+restart:
+	spin_lock(&sb_lock);
+	for (sb = sb_entry(super_blocks.next); sb != sb_entry(&super_blocks);
+			sb = sb_entry(sb->s_list.next)) {
+		if (!sb->s_need_sync_fs)
+			continue;
+		sb->s_need_sync_fs = 0;
+		if (sb->s_flags & MS_RDONLY)
+			continue;	/* hm.  Was remounted r/w meanwhile */
+		sb->s_count++;
+		spin_unlock(&sb_lock);
+		down_read(&sb->s_umount);
+		sb->s_op->sync_fs(sb, wait);
+		drop_super(sb);
+		goto restart;
+	}
+	spin_unlock(&sb_lock);
+}
+
 /**
  *	get_super	-	get the superblock of a device
  *	@dev: device to get the superblock for
--- 25/Documentation/filesystems/Locking~sync_fs	Fri Dec  6 12:54:47 2002
+++ 25-akpm/Documentation/filesystems/Locking	Fri Dec  6 12:54:47 2002
@@ -92,6 +92,7 @@ prototypes:
 	void (*delete_inode) (struct inode *);
 	void (*put_super) (struct super_block *);
 	void (*write_super) (struct super_block *);
+	void (*sync_fs) (struct super_block *);
 	int (*statfs) (struct super_block *, struct statfs *);
 	int (*remount_fs) (struct super_block *, int *, char *);
 	void (*clear_inode) (struct inode *);
@@ -108,6 +109,7 @@ delete_inode:	no	
 clear_inode:	no	
 put_super:	yes	yes	maybe		(see below)
 write_super:	no	yes	maybe		(see below)
+sync_fs:	no	no	maybe		(see below)
 statfs:		no	no	no
 remount_fs:	yes	yes	maybe		(see below)
 umount_begin:	yes	no	maybe		(see below)

_

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2002-12-10 20:02 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-12-10 20:01 sync_fs for 2.5 Andrew Morton

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).