1
2
3
4
5#include <linux/kernel.h>
6#include <linux/file.h>
7#include <linux/fs.h>
8#include <linux/slab.h>
9#include <linux/export.h>
10#include <linux/namei.h>
11#include <linux/sched.h>
12#include <linux/writeback.h>
13#include <linux/syscalls.h>
14#include <linux/linkage.h>
15#include <linux/pagemap.h>
16#include <linux/quotaops.h>
17#include <linux/backing-dev.h>
18#include "internal.h"
19
20#define VALID_FLAGS (SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE| \
21 SYNC_FILE_RANGE_WAIT_AFTER)
22
23
24
25
26
27
28
29
30static int __sync_filesystem(struct super_block *sb, int wait,
31 unsigned long start)
32{
33 if (wait)
34 sync_inodes_sb(sb, start);
35 else
36 writeback_inodes_sb(sb, WB_REASON_SYNC);
37
38 if (sb->s_op->sync_fs)
39 sb->s_op->sync_fs(sb, wait);
40 return __sync_blockdev(sb->s_bdev, wait);
41}
42
43
44
45
46
47
48int sync_filesystem(struct super_block *sb)
49{
50 int ret;
51 unsigned long start = jiffies;
52
53
54
55
56
57 WARN_ON(!rwsem_is_locked(&sb->s_umount));
58
59
60
61
62 if (sb->s_flags & MS_RDONLY)
63 return 0;
64
65 ret = __sync_filesystem(sb, 0, start);
66 if (ret < 0)
67 return ret;
68 return __sync_filesystem(sb, 1, start);
69}
70EXPORT_SYMBOL_GPL(sync_filesystem);
71
72static void sync_inodes_one_sb(struct super_block *sb, void *arg)
73{
74 if (!(sb->s_flags & MS_RDONLY))
75 sync_inodes_sb(sb, *((unsigned long *)arg));
76}
77
78static void sync_fs_one_sb(struct super_block *sb, void *arg)
79{
80 if (!(sb->s_flags & MS_RDONLY) && sb->s_op->sync_fs)
81 sb->s_op->sync_fs(sb, *(int *)arg);
82}
83
84static void fdatawrite_one_bdev(struct block_device *bdev, void *arg)
85{
86 filemap_fdatawrite(bdev->bd_inode->i_mapping);
87}
88
89static void fdatawait_one_bdev(struct block_device *bdev, void *arg)
90{
91 filemap_fdatawait(bdev->bd_inode->i_mapping);
92}
93
94
95
96
97
98
99
100
101
102
103
104SYSCALL_DEFINE0(sync)
105{
106 int nowait = 0, wait = 1;
107 unsigned long start = jiffies;
108
109 wakeup_flusher_threads(0, WB_REASON_SYNC);
110 iterate_supers(sync_inodes_one_sb, &start);
111 iterate_supers(sync_fs_one_sb, &nowait);
112 iterate_supers(sync_fs_one_sb, &wait);
113 iterate_bdevs(fdatawrite_one_bdev, NULL);
114 iterate_bdevs(fdatawait_one_bdev, NULL);
115 if (unlikely(laptop_mode))
116 laptop_sync_completion();
117 return 0;
118}
119
120static void do_sync_work(struct work_struct *work)
121{
122 int nowait = 0;
123
124
125
126
127
128 iterate_supers(sync_inodes_one_sb, &nowait);
129 iterate_supers(sync_fs_one_sb, &nowait);
130 iterate_bdevs(fdatawrite_one_bdev, NULL);
131 iterate_supers(sync_inodes_one_sb, &nowait);
132 iterate_supers(sync_fs_one_sb, &nowait);
133 iterate_bdevs(fdatawrite_one_bdev, NULL);
134 printk("Emergency Sync complete\n");
135 kfree(work);
136}
137
138void emergency_sync(void)
139{
140 struct work_struct *work;
141
142 work = kmalloc(sizeof(*work), GFP_ATOMIC);
143 if (work) {
144 INIT_WORK(work, do_sync_work);
145 schedule_work(work);
146 }
147}
148
149
150
151
152SYSCALL_DEFINE1(syncfs, int, fd)
153{
154 struct fd f = fdget(fd);
155 struct super_block *sb;
156 int ret;
157
158 if (!f.file)
159 return -EBADF;
160 sb = f.file->f_dentry->d_sb;
161
162 down_read(&sb->s_umount);
163 ret = sync_filesystem(sb);
164 up_read(&sb->s_umount);
165
166 fdput(f);
167 return ret;
168}
169
170
171
172
173
174
175
176
177
178
179
180
181int vfs_fsync_range(struct file *file, loff_t start, loff_t end, int datasync)
182{
183 if (!file->f_op->fsync)
184 return -EINVAL;
185 return file->f_op->fsync(file, start, end, datasync);
186}
187EXPORT_SYMBOL(vfs_fsync_range);
188
189
190
191
192
193
194
195
196
197int vfs_fsync(struct file *file, int datasync)
198{
199 return vfs_fsync_range(file, 0, LLONG_MAX, datasync);
200}
201EXPORT_SYMBOL(vfs_fsync);
202
203static int do_fsync(unsigned int fd, int datasync)
204{
205 struct fd f = fdget(fd);
206 int ret = -EBADF;
207
208 if (f.file) {
209 ret = vfs_fsync(f.file, datasync);
210 fdput(f);
211 }
212 return ret;
213}
214
215SYSCALL_DEFINE1(fsync, unsigned int, fd)
216{
217 return do_fsync(fd, 0);
218}
219
220SYSCALL_DEFINE1(fdatasync, unsigned int, fd)
221{
222 return do_fsync(fd, 1);
223}
224
225
226
227
228
229
230
231
232
233int generic_write_sync(struct file *file, loff_t pos, loff_t count)
234{
235 if (!(file->f_flags & O_DSYNC) && !IS_SYNC(file->f_mapping->host))
236 return 0;
237 return vfs_fsync_range(file, pos, pos + count - 1,
238 (file->f_flags & __O_SYNC) ? 0 : 1);
239}
240EXPORT_SYMBOL(generic_write_sync);
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289SYSCALL_DEFINE4(sync_file_range, int, fd, loff_t, offset, loff_t, nbytes,
290 unsigned int, flags)
291{
292 int ret;
293 struct fd f;
294 struct address_space *mapping;
295 loff_t endbyte;
296 umode_t i_mode;
297
298 ret = -EINVAL;
299 if (flags & ~VALID_FLAGS)
300 goto out;
301
302 endbyte = offset + nbytes;
303
304 if ((s64)offset < 0)
305 goto out;
306 if ((s64)endbyte < 0)
307 goto out;
308 if (endbyte < offset)
309 goto out;
310
311 if (sizeof(pgoff_t) == 4) {
312 if (offset >= (0x100000000ULL << PAGE_CACHE_SHIFT)) {
313
314
315
316
317 ret = 0;
318 goto out;
319 }
320 if (endbyte >= (0x100000000ULL << PAGE_CACHE_SHIFT)) {
321
322
323
324 nbytes = 0;
325 }
326 }
327
328 if (nbytes == 0)
329 endbyte = LLONG_MAX;
330 else
331 endbyte--;
332
333 ret = -EBADF;
334 f = fdget(fd);
335 if (!f.file)
336 goto out;
337
338 i_mode = file_inode(f.file)->i_mode;
339 ret = -ESPIPE;
340 if (!S_ISREG(i_mode) && !S_ISBLK(i_mode) && !S_ISDIR(i_mode) &&
341 !S_ISLNK(i_mode))
342 goto out_put;
343
344 mapping = f.file->f_mapping;
345 if (!mapping) {
346 ret = -EINVAL;
347 goto out_put;
348 }
349
350 ret = 0;
351 if (flags & SYNC_FILE_RANGE_WAIT_BEFORE) {
352 ret = filemap_fdatawait_range(mapping, offset, endbyte);
353 if (ret < 0)
354 goto out_put;
355 }
356
357 if (flags & SYNC_FILE_RANGE_WRITE) {
358 ret = filemap_fdatawrite_range(mapping, offset, endbyte);
359 if (ret < 0)
360 goto out_put;
361 }
362
363 if (flags & SYNC_FILE_RANGE_WAIT_AFTER)
364 ret = filemap_fdatawait_range(mapping, offset, endbyte);
365
366out_put:
367 fdput(f);
368out:
369 return ret;
370}
371
372
373
374SYSCALL_DEFINE4(sync_file_range2, int, fd, unsigned int, flags,
375 loff_t, offset, loff_t, nbytes)
376{
377 return sys_sync_file_range(fd, offset, nbytes, flags);
378}
379