[LWN Logo]
[LWN.net]
From:	 Andrew Morton <akpm@zip.com.au>
To:	 lkml <linux-kernel@vger.kernel.org>
Subject: synchronous mounts
Date:	 Thu, 15 Nov 2001 00:03:57 -0800
Cc:	 Neil Brown <neilb@cse.unsw.edu.au>

Linux is not syncing write() data for files on synchronously mounted
filesystems, and it isn't syncing write() data for ext2/3 files which
are operating under `chattr +S'.

Is this deliberate, or a bug?

This patch makes write()s data-synchronous.  There's a fix-for-the-fix
here for ext3.  Other filesystems which are second-guessing the generic
layer's behaviour may also end up doing a double sync with this patch.

Really, generic_osync_inode() needs to be front-ended by
an inode_operations method.


--- linux-2.4.15-pre4/mm/filemap.c	Mon Nov 12 11:16:12 2001
+++ linux-akpm/mm/filemap.c	Wed Nov 14 22:50:25 2001
@@ -2916,8 +2916,10 @@ unlock:
 
 	/* For now, when the user asks for O_SYNC, we'll actually
 	 * provide O_DSYNC. */
-	if ((status >= 0) && (file->f_flags & O_SYNC))
-		status = generic_osync_inode(inode, OSYNC_METADATA|OSYNC_DATA);
+	if (status >= 0) {
+		if ((file->f_flags & O_SYNC) || IS_SYNC(inode))
+			status = generic_osync_inode(inode, OSYNC_METADATA|OSYNC_DATA);
+	}
 	
 	err = written ? written : status;
 out:
--- linux-2.4.15-pre4/fs/ext3/file.c	Mon Nov 12 11:16:12 2001
+++ linux-akpm/fs/ext3/file.c	Wed Nov 14 23:52:08 2001
@@ -61,22 +61,19 @@ static int ext3_open_file (struct inode 
 static ssize_t
 ext3_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
 {
-	int ret;
 	struct inode *inode = file->f_dentry->d_inode;
 
-	ret = generic_file_write(file, buf, count, ppos);
-	if ((ret >= 0) && IS_SYNC(inode)) {
-		if (file->f_flags & O_SYNC) {
-			/*
-			 * generic_osync_inode() has already done the sync
-			 */
-		} else {
-			int ret2 = ext3_force_commit(inode->i_sb);
-			if (ret2)
-				ret = ret2;
-		}
-	}
-	return ret;
+	/*
+	 * Nasty: if the file is subject to synchronous writes then we need
+	 * to force generic_osync_inode() to call ext3_write_inode().
+	 * We do that by marking the inode dirty.  This adds much more
+	 * computational expense than we need, but we're going to sync
+	 * anyway.
+	 */
+	if (IS_SYNC(inode) || (file->f_flags & O_SYNC))
+		mark_inode_dirty(inode);
+
+	return generic_file_write(file, buf, count, ppos);
 }
 
 struct file_operations ext3_file_operations = {
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/