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_op->sync_fs)
80 sb->s_op->sync_fs(sb, *(int *)arg);
81}
82
83static void fdatawrite_one_bdev(struct block_device *bdev, void *arg)
84{
85 filemap_fdatawrite(bdev->bd_inode->i_mapping);
86}
87
88static void fdatawait_one_bdev(struct block_device *bdev, void *arg)
89{
90
91
92
93
94
95 filemap_fdatawait_keep_errors(bdev->bd_inode->i_mapping);
96}
97
98
99
100
101
102
103
104
105
106
107
108void ksys_sync(void)
109{
110 int nowait = 0, wait = 1;
111
112 wakeup_flusher_threads(WB_REASON_SYNC);
113 iterate_supers(sync_inodes_one_sb, NULL);
114 iterate_supers(sync_fs_one_sb, &nowait);
115 iterate_supers(sync_fs_one_sb, &wait);
116 iterate_bdevs(fdatawrite_one_bdev, NULL);
117 iterate_bdevs(fdatawait_one_bdev, NULL);
118 if (unlikely(laptop_mode))
119 laptop_sync_completion();
120}
121
122SYSCALL_DEFINE0(sync)
123{
124 ksys_sync();
125 return 0;
126}
127
128static void do_sync_work(struct work_struct *work)
129{
130 int nowait = 0;
131
132
133
134
135
136 iterate_supers(sync_inodes_one_sb, &nowait);
137 iterate_supers(sync_fs_one_sb, &nowait);
138 iterate_bdevs(fdatawrite_one_bdev, NULL);
139 iterate_supers(sync_inodes_one_sb, &nowait);
140 iterate_supers(sync_fs_one_sb, &nowait);
141 iterate_bdevs(fdatawrite_one_bdev, NULL);
142 printk("Emergency Sync complete\n");
143 kfree(work);
144}
145
146void emergency_sync(void)
147{
148 struct work_struct *work;
149
150 work = kmalloc(sizeof(*work), GFP_ATOMIC);
151 if (work) {
152 INIT_WORK(work, do_sync_work);
153 schedule_work(work);
154 }
155}
156
157
158
159
160SYSCALL_DEFINE1(syncfs, int, fd)
161{
162 struct fd f = fdget(fd);
163 struct super_block *sb;
164 int ret;
165
166 if (!f.file)
167 return -EBADF;
168 sb = f.file->f_path.dentry->d_sb;
169
170 down_read(&sb->s_umount);
171 ret = sync_filesystem(sb);
172 up_read(&sb->s_umount);
173
174 fdput(f);
175 return ret;
176}
177
178
179
180
181
182
183
184
185
186
187
188
189int vfs_fsync_range(struct file *file, loff_t start, loff_t end, int datasync)
190{
191 struct inode *inode = file->f_mapping->host;
192
193 if (!file->f_op->fsync)
194 return -EINVAL;
195 if (!datasync && (inode->i_state & I_DIRTY_TIME))
196 mark_inode_dirty_sync(inode);
197 return file->f_op->fsync(file, start, end, datasync);
198}
199EXPORT_SYMBOL(vfs_fsync_range);
200
201
202
203
204
205
206
207
208
209int vfs_fsync(struct file *file, int datasync)
210{
211 return vfs_fsync_range(file, 0, LLONG_MAX, datasync);
212}
213EXPORT_SYMBOL(vfs_fsync);
214
215static int do_fsync(unsigned int fd, int datasync)
216{
217 struct fd f = fdget(fd);
218 int ret = -EBADF;
219
220 if (f.file) {
221 ret = vfs_fsync(f.file, datasync);
222 fdput(f);
223 }
224 return ret;
225}
226
227SYSCALL_DEFINE1(fsync, unsigned int, fd)
228{
229 return do_fsync(fd, 0);
230}
231
232SYSCALL_DEFINE1(fdatasync, unsigned int, fd)
233{
234 return do_fsync(fd, 1);
235}
236
237int sync_file_range(struct file *file, loff_t offset, loff_t nbytes,
238 unsigned int flags)
239{
240 int ret;
241 struct address_space *mapping;
242 loff_t endbyte;
243 umode_t i_mode;
244
245 ret = -EINVAL;
246 if (flags & ~VALID_FLAGS)
247 goto out;
248
249 endbyte = offset + nbytes;
250
251 if ((s64)offset < 0)
252 goto out;
253 if ((s64)endbyte < 0)
254 goto out;
255 if (endbyte < offset)
256 goto out;
257
258 if (sizeof(pgoff_t) == 4) {
259 if (offset >= (0x100000000ULL << PAGE_SHIFT)) {
260
261
262
263
264 ret = 0;
265 goto out;
266 }
267 if (endbyte >= (0x100000000ULL << PAGE_SHIFT)) {
268
269
270
271 nbytes = 0;
272 }
273 }
274
275 if (nbytes == 0)
276 endbyte = LLONG_MAX;
277 else
278 endbyte--;
279
280 i_mode = file_inode(file)->i_mode;
281 ret = -ESPIPE;
282 if (!S_ISREG(i_mode) && !S_ISBLK(i_mode) && !S_ISDIR(i_mode) &&
283 !S_ISLNK(i_mode))
284 goto out;
285
286 mapping = file->f_mapping;
287 ret = 0;
288 if (flags & SYNC_FILE_RANGE_WAIT_BEFORE) {
289 ret = file_fdatawait_range(file, offset, endbyte);
290 if (ret < 0)
291 goto out;
292 }
293
294 if (flags & SYNC_FILE_RANGE_WRITE) {
295 ret = __filemap_fdatawrite_range(mapping, offset, endbyte,
296 WB_SYNC_NONE);
297 if (ret < 0)
298 goto out;
299 }
300
301 if (flags & SYNC_FILE_RANGE_WAIT_AFTER)
302 ret = file_fdatawait_range(file, offset, endbyte);
303
304out:
305 return ret;
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
377
378SYSCALL_DEFINE4(sync_file_range2, int, fd, unsigned int, flags,
379 loff_t, offset, loff_t, nbytes)
380{
381 return ksys_sync_file_range(fd, offset, nbytes, flags);
382}
383