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 ();