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;
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 fdput(f);
176 return ret;
177}
178
179
180
181
182
183
184
185
186
187
188
189
190int vfs_fsync_range(struct file *file, loff_t start, loff_t end, int datasync)
191{
192 struct inode *inode = file->f_mapping->host;
193
194 if (!file->f_op->fsync)
195 return -EINVAL;
196 if (!datasync && (inode->i_state & I_DIRTY_TIME))
197 mark_inode_dirty_sync(inode);
198 return file->f_op->fsync(file, start, end, datasync);
199}
200EXPORT_SYMBOL(vfs_fsync_range);
201
202
203
204
205
206
207
208
209
210int vfs_fsync(struct file *file, int datasync)
211{
212 return vfs_fsync_range(file, 0, LLONG_MAX, datasync);
213}
214EXPORT_SYMBOL(vfs_fsync);
215
216static int do_fsync(unsigned int fd, int datasync)
217{
218 struct fd f = fdget(fd);
219 int ret = -EBADF;
220
221 if (f.file) {
222 ret = vfs_fsync(f.file, datasync);
223 fdput(f);
224 }
225 return ret;
226}
227
228SYSCALL_DEFINE1(fsync, unsigned int, fd)
229{
230 return do_fsync(fd, 0);
231}
232
233SYSCALL_DEFINE1(fdatasync, unsigned int, fd)
234{
235 return do_fsync(fd, 1);
236}
237
238int sync_file_range(struct file *file, loff_t offset, loff_t nbytes,
239 unsigned int flags)
240{
241 int ret;
242 struct address_space *mapping;
243 loff_t endbyte;
244 umode_t i_mode;
245
246 ret = -EINVAL;
247 if (flags & ~VALID_FLAGS)
248 goto out;
249
250 endbyte = offset + nbytes;
251
252 if ((s64)offset < 0)
253 goto out;
254 if ((s64)endbyte < 0)
255 goto out;
256 if (endbyte < offset)
257 goto out;
258
259 if (sizeof(pgoff_t) == 4) {
260 if (offset >= (0x100000000ULL << PAGE_SHIFT)) {
261
262
263
264
265 ret = 0;
266 goto out;
267 }
268 if (endbyte >= (0x100000000ULL << PAGE_SHIFT)) {
269
270
271
272 nbytes = 0;
273 }
274 }
275
276 if (nbytes == 0)
277 endbyte = LLONG_MAX;
278 else
279 endbyte--;
280
281 i_mode = file_inode(file)->i_mode;
282 ret = -ESPIPE;
283 if (!S_ISREG(i_mode) && !S_ISBLK(i_mode) && !S_ISDIR(i_mode) &&
284 !S_ISLNK(i_mode))
285 goto out;
286
287 mapping = file->f_mapping;
288 ret = 0;
289 if (flags & SYNC_FILE_RANGE_WAIT_BEFORE) {
290 ret = file_fdatawait_range(file, offset, endbyte);
291 if (ret < 0)
292 goto out;
293 }
294
295 if (flags & SYNC_FILE_RANGE_WRITE) {
296 ret = __filemap_fdatawrite_range(mapping, offset, endbyte,
297 WB_SYNC_NONE);
298 if (ret < 0)
299 goto out;
300 }
301
302 if (flags & SYNC_FILE_RANGE_WAIT_AFTER)
303 ret = file_fdatawait_range(file, offset, endbyte);
304
305out:
306 return ret;
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
355
356int ksys_sync_file_range(int fd, loff_t offset, loff_t nbytes,
357 unsigned int flags)
358{
359 int ret;
360 struct fd f;
361
362 ret = -EBADF;
363 f = fdget(fd);
364 if (f.file)
365 ret = sync_file_range(f.file, offset, nbytes, flags);
366
367 fdput(f);
368 return ret;
369}
370
371SYSCALL_DEFINE4(sync_file_range, int, fd, loff_t, offset, loff_t, nbytes,
372 unsigned int, flags)
373{
374 return ksys_sync_file_range(fd, offset, nbytes, flags);
375}
376
377
378
379SYSCALL_DEFINE4(sync_file_range2, int, fd, unsigned int, flags,
380 loff_t, offset, loff_t, nbytes)
381{
382 return ksys_sync_file_range(fd, offset, nbytes, flags);
383}
384