All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.