On Fri, Aug 03, 2001 at 06:34:14PM +0000, Linus Torvalds wrote:
fsync(int fd)
{
dentry = fdget(fd);
do_fsync(dentry);
for (;;) {
tmp = dentry;
dentry = dentry->d_parent;
if (dentry == tmp)
break;
do_fdatasync(dentry);
}
}
I really like this idea. Can people please try out the attached patch?
Please note, it contains a couple of things that need not be there in
the final version.
Note, there is also a reiserfs fix in here because we can call
f_op->fsync on a directory and without this fix it will BUG! Chris,
perhaps you can suggest a better fix?
Linus, one more thing --- the first argument to ->fsync is struct file*
and nothing uses it, I'd like to blow it away or would you prefer we
wait to 2.5.x as its essentially and API change and will break XFS,
JFS, etc.
--cw
--uAKRQypu60I7Lcqm
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="2.4.8-pre3_fsync-entire-path.patch"
diff -Nur --exclude=*.o --exclude=*~ linux-2.4.8-pre3/fs/buffer.c linux-2.4.8-pre3+expt/fs/buffer.c
--- linux-2.4.8-pre3/fs/buffer.c Wed Jul 25 19:03:05 2001
+++ linux-2.4.8-pre3+expt/fs/buffer.c Sat Aug 4 10:53:07 2001
@@ -379,33 +379,45 @@
asmlinkage long sys_fsync(unsigned int fd)
{
- struct file * file;
- struct dentry * dentry;
- struct inode * inode;
+ struct file *file;
+ struct dentry *dentry;
+ struct inode *inode;
int err;
err = -EBADF;
file = fget(fd);
if (!file)
goto out;
-
- dentry = file->f_dentry;
- inode = dentry->d_inode;
-
err = -EINVAL;
if (!file->f_op || !file->f_op->fsync)
goto out_putf;
- /* We need to protect against concurrent writers.. */
- down(&inode->i_sem);
- filemap_fdatasync(inode->i_mapping);
- err = file->f_op->fsync(file, dentry, 0);
- filemap_fdatawait(inode->i_mapping);
- up(&inode->i_sem);
+ /* walk the path (dentry chain) fsync'ing everything along
+ it. This algorithm to do "do what the user _expects_ you to
+ do" was suggested by Linus. --cw */
+ dentry = file->f_dentry;
+ do {
+ inode = dentry->d_inode;
+ /* We need to protect against concurrent writers.. */
+ down(&inode->i_sem);
+ filemap_fdatasync(inode->i_mapping);
+ err = -EINVAL;
+ if (!file->f_op || !file->f_op->fsync)
+ goto out_putf;
+ err = file->f_op->fsync(file, dentry, 0);
+ filemap_fdatawait(inode->i_mapping);
+ up(&inode->i_sem);
+
+ /* stop at root of fs */
+ if(dentry == dentry->d_parent)
+ break;
+
+ dentry = dentry->d_parent;
+ } while(dentry && !err);
-out_putf:
+ out_putf:
fput(file);
-out:
+ out:
return err;
}
diff -Nur --exclude=*.o --exclude=*~ linux-2.4.8-pre3/fs/reiserfs/file.c linux-2.4.8-pre3+expt/fs/reiserfs/file.c
--- linux-2.4.8-pre3/fs/reiserfs/file.c Fri Jul 20 20:37:09 2001
+++ linux-2.4.8-pre3+expt/fs/reiserfs/file.c Sat Aug 4 09:06:14 2001
@@ -90,6 +90,9 @@
lock_kernel() ;
+ if (S_ISDIR(p_s_inode->i_mode))
+ return reiserfs_dir_fsync(p_s_filp, p_s_dentry, datasync);
+
if (!S_ISREG(p_s_inode->i_mode))
BUG ();
--uAKRQypu60I7Lcqm--
-
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/