Re: [RFC PATCH v5 06/10] ovl: implement overlayfs' ->write_inode operation

From: Jan Kara
Date: Thu Oct 07 2021 - 05:50:41 EST


On Thu 23-09-21 21:08:10, Chengguang Xu wrote:
> Implement overlayfs' ->write_inode to sync dirty data
> and redirty overlayfs' inode if necessary.
>
> Signed-off-by: Chengguang Xu <cgxu519@xxxxxxxxxxxx>

...

> +static int ovl_write_inode(struct inode *inode,
> + struct writeback_control *wbc)
> +{
> + struct ovl_fs *ofs = inode->i_sb->s_fs_info;
> + struct inode *upper = ovl_inode_upper(inode);
> + unsigned long iflag = 0;
> + int ret = 0;
> +
> + if (!upper)
> + return 0;
> +
> + if (!ovl_should_sync(ofs))
> + return 0;
> +
> + if (upper->i_sb->s_op->write_inode)
> + ret = upper->i_sb->s_op->write_inode(inode, wbc);
> +

I'm somewhat confused here. 'inode' is overlayfs inode AFAIU, so how is it
correct to pass it to ->write_inode function of upper filesystem? Shouldn't
you pass 'upper' there instead?

> + if (mapping_writably_mapped(upper->i_mapping) ||
> + mapping_tagged(upper->i_mapping, PAGECACHE_TAG_WRITEBACK))
> + iflag |= I_DIRTY_PAGES;
> +
> + iflag |= upper->i_state & I_DIRTY_ALL;

Also since you call ->write_inode directly upper->i_state won't be updated
to reflect that inode has been written out (I_DIRTY flags get cleared in
__writeback_single_inode()). So it seems to me overlayfs will keep writing
out upper inode until flush worker on upper filesystem also writes the
inode and clears the dirty flags? So you rather need to call something like
write_inode_now() that will handle the flag clearing and do writeback list
handling for you?

Honza

--
Jan Kara <jack@xxxxxxxx>
SUSE Labs, CR