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

From: Chengguang Xu
Date: Thu Oct 07 2021 - 08:27:17 EST


---- 在 星期四, 2021-10-07 17:01:57 Jan Kara <jack@xxxxxxx> 撰写 ----
> 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?

That's right!

>
> > + 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?
>

Calling ->write_inode directly upper->i_state won't be updated,
however, I don't think overlayfs will keep writing out upper inode since ->write_inode
will be called when only overlay inode itself marked dirty. Am I missing something?


Thanks,
Chengguang