lkml.org 
[lkml]   [2013]   [Nov]   [8]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
Subjectlinux-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@canb.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;
}

/**
[unhandled content-type:application/pgp-signature]
\
 
 \ /
  Last update: 2013-11-08 08:21    [W:0.018 / U:1.584 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site