Commit 7bb5226c authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull misc vfs updates from Al Viro:
 "Assorted patches from previous cycle(s)..."

* 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  fix hostfs_open() use of ->f_path.dentry
  Make sure that make_create_in_sticky() never sees uninitialized value of dir_mode
  fs: Kill DCACHE_DONTCACHE dentry even if DCACHE_REFERENCED is set
  fs: Handle I_DONTCACHE in iput_final() instead of generic_drop_inode()
  fs/namespace.c: WARN if mnt_count has become negative
parents 71c5f031 2e2cbaf9
...@@ -793,10 +793,17 @@ static inline bool fast_dput(struct dentry *dentry) ...@@ -793,10 +793,17 @@ static inline bool fast_dput(struct dentry *dentry)
* a reference to the dentry and change that, but * a reference to the dentry and change that, but
* our work is done - we can leave the dentry * our work is done - we can leave the dentry
* around with a zero refcount. * around with a zero refcount.
*
* Nevertheless, there are two cases that we should kill
* the dentry anyway.
* 1. free disconnected dentries as soon as their refcount
* reached zero.
* 2. free dentries if they should not be cached.
*/ */
smp_rmb(); smp_rmb();
d_flags = READ_ONCE(dentry->d_flags); d_flags = READ_ONCE(dentry->d_flags);
d_flags &= DCACHE_REFERENCED | DCACHE_LRU_LIST | DCACHE_DISCONNECTED; d_flags &= DCACHE_REFERENCED | DCACHE_LRU_LIST |
DCACHE_DISCONNECTED | DCACHE_DONTCACHE;
/* Nothing to do? Dropping the reference was all we needed? */ /* Nothing to do? Dropping the reference was all we needed? */
if (d_flags == (DCACHE_REFERENCED | DCACHE_LRU_LIST) && !d_unhashed(dentry)) if (d_flags == (DCACHE_REFERENCED | DCACHE_LRU_LIST) && !d_unhashed(dentry))
......
...@@ -315,7 +315,7 @@ static int hostfs_open(struct inode *ino, struct file *file) ...@@ -315,7 +315,7 @@ static int hostfs_open(struct inode *ino, struct file *file)
if (mode & FMODE_WRITE) if (mode & FMODE_WRITE)
r = w = 1; r = w = 1;
name = dentry_name(file->f_path.dentry); name = dentry_name(d_real(file->f_path.dentry, file->f_inode));
if (name == NULL) if (name == NULL)
return -ENOMEM; return -ENOMEM;
......
...@@ -1624,7 +1624,9 @@ static void iput_final(struct inode *inode) ...@@ -1624,7 +1624,9 @@ static void iput_final(struct inode *inode)
else else
drop = generic_drop_inode(inode); drop = generic_drop_inode(inode);
if (!drop && (sb->s_flags & SB_ACTIVE)) { if (!drop &&
!(inode->i_state & I_DONTCACHE) &&
(sb->s_flags & SB_ACTIVE)) {
inode_add_lru(inode); inode_add_lru(inode);
spin_unlock(&inode->i_lock); spin_unlock(&inode->i_lock);
return; return;
......
...@@ -2114,8 +2114,10 @@ static int link_path_walk(const char *name, struct nameidata *nd) ...@@ -2114,8 +2114,10 @@ static int link_path_walk(const char *name, struct nameidata *nd)
return PTR_ERR(name); return PTR_ERR(name);
while (*name=='/') while (*name=='/')
name++; name++;
if (!*name) if (!*name) {
nd->dir_mode = 0; // short-circuit the 'hardening' idiocy
return 0; return 0;
}
/* At this point we know we have a real path component. */ /* At this point we know we have a real path component. */
for(;;) { for(;;) {
......
...@@ -156,10 +156,10 @@ static inline void mnt_add_count(struct mount *mnt, int n) ...@@ -156,10 +156,10 @@ static inline void mnt_add_count(struct mount *mnt, int n)
/* /*
* vfsmount lock must be held for write * vfsmount lock must be held for write
*/ */
unsigned int mnt_get_count(struct mount *mnt) int mnt_get_count(struct mount *mnt)
{ {
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
unsigned int count = 0; int count = 0;
int cpu; int cpu;
for_each_possible_cpu(cpu) { for_each_possible_cpu(cpu) {
...@@ -1139,6 +1139,7 @@ static DECLARE_DELAYED_WORK(delayed_mntput_work, delayed_mntput); ...@@ -1139,6 +1139,7 @@ static DECLARE_DELAYED_WORK(delayed_mntput_work, delayed_mntput);
static void mntput_no_expire(struct mount *mnt) static void mntput_no_expire(struct mount *mnt)
{ {
LIST_HEAD(list); LIST_HEAD(list);
int count;
rcu_read_lock(); rcu_read_lock();
if (likely(READ_ONCE(mnt->mnt_ns))) { if (likely(READ_ONCE(mnt->mnt_ns))) {
...@@ -1162,7 +1163,9 @@ static void mntput_no_expire(struct mount *mnt) ...@@ -1162,7 +1163,9 @@ static void mntput_no_expire(struct mount *mnt)
*/ */
smp_mb(); smp_mb();
mnt_add_count(mnt, -1); mnt_add_count(mnt, -1);
if (mnt_get_count(mnt)) { count = mnt_get_count(mnt);
if (count != 0) {
WARN_ON(count < 0);
rcu_read_unlock(); rcu_read_unlock();
unlock_mount_hash(); unlock_mount_hash();
return; return;
......
...@@ -44,7 +44,7 @@ int propagate_mount_busy(struct mount *, int); ...@@ -44,7 +44,7 @@ int propagate_mount_busy(struct mount *, int);
void propagate_mount_unlock(struct mount *); void propagate_mount_unlock(struct mount *);
void mnt_release_group_id(struct mount *); void mnt_release_group_id(struct mount *);
int get_dominating_id(struct mount *mnt, const struct path *root); int get_dominating_id(struct mount *mnt, const struct path *root);
unsigned int mnt_get_count(struct mount *mnt); int mnt_get_count(struct mount *mnt);
void mnt_set_mountpoint(struct mount *, struct mountpoint *, void mnt_set_mountpoint(struct mount *, struct mountpoint *,
struct mount *); struct mount *);
void mnt_change_mountpoint(struct mount *parent, struct mountpoint *mp, void mnt_change_mountpoint(struct mount *parent, struct mountpoint *mp,
......
...@@ -2876,8 +2876,7 @@ extern int inode_needs_sync(struct inode *inode); ...@@ -2876,8 +2876,7 @@ extern int inode_needs_sync(struct inode *inode);
extern int generic_delete_inode(struct inode *inode); extern int generic_delete_inode(struct inode *inode);
static inline int generic_drop_inode(struct inode *inode) static inline int generic_drop_inode(struct inode *inode)
{ {
return !inode->i_nlink || inode_unhashed(inode) || return !inode->i_nlink || inode_unhashed(inode);
(inode->i_state & I_DONTCACHE);
} }
extern void d_mark_dontcache(struct inode *inode); extern void d_mark_dontcache(struct inode *inode);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment