Loading fs/overlayfs/copy_up.c +1 −2 Original line number Diff line number Diff line Loading @@ -417,8 +417,7 @@ static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir, goto out_cleanup; newdentry = dget(tmpfile ? upper : temp); ovl_dentry_update(dentry, newdentry); ovl_inode_update(d_inode(dentry), d_inode(newdentry)); ovl_inode_update(d_inode(dentry), newdentry); /* Restore timestamps on parent (best effort) */ ovl_set_timestamps(upperdir, pstat); Loading fs/overlayfs/dir.c +4 −4 Original line number Diff line number Diff line Loading @@ -154,12 +154,12 @@ static void ovl_instantiate(struct dentry *dentry, struct inode *inode, struct dentry *newdentry, bool hardlink) { ovl_dentry_version_inc(dentry->d_parent); ovl_dentry_update(dentry, newdentry); if (!hardlink) { ovl_inode_update(inode, d_inode(newdentry)); ovl_inode_update(inode, newdentry); ovl_copyattr(newdentry->d_inode, inode); } else { WARN_ON(ovl_inode_real(inode, NULL) != d_inode(newdentry)); WARN_ON(ovl_inode_real(inode) != d_inode(newdentry)); dput(newdentry); inc_nlink(inode); } d_instantiate(dentry, inode); Loading Loading @@ -1003,7 +1003,7 @@ static int ovl_rename(struct inode *olddir, struct dentry *old, new_opaque = ovl_dentry_is_opaque(new); err = -ESTALE; if (ovl_dentry_upper(new)) { if (d_inode(new) && ovl_dentry_upper(new)) { if (opaquedir) { if (newdentry != opaquedir) goto out_dput; Loading fs/overlayfs/inode.c +17 −9 Original line number Diff line number Diff line Loading @@ -134,8 +134,8 @@ int ovl_getattr(const struct path *path, struct kstat *stat, int ovl_permission(struct inode *inode, int mask) { bool is_upper; struct inode *realinode = ovl_inode_real(inode, &is_upper); struct inode *upperinode = ovl_inode_upper(inode); struct inode *realinode = upperinode ?: ovl_inode_lower(inode); const struct cred *old_cred; int err; Loading @@ -154,7 +154,8 @@ int ovl_permission(struct inode *inode, int mask) return err; old_cred = ovl_override_creds(inode->i_sb); if (!is_upper && !special_file(realinode->i_mode) && mask & MAY_WRITE) { if (!upperinode && !special_file(realinode->i_mode) && mask & MAY_WRITE) { mask &= ~(MAY_WRITE | MAY_APPEND); /* Make sure mounter can read file for copy up later */ mask |= MAY_READ; Loading Loading @@ -286,7 +287,7 @@ ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size) struct posix_acl *ovl_get_acl(struct inode *inode, int type) { struct inode *realinode = ovl_inode_real(inode, NULL); struct inode *realinode = ovl_inode_real(inode); const struct cred *old_cred; struct posix_acl *acl; Loading Loading @@ -462,17 +463,24 @@ static int ovl_inode_set(struct inode *inode, void *data) return 0; } struct inode *ovl_get_inode(struct dentry *dentry) struct inode *ovl_get_inode(struct dentry *dentry, struct dentry *upperdentry) { struct dentry *upperdentry = ovl_dentry_upper(dentry); struct inode *realinode = d_inode(ovl_dentry_real(dentry)); struct dentry *lowerdentry = ovl_dentry_lower(dentry); struct inode *realinode = upperdentry ? d_inode(upperdentry) : NULL; struct inode *inode; if (!realinode) realinode = d_inode(lowerdentry); if (upperdentry && !d_is_dir(upperdentry)) { inode = iget5_locked(dentry->d_sb, (unsigned long) realinode, ovl_inode_test, ovl_inode_set, realinode); if (!inode || !(inode->i_state & I_NEW)) if (!inode) goto out; if (!(inode->i_state & I_NEW)) { dput(upperdentry); goto out; } set_nlink(inode, realinode->i_nlink); } else { Loading @@ -481,7 +489,7 @@ struct inode *ovl_get_inode(struct dentry *dentry) goto out; } ovl_fill_inode(inode, realinode->i_mode, realinode->i_rdev); ovl_inode_init(inode, dentry); ovl_inode_init(inode, upperdentry, lowerdentry); if (inode->i_state & I_NEW) unlock_new_inode(inode); out: Loading fs/overlayfs/namei.c +3 −4 Original line number Diff line number Diff line Loading @@ -359,7 +359,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, return ERR_PTR(-ENAMETOOLONG); old_cred = ovl_override_creds(dentry->d_sb); upperdir = ovl_upperdentry_dereference(poe); upperdir = ovl_dentry_upper(dentry->d_parent); if (upperdir) { err = ovl_lookup_layer(upperdir, &d, &upperdentry); if (err) Loading Loading @@ -436,13 +436,12 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, oe->opaque = upperopaque; oe->impure = upperimpure; oe->redirect = upperredirect; oe->__upperdentry = upperdentry; memcpy(oe->lowerstack, stack, sizeof(struct path) * ctr); dentry->d_fsdata = oe; if (upperdentry || ctr) { err = -ENOMEM; inode = ovl_get_inode(dentry); inode = ovl_get_inode(dentry, upperdentry); if (!inode) goto out_free_oe; } Loading Loading @@ -487,7 +486,7 @@ bool ovl_lower_positive(struct dentry *dentry) return oe->opaque; /* Negative upper -> positive lower */ if (!oe->__upperdentry) if (!ovl_dentry_upper(dentry)) return true; /* Positive upper -> have to look up lower to see whether it exists */ Loading fs/overlayfs/overlayfs.h +7 −5 Original line number Diff line number Diff line Loading @@ -189,7 +189,9 @@ enum ovl_path_type ovl_path_real(struct dentry *dentry, struct path *path); struct dentry *ovl_dentry_upper(struct dentry *dentry); struct dentry *ovl_dentry_lower(struct dentry *dentry); struct dentry *ovl_dentry_real(struct dentry *dentry); struct inode *ovl_inode_real(struct inode *inode, bool *is_upper); struct inode *ovl_inode_upper(struct inode *inode); struct inode *ovl_inode_lower(struct inode *inode); struct inode *ovl_inode_real(struct inode *inode); struct ovl_dir_cache *ovl_dir_cache(struct dentry *dentry); void ovl_set_dir_cache(struct dentry *dentry, struct ovl_dir_cache *cache); bool ovl_dentry_is_opaque(struct dentry *dentry); Loading @@ -199,9 +201,9 @@ void ovl_dentry_set_opaque(struct dentry *dentry); bool ovl_redirect_dir(struct super_block *sb); const char *ovl_dentry_get_redirect(struct dentry *dentry); void ovl_dentry_set_redirect(struct dentry *dentry, const char *redirect); void ovl_dentry_update(struct dentry *dentry, struct dentry *upperdentry); void ovl_inode_init(struct inode *inode, struct dentry *dentry); void ovl_inode_update(struct inode *inode, struct inode *upperinode); void ovl_inode_init(struct inode *inode, struct dentry *upperdentry, struct dentry *lowerdentry); void ovl_inode_update(struct inode *inode, struct dentry *upperdentry); void ovl_dentry_version_inc(struct dentry *dentry); u64 ovl_dentry_version_get(struct dentry *dentry); bool ovl_is_whiteout(struct dentry *dentry); Loading Loading @@ -250,7 +252,7 @@ int ovl_update_time(struct inode *inode, struct timespec *ts, int flags); bool ovl_is_private_xattr(const char *name); struct inode *ovl_new_inode(struct super_block *sb, umode_t mode, dev_t rdev); struct inode *ovl_get_inode(struct dentry *dentry); struct inode *ovl_get_inode(struct dentry *dentry, struct dentry *upperdentry); static inline void ovl_copyattr(struct inode *from, struct inode *to) { to->i_uid = from->i_uid; Loading Loading
fs/overlayfs/copy_up.c +1 −2 Original line number Diff line number Diff line Loading @@ -417,8 +417,7 @@ static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir, goto out_cleanup; newdentry = dget(tmpfile ? upper : temp); ovl_dentry_update(dentry, newdentry); ovl_inode_update(d_inode(dentry), d_inode(newdentry)); ovl_inode_update(d_inode(dentry), newdentry); /* Restore timestamps on parent (best effort) */ ovl_set_timestamps(upperdir, pstat); Loading
fs/overlayfs/dir.c +4 −4 Original line number Diff line number Diff line Loading @@ -154,12 +154,12 @@ static void ovl_instantiate(struct dentry *dentry, struct inode *inode, struct dentry *newdentry, bool hardlink) { ovl_dentry_version_inc(dentry->d_parent); ovl_dentry_update(dentry, newdentry); if (!hardlink) { ovl_inode_update(inode, d_inode(newdentry)); ovl_inode_update(inode, newdentry); ovl_copyattr(newdentry->d_inode, inode); } else { WARN_ON(ovl_inode_real(inode, NULL) != d_inode(newdentry)); WARN_ON(ovl_inode_real(inode) != d_inode(newdentry)); dput(newdentry); inc_nlink(inode); } d_instantiate(dentry, inode); Loading Loading @@ -1003,7 +1003,7 @@ static int ovl_rename(struct inode *olddir, struct dentry *old, new_opaque = ovl_dentry_is_opaque(new); err = -ESTALE; if (ovl_dentry_upper(new)) { if (d_inode(new) && ovl_dentry_upper(new)) { if (opaquedir) { if (newdentry != opaquedir) goto out_dput; Loading
fs/overlayfs/inode.c +17 −9 Original line number Diff line number Diff line Loading @@ -134,8 +134,8 @@ int ovl_getattr(const struct path *path, struct kstat *stat, int ovl_permission(struct inode *inode, int mask) { bool is_upper; struct inode *realinode = ovl_inode_real(inode, &is_upper); struct inode *upperinode = ovl_inode_upper(inode); struct inode *realinode = upperinode ?: ovl_inode_lower(inode); const struct cred *old_cred; int err; Loading @@ -154,7 +154,8 @@ int ovl_permission(struct inode *inode, int mask) return err; old_cred = ovl_override_creds(inode->i_sb); if (!is_upper && !special_file(realinode->i_mode) && mask & MAY_WRITE) { if (!upperinode && !special_file(realinode->i_mode) && mask & MAY_WRITE) { mask &= ~(MAY_WRITE | MAY_APPEND); /* Make sure mounter can read file for copy up later */ mask |= MAY_READ; Loading Loading @@ -286,7 +287,7 @@ ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size) struct posix_acl *ovl_get_acl(struct inode *inode, int type) { struct inode *realinode = ovl_inode_real(inode, NULL); struct inode *realinode = ovl_inode_real(inode); const struct cred *old_cred; struct posix_acl *acl; Loading Loading @@ -462,17 +463,24 @@ static int ovl_inode_set(struct inode *inode, void *data) return 0; } struct inode *ovl_get_inode(struct dentry *dentry) struct inode *ovl_get_inode(struct dentry *dentry, struct dentry *upperdentry) { struct dentry *upperdentry = ovl_dentry_upper(dentry); struct inode *realinode = d_inode(ovl_dentry_real(dentry)); struct dentry *lowerdentry = ovl_dentry_lower(dentry); struct inode *realinode = upperdentry ? d_inode(upperdentry) : NULL; struct inode *inode; if (!realinode) realinode = d_inode(lowerdentry); if (upperdentry && !d_is_dir(upperdentry)) { inode = iget5_locked(dentry->d_sb, (unsigned long) realinode, ovl_inode_test, ovl_inode_set, realinode); if (!inode || !(inode->i_state & I_NEW)) if (!inode) goto out; if (!(inode->i_state & I_NEW)) { dput(upperdentry); goto out; } set_nlink(inode, realinode->i_nlink); } else { Loading @@ -481,7 +489,7 @@ struct inode *ovl_get_inode(struct dentry *dentry) goto out; } ovl_fill_inode(inode, realinode->i_mode, realinode->i_rdev); ovl_inode_init(inode, dentry); ovl_inode_init(inode, upperdentry, lowerdentry); if (inode->i_state & I_NEW) unlock_new_inode(inode); out: Loading
fs/overlayfs/namei.c +3 −4 Original line number Diff line number Diff line Loading @@ -359,7 +359,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, return ERR_PTR(-ENAMETOOLONG); old_cred = ovl_override_creds(dentry->d_sb); upperdir = ovl_upperdentry_dereference(poe); upperdir = ovl_dentry_upper(dentry->d_parent); if (upperdir) { err = ovl_lookup_layer(upperdir, &d, &upperdentry); if (err) Loading Loading @@ -436,13 +436,12 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, oe->opaque = upperopaque; oe->impure = upperimpure; oe->redirect = upperredirect; oe->__upperdentry = upperdentry; memcpy(oe->lowerstack, stack, sizeof(struct path) * ctr); dentry->d_fsdata = oe; if (upperdentry || ctr) { err = -ENOMEM; inode = ovl_get_inode(dentry); inode = ovl_get_inode(dentry, upperdentry); if (!inode) goto out_free_oe; } Loading Loading @@ -487,7 +486,7 @@ bool ovl_lower_positive(struct dentry *dentry) return oe->opaque; /* Negative upper -> positive lower */ if (!oe->__upperdentry) if (!ovl_dentry_upper(dentry)) return true; /* Positive upper -> have to look up lower to see whether it exists */ Loading
fs/overlayfs/overlayfs.h +7 −5 Original line number Diff line number Diff line Loading @@ -189,7 +189,9 @@ enum ovl_path_type ovl_path_real(struct dentry *dentry, struct path *path); struct dentry *ovl_dentry_upper(struct dentry *dentry); struct dentry *ovl_dentry_lower(struct dentry *dentry); struct dentry *ovl_dentry_real(struct dentry *dentry); struct inode *ovl_inode_real(struct inode *inode, bool *is_upper); struct inode *ovl_inode_upper(struct inode *inode); struct inode *ovl_inode_lower(struct inode *inode); struct inode *ovl_inode_real(struct inode *inode); struct ovl_dir_cache *ovl_dir_cache(struct dentry *dentry); void ovl_set_dir_cache(struct dentry *dentry, struct ovl_dir_cache *cache); bool ovl_dentry_is_opaque(struct dentry *dentry); Loading @@ -199,9 +201,9 @@ void ovl_dentry_set_opaque(struct dentry *dentry); bool ovl_redirect_dir(struct super_block *sb); const char *ovl_dentry_get_redirect(struct dentry *dentry); void ovl_dentry_set_redirect(struct dentry *dentry, const char *redirect); void ovl_dentry_update(struct dentry *dentry, struct dentry *upperdentry); void ovl_inode_init(struct inode *inode, struct dentry *dentry); void ovl_inode_update(struct inode *inode, struct inode *upperinode); void ovl_inode_init(struct inode *inode, struct dentry *upperdentry, struct dentry *lowerdentry); void ovl_inode_update(struct inode *inode, struct dentry *upperdentry); void ovl_dentry_version_inc(struct dentry *dentry); u64 ovl_dentry_version_get(struct dentry *dentry); bool ovl_is_whiteout(struct dentry *dentry); Loading Loading @@ -250,7 +252,7 @@ int ovl_update_time(struct inode *inode, struct timespec *ts, int flags); bool ovl_is_private_xattr(const char *name); struct inode *ovl_new_inode(struct super_block *sb, umode_t mode, dev_t rdev); struct inode *ovl_get_inode(struct dentry *dentry); struct inode *ovl_get_inode(struct dentry *dentry, struct dentry *upperdentry); static inline void ovl_copyattr(struct inode *from, struct inode *to) { to->i_uid = from->i_uid; Loading