introduce sys_syncfs to sync a single file system
It is frequently useful to sync a single file system, instead of all mounted file systems via sync(2): - On machines with many mounts, it is not at all uncommon for some of them to hang (e.g. unresponsive NFS server). sync(2) will get stuck on those and may never get to the one you do care about (e.g., /). - Some applications write lots of data to the file system and then want to make sure it is flushed to disk. Calling fsync(2) on each file introduces unnecessary ordering constraints that result in a large amount of sub-optimal writeback/flush/commit behavior by the file system. There are currently two ways (that I know of) to sync a single super_block: - BLKFLSBUF ioctl on the block device: That also invalidates the bdev mapping, which isn't usually desirable, and doesn't work for non-block file systems. - 'mount -o remount,rw' will call sync_filesystem as an artifact of the current implemention. Relying on this little-known side effect for something like data safety sounds foolish. Both of these approaches require root privileges, which some applications do not have (nor should they need?) given that sync(2) is an unprivileged operation. This patch introduces a new system call syncfs(2) that takes an fd and syncs only the file system it references. Maybe someday we can $ sync /some/path and not get sync: ignoring all arguments The syscall is motivated by comments by Al and Christoph at the last LSF. syncfs(2) seems like an appropriate name given statfs(2). A similar ioctl was also proposed a while back, see http://marc.info/?l=linux-fsdevel&m=127970513829285&w=2 Signed-off-by: Sage Weil <sage@newdream.net> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
1bef82917c
commit
b7ed78f565
7 changed files with 34 additions and 2 deletions
|
@ -847,4 +847,5 @@ ia32_sys_call_table:
|
|||
.quad sys_name_to_handle_at
|
||||
.quad compat_sys_open_by_handle_at
|
||||
.quad compat_sys_clock_adjtime
|
||||
.quad sys_syncfs
|
||||
ia32_syscall_end:
|
||||
|
|
|
@ -349,10 +349,11 @@
|
|||
#define __NR_name_to_handle_at 341
|
||||
#define __NR_open_by_handle_at 342
|
||||
#define __NR_clock_adjtime 343
|
||||
#define __NR_syncfs 344
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#define NR_syscalls 344
|
||||
#define NR_syscalls 345
|
||||
|
||||
#define __ARCH_WANT_IPC_PARSE_VERSION
|
||||
#define __ARCH_WANT_OLD_READDIR
|
||||
|
|
|
@ -675,6 +675,8 @@ __SYSCALL(__NR_name_to_handle_at, sys_name_to_handle_at)
|
|||
__SYSCALL(__NR_open_by_handle_at, sys_open_by_handle_at)
|
||||
#define __NR_clock_adjtime 305
|
||||
__SYSCALL(__NR_clock_adjtime, sys_clock_adjtime)
|
||||
#define __NR_syncfs 306
|
||||
__SYSCALL(__NR_syncfs, sys_syncfs)
|
||||
|
||||
#ifndef __NO_STUBS
|
||||
#define __ARCH_WANT_OLD_READDIR
|
||||
|
|
|
@ -343,3 +343,4 @@ ENTRY(sys_call_table)
|
|||
.long sys_name_to_handle_at
|
||||
.long sys_open_by_handle_at
|
||||
.long sys_clock_adjtime
|
||||
.long sys_syncfs
|
||||
|
|
24
fs/sync.c
24
fs/sync.c
|
@ -7,6 +7,7 @@
|
|||
#include <linux/fs.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/namei.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/writeback.h>
|
||||
#include <linux/syscalls.h>
|
||||
|
@ -128,6 +129,29 @@ void emergency_sync(void)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* sync a single super
|
||||
*/
|
||||
SYSCALL_DEFINE1(syncfs, int, fd)
|
||||
{
|
||||
struct file *file;
|
||||
struct super_block *sb;
|
||||
int ret;
|
||||
int fput_needed;
|
||||
|
||||
file = fget_light(fd, &fput_needed);
|
||||
if (!file)
|
||||
return -EBADF;
|
||||
sb = file->f_dentry->d_sb;
|
||||
|
||||
down_read(&sb->s_umount);
|
||||
ret = sync_filesystem(sb);
|
||||
up_read(&sb->s_umount);
|
||||
|
||||
fput_light(file, fput_needed);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* vfs_fsync_range - helper to sync a range of data & metadata to disk
|
||||
* @file: file to sync
|
||||
|
|
|
@ -652,9 +652,11 @@ __SYSCALL(__NR_name_to_handle_at, sys_name_to_handle_at)
|
|||
__SYSCALL(__NR_open_by_handle_at, sys_open_by_handle_at)
|
||||
#define __NR_clock_adjtime 266
|
||||
__SYSCALL(__NR_clock_adjtime, sys_clock_adjtime)
|
||||
#define __NR_syncfs 264
|
||||
__SYSCALL(__NR_syncfs, sys_syncfs)
|
||||
|
||||
#undef __NR_syscalls
|
||||
#define __NR_syscalls 267
|
||||
#define __NR_syscalls 268
|
||||
|
||||
/*
|
||||
* All syscalls below here should go away really,
|
||||
|
|
|
@ -825,6 +825,7 @@ asmlinkage long sys_fanotify_init(unsigned int flags, unsigned int event_f_flags
|
|||
asmlinkage long sys_fanotify_mark(int fanotify_fd, unsigned int flags,
|
||||
u64 mask, int fd,
|
||||
const char __user *pathname);
|
||||
asmlinkage long sys_syncfs(int fd);
|
||||
|
||||
int kernel_execve(const char *filename, const char *const argv[], const char *const envp[]);
|
||||
|
||||
|
|
Loading…
Reference in a new issue