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/