synchronous mounts

Andrew Morton (akpm@zip.com.au)
Thu, 15 Nov 2001 00:03:57 -0800


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/