sys_fsync() and sys_sync() question

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Dear All,

I read kernel 2.6.9 page cache code and have some questions.
Please help ..

1. Why should sys_fsync() call filemap_fdatawrite()? Isn't it redundant in
kernel 2.6?
   since do_writepages() -> mpage_writepages() will walk the list of dirty
pages of the
   given address space and writepage() all of them, and, both
filemap_fdatawrite() and
   file->f_op->fsync() (ext2, for example) eventually call do_writepages()
function.

-----------------------------
asmlinkage long sys_fsync(unsigned int fd)
{
	struct file * file;
	struct address_space *mapping;
	int ret, err;

	ret = -EBADF;
	file = fget(fd);
	if (!file)
		goto out;

	mapping = file->f_mapping;

	ret = -EINVAL;
	if (!file->f_op || !file->f_op->fsync) {
		/* Why?  We can still call filemap_fdatawrite */
		goto out_putf;
	}

	/* We need to protect against concurrent writers.. */
	down(&mapping->host->i_sem);
	current->flags |= PF_SYNCWRITE;
	ret = filemap_fdatawrite(mapping);
	err = file->f_op->fsync(file, file->f_dentry, 0);
	if (!ret)
		ret = err;
	err = filemap_fdatawait(mapping);
	if (!ret)
		ret = err;
	current->flags &= ~PF_SYNCWRITE;
	up(&mapping->host->i_sem);

out_putf:
	fput(file);
out:
	return ret;
}
-----------------------------


2. for ext2, the purpose of sync_mapping_buffers() is to write out all
indirect blocks of 
   an address_space, which is called by ext2_sync_file()<-sys_fsync(). How
do these 
   buffers got sync'ed at sys_sync()? I don't find code writing out these
private buffers.
   If sync_mapping_buffers() is not needed for sys_sync(), then this should
apply for 
   ext2_sync_file().

-----------------------------
int ext2_sync_file(struct file *file, struct dentry *dentry, int datasync)
{
	struct inode *inode = dentry->d_inode;
	int err;
	int ret;

	ret = sync_mapping_buffers(inode->i_mapping);
	if (!(inode->i_state & I_DIRTY))
		return ret;
	if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
		return ret;

	err = ext2_sync_inode(inode);
	if (ret == 0)
		ret = err;
	return ret;
}

static void do_sync(unsigned long wait)
{
	wakeup_bdflush(0);
	sync_inodes(0);		/* All mappings, inodes and their blockdevs
*/
	DQUOT_SYNC(NULL);
	sync_supers();		/* Write the superblocks */
	sync_filesystems(0);	/* Start syncing the filesystems */
	sync_filesystems(wait);	/* Waitingly sync the filesystems */
	sync_inodes(wait);	/* Mappings, inodes and blockdevs, again. */
	if (!wait)
		printk("Emergency Sync complete\n");
	if (unlikely(laptop_mode))
		laptop_sync_completion();
}

asmlinkage long sys_sync(void)
{
	do_sync(1);
	return 0;
}
-----------------------------



Thank you,
Hao-Ran Liu






--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive:       http://mail.nl.linux.org/kernelnewbies/
FAQ:           http://kernelnewbies.org/faq/


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux