From patchwork Wed May 20 22:05:30 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Eric W. Biederman" X-Patchwork-Id: 6450641 Return-Path: X-Original-To: patchwork-linux-fsdevel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 738CF9F1C1 for ; Wed, 20 May 2015 22:10:33 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 5924F203ED for ; Wed, 20 May 2015 22:10:32 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7C826203B0 for ; Wed, 20 May 2015 22:10:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754351AbbETWK0 (ORCPT ); Wed, 20 May 2015 18:10:26 -0400 Received: from out03.mta.xmission.com ([166.70.13.233]:52334 "EHLO out03.mta.xmission.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753607AbbETWKX convert rfc822-to-8bit (ORCPT ); Wed, 20 May 2015 18:10:23 -0400 Received: from in01.mta.xmission.com ([166.70.13.51]) by out03.mta.xmission.com with esmtps (TLS1.2:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.82) (envelope-from ) id 1YvCBx-0004vh-A4; Wed, 20 May 2015 16:10:21 -0600 Received: from 67-3-205-90.omah.qwest.net ([67.3.205.90] helo=x220.int.ebiederm.org.xmission.com) by in01.mta.xmission.com with esmtpsa (TLS1.2:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.82) (envelope-from ) id 1YvCBw-0000ys-9h; Wed, 20 May 2015 16:10:21 -0600 From: ebiederm@xmission.com (Eric W. Biederman) To: Omar Sandoval Cc: Ivan Delalande , Al Viro , linux-fsdevel@vger.kernel.org References: <20150515185820.GQ20468@ycc.fr> <20150520100557.GB32189@mew> Date: Wed, 20 May 2015 17:05:30 -0500 In-Reply-To: <20150520100557.GB32189@mew> (Omar Sandoval's message of "Wed, 20 May 2015 03:05:57 -0700") Message-ID: <87bnhedhw5.fsf_-_@x220.int.ebiederm.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) MIME-Version: 1.0 X-XM-AID: U2FsdGVkX1/VDusI2F42csQqtzWwk0Kpoyh2CC3K+Ww= X-SA-Exim-Connect-IP: 67.3.205.90 X-SA-Exim-Mail-From: ebiederm@xmission.com X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-DCC: XMission; sa07 1397; Body=1 Fuz1=1 Fuz2=1 X-Spam-Combo: ;Omar Sandoval X-Spam-Relay-Country: X-Spam-Timing: total 532 ms - load_scoreonly_sql: 0.10 (0.0%), signal_user_changed: 8 (1.4%), b_tie_ro: 6 (1.1%), parse: 1.08 (0.2%), extract_message_metadata: 21 (4.0%), get_uri_detail_list: 3.4 (0.6%), tests_pri_-1000: 9 (1.7%), tests_pri_-950: 1.47 (0.3%), tests_pri_-900: 1.17 (0.2%), tests_pri_-400: 34 (6.4%), check_bayes: 33 (6.2%), b_tokenize: 10 (1.9%), b_tok_get_all: 12 (2.2%), b_comp_prob: 2.8 (0.5%), b_tok_touch_all: 5 (1.0%), b_finish: 0.75 (0.1%), tests_pri_0: 446 (83.7%), tests_pri_500: 7 (1.3%), rewrite_mail: 0.00 (0.0%) Subject: [PATCH] vfs: Fix, simpliy and stop using d_dname for the /proc/*/ns/* files. X-SA-Exim-Version: 4.2.1 (built Wed, 24 Sep 2014 11:00:52 -0600) X-SA-Exim-Scanned: Yes (on in01.mta.xmission.com) Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Omar Sandoval writes: > On Fri, May 15, 2015 at 08:58:20PM +0200, Ivan Delalande wrote: >> Hi, >> >> I’m still struggling to understand all the relations between the VFS >> structures and at which point they get initialized precisely. Do you >> have any idea how to fix this problem? The relationships in this case are quite odd and can be simplified. > I'm attaching a minimal script that reproduces this on 4.1-rc4. I'm > taking a look, but Eric or Al will probably figure this out before I get > the chance :) This works for me, can you confirm it works for you folks as well? Thank you, Eric From: "Eric W. Biederman" Date: Wed, 20 May 2015 16:39:00 -0500 Subject: [PATCH] vfs: Fix, simpliy and stop using d_dname for the /proc/*/ns/* files. Now that these files are no longer in proc we can stop playing games with d_alloc_pseudo and d_dname. This change causes a couple of user visible changes: - Opening /proc/*/ns/* and then readlink on /proc/self/fd/N now sees a prepended / in the filename. - /proc/mountinfo now gives useful information on what is mounted. - Bind mounting /proc/*/ns/*, opening the mounted file, removing the bind mount, and readlink on /proc/self/fd/N now sees / (as it should) instead of triggering a warning and a kernel stack backtrace from prepend_path. Cc: stable@vger.kernel.org Reported-by: Ivan Delalande Reported-by: Omar Sandoval Signed-off-by: "Eric W. Biederman" Tested-by: Ivan Delalande --- fs/dcache.c | 7 +------ fs/nsfs.c | 19 +++++-------------- 2 files changed, 6 insertions(+), 20 deletions(-) diff --git a/fs/dcache.c b/fs/dcache.c index 656ce522a218..e0f0967ef24c 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -3087,13 +3087,8 @@ char *d_path(const struct path *path, char *buf, int buflen) * thus don't need to be hashed. They also don't need a name until a * user wants to identify the object in /proc/pid/fd/. The little hack * below allows us to generate a name for these objects on demand: - * - * Some pseudo inodes are mountable. When they are mounted - * path->dentry == path->mnt->mnt_root. In that case don't call d_dname - * and instead have d_path return the mounted path. */ - if (path->dentry->d_op && path->dentry->d_op->d_dname && - (!IS_ROOT(path->dentry) || path->dentry != path->mnt->mnt_root)) + if (path->dentry->d_op && path->dentry->d_op->d_dname) return path->dentry->d_op->d_dname(path->dentry, buf, buflen); rcu_read_lock(); diff --git a/fs/nsfs.c b/fs/nsfs.c index 99521e7c492b..b9ecfa6cb46d 100644 --- a/fs/nsfs.c +++ b/fs/nsfs.c @@ -11,15 +11,6 @@ static const struct file_operations ns_file_operations = { .llseek = no_llseek, }; -static char *ns_dname(struct dentry *dentry, char *buffer, int buflen) -{ - struct inode *inode = d_inode(dentry); - const struct proc_ns_operations *ns_ops = dentry->d_fsdata; - - return dynamic_dname(dentry, buffer, buflen, "%s:[%lu]", - ns_ops->name, inode->i_ino); -} - static void ns_prune_dentry(struct dentry *dentry) { struct inode *inode = d_inode(dentry); @@ -33,7 +24,6 @@ const struct dentry_operations ns_dentry_operations = { .d_prune = ns_prune_dentry, .d_delete = always_delete_dentry, - .d_dname = ns_dname, }; static void nsfs_evict(struct inode *inode) @@ -47,7 +37,7 @@ void *ns_get_path(struct path *path, struct task_struct *task, const struct proc_ns_operations *ns_ops) { struct vfsmount *mnt = mntget(nsfs_mnt); - struct qstr qname = { .name = "", }; + char name[DNAME_INLINE_LEN]; struct dentry *dentry; struct inode *inode; struct ns_common *ns; @@ -80,6 +70,7 @@ slow: mntput(mnt); return ERR_PTR(-ENOMEM); } + snprintf(name, sizeof(name), "%s:[%u]", ns_ops->name, ns->inum); inode->i_ino = ns->inum; inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; inode->i_flags |= S_IMMUTABLE; @@ -87,13 +78,13 @@ slow: inode->i_fop = &ns_file_operations; inode->i_private = ns; - dentry = d_alloc_pseudo(mnt->mnt_sb, &qname); + dentry = d_alloc_name(mnt->mnt_root, name); if (!dentry) { iput(inode); mntput(mnt); return ERR_PTR(-ENOMEM); } - d_instantiate(dentry, inode); + d_add(dentry, inode); dentry->d_fsdata = (void *)ns_ops; d = atomic_long_cmpxchg(&ns->stashed, 0, (unsigned long)dentry); if (d) { @@ -143,7 +134,7 @@ static const struct super_operations nsfs_ops = { static struct dentry *nsfs_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *data) { - return mount_pseudo(fs_type, "nsfs:", &nsfs_ops, + return mount_pseudo(fs_type, "/", &nsfs_ops, &ns_dentry_operations, NSFS_MAGIC); } static struct file_system_type nsfs = {