aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/buffer.c43
-rw-r--r--include/linux/fs.h1
2 files changed, 24 insertions, 20 deletions
diff --git a/fs/buffer.c b/fs/buffer.c
index 24262ea8cc5..6d77ce9f54e 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -327,31 +327,24 @@ int file_fsync(struct file *filp, struct dentry *dentry, int datasync)
return ret;
}
-static long do_fsync(unsigned int fd, int datasync)
+long do_fsync(struct file *file, int datasync)
{
- struct file * file;
- struct address_space *mapping;
- int ret, err;
-
- ret = -EBADF;
- file = fget(fd);
- if (!file)
- goto out;
+ int ret;
+ int err;
+ struct address_space *mapping = file->f_mapping;
- ret = -EINVAL;
if (!file->f_op || !file->f_op->fsync) {
/* Why? We can still call filemap_fdatawrite */
- goto out_putf;
+ ret = -EINVAL;
+ goto out;
}
- mapping = file->f_mapping;
-
current->flags |= PF_SYNCWRITE;
ret = filemap_fdatawrite(mapping);
/*
- * We need to protect against concurrent writers,
- * which could cause livelocks in fsync_buffers_list
+ * 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, file->f_dentry, datasync);
@@ -362,21 +355,31 @@ static long do_fsync(unsigned int fd, int datasync)
if (!ret)
ret = err;
current->flags &= ~PF_SYNCWRITE;
-
-out_putf:
- fput(file);
out:
return ret;
}
+static long __do_fsync(unsigned int fd, int datasync)
+{
+ struct file *file;
+ int ret = -EBADF;
+
+ file = fget(fd);
+ if (file) {
+ ret = do_fsync(file, datasync);
+ fput(file);
+ }
+ return ret;
+}
+
asmlinkage long sys_fsync(unsigned int fd)
{
- return do_fsync(fd, 0);
+ return __do_fsync(fd, 0);
}
asmlinkage long sys_fdatasync(unsigned int fd)
{
- return do_fsync(fd, 1);
+ return __do_fsync(fd, 1);
}
/*
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 092cfaee0cd..215696a0f16 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1478,6 +1478,7 @@ extern int wait_on_page_writeback_range(struct address_space *mapping,
extern int __filemap_fdatawrite_range(struct address_space *mapping,
loff_t start, loff_t end, int sync_mode);
+extern long do_fsync(struct file *file, int datasync);
extern void sync_supers(void);
extern void sync_filesystems(int wait);
extern void emergency_sync(void);