From patchwork Fri Mar 4 10:17:22 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miklos Szeredi X-Patchwork-Id: 8501771 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 21EF69F659 for ; Fri, 4 Mar 2016 10:16:31 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 2A73B201B9 for ; Fri, 4 Mar 2016 10:16:30 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 1C804201F2 for ; Fri, 4 Mar 2016 10:16:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757211AbcCDKQ1 (ORCPT ); Fri, 4 Mar 2016 05:16:27 -0500 Received: from mail-wm0-f67.google.com ([74.125.82.67]:35694 "EHLO mail-wm0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758050AbcCDKQY (ORCPT ); Fri, 4 Mar 2016 05:16:24 -0500 Received: by mail-wm0-f67.google.com with SMTP id 1so3374516wmg.2 for ; Fri, 04 Mar 2016 02:16:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=szeredi.hu; s=google; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=GYw3lq979wM/ywg8dL5wf22gHA4VmMllQwQep8SYCwQ=; b=HGgv6P2XhdzmL8H0jOnpLJPT+HnI/PhjeotYTkC9qjG21m5QtPlvOh9Ab2lsv7QQMi BAuq+U51dizWB+dgImsPNWpleYICTl/x/IgNUQv91tnJEVbUHhTfDz9olGuPe6wM2fn/ 2anggA6y7tfKr2jRV3FOkkJ3sd01cJcIeHgkQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=GYw3lq979wM/ywg8dL5wf22gHA4VmMllQwQep8SYCwQ=; b=lrMt6YdxAsOPN4d8F+X0mIa9hZeAxj61S+2uY243/tmA9ed5Xz68et+fTSMj+/boE8 blPcho6+nqvvjsSYYJxGFpnKKng0+9syUeD9/6jnDt+OEVXsZJ04J6oTcujUO1DqRzAr WQG4nc978a4vUMruEOFZbwoAnEOltud66sviXN+qyz/f9Pf2DrUyy9vOQ7hvyGdfsayw AqiKvAPL+t3KLy+BpmFNm8IH5WZ/Sc3spjYNtm7WwmA8StaatQKgcwYDfdSSXxsFVBKx tMWNtRhQiSod7KJKqQAnxLNzxuZ7BK7Sv7qmXk5ZoZLh9/6tBwfusXjJ/3DmF1hDoFw6 b9OQ== X-Gm-Message-State: AD7BkJJZaBcQn9g4UzxXsZGX4Dfi5241lVsj2UkMY3DrZ0tIqNOO6waqTT1SJz6rFoIL4A== X-Received: by 10.194.184.112 with SMTP id et16mr8224437wjc.75.1457086582563; Fri, 04 Mar 2016 02:16:22 -0800 (PST) Received: from tucsk (pool-dsl-2c-0018.externet.hu. [217.173.44.24]) by smtp.gmail.com with ESMTPSA id z6sm2599372wme.9.2016.03.04.02.16.20 (version=TLS1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 04 Mar 2016 02:16:21 -0800 (PST) Date: Fri, 4 Mar 2016 11:17:22 +0100 From: Miklos Szeredi To: Goldwyn Rodrigues Cc: Trond Myklebust , "linux-unionfs@vger.kernel.org" , Linux FS-devel Mailing List , Linux NFS Mailing List , David Howells , Al Viro Subject: Re: [PATCH 3/3] nfs: Store and use inode in nfs_open_context Message-ID: <20160304101722.GA8655@tucsk> References: <1456855928-29913-1-git-send-email-rgoldwyn@suse.de> <1456855928-29913-4-git-send-email-rgoldwyn@suse.de> <56D6F84B.5040301@suse.de> <56D70D64.9010705@suse.de> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,RP_MATCHES_RCVD,T_DKIM_INVALID,UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP On Thu, Mar 03, 2016 at 09:16:33AM +0100, Miklos Szeredi wrote: > My plan was to introduce a file_dentry() helper that MUST be used by > filesystems to get the dentry from the file and that makes sure it's > the right one (check against file_inode()). If not, then we could > call into overlayfs to return the right one, similar to > ->d_select_inode(), except we want to have a dentry and we want to > have *a particular dentry* matching file_inode() (the file could have > been copied up in the mean time). Something like the following (untested, against overlayfs-next.git) Thanks, Miklos Tested-by: Goldwyn Rodrigues --- fs/nfs/dir.c | 6 +++--- fs/nfs/inode.c | 2 +- fs/nfs/nfs4file.c | 4 ++-- fs/open.c | 11 +++++++++++ fs/overlayfs/super.c | 16 ++++++++++++++++ include/linux/dcache.h | 1 + include/linux/fs.h | 2 ++ 7 files changed, 36 insertions(+), 6 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -377,7 +377,7 @@ int nfs_readdir_xdr_filler(struct page * again: timestamp = jiffies; gencount = nfs_inc_attr_generation_counter(); - error = NFS_PROTO(inode)->readdir(file->f_path.dentry, cred, entry->cookie, pages, + error = NFS_PROTO(inode)->readdir(file_dentry(file), cred, entry->cookie, pages, NFS_SERVER(inode)->dtsize, desc->plus); if (error < 0) { /* We requested READDIRPLUS, but the server doesn't grok it */ @@ -560,7 +560,7 @@ int nfs_readdir_page_filler(nfs_readdir_ count++; if (desc->plus != 0) - nfs_prime_dcache(desc->file->f_path.dentry, entry); + nfs_prime_dcache(file_dentry(desc->file), entry); status = nfs_readdir_add_to_array(entry, page); if (status != 0) @@ -864,7 +864,7 @@ static bool nfs_dir_mapping_need_revalid */ static int nfs_readdir(struct file *file, struct dir_context *ctx) { - struct dentry *dentry = file->f_path.dentry; + struct dentry *dentry = file_dentry(file); struct inode *inode = d_inode(dentry); nfs_readdir_descriptor_t my_desc, *desc = &my_desc; --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -940,7 +940,7 @@ int nfs_open(struct inode *inode, struct { struct nfs_open_context *ctx; - ctx = alloc_nfs_open_context(filp->f_path.dentry, filp->f_mode); + ctx = alloc_nfs_open_context(file_dentry(filp), filp->f_mode); if (IS_ERR(ctx)) return PTR_ERR(ctx); nfs_file_set_open_context(filp, ctx); --- a/fs/nfs/nfs4file.c +++ b/fs/nfs/nfs4file.c @@ -26,7 +26,7 @@ static int nfs4_file_open(struct inode *inode, struct file *filp) { struct nfs_open_context *ctx; - struct dentry *dentry = filp->f_path.dentry; + struct dentry *dentry = file_dentry(filp); struct dentry *parent = NULL; struct inode *dir; unsigned openflags = filp->f_flags; @@ -57,7 +57,7 @@ nfs4_file_open(struct inode *inode, stru parent = dget_parent(dentry); dir = d_inode(parent); - ctx = alloc_nfs_open_context(filp->f_path.dentry, filp->f_mode); + ctx = alloc_nfs_open_context(file_dentry(filp), filp->f_mode); err = PTR_ERR(ctx); if (IS_ERR(ctx)) goto out; --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1234,6 +1234,8 @@ static inline struct inode *file_inode(c return f->f_inode; } +extern struct dentry *file_dentry(const struct file *file); + static inline int locks_lock_file_wait(struct file *filp, struct file_lock *fl) { return locks_lock_inode_wait(file_inode(filp), fl); --- a/fs/open.c +++ b/fs/open.c @@ -831,6 +831,17 @@ char *file_path(struct file *filp, char } EXPORT_SYMBOL(file_path); +struct dentry *file_dentry(const struct file *file) +{ + struct dentry *dentry = file->f_path.dentry; + + if (d_inode(dentry) == file_inode(file)) + return dentry; + else + return dentry->d_op->d_select_dentry(dentry, file_inode(file)); +} +EXPORT_SYMBOL(file_dentry); + /** * vfs_open - open the file at the given path * @path: path to open --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c @@ -336,14 +336,30 @@ static int ovl_dentry_weak_revalidate(st return ret; } +static struct dentry *ovl_d_select_dentry(struct dentry *dentry, + struct inode *inode) +{ + struct ovl_entry *oe = dentry->d_fsdata; + struct dentry *realentry = ovl_upperdentry_dereference(oe); + + if (realentry && inode == d_inode(realentry)) + return realentry; + realentry = __ovl_dentry_lower(oe); + if (realentry && inode == d_inode(realentry)) + return realentry; + BUG(); +} + static const struct dentry_operations ovl_dentry_operations = { .d_release = ovl_dentry_release, .d_select_inode = ovl_d_select_inode, + .d_select_dentry = ovl_d_select_dentry, }; static const struct dentry_operations ovl_reval_dentry_operations = { .d_release = ovl_dentry_release, .d_select_inode = ovl_d_select_inode, + .d_select_dentry = ovl_d_select_dentry, .d_revalidate = ovl_dentry_revalidate, .d_weak_revalidate = ovl_dentry_weak_revalidate, }; --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -161,6 +161,7 @@ struct dentry_operations { struct vfsmount *(*d_automount)(struct path *); int (*d_manage)(struct dentry *, bool); struct inode *(*d_select_inode)(struct dentry *, unsigned); + struct dentry *(*d_select_dentry)(struct dentry *, struct inode *); } ____cacheline_aligned; /*