USB: ftdi_sio: fix status line change handling for TIOCMIWAIT and TIOCGICOUNT
[linux-flexiantxendom0.git] / fs / sync.c
index c9f83f4..101b8ef 100644 (file)
--- a/fs/sync.c
+++ b/fs/sync.c
@@ -7,6 +7,7 @@
 #include <linux/fs.h>
 #include <linux/slab.h>
 #include <linux/module.h>
+#include <linux/namei.h>
 #include <linux/sched.h>
 #include <linux/writeback.h>
 #include <linux/syscalls.h>
@@ -33,7 +34,7 @@ static int __sync_filesystem(struct super_block *sb, int wait)
         * This should be safe, as we require bdi backing to actually
         * write out data in the first place
         */
-       if (!sb->s_bdi || sb->s_bdi == &noop_backing_dev_info)
+       if (sb->s_bdi == &noop_backing_dev_info)
                return 0;
 
        if (sb->s_qcop && sb->s_qcop->quota_sync)
@@ -42,7 +43,7 @@ static int __sync_filesystem(struct super_block *sb, int wait)
        if (wait)
                sync_inodes_sb(sb);
        else
-               writeback_inodes_sb_locked(sb);
+               writeback_inodes_sb(sb, WB_REASON_SYNC);
 
        if (sb->s_op->sync_fs)
                sb->s_op->sync_fs(sb, wait);
@@ -79,7 +80,7 @@ EXPORT_SYMBOL_GPL(sync_filesystem);
 
 static void sync_one_sb(struct super_block *sb, void *arg)
 {
-       if (!(sb->s_flags & MS_RDONLY) && sb->s_bdi)
+       if (!(sb->s_flags & MS_RDONLY))
                __sync_filesystem(sb, *(int *)arg);
 }
 /*
@@ -97,7 +98,7 @@ static void sync_filesystems(int wait)
  */
 SYSCALL_DEFINE0(sync)
 {
-       wakeup_flusher_threads(0);
+       wakeup_flusher_threads(0, WB_REASON_SYNC);
        sync_filesystems(0);
        sync_filesystems(1);
        if (unlikely(laptop_mode))
@@ -129,29 +130,27 @@ void emergency_sync(void)
 }
 
 /*
- * Generic function to fsync a file.
+ * sync a single super
  */
-int file_fsync(struct file *filp, int datasync)
+SYSCALL_DEFINE1(syncfs, int, fd)
 {
-       struct inode *inode = filp->f_mapping->host;
-       struct super_block * sb;
-       int ret, err;
-
-       /* sync the inode to buffers */
-       ret = write_inode_now(inode, 0);
-
-       /* sync the superblock to buffers */
-       sb = inode->i_sb;
-       if (sb->s_dirt && sb->s_op->write_super)
-               sb->s_op->write_super(sb);
-
-       /* .. finally sync the buffers to disk */
-       err = sync_blockdev(sb->s_bdev);
-       if (!ret)
-               ret = err;
+       struct file *file;
+       struct super_block *sb;
+       int ret;
+       int fput_needed;
+
+       file = fget_light(fd, &fput_needed);
+       if (!file)
+               return -EBADF;
+       sb = file->f_dentry->d_sb;
+
+       down_read(&sb->s_umount);
+       ret = sync_filesystem(sb);
+       up_read(&sb->s_umount);
+
+       fput_light(file, fput_needed);
        return ret;
 }
-EXPORT_SYMBOL(file_fsync);
 
 /**
  * vfs_fsync_range - helper to sync a range of data & metadata to disk
@@ -166,28 +165,9 @@ EXPORT_SYMBOL(file_fsync);
  */
 int vfs_fsync_range(struct file *file, loff_t start, loff_t end, int datasync)
 {
-       struct address_space *mapping = file->f_mapping;
-       int err, ret;
-
-       if (!file->f_op || !file->f_op->fsync) {
-               ret = -EINVAL;
-               goto out;
-       }
-
-       ret = filemap_write_and_wait_range(mapping, start, end);
-
-       /*
-        * We need to protect against concurrent writers, which could cause
-        * livelocks in fsync_buffers_list().
-        */
-       mutex_lock(&mapping->host->i_mutex);
-       err = file->f_op->fsync(file, datasync);
-       if (!ret)
-               ret = err;
-       mutex_unlock(&mapping->host->i_mutex);
-
-out:
-       return ret;
+       if (!file->f_op || !file->f_op->fsync)
+               return -EINVAL;
+       return file->f_op->fsync(file, start, end, datasync);
 }
 EXPORT_SYMBOL(vfs_fsync_range);