当前位置: 首页 > 工具软件 > fsync > 使用案例 >

Linux sync/fsync/fdatasync 函数

路昆杰
2023-12-01

一、函数声明

#include <unistd.h>

int fsync(int fd);
int fdatasync(int fd);
void sync(void);

二、意义

  1. sync,将所有修改过的缓冲区块,排入到写队列。就立即返回。【并不等待系统的update守护进程,将数据写入到物理硬盘】

    update守护进程会周期性的执行磁盘写入任务。【延迟写】

  2. fsync,将等待update将数据写入到物理硬盘后才返回。

  3. fdatasync,等待update将数据写入到物理硬盘后才返回,特点是只会影响文件的数据。而fsync还会更新文件的属性。

主要就是用于数据需要高可靠的应用程序。例如数据库。

三、实例

这两个函数,在进行实际编程时,很难显示出区别,因为基本上。write调用完,在很短时间内数据就已经写入到磁盘了。而且使用也不复杂。所以不写实例了。

四、fsync和fdatasync所说的更新文件属性,指的是更新哪些文件的属性呢。

linux中对fsync和fdatasync的定义

static int do_fsync(unsigned int fd, int datasync)
{
	struct fd f = fdget(fd);
	int ret = -EBADF;

	if (f.file) {
		ret = vfs_fsync(f.file, datasync);
		fdput(f);
	}
	return ret;
}

SYSCALL_DEFINE1(fsync, unsigned int, fd)
{
	return do_fsync(fd, 0);
}

SYSCALL_DEFINE1(fdatasync, unsigned int, fd)
{
	return do_fsync(fd, 1);
}

上面vfs_sync是调用的struct file中f_op中的fsync函数。这个函数指针,具体执行什么操作,要看使用的什么文件系统。linux支持的文件系统非常之多。我们就看看常见的ext4。

从 linux/fs/ext4/fsync.c 文件中找到。ext4文件系统对fsync的具体实现函数。

int ext4_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
{
...
if (!sbi->s_journal)
		ret = ext4_fsync_nojournal(inode, datasync, &needs_barrier);
	else if (ext4_should_journal_data(inode))
		ret = ext4_force_commit(inode->i_sb);
	else
		ret = ext4_fsync_journal(inode, datasync, &needs_barrier);
...
}

继续寻找ext4_fsync_journal或者ext4_fsync_nojournal

日志文件系统(journaling file systems),nojournaling,是指的无日志文件系统。

static int ext4_fsync_nojournal(struct inode *inode, bool datasync,
				bool *needs_barrier)
{
	int ret, err;

	ret = sync_mapping_buffers(inode->i_mapping);
	if (!(inode->i_state & I_DIRTY_ALL))
		return ret;
	// 当设置了datasync=1,并且数据已经同步,则直接返回。而不会运行下面的同步metadata。
	if (datasync && !(inode->i_state & I_DIRTY_DATASYNC)) 
		return ret;

	err = sync_inode_metadata(inode, 1);
	if (!ret)
		ret = err;

	if (!ret)
		ret = ext4_sync_parent(inode);
	if (test_opt(inode->i_sb, BARRIER))
		*needs_barrier = true;

	return ret;
}

从这里我们得知,实际上fsync比fdatasync多了一个同步metadata(中文翻译为:元数据)
从网上收集得到:

File system metadata includes the times recorded by the operating system when a file is modified, accessed, or created. File system metadata is easily misinterpreted and can be very difficult to understand. For this reason, file system metadata is covered in detail in…

其实文件系统中文件的metadata。就是那些文件属性。文件创建时间、文件上次访问时间、文件上次修改时间等等。可以通过linux stat命令查看文件的metadata信息。

Linux stat命令用于显示inode内容。

所以说最终结论就是:
在Linux系统下,文件系统中文件的metadata信息,指的就是inode结构体中的信息,包含以下项。所以fsync和fdatasyn两个系统调用的区别,就是fsync会等待后台磁盘数据同步进程,将文件的数据以及inode中的信息都同步到磁盘中才会返回。而fdatasync只等待数据写入完成后就返回
【而且,顺序是,先写入文件数据,再去更新inode的数据】

hotice0@ubuntu:~/Documents/Unix_Program$ stat test1
  File: test1
  Size: 7               Blocks: 8          IO Block: 4096   regular file
Device: 805h/2053d      Inode: 1841817     Links: 1
Access: (0700/-rwx------)  Uid: ( 1000/ hotice0)   Gid: ( 1000/ hotice0)
Access: 2020-07-29 06:08:33.785372080 -0700
Modify: 2020-07-29 06:08:33.785372080 -0700
Change: 2020-07-29 06:08:33.785372080 -0700
 Birth: -
 类似资料: