Commit 7bb5226c authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -793,10 +793,17 @@ static inline bool fast_dput(struct dentry *dentry)
	 * a reference to the dentry and change that, but
	 * our work is done - we can leave the dentry
	 * 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();
	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? */
	if (d_flags == (DCACHE_REFERENCED | DCACHE_LRU_LIST) && !d_unhashed(dentry))
+1 −1
Original line number Diff line number Diff line
@@ -315,7 +315,7 @@ retry:
	if (mode & FMODE_WRITE)
		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)
		return -ENOMEM;

+3 −1
Original line number Diff line number Diff line
@@ -1624,7 +1624,9 @@ static void iput_final(struct inode *inode)
	else
		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);
		spin_unlock(&inode->i_lock);
		return;
+3 −1
Original line number Diff line number Diff line
@@ -2114,8 +2114,10 @@ static int link_path_walk(const char *name, struct nameidata *nd)
		return PTR_ERR(name);
	while (*name=='/')
		name++;
	if (!*name)
	if (!*name) {
		nd->dir_mode = 0; // short-circuit the 'hardening' idiocy
		return 0;
	}

	/* At this point we know we have a real path component. */
	for(;;) {
+6 −3
Original line number Diff line number Diff line
@@ -156,10 +156,10 @@ static inline void mnt_add_count(struct mount *mnt, int n)
/*
 * 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
	unsigned int count = 0;
	int count = 0;
	int cpu;

	for_each_possible_cpu(cpu) {
@@ -1139,6 +1139,7 @@ static DECLARE_DELAYED_WORK(delayed_mntput_work, delayed_mntput);
static void mntput_no_expire(struct mount *mnt)
{
	LIST_HEAD(list);
	int count;

	rcu_read_lock();
	if (likely(READ_ONCE(mnt->mnt_ns))) {
@@ -1162,7 +1163,9 @@ static void mntput_no_expire(struct mount *mnt)
	 */
	smp_mb();
	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();
		unlock_mount_hash();
		return;
Loading