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