aboutsummaryrefslogtreecommitdiffstats
path: root/fs/sync.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /fs/sync.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'fs/sync.c')
-rw-r--r--fs/sync.c86
1 files changed, 36 insertions, 50 deletions
diff --git a/fs/sync.c b/fs/sync.c
index d104591b066b..92b228176f7c 100644
--- a/fs/sync.c
+++ b/fs/sync.c
@@ -5,6 +5,7 @@
5#include <linux/kernel.h> 5#include <linux/kernel.h>
6#include <linux/file.h> 6#include <linux/file.h>
7#include <linux/fs.h> 7#include <linux/fs.h>
8#include <linux/slab.h>
8#include <linux/module.h> 9#include <linux/module.h>
9#include <linux/sched.h> 10#include <linux/sched.h>
10#include <linux/writeback.h> 11#include <linux/writeback.h>
@@ -13,6 +14,7 @@
13#include <linux/pagemap.h> 14#include <linux/pagemap.h>
14#include <linux/quotaops.h> 15#include <linux/quotaops.h>
15#include <linux/buffer_head.h> 16#include <linux/buffer_head.h>
17#include <linux/backing-dev.h>
16#include "internal.h" 18#include "internal.h"
17 19
18#define VALID_FLAGS (SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE| \ 20#define VALID_FLAGS (SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE| \
@@ -31,17 +33,17 @@ static int __sync_filesystem(struct super_block *sb, int wait)
31 * This should be safe, as we require bdi backing to actually 33 * This should be safe, as we require bdi backing to actually
32 * write out data in the first place 34 * write out data in the first place
33 */ 35 */
34 if (!sb->s_bdi) 36 if (!sb->s_bdi || sb->s_bdi == &noop_backing_dev_info)
35 return 0; 37 return 0;
36 38
37 /* Avoid doing twice syncing and cache pruning for quota sync */ 39 if (sb->s_qcop && sb->s_qcop->quota_sync)
38 if (!wait) { 40 sb->s_qcop->quota_sync(sb, -1, wait);
39 writeout_quota_sb(sb, -1); 41
40 writeback_inodes_sb(sb); 42 if (wait)
41 } else {
42 sync_quota_sb(sb, -1);
43 sync_inodes_sb(sb); 43 sync_inodes_sb(sb);
44 } 44 else
45 writeback_inodes_sb(sb);
46
45 if (sb->s_op->sync_fs) 47 if (sb->s_op->sync_fs)
46 sb->s_op->sync_fs(sb, wait); 48 sb->s_op->sync_fs(sb, wait);
47 return __sync_blockdev(sb->s_bdev, wait); 49 return __sync_blockdev(sb->s_bdev, wait);
@@ -295,10 +297,11 @@ SYSCALL_DEFINE1(fdatasync, unsigned int, fd)
295 */ 297 */
296int generic_write_sync(struct file *file, loff_t pos, loff_t count) 298int generic_write_sync(struct file *file, loff_t pos, loff_t count)
297{ 299{
298 if (!(file->f_flags & O_SYNC) && !IS_SYNC(file->f_mapping->host)) 300 if (!(file->f_flags & O_DSYNC) && !IS_SYNC(file->f_mapping->host))
299 return 0; 301 return 0;
300 return vfs_fsync_range(file, file->f_path.dentry, pos, 302 return vfs_fsync_range(file, file->f_path.dentry, pos,
301 pos + count - 1, 1); 303 pos + count - 1,
304 (file->f_flags & __O_SYNC) ? 0 : 1);
302} 305}
303EXPORT_SYMBOL(generic_write_sync); 306EXPORT_SYMBOL(generic_write_sync);
304 307
@@ -354,6 +357,7 @@ SYSCALL_DEFINE(sync_file_range)(int fd, loff_t offset, loff_t nbytes,
354{ 357{
355 int ret; 358 int ret;
356 struct file *file; 359 struct file *file;
360 struct address_space *mapping;
357 loff_t endbyte; /* inclusive */ 361 loff_t endbyte; /* inclusive */
358 int fput_needed; 362 int fput_needed;
359 umode_t i_mode; 363 umode_t i_mode;
@@ -404,7 +408,28 @@ SYSCALL_DEFINE(sync_file_range)(int fd, loff_t offset, loff_t nbytes,
404 !S_ISLNK(i_mode)) 408 !S_ISLNK(i_mode))
405 goto out_put; 409 goto out_put;
406 410
407 ret = do_sync_mapping_range(file->f_mapping, offset, endbyte, flags); 411 mapping = file->f_mapping;
412 if (!mapping) {
413 ret = -EINVAL;
414 goto out_put;
415 }
416
417 ret = 0;
418 if (flags & SYNC_FILE_RANGE_WAIT_BEFORE) {
419 ret = filemap_fdatawait_range(mapping, offset, endbyte);
420 if (ret < 0)
421 goto out_put;
422 }
423
424 if (flags & SYNC_FILE_RANGE_WRITE) {
425 ret = filemap_fdatawrite_range(mapping, offset, endbyte);
426 if (ret < 0)
427 goto out_put;
428 }
429
430 if (flags & SYNC_FILE_RANGE_WAIT_AFTER)
431 ret = filemap_fdatawait_range(mapping, offset, endbyte);
432
408out_put: 433out_put:
409 fput_light(file, fput_needed); 434 fput_light(file, fput_needed);
410out: 435out:
@@ -436,42 +461,3 @@ asmlinkage long SyS_sync_file_range2(long fd, long flags,
436} 461}
437SYSCALL_ALIAS(sys_sync_file_range2, SyS_sync_file_range2); 462SYSCALL_ALIAS(sys_sync_file_range2, SyS_sync_file_range2);
438#endif 463#endif
439
440/*
441 * `endbyte' is inclusive
442 */
443int do_sync_mapping_range(struct address_space *mapping, loff_t offset,
444 loff_t endbyte, unsigned int flags)
445{
446 int ret;
447
448 if (!mapping) {
449 ret = -EINVAL;
450 goto out;
451 }
452
453 ret = 0;
454 if (flags & SYNC_FILE_RANGE_WAIT_BEFORE) {
455 ret = wait_on_page_writeback_range(mapping,
456 offset >> PAGE_CACHE_SHIFT,
457 endbyte >> PAGE_CACHE_SHIFT);
458 if (ret < 0)
459 goto out;
460 }
461
462 if (flags & SYNC_FILE_RANGE_WRITE) {
463 ret = __filemap_fdatawrite_range(mapping, offset, endbyte,
464 WB_SYNC_ALL);
465 if (ret < 0)
466 goto out;
467 }
468
469 if (flags & SYNC_FILE_RANGE_WAIT_AFTER) {
470 ret = wait_on_page_writeback_range(mapping,
471 offset >> PAGE_CACHE_SHIFT,
472 endbyte >> PAGE_CACHE_SHIFT);
473 }
474out:
475 return ret;
476}
477EXPORT_SYMBOL_GPL(do_sync_mapping_range);