Loading fs/overlayfs/overlayfs.h +3 −3 Original line number Diff line number Diff line Loading @@ -401,7 +401,7 @@ const char *ovl_dentry_get_redirect(struct dentry *dentry); void ovl_dentry_set_redirect(struct dentry *dentry, const char *redirect); void ovl_inode_update(struct inode *inode, struct dentry *upperdentry); void ovl_dir_modified(struct dentry *dentry, bool impurity); u64 ovl_dentry_version_get(struct dentry *dentry); u64 ovl_inode_version_get(struct inode *inode); bool ovl_is_whiteout(struct dentry *dentry); struct file *ovl_path_open(const struct path *path, int flags); int ovl_copy_up_start(struct dentry *dentry, int flags); Loading Loading @@ -571,9 +571,9 @@ int ovl_indexdir_cleanup(struct ovl_fs *ofs); * lower dir was removed under it and possibly before it was rotated from upper * to lower layer. */ static inline bool ovl_dir_is_real(struct dentry *dir) static inline bool ovl_dir_is_real(struct inode *dir) { return !ovl_test_flag(OVL_WHITEOUTS, d_inode(dir)); return !ovl_test_flag(OVL_WHITEOUTS, dir); } /* inode.c */ Loading fs/overlayfs/readdir.c +24 −22 Original line number Diff line number Diff line Loading @@ -235,15 +235,15 @@ void ovl_dir_cache_free(struct inode *inode) } } static void ovl_cache_put(struct ovl_dir_file *od, struct dentry *dentry) static void ovl_cache_put(struct ovl_dir_file *od, struct inode *inode) { struct ovl_dir_cache *cache = od->cache; WARN_ON(cache->refcount <= 0); cache->refcount--; if (!cache->refcount) { if (ovl_dir_cache(d_inode(dentry)) == cache) ovl_set_dir_cache(d_inode(dentry), NULL); if (ovl_dir_cache(inode) == cache) ovl_set_dir_cache(inode, NULL); ovl_cache_free(&cache->entries); kfree(cache); Loading Loading @@ -323,15 +323,15 @@ static void ovl_dir_reset(struct file *file) { struct ovl_dir_file *od = file->private_data; struct ovl_dir_cache *cache = od->cache; struct dentry *dentry = file->f_path.dentry; struct inode *inode = file_inode(file); bool is_real; if (cache && ovl_dentry_version_get(dentry) != cache->version) { ovl_cache_put(od, dentry); if (cache && ovl_inode_version_get(inode) != cache->version) { ovl_cache_put(od, inode); od->cache = NULL; od->cursor = NULL; } is_real = ovl_dir_is_real(dentry); is_real = ovl_dir_is_real(inode); if (od->is_real != is_real) { /* is_real can only become false when dir is copied up */ if (WARN_ON(is_real)) Loading Loading @@ -394,9 +394,10 @@ static struct ovl_dir_cache *ovl_cache_get(struct dentry *dentry) { int res; struct ovl_dir_cache *cache; struct inode *inode = d_inode(dentry); cache = ovl_dir_cache(d_inode(dentry)); if (cache && ovl_dentry_version_get(dentry) == cache->version) { cache = ovl_dir_cache(inode); if (cache && ovl_inode_version_get(inode) == cache->version) { WARN_ON(!cache->refcount); cache->refcount++; return cache; Loading @@ -418,8 +419,8 @@ static struct ovl_dir_cache *ovl_cache_get(struct dentry *dentry) return ERR_PTR(res); } cache->version = ovl_dentry_version_get(dentry); ovl_set_dir_cache(d_inode(dentry), cache); cache->version = ovl_inode_version_get(inode); ovl_set_dir_cache(inode, cache); return cache; } Loading Loading @@ -596,16 +597,17 @@ static struct ovl_dir_cache *ovl_cache_get_impure(const struct path *path) { int res; struct dentry *dentry = path->dentry; struct inode *inode = d_inode(dentry); struct ovl_fs *ofs = OVL_FS(dentry->d_sb); struct ovl_dir_cache *cache; cache = ovl_dir_cache(d_inode(dentry)); if (cache && ovl_dentry_version_get(dentry) == cache->version) cache = ovl_dir_cache(inode); if (cache && ovl_inode_version_get(inode) == cache->version) return cache; /* Impure cache is not refcounted, free it here */ ovl_dir_cache_free(d_inode(dentry)); ovl_set_dir_cache(d_inode(dentry), NULL); ovl_dir_cache_free(inode); ovl_set_dir_cache(inode, NULL); cache = kzalloc(sizeof(struct ovl_dir_cache), GFP_KERNEL); if (!cache) Loading @@ -627,13 +629,13 @@ static struct ovl_dir_cache *ovl_cache_get_impure(const struct path *path) OVL_XATTR_IMPURE); ovl_drop_write(dentry); } ovl_clear_flag(OVL_IMPURE, d_inode(dentry)); ovl_clear_flag(OVL_IMPURE, inode); kfree(cache); return NULL; } cache->version = ovl_dentry_version_get(dentry); ovl_set_dir_cache(d_inode(dentry), cache); cache->version = ovl_inode_version_get(inode); ovl_set_dir_cache(inode, cache); return cache; } Loading Loading @@ -675,7 +677,7 @@ static bool ovl_fill_real(struct dir_context *ctx, const char *name, static bool ovl_is_impure_dir(struct file *file) { struct ovl_dir_file *od = file->private_data; struct inode *dir = d_inode(file->f_path.dentry); struct inode *dir = file_inode(file); /* * Only upper dir can be impure, but if we are in the middle of Loading Loading @@ -893,7 +895,7 @@ static int ovl_dir_fsync(struct file *file, loff_t start, loff_t end, struct file *realfile; int err; err = ovl_sync_status(OVL_FS(file->f_path.dentry->d_sb)); err = ovl_sync_status(OVL_FS(file_inode(file)->i_sb)); if (err <= 0) return err; Loading @@ -913,7 +915,7 @@ static int ovl_dir_release(struct inode *inode, struct file *file) if (od->cache) { inode_lock(inode); ovl_cache_put(od, file->f_path.dentry); ovl_cache_put(od, inode); inode_unlock(inode); } fput(od->realfile); Loading Loading @@ -942,7 +944,7 @@ static int ovl_dir_open(struct inode *inode, struct file *file) return PTR_ERR(realfile); } od->realfile = realfile; od->is_real = ovl_dir_is_real(file->f_path.dentry); od->is_real = ovl_dir_is_real(inode); od->is_upper = OVL_TYPE_UPPER(type); file->private_data = od; Loading fs/overlayfs/util.c +2 −4 Original line number Diff line number Diff line Loading @@ -463,7 +463,7 @@ static void ovl_dir_version_inc(struct dentry *dentry, bool impurity) * which have been copied up and have origins), so only need to note * changes to impure entries. */ if (!ovl_dir_is_real(dentry) || impurity) if (!ovl_dir_is_real(inode) || impurity) OVL_I(inode)->version++; } Loading @@ -475,10 +475,8 @@ void ovl_dir_modified(struct dentry *dentry, bool impurity) ovl_dir_version_inc(dentry, impurity); } u64 ovl_dentry_version_get(struct dentry *dentry) u64 ovl_inode_version_get(struct inode *inode) { struct inode *inode = d_inode(dentry); WARN_ON(!inode_is_locked(inode)); return OVL_I(inode)->version; } Loading Loading
fs/overlayfs/overlayfs.h +3 −3 Original line number Diff line number Diff line Loading @@ -401,7 +401,7 @@ const char *ovl_dentry_get_redirect(struct dentry *dentry); void ovl_dentry_set_redirect(struct dentry *dentry, const char *redirect); void ovl_inode_update(struct inode *inode, struct dentry *upperdentry); void ovl_dir_modified(struct dentry *dentry, bool impurity); u64 ovl_dentry_version_get(struct dentry *dentry); u64 ovl_inode_version_get(struct inode *inode); bool ovl_is_whiteout(struct dentry *dentry); struct file *ovl_path_open(const struct path *path, int flags); int ovl_copy_up_start(struct dentry *dentry, int flags); Loading Loading @@ -571,9 +571,9 @@ int ovl_indexdir_cleanup(struct ovl_fs *ofs); * lower dir was removed under it and possibly before it was rotated from upper * to lower layer. */ static inline bool ovl_dir_is_real(struct dentry *dir) static inline bool ovl_dir_is_real(struct inode *dir) { return !ovl_test_flag(OVL_WHITEOUTS, d_inode(dir)); return !ovl_test_flag(OVL_WHITEOUTS, dir); } /* inode.c */ Loading
fs/overlayfs/readdir.c +24 −22 Original line number Diff line number Diff line Loading @@ -235,15 +235,15 @@ void ovl_dir_cache_free(struct inode *inode) } } static void ovl_cache_put(struct ovl_dir_file *od, struct dentry *dentry) static void ovl_cache_put(struct ovl_dir_file *od, struct inode *inode) { struct ovl_dir_cache *cache = od->cache; WARN_ON(cache->refcount <= 0); cache->refcount--; if (!cache->refcount) { if (ovl_dir_cache(d_inode(dentry)) == cache) ovl_set_dir_cache(d_inode(dentry), NULL); if (ovl_dir_cache(inode) == cache) ovl_set_dir_cache(inode, NULL); ovl_cache_free(&cache->entries); kfree(cache); Loading Loading @@ -323,15 +323,15 @@ static void ovl_dir_reset(struct file *file) { struct ovl_dir_file *od = file->private_data; struct ovl_dir_cache *cache = od->cache; struct dentry *dentry = file->f_path.dentry; struct inode *inode = file_inode(file); bool is_real; if (cache && ovl_dentry_version_get(dentry) != cache->version) { ovl_cache_put(od, dentry); if (cache && ovl_inode_version_get(inode) != cache->version) { ovl_cache_put(od, inode); od->cache = NULL; od->cursor = NULL; } is_real = ovl_dir_is_real(dentry); is_real = ovl_dir_is_real(inode); if (od->is_real != is_real) { /* is_real can only become false when dir is copied up */ if (WARN_ON(is_real)) Loading Loading @@ -394,9 +394,10 @@ static struct ovl_dir_cache *ovl_cache_get(struct dentry *dentry) { int res; struct ovl_dir_cache *cache; struct inode *inode = d_inode(dentry); cache = ovl_dir_cache(d_inode(dentry)); if (cache && ovl_dentry_version_get(dentry) == cache->version) { cache = ovl_dir_cache(inode); if (cache && ovl_inode_version_get(inode) == cache->version) { WARN_ON(!cache->refcount); cache->refcount++; return cache; Loading @@ -418,8 +419,8 @@ static struct ovl_dir_cache *ovl_cache_get(struct dentry *dentry) return ERR_PTR(res); } cache->version = ovl_dentry_version_get(dentry); ovl_set_dir_cache(d_inode(dentry), cache); cache->version = ovl_inode_version_get(inode); ovl_set_dir_cache(inode, cache); return cache; } Loading Loading @@ -596,16 +597,17 @@ static struct ovl_dir_cache *ovl_cache_get_impure(const struct path *path) { int res; struct dentry *dentry = path->dentry; struct inode *inode = d_inode(dentry); struct ovl_fs *ofs = OVL_FS(dentry->d_sb); struct ovl_dir_cache *cache; cache = ovl_dir_cache(d_inode(dentry)); if (cache && ovl_dentry_version_get(dentry) == cache->version) cache = ovl_dir_cache(inode); if (cache && ovl_inode_version_get(inode) == cache->version) return cache; /* Impure cache is not refcounted, free it here */ ovl_dir_cache_free(d_inode(dentry)); ovl_set_dir_cache(d_inode(dentry), NULL); ovl_dir_cache_free(inode); ovl_set_dir_cache(inode, NULL); cache = kzalloc(sizeof(struct ovl_dir_cache), GFP_KERNEL); if (!cache) Loading @@ -627,13 +629,13 @@ static struct ovl_dir_cache *ovl_cache_get_impure(const struct path *path) OVL_XATTR_IMPURE); ovl_drop_write(dentry); } ovl_clear_flag(OVL_IMPURE, d_inode(dentry)); ovl_clear_flag(OVL_IMPURE, inode); kfree(cache); return NULL; } cache->version = ovl_dentry_version_get(dentry); ovl_set_dir_cache(d_inode(dentry), cache); cache->version = ovl_inode_version_get(inode); ovl_set_dir_cache(inode, cache); return cache; } Loading Loading @@ -675,7 +677,7 @@ static bool ovl_fill_real(struct dir_context *ctx, const char *name, static bool ovl_is_impure_dir(struct file *file) { struct ovl_dir_file *od = file->private_data; struct inode *dir = d_inode(file->f_path.dentry); struct inode *dir = file_inode(file); /* * Only upper dir can be impure, but if we are in the middle of Loading Loading @@ -893,7 +895,7 @@ static int ovl_dir_fsync(struct file *file, loff_t start, loff_t end, struct file *realfile; int err; err = ovl_sync_status(OVL_FS(file->f_path.dentry->d_sb)); err = ovl_sync_status(OVL_FS(file_inode(file)->i_sb)); if (err <= 0) return err; Loading @@ -913,7 +915,7 @@ static int ovl_dir_release(struct inode *inode, struct file *file) if (od->cache) { inode_lock(inode); ovl_cache_put(od, file->f_path.dentry); ovl_cache_put(od, inode); inode_unlock(inode); } fput(od->realfile); Loading Loading @@ -942,7 +944,7 @@ static int ovl_dir_open(struct inode *inode, struct file *file) return PTR_ERR(realfile); } od->realfile = realfile; od->is_real = ovl_dir_is_real(file->f_path.dentry); od->is_real = ovl_dir_is_real(inode); od->is_upper = OVL_TYPE_UPPER(type); file->private_data = od; Loading
fs/overlayfs/util.c +2 −4 Original line number Diff line number Diff line Loading @@ -463,7 +463,7 @@ static void ovl_dir_version_inc(struct dentry *dentry, bool impurity) * which have been copied up and have origins), so only need to note * changes to impure entries. */ if (!ovl_dir_is_real(dentry) || impurity) if (!ovl_dir_is_real(inode) || impurity) OVL_I(inode)->version++; } Loading @@ -475,10 +475,8 @@ void ovl_dir_modified(struct dentry *dentry, bool impurity) ovl_dir_version_inc(dentry, impurity); } u64 ovl_dentry_version_get(struct dentry *dentry) u64 ovl_inode_version_get(struct inode *inode) { struct inode *inode = d_inode(dentry); WARN_ON(!inode_is_locked(inode)); return OVL_I(inode)->version; } Loading