Introduce
sync, linux command, using to write any data buffer in memory out to disk.
It do nothing, but exercise the ‘sync’ system call
So, if we want to study what the ‘sync’ really do, go in the kernel.
sync command
File: coreutils-8.9/src/sync.c
int
main (int argc, char **argv)
{
initialize_main (&argc, &argv);
set_program_name (argv[0]);
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
atexit (close_stdout);
parse_long_options (argc, argv, PROGRAM_NAME, PACKAGE, Version,
usage, AUTHORS, (char const *) NULL);
if (getopt_long (argc, argv, "", NULL, NULL) != -1)
usage (EXIT_FAILURE);
if (optind < argc)
error (0, 0, _("ignoring all arguments"));
sync ();
exit (EXIT_SUCCESS);
}
Do nothing, but do system call sync()
sync architecture in kernel
system call sync()
is defined in fs/sync.c
/*
* sync everything. Start out by waking pdflush, because that writes back
* all queues in parallel.
*/
SYSCALL_DEFINE0(sync)
{
wakeup_flusher_threads(0);
sync_filesystems(0);
sync_filesystems(1);
if (unlikely(laptop_mode))
laptop_sync_completion();
return 0;
}
sync
call sync_filesystems
static void sync_filesystems(int wait)
{
struct super_block *sb;
static DEFINE_MUTEX(mutex);
mutex_lock(&mutex); /* Could be down_interruptible */
spin_lock(&sb_lock);
list_for_each_entry(sb, &super_blocks, s_list)
sb->s_need_sync = 1;
restart:
list_for_each_entry(sb, &super_blocks, s_list) {
if (!sb->s_need_sync)
continue;
sb->s_need_sync = 0;
sb->s_count++;
spin_unlock(&sb_lock);
down_read(&sb->s_umount);
if (!(sb->s_flags & MS_RDONLY) && sb->s_root && sb->s_bdi)
__sync_filesystem(sb, wait);
up_read(&sb->s_umount);
/* restart only when sb is no longer on the list */
spin_lock(&sb_lock);
if (__put_super_and_need_restart(sb))
goto restart;
}
spin_unlock(&sb_lock);
mutex_unlock(&mutex);
}
sync_filesystems
call __sync_filesystem
static int __sync_filesystem(struct super_block *sb, int wait)
{
/*
* This should be safe, as we require bdi backing to actually
* write out data in the first place
*/
if (!sb->s_bdi)
return 0;
/* Avoid doing twice syncing and cache pruning for quota sync */
if (!wait) {
writeout_quota_sb(sb, -1);
writeback_inodes_sb(sb);
} else {
sync_quota_sb(sb, -1);
sync_inodes_sb(sb);
}
if (sb->s_op->sync_fs)
sb->s_op->sync_fs(sb, wait);
return __sync_blockdev(sb->s_bdev, wait);
}
__sync_filesystem
call sb->s_op->sync_fs(sb, wait)
, each filesystem should
implement the sync_fs()
when to use
- before shutdown computer, using
sync
more than twice - after write big file to disk, such as using command
cp
- to be continue
sync,fsync,fdatasync
- sync, add the modified buffer to write_queue, then return immediately, not wait
for the reality disk writed. - fsync, used for single file with specify file description,and wait the disk write finish.
- fdatasync, similar to fsync, but just do effect to the data part. fsync make
effect to data and file property.
special application
- How if I want to sync from serval Virtual Disks, and ignore serval VDs
- To be continue
Reference
- man sync
- info coreutils ‘sync invocation’
- kernel code
- coreutils-8.9
- sync、fsync和fdatasync函数
- 缓存同步操作–sys_sync系统调用