vfs: Make sys_sync() use fsync_super() (version 4)
[linux-2.6.git] / fs / sync.c
1 /*
2  * High-level sync()-related operations
3  */
4
5 #include <linux/kernel.h>
6 #include <linux/file.h>
7 #include <linux/fs.h>
8 #include <linux/module.h>
9 #include <linux/sched.h>
10 #include <linux/writeback.h>
11 #include <linux/syscalls.h>
12 #include <linux/linkage.h>
13 #include <linux/pagemap.h>
14 #include <linux/quotaops.h>
15 #include <linux/buffer_head.h>
16 #include "internal.h"
17
18 #define VALID_FLAGS (SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE| \
19                         SYNC_FILE_RANGE_WAIT_AFTER)
20
21 SYSCALL_DEFINE0(sync)
22 {
23         sync_filesystems(0);
24         sync_filesystems(1);
25         if (unlikely(laptop_mode))
26                 laptop_sync_completion();
27         return 0;
28 }
29
30 static void do_sync_work(struct work_struct *work)
31 {
32         /*
33          * Sync twice to reduce the possibility we skipped some inodes / pages
34          * because they were temporarily locked
35          */
36         sync_filesystems(0);
37         sync_filesystems(0);
38         printk("Emergency Sync complete\n");
39         kfree(work);
40 }
41
42 void emergency_sync(void)
43 {
44         struct work_struct *work;
45
46         work = kmalloc(sizeof(*work), GFP_ATOMIC);
47         if (work) {
48                 INIT_WORK(work, do_sync_work);
49                 schedule_work(work);
50         }
51 }
52
53 /*
54  * Generic function to fsync a file.
55  *
56  * filp may be NULL if called via the msync of a vma.
57  */
58 int file_fsync(struct file *filp, struct dentry *dentry, int datasync)
59 {
60         struct inode * inode = dentry->d_inode;
61         struct super_block * sb;
62         int ret, err;
63
64         /* sync the inode to buffers */
65         ret = write_inode_now(inode, 0);
66
67         /* sync the superblock to buffers */
68         sb = inode->i_sb;
69         lock_super(sb);
70         if (sb->s_dirt && sb->s_op->write_super)
71                 sb->s_op->write_super(sb);
72         unlock_super(sb);
73
74         /* .. finally sync the buffers to disk */
75         err = sync_blockdev(sb->s_bdev);
76         if (!ret)
77                 ret = err;
78         return ret;
79 }
80
81 /**
82  * vfs_fsync - perform a fsync or fdatasync on a file
83  * @file:               file to sync
84  * @dentry:             dentry of @file
85  * @data:               only perform a fdatasync operation
86  *
87  * Write back data and metadata for @file to disk.  If @datasync is
88  * set only metadata needed to access modified file data is written.
89  *
90  * In case this function is called from nfsd @file may be %NULL and
91  * only @dentry is set.  This can only happen when the filesystem
92  * implements the export_operations API.
93  */
94 int vfs_fsync(struct file *file, struct dentry *dentry, int datasync)
95 {
96         const struct file_operations *fop;
97         struct address_space *mapping;
98         int err, ret;
99
100         /*
101          * Get mapping and operations from the file in case we have
102          * as file, or get the default values for them in case we
103          * don't have a struct file available.  Damn nfsd..
104          */
105         if (file) {
106                 mapping = file->f_mapping;
107                 fop = file->f_op;
108         } else {
109                 mapping = dentry->d_inode->i_mapping;
110                 fop = dentry->d_inode->i_fop;
111         }
112
113         if (!fop || !fop->fsync) {
114                 ret = -EINVAL;
115                 goto out;
116         }
117
118         ret = filemap_fdatawrite(mapping);
119
120         /*
121          * We need to protect against concurrent writers, which could cause
122          * livelocks in fsync_buffers_list().
123          */
124         mutex_lock(&mapping->host->i_mutex);
125         err = fop->fsync(file, dentry, datasync);
126         if (!ret)
127                 ret = err;
128         mutex_unlock(&mapping->host->i_mutex);
129         err = filemap_fdatawait(mapping);
130         if (!ret)
131                 ret = err;
132 out:
133         return ret;
134 }
135 EXPORT_SYMBOL(vfs_fsync);
136
137 static int do_fsync(unsigned int fd, int datasync)
138 {
139         struct file *file;
140         int ret = -EBADF;
141
142         file = fget(fd);
143         if (file) {
144                 ret = vfs_fsync(file, file->f_path.dentry, datasync);
145                 fput(file);
146         }
147         return ret;
148 }
149
150 SYSCALL_DEFINE1(fsync, unsigned int, fd)
151 {
152         return do_fsync(fd, 0);
153 }
154
155 SYSCALL_DEFINE1(fdatasync, unsigned int, fd)
156 {
157         return do_fsync(fd, 1);
158 }
159
160 /*
161  * sys_sync_file_range() permits finely controlled syncing over a segment of
162  * a file in the range offset .. (offset+nbytes-1) inclusive.  If nbytes is
163  * zero then sys_sync_file_range() will operate from offset out to EOF.
164  *
165  * The flag bits are:
166  *
167  * SYNC_FILE_RANGE_WAIT_BEFORE: wait upon writeout of all pages in the range
168  * before performing the write.
169  *
170  * SYNC_FILE_RANGE_WRITE: initiate writeout of all those dirty pages in the
171  * range which are not presently under writeback. Note that this may block for
172  * significant periods due to exhaustion of disk request structures.
173  *
174  * SYNC_FILE_RANGE_WAIT_AFTER: wait upon writeout of all pages in the range
175  * after performing the write.
176  *
177  * Useful combinations of the flag bits are:
178  *
179  * SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE: ensures that all pages
180  * in the range which were dirty on entry to sys_sync_file_range() are placed
181  * under writeout.  This is a start-write-for-data-integrity operation.
182  *
183  * SYNC_FILE_RANGE_WRITE: start writeout of all dirty pages in the range which
184  * are not presently under writeout.  This is an asynchronous flush-to-disk
185  * operation.  Not suitable for data integrity operations.
186  *
187  * SYNC_FILE_RANGE_WAIT_BEFORE (or SYNC_FILE_RANGE_WAIT_AFTER): wait for
188  * completion of writeout of all pages in the range.  This will be used after an
189  * earlier SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE operation to wait
190  * for that operation to complete and to return the result.
191  *
192  * SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE|SYNC_FILE_RANGE_WAIT_AFTER:
193  * a traditional sync() operation.  This is a write-for-data-integrity operation
194  * which will ensure that all pages in the range which were dirty on entry to
195  * sys_sync_file_range() are committed to disk.
196  *
197  *
198  * SYNC_FILE_RANGE_WAIT_BEFORE and SYNC_FILE_RANGE_WAIT_AFTER will detect any
199  * I/O errors or ENOSPC conditions and will return those to the caller, after
200  * clearing the EIO and ENOSPC flags in the address_space.
201  *
202  * It should be noted that none of these operations write out the file's
203  * metadata.  So unless the application is strictly performing overwrites of
204  * already-instantiated disk blocks, there are no guarantees here that the data
205  * will be available after a crash.
206  */
207 SYSCALL_DEFINE(sync_file_range)(int fd, loff_t offset, loff_t nbytes,
208                                 unsigned int flags)
209 {
210         int ret;
211         struct file *file;
212         loff_t endbyte;                 /* inclusive */
213         int fput_needed;
214         umode_t i_mode;
215
216         ret = -EINVAL;
217         if (flags & ~VALID_FLAGS)
218                 goto out;
219
220         endbyte = offset + nbytes;
221
222         if ((s64)offset < 0)
223                 goto out;
224         if ((s64)endbyte < 0)
225                 goto out;
226         if (endbyte < offset)
227                 goto out;
228
229         if (sizeof(pgoff_t) == 4) {
230                 if (offset >= (0x100000000ULL << PAGE_CACHE_SHIFT)) {
231                         /*
232                          * The range starts outside a 32 bit machine's
233                          * pagecache addressing capabilities.  Let it "succeed"
234                          */
235                         ret = 0;
236                         goto out;
237                 }
238                 if (endbyte >= (0x100000000ULL << PAGE_CACHE_SHIFT)) {
239                         /*
240                          * Out to EOF
241                          */
242                         nbytes = 0;
243                 }
244         }
245
246         if (nbytes == 0)
247                 endbyte = LLONG_MAX;
248         else
249                 endbyte--;              /* inclusive */
250
251         ret = -EBADF;
252         file = fget_light(fd, &fput_needed);
253         if (!file)
254                 goto out;
255
256         i_mode = file->f_path.dentry->d_inode->i_mode;
257         ret = -ESPIPE;
258         if (!S_ISREG(i_mode) && !S_ISBLK(i_mode) && !S_ISDIR(i_mode) &&
259                         !S_ISLNK(i_mode))
260                 goto out_put;
261
262         ret = do_sync_mapping_range(file->f_mapping, offset, endbyte, flags);
263 out_put:
264         fput_light(file, fput_needed);
265 out:
266         return ret;
267 }
268 #ifdef CONFIG_HAVE_SYSCALL_WRAPPERS
269 asmlinkage long SyS_sync_file_range(long fd, loff_t offset, loff_t nbytes,
270                                     long flags)
271 {
272         return SYSC_sync_file_range((int) fd, offset, nbytes,
273                                     (unsigned int) flags);
274 }
275 SYSCALL_ALIAS(sys_sync_file_range, SyS_sync_file_range);
276 #endif
277
278 /* It would be nice if people remember that not all the world's an i386
279    when they introduce new system calls */
280 SYSCALL_DEFINE(sync_file_range2)(int fd, unsigned int flags,
281                                  loff_t offset, loff_t nbytes)
282 {
283         return sys_sync_file_range(fd, offset, nbytes, flags);
284 }
285 #ifdef CONFIG_HAVE_SYSCALL_WRAPPERS
286 asmlinkage long SyS_sync_file_range2(long fd, long flags,
287                                      loff_t offset, loff_t nbytes)
288 {
289         return SYSC_sync_file_range2((int) fd, (unsigned int) flags,
290                                      offset, nbytes);
291 }
292 SYSCALL_ALIAS(sys_sync_file_range2, SyS_sync_file_range2);
293 #endif
294
295 /*
296  * `endbyte' is inclusive
297  */
298 int do_sync_mapping_range(struct address_space *mapping, loff_t offset,
299                           loff_t endbyte, unsigned int flags)
300 {
301         int ret;
302
303         if (!mapping) {
304                 ret = -EINVAL;
305                 goto out;
306         }
307
308         ret = 0;
309         if (flags & SYNC_FILE_RANGE_WAIT_BEFORE) {
310                 ret = wait_on_page_writeback_range(mapping,
311                                         offset >> PAGE_CACHE_SHIFT,
312                                         endbyte >> PAGE_CACHE_SHIFT);
313                 if (ret < 0)
314                         goto out;
315         }
316
317         if (flags & SYNC_FILE_RANGE_WRITE) {
318                 ret = __filemap_fdatawrite_range(mapping, offset, endbyte,
319                                                 WB_SYNC_ALL);
320                 if (ret < 0)
321                         goto out;
322         }
323
324         if (flags & SYNC_FILE_RANGE_WAIT_AFTER) {
325                 ret = wait_on_page_writeback_range(mapping,
326                                         offset >> PAGE_CACHE_SHIFT,
327                                         endbyte >> PAGE_CACHE_SHIFT);
328         }
329 out:
330         return ret;
331 }
332 EXPORT_SYMBOL_GPL(do_sync_mapping_range);