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