aboutsummaryrefslogtreecommitdiffstats
path: root/fs/sync.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/sync.c')
-rw-r--r--fs/sync.c48
1 files changed, 37 insertions, 11 deletions
diff --git a/fs/sync.c b/fs/sync.c
index 2967562d416f..0921d6d4b5e6 100644
--- a/fs/sync.c
+++ b/fs/sync.c
@@ -75,14 +75,39 @@ int file_fsync(struct file *filp, struct dentry *dentry, int datasync)
75 return ret; 75 return ret;
76} 76}
77 77
78long do_fsync(struct file *file, int datasync) 78/**
79 * vfs_fsync - perform a fsync or fdatasync on a file
80 * @file: file to sync
81 * @dentry: dentry of @file
82 * @data: only perform a fdatasync operation
83 *
84 * Write back data and metadata for @file to disk. If @datasync is
85 * set only metadata needed to access modified file data is written.
86 *
87 * In case this function is called from nfsd @file may be %NULL and
88 * only @dentry is set. This can only happen when the filesystem
89 * implements the export_operations API.
90 */
91int vfs_fsync(struct file *file, struct dentry *dentry, int datasync)
79{ 92{
80 int ret; 93 const struct file_operations *fop;
81 int err; 94 struct address_space *mapping;
82 struct address_space *mapping = file->f_mapping; 95 int err, ret;
96
97 /*
98 * Get mapping and operations from the file in case we have
99 * as file, or get the default values for them in case we
100 * don't have a struct file available. Damn nfsd..
101 */
102 if (file) {
103 mapping = file->f_mapping;
104 fop = file->f_op;
105 } else {
106 mapping = dentry->d_inode->i_mapping;
107 fop = dentry->d_inode->i_fop;
108 }
83 109
84 if (!file->f_op || !file->f_op->fsync) { 110 if (!fop || !fop->fsync) {
85 /* Why? We can still call filemap_fdatawrite */
86 ret = -EINVAL; 111 ret = -EINVAL;
87 goto out; 112 goto out;
88 } 113 }
@@ -94,7 +119,7 @@ long do_fsync(struct file *file, int datasync)
94 * livelocks in fsync_buffers_list(). 119 * livelocks in fsync_buffers_list().
95 */ 120 */
96 mutex_lock(&mapping->host->i_mutex); 121 mutex_lock(&mapping->host->i_mutex);
97 err = file->f_op->fsync(file, file->f_path.dentry, datasync); 122 err = fop->fsync(file, dentry, datasync);
98 if (!ret) 123 if (!ret)
99 ret = err; 124 ret = err;
100 mutex_unlock(&mapping->host->i_mutex); 125 mutex_unlock(&mapping->host->i_mutex);
@@ -104,15 +129,16 @@ long do_fsync(struct file *file, int datasync)
104out: 129out:
105 return ret; 130 return ret;
106} 131}
132EXPORT_SYMBOL(vfs_fsync);
107 133
108static long __do_fsync(unsigned int fd, int datasync) 134static int do_fsync(unsigned int fd, int datasync)
109{ 135{
110 struct file *file; 136 struct file *file;
111 int ret = -EBADF; 137 int ret = -EBADF;
112 138
113 file = fget(fd); 139 file = fget(fd);
114 if (file) { 140 if (file) {
115 ret = do_fsync(file, datasync); 141 ret = vfs_fsync(file, file->f_path.dentry, datasync);
116 fput(file); 142 fput(file);
117 } 143 }
118 return ret; 144 return ret;
@@ -120,12 +146,12 @@ static long __do_fsync(unsigned int fd, int datasync)
120 146
121asmlinkage long sys_fsync(unsigned int fd) 147asmlinkage long sys_fsync(unsigned int fd)
122{ 148{
123 return __do_fsync(fd, 0); 149 return do_fsync(fd, 0);
124} 150}
125 151
126asmlinkage long sys_fdatasync(unsigned int fd) 152asmlinkage long sys_fdatasync(unsigned int fd)
127{ 153{
128 return __do_fsync(fd, 1); 154 return do_fsync(fd, 1);
129} 155}
130 156
131/* 157/*