On Sun 08-11-20 22:03:04, Chengguang Xu wrote: > +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); > + > + iflag |= upper->i_state & I_DIRTY_ALL; > + > + if (mapping_writably_mapped(upper->i_mapping) || > + mapping_tagged(upper->i_mapping, PAGECACHE_TAG_WRITEBACK)) > + iflag |= I_DIRTY_PAGES; > + > + if (iflag) > + ovl_mark_inode_dirty(inode); I think you didn't incorporate feedback we were speaking about in the last version of the series. May comment in [1] still applies - you can miss inodes dirtied through mmap when you decide to clean the inode here. So IMHO you need something like: if (inode_is_open_for_write(inode)) ovl_mark_inode_dirty(inode); here to keep inode dirty while it is open for write (and not based on upper inode state which is unreliable). Honza [1] https://lore.kernel.org/linux-fsdevel/20201105140332.GG32718@xxxxxxxxxxxxxx/ > + > + return ret; > +} > + > static void ovl_evict_inode(struct inode *inode) > { > struct ovl_fs *ofs = inode->i_sb->s_fs_info; > @@ -411,6 +440,7 @@ static const struct super_operations ovl_super_operations = { > .destroy_inode = ovl_destroy_inode, > .drop_inode = generic_delete_inode, > .evict_inode = ovl_evict_inode, > + .write_inode = ovl_write_inode, > .put_super = ovl_put_super, > .sync_fs = ovl_sync_fs, > .statfs = ovl_statfs, > -- > 2.26.2 > > -- Jan Kara <jack@xxxxxxxx> SUSE Labs, CR