lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:	Fri, 8 Nov 2013 17:50:55 +1100
From:	Stephen Rothwell <sfr@...b.auug.org.au>
To:	"Eric W. Biederman" <ebiederm@...ssion.com>,
	Al Viro <viro@...IV.linux.org.uk>
Cc:	linux-next@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: linux-next: manual merge of the userns tree with the vfs tree

Hi Eric,

Today's linux-next merge of the userns tree got a conflict in fs/dcache.c
between commit 84550b9356af ("RCU'd vfsmounts") from the vfs tree and
commit 40216baa0101 ("vfs: Lazily remove mounts on unlinked files and
directories. v2") from the userns tree.

I fixed it up (I think - see below) and can carry the fix as necessary
(no action is required).

Al, I do have to wonder why a commit whose whole commit message is:

"RCU'd vfsmounts
    
_very_ preliminary, barely tested."

is in linux-next as is not being kept over for v3.14 at this point.
-- 
Cheers,
Stephen Rothwell                    sfr@...b.auug.org.au

diff --cc fs/dcache.c
index 6f418c540f76,1e9bf96b0132..000000000000
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@@ -1362,110 -1478,17 +1362,101 @@@ void shrink_dcache_parent(struct dentr
  }
  EXPORT_SYMBOL(shrink_dcache_parent);
  
 +static enum d_walk_ret umount_collect(void *_data, struct dentry *dentry)
 +{
 +	struct select_data *data = _data;
 +	enum d_walk_ret ret = D_WALK_CONTINUE;
 +
 +	if (dentry->d_lockref.count) {
 +		dentry_lru_del(dentry);
 +		if (likely(!list_empty(&dentry->d_subdirs)))
 +			goto out;
 +		if (dentry == data->start && dentry->d_lockref.count == 1)
 +			goto out;
 +		printk(KERN_ERR
 +		       "BUG: Dentry %p{i=%lx,n=%s}"
 +		       " still in use (%d)"
 +		       " [unmount of %s %s]\n",
 +		       dentry,
 +		       dentry->d_inode ?
 +		       dentry->d_inode->i_ino : 0UL,
 +		       dentry->d_name.name,
 +		       dentry->d_lockref.count,
 +		       dentry->d_sb->s_type->name,
 +		       dentry->d_sb->s_id);
 +		BUG();
 +	} else if (!(dentry->d_flags & DCACHE_SHRINK_LIST)) {
 +		/*
 +		 * We can't use d_lru_shrink_move() because we
 +		 * need to get the global LRU lock and do the
 +		 * LRU accounting.
 +		 */
 +		d_lru_del(dentry);
 +		d_shrink_add(dentry, &data->dispose);
 +		data->found++;
 +		ret = D_WALK_NORETRY;
 +	}
 +out:
 +	if (data->found && need_resched())
 +		ret = D_WALK_QUIT;
 +	return ret;
 +}
 +
 +/*
 + * destroy the dentries attached to a superblock on unmounting
 + */
 +void shrink_dcache_for_umount(struct super_block *sb)
 +{
 +	struct dentry *dentry;
 +
 +	if (down_read_trylock(&sb->s_umount))
 +		BUG();
 +
 +	dentry = sb->s_root;
 +	sb->s_root = NULL;
 +	for (;;) {
 +		struct select_data data;
 +
 +		INIT_LIST_HEAD(&data.dispose);
 +		data.start = dentry;
 +		data.found = 0;
 +
 +		d_walk(dentry, &data, umount_collect, NULL);
 +		if (!data.found)
 +			break;
 +
 +		shrink_dentry_list(&data.dispose);
 +		cond_resched();
 +	}
 +	d_drop(dentry);
 +	dput(dentry);
 +
 +	while (!hlist_bl_empty(&sb->s_anon)) {
 +		struct select_data data;
 +		dentry = hlist_bl_entry(hlist_bl_first(&sb->s_anon), struct dentry, d_hash);
 +
 +		INIT_LIST_HEAD(&data.dispose);
 +		data.start = NULL;
 +		data.found = 0;
 +
 +		d_walk(dentry, &data, umount_collect, NULL);
 +		if (data.found)
 +			shrink_dentry_list(&data.dispose);
 +		cond_resched();
 +	}
 +}
 +
- static enum d_walk_ret check_and_collect(void *_data, struct dentry *dentry)
+ struct detach_data {
+ 	struct dentry *found;
+ };
+ static enum d_walk_ret do_detach_submounts(void *ptr, struct dentry *dentry)
  {
- 	struct select_data *data = _data;
+ 	struct detach_data *data = ptr;
  
- 	if (d_mountpoint(dentry)) {
- 		data->found = -EBUSY;
- 		return D_WALK_QUIT;
- 	}
+ 	if (d_mountpoint(dentry))
+ 		data->found = dentry;
  
- 	return select_collect(_data, dentry);
- }
- 
- static void check_and_drop(void *_data)
- {
- 	struct select_data *data = _data;
- 
- 	if (d_mountpoint(data->start))
- 		data->found = -EBUSY;
- 	if (!data->found)
- 		__d_drop(data->start);
+ 	return data->found ? D_WALK_QUIT : D_WALK_CONTINUE;
  }
  
  /**

Content of type "application/pgp-signature" skipped

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ