Many upper inodes that overlayfs modifies have no overlay inode that could be on the dirty list: whiteouts, index entries, the work directories. overlayfs modifies the namespace and the attributes of the upper filesystem through the ovl_do_*() helpers, and each helper knows which upper inodes it touches. Have them call ovl_upper_modified(), which gives the upper inode a fake overlay inode and marks that dirty. A fake inode is hashed by the real inode and has no dentry, like a trap inode. From there on it is an ordinary dirty overlay inode. An upper inode only gets a fake inode if the VFS considers it dirty, sync_filesystem() would not write it otherwise. The flusher clears the dirty flags when it starts, so also look at I_SYNC and the page cache tags. If there is no memory for a fake inode, write the upper inode right away. If that fails, or the lookup of the whiteout that RENAME_WHITEOUT made, the next syncfs() returns the error. Not covered: the atime of an upper directory that cannot be opened with O_NOATIME, and inodes that the upper filesystem dirties on its own, like the quota file of ext2 and jfs. Signed-off-by: Josef Bacik --- fs/overlayfs/inode.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++- fs/overlayfs/overlayfs.h | 90 +++++++++++++++++++++++++++++++-------- fs/overlayfs/ovl_entry.h | 2 + fs/overlayfs/super.c | 18 +++++--- fs/overlayfs/util.c | 42 +++++++++++++++++++ 5 files changed, 235 insertions(+), 24 deletions(-) diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c index 88cec47d0bc8..85ccbb773534 100644 --- a/fs/overlayfs/inode.c +++ b/fs/overlayfs/inode.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include "overlayfs.h" @@ -752,7 +753,7 @@ int ovl_fileattr_get(struct dentry *dentry, struct file_kattr *fa) */ void ovl_sync_lazytime(struct inode *inode) { - struct inode *upper = ovl_inode_upper(inode); + struct inode *upper = ovl_inode_upper_to_write(inode); if (upper && (inode_state_read_once(upper) & I_DIRTY_TIME)) mark_inode_dirty_sync(upper); @@ -1169,6 +1170,110 @@ struct inode *ovl_lookup_inode(struct super_block *sb, struct dentry *real, return inode; } +static const struct inode_operations ovl_fake_inode_operations = { + .sync_lazytime = ovl_sync_lazytime, +}; + +/* The upper inode that ovl_write_inode() has to write for @inode */ +struct inode *ovl_inode_upper_to_write(struct inode *inode) +{ + if (ovl_test_flag(OVL_FAKE, inode)) + return inode->i_private; + + return ovl_inode_upper(inode); +} + +/* + * Is there anything sync_filesystem() would write or wait for on @upper? + * + * The dirty flags alone cannot tell, because the flusher of the upper + * filesystem clears them when it starts to write the inode. But it sets I_SYNC + * before it clears them, it clears I_SYNC after ->write_inode() has returned, + * and all of them are in one word. The caller has modified @upper before it + * gets here. So if neither a dirty flag nor I_SYNC is set, the modification + * has not dirtied the inode, or the flusher has handed all of it to the + * filesystem. Pages whose writeback has been started but not completed show in + * the page cache tags. + */ +static bool ovl_upper_inode_dirty(struct inode *upper) +{ + struct address_space *mapping = upper->i_mapping; + unsigned int state = inode_state_read_once(upper); + + /* The data of a regular file is left to its overlay inode */ + if (S_ISREG(upper->i_mode)) + return state & (I_DIRTY_INODE | I_DIRTY_TIME | I_SYNC); + + return (state & (I_DIRTY_ALL | I_SYNC)) || + mapping_tagged(mapping, PAGECACHE_TAG_DIRTY) || + mapping_tagged(mapping, PAGECACHE_TAG_WRITEBACK); +} + +/* + * overlayfs has modified @upper on the upper filesystem. Many of these inodes + * have no overlay inode that could be on the dirty list of the overlay: + * whiteouts, index entries and the work directories. Give @upper a fake + * overlay inode and mark that dirty. From there on it is treated like any + * other dirty overlay inode. syncfs(), unmount and the flusher find it on the + * dirty list, ovl_write_inode() writes @upper, and ovl_drop_inode() keeps the + * fake inode for as long as it is dirty. + * + * Like a trap inode, a fake inode is hashed by the real inode and has no + * dentry. It holds a reference to @upper. + * + * sync_filesystem() on the upper filesystem would only write the inodes that + * are on a dirty list there. So an inode that the VFS does not consider dirty + * after it was modified does not need a fake inode. This is the normal case + * for a filesystem that logs its metadata. + */ +void ovl_upper_modified(struct ovl_fs *ofs, struct inode *upper) +{ + struct inode *fake; + + if (!upper || !ovl_tracks_dirty(ofs)) + return; + + /* + * Nobody is going to look for an inode that has no name left. Drop its + * fake inode, so that the space of @upper is freed. + */ + if (!upper->i_nlink) { + fake = ovl_ilookup(ofs->sb, upper, true); + if (fake) { + /* clear_nlink() counts, it must not run twice */ + spin_lock(&fake->i_lock); + clear_nlink(fake); + spin_unlock(&fake->i_lock); + iput(fake); + } + return; + } + + if (!ovl_upper_inode_dirty(upper)) + return; + + fake = ovl_iget_locked(ofs->sb, upper, true); + if (!fake) { + /* + * There is no memory to remember @upper, so write it now. The + * modification itself has succeeded, so this is not an error of + * the caller. If the write fails, the next syncfs() says so. + */ + ovl_write_upper_inode(ofs->sb, upper, OVL_WRITE_WAIT); + return; + } + + if (inode_state_read_once(fake) & I_NEW) { + ihold(upper); + fake->i_mode = upper->i_mode & S_IFMT; + fake->i_op = &ovl_fake_inode_operations; + unlock_new_inode(fake); + } + + ovl_mark_inode_dirty(fake); + iput(fake); +} + bool ovl_lookup_trap_inode(struct super_block *sb, struct dentry *dir) { struct inode *key = d_inode(dir); diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h index 83e25700c8a0..98a6946a96af 100644 --- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h @@ -210,28 +210,58 @@ static inline const char *ovl_xattr(struct ovl_fs *ofs, enum ovl_xattr ox) * care to map 1000 to 1001. * The mnt idmapping helpers are nops if the upper layer isn't idmapped. */ +void ovl_upper_modified(struct ovl_fs *ofs, struct inode *upper); + +/* + * The ovl_do_*() helpers below are how overlayfs modifies the namespace and the + * attributes of the upper filesystem. Each of them calls ovl_upper_modified() + * for all the upper inodes that it has modified, which puts them on the dirty + * list of the overlay. Code that modifies the upper filesystem in another way + * has to mark the overlay inode of the file dirty. + */ static inline int ovl_do_notify_change(struct ovl_fs *ofs, struct dentry *upperdentry, struct iattr *attr) { - return notify_change(ovl_upper_mnt_idmap(ofs), upperdentry, attr, NULL); + int err = notify_change(ovl_upper_mnt_idmap(ofs), upperdentry, attr, + NULL); + + if (!err) + ovl_upper_modified(ofs, d_inode(upperdentry)); + return err; } static inline int ovl_do_rmdir(struct ovl_fs *ofs, struct inode *dir, struct dentry *dentry) { - int err = vfs_rmdir(ovl_upper_mnt_idmap(ofs), dir, dentry, NULL); + struct inode *inode = d_inode(dentry); + int err; + ihold(inode); + err = vfs_rmdir(ovl_upper_mnt_idmap(ofs), dir, dentry, NULL); pr_debug("rmdir(%pd2) = %i\n", dentry, err); + if (!err) { + ovl_upper_modified(ofs, dir); + ovl_upper_modified(ofs, inode); + } + iput(inode); return err; } static inline int ovl_do_unlink(struct ovl_fs *ofs, struct inode *dir, struct dentry *dentry) { - int err = vfs_unlink(ovl_upper_mnt_idmap(ofs), dir, dentry, NULL); + struct inode *inode = d_inode(dentry); + int err; + ihold(inode); + err = vfs_unlink(ovl_upper_mnt_idmap(ofs), dir, dentry, NULL); pr_debug("unlink(%pd2) = %i\n", dentry, err); + if (!err) { + ovl_upper_modified(ofs, dir); + ovl_upper_modified(ofs, inode); + } + iput(inode); return err; } @@ -242,6 +272,10 @@ static inline int ovl_do_link(struct ovl_fs *ofs, struct dentry *old_dentry, new_dentry, NULL); pr_debug("link(%pd2, %pd2) = %i\n", old_dentry, new_dentry, err); + if (!err) { + ovl_upper_modified(ofs, dir); + ovl_upper_modified(ofs, d_inode(old_dentry)); + } return err; } @@ -252,6 +286,10 @@ static inline int ovl_do_create(struct ovl_fs *ofs, int err = vfs_create(ovl_upper_mnt_idmap(ofs), dentry, mode, NULL); pr_debug("create(%pd2, 0%o) = %i\n", dentry, mode, err); + if (!err) { + ovl_upper_modified(ofs, dir); + ovl_upper_modified(ofs, d_inode(dentry)); + } return err; } @@ -266,6 +304,10 @@ static inline struct dentry *ovl_do_mkdir(struct ovl_fs *ofs, pr_debug("mkdir(%pd2, 0%o)\n", dentry, mode); ret = vfs_mkdir(ovl_upper_mnt_idmap(ofs), dir, dentry, mode, NULL); pr_debug("...mkdir = %i\n", PTR_ERR_OR_ZERO(ret)); + if (!IS_ERR(ret)) { + ovl_upper_modified(ofs, dir); + ovl_upper_modified(ofs, d_inode(ret)); + } return ret; } @@ -276,6 +318,10 @@ static inline int ovl_do_mknod(struct ovl_fs *ofs, int err = vfs_mknod(ovl_upper_mnt_idmap(ofs), dir, dentry, mode, dev, NULL); pr_debug("mknod(%pd2, 0%o, 0%o) = %i\n", dentry, mode, dev, err); + if (!err) { + ovl_upper_modified(ofs, dir); + ovl_upper_modified(ofs, d_inode(dentry)); + } return err; } @@ -286,6 +332,10 @@ static inline int ovl_do_symlink(struct ovl_fs *ofs, int err = vfs_symlink(ovl_upper_mnt_idmap(ofs), dir, dentry, oldname, NULL); pr_debug("symlink(\"%s\", %pd2) = %i\n", oldname, dentry, err); + if (!err) { + ovl_upper_modified(ofs, dir); + ovl_upper_modified(ofs, d_inode(dentry)); + } return err; } @@ -336,6 +386,8 @@ static inline int ovl_do_setxattr(struct ovl_fs *ofs, struct dentry *dentry, pr_debug("setxattr(%pd2, \"%s\", \"%*pE\", %zu, %d) = %i\n", dentry, name, min((int)size, 48), value, size, flags, err); + if (!err) + ovl_upper_modified(ofs, d_inode(dentry)); return err; } @@ -351,6 +403,8 @@ static inline int ovl_do_removexattr(struct ovl_fs *ofs, struct dentry *dentry, { int err = vfs_removexattr(ovl_upper_mnt_idmap(ofs), dentry, name); pr_debug("removexattr(%pd2, \"%s\") = %i\n", dentry, name, err); + if (!err) + ovl_upper_modified(ofs, d_inode(dentry)); return err; } @@ -363,30 +417,25 @@ static inline int ovl_removexattr(struct ovl_fs *ofs, struct dentry *dentry, static inline int ovl_do_set_acl(struct ovl_fs *ofs, struct dentry *dentry, const char *acl_name, struct posix_acl *acl) { - return vfs_set_acl(ovl_upper_mnt_idmap(ofs), dentry, acl_name, acl); + int err = vfs_set_acl(ovl_upper_mnt_idmap(ofs), dentry, acl_name, acl); + + if (!err) + ovl_upper_modified(ofs, d_inode(dentry)); + return err; } static inline int ovl_do_remove_acl(struct ovl_fs *ofs, struct dentry *dentry, const char *acl_name) { - return vfs_remove_acl(ovl_upper_mnt_idmap(ofs), dentry, acl_name); -} + int err = vfs_remove_acl(ovl_upper_mnt_idmap(ofs), dentry, acl_name); -static inline int ovl_do_rename_rd(struct ovl_fs *ofs, - struct renamedata *rd) -{ - int err; - - pr_debug("rename(%pd2, %pd2, 0x%x)\n", rd->old_dentry, rd->new_dentry, - rd->flags); - err = vfs_rename(rd); - if (err) { - pr_debug("...rename(%pd2, %pd2, ...) = %i\n", - rd->old_dentry, rd->new_dentry, err); - } + if (!err) + ovl_upper_modified(ofs, d_inode(dentry)); return err; } +int ovl_do_rename_rd(struct ovl_fs *ofs, struct renamedata *rd); + static inline int ovl_do_rename(struct ovl_fs *ofs, struct dentry *olddir, struct dentry *olddentry, struct dentry *newdir, struct dentry *newdentry, unsigned int flags) @@ -408,6 +457,10 @@ static inline int ovl_do_whiteout(struct ovl_fs *ofs, { int err = vfs_whiteout(ovl_upper_mnt_idmap(ofs), dir, dentry); pr_debug("whiteout(%pd2) = %i\n", dentry, err); + if (!err) { + ovl_upper_modified(ofs, dir); + ovl_upper_modified(ofs, d_inode(dentry)); + } return err; } @@ -516,6 +569,7 @@ const struct ovl_layer *ovl_layer_lower(struct dentry *dentry); struct dentry *ovl_dentry_real(struct dentry *dentry); struct dentry *ovl_i_dentry_upper(struct inode *inode); struct inode *ovl_inode_upper(struct inode *inode); +struct inode *ovl_inode_upper_to_write(struct inode *inode); /* How ovl_write_upper_inode() writes an upper inode */ enum ovl_write_mode { diff --git a/fs/overlayfs/ovl_entry.h b/fs/overlayfs/ovl_entry.h index ac07e8769f9b..ed9a3a959fc0 100644 --- a/fs/overlayfs/ovl_entry.h +++ b/fs/overlayfs/ovl_entry.h @@ -85,6 +85,8 @@ struct ovl_fs { int xino_mode; /* For allocation of non-persistent inode numbers */ atomic_long_t last_ino; + /* For ovl_upper_modified(), which only gets to see upper inodes */ + struct super_block *sb; /* Shared whiteout cache */ struct dentry *whiteout; bool no_shared_whiteout; diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index c43f8fdd6230..84258edb5530 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c @@ -235,6 +235,8 @@ static void ovl_destroy_inode(struct inode *inode) { struct ovl_inode *oi = OVL_I(inode); + if (ovl_test_flag(OVL_FAKE, inode)) + iput(inode->i_private); dput(oi->__upperdentry); ovl_stack_put(ovl_lowerstack(oi->oe), ovl_numlower(oi->oe)); if (S_ISDIR(inode->i_mode)) @@ -336,12 +338,16 @@ static int ovl_statfs(struct dentry *dentry, struct kstatfs *buf) * the mapping goes away at the latest. i_writecount drops after that, when the * file is released, with the full barrier of the last fput() in between. */ -static bool ovl_upper_unfinished(struct inode *upper) +static bool ovl_upper_unfinished(struct inode *inode, struct inode *upper) { struct address_space *mapping = upper->i_mapping; - return atomic_read_acquire(&upper->i_writecount) > 0 || - mapping_tagged(mapping, PAGECACHE_TAG_DIRTY) || + /* A file that can be mapped has an overlay inode, which keeps track */ + if (!ovl_test_flag(OVL_FAKE, inode) && + atomic_read_acquire(&upper->i_writecount) > 0) + return true; + + return mapping_tagged(mapping, PAGECACHE_TAG_DIRTY) || mapping_tagged(mapping, PAGECACHE_TAG_WRITEBACK) || (inode_state_read_once(upper) & (I_DIRTY | I_SYNC)); } @@ -395,7 +401,7 @@ static void ovl_park_inode(struct inode *inode) static int ovl_write_inode(struct inode *inode, struct writeback_control *wbc) { - struct inode *upper = ovl_inode_upper(inode); + struct inode *upper = ovl_inode_upper_to_write(inode); int ret = 0; if (!upper) @@ -411,7 +417,7 @@ static int ovl_write_inode(struct inode *inode, struct writeback_control *wbc) ret = ovl_write_upper_inode(inode->i_sb, upper, ovl_write_mode(inode, upper, wbc)); - if (ovl_upper_unfinished(upper)) + if (ovl_upper_unfinished(inode, upper)) ovl_mark_inode_dirty(inode); else if (inode_state_read_once(upper) & I_DIRTY_TIME) ovl_park_inode(inode); @@ -1697,6 +1703,8 @@ int ovl_fill_super(struct super_block *sb, struct fs_context *fc) struct ovl_fs *ofs = sb->s_fs_info; int err; + ofs->sb = sb; + err = -EINVAL; /* The fscontext fd may have been passed to another user namespace. */ if (fc->user_ns != current_user_ns()) diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c index 76e090b2a0c5..ff43f8c39979 100644 --- a/fs/overlayfs/util.c +++ b/fs/overlayfs/util.c @@ -1580,3 +1580,45 @@ int ovl_write_upper_inode(struct super_block *sb, struct inode *upper, errseq_set(&sb->s_wb_err, err); return err; } + +int ovl_do_rename_rd(struct ovl_fs *ofs, struct renamedata *rd) +{ + struct inode *target = d_inode(rd->new_dentry); + struct name_snapshot old_name; + struct dentry *whiteout; + int err; + + pr_debug("rename(%pd2, %pd2, 0x%x)\n", rd->old_dentry, rd->new_dentry, + rd->flags); + + /* The old dentry is going to have the new name */ + take_dentry_name_snapshot(&old_name, rd->old_dentry); + + err = vfs_rename(rd); + if (err) { + pr_debug("...rename(%pd2, %pd2, ...) = %i\n", + rd->old_dentry, rd->new_dentry, err); + goto out; + } + + ovl_upper_modified(ofs, d_inode(rd->old_parent)); + ovl_upper_modified(ofs, d_inode(rd->new_parent)); + ovl_upper_modified(ofs, d_inode(rd->old_dentry)); + ovl_upper_modified(ofs, target); + + /* The upper filesystem has made this inode itself, so look it up */ + if ((rd->flags & RENAME_WHITEOUT) && ovl_tracks_dirty(ofs)) { + whiteout = lookup_one(rd->mnt_idmap, &old_name.name, + rd->old_parent); + if (!IS_ERR(whiteout)) { + ovl_upper_modified(ofs, d_inode(whiteout)); + dput(whiteout); + } else { + /* The rename has succeeded, let syncfs() say it */ + errseq_set(&ofs->sb->s_wb_err, PTR_ERR(whiteout)); + } + } +out: + release_dentry_name_snapshot(&old_name); + return err; +} -- 2.55.0