From patchwork Wed Mar 13 09:50:42 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Pisati X-Patchwork-Id: 227214 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) by ozlabs.org (Postfix) with ESMTP id 6A6572C02AE for ; Wed, 13 Mar 2013 20:51:11 +1100 (EST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.76) (envelope-from ) id 1UFiKl-0001cv-Op; Wed, 13 Mar 2013 09:50:55 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtp (Exim 4.76) (envelope-from ) id 1UFiKj-0001aZ-QD for kernel-team@lists.ubuntu.com; Wed, 13 Mar 2013 09:50:53 +0000 Received: from 2-230-238-136.ip204.fastwebnet.it ([2.230.238.136] helo=canonical.com) by youngberry.canonical.com with esmtpsa (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1UFiKj-0000tk-MJ for kernel-team@lists.ubuntu.com; Wed, 13 Mar 2013 09:50:53 +0000 From: Paolo Pisati To: kernel-team@lists.ubuntu.com Subject: [PATCH 02/11] UBUNTU: ubuntu: overlayfs -- vfs: add i_op->open() Date: Wed, 13 Mar 2013 10:50:42 +0100 Message-Id: <1363168251-9374-3-git-send-email-paolo.pisati@canonical.com> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1363168251-9374-1-git-send-email-paolo.pisati@canonical.com> References: <1363168251-9374-1-git-send-email-paolo.pisati@canonical.com> X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.14 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: kernel-team-bounces@lists.ubuntu.com From: Miklos Szeredi Add a new inode operation i_op->open(). This is for stacked filesystems that want to return a struct file from a different filesystem. Signed-off-by: Miklos Szeredi Signed-off-by: Andy Whitcroft (cherry picked from commit f8d4214681dceab8ddaf55eb24ac93377ba42cb8) BugLink: http://bugs.launchpad.net/bugs/1076317 Signed-off-by: Paolo Pisati --- Documentation/filesystems/Locking | 2 ++ Documentation/filesystems/vfs.txt | 8 ++++++++ fs/open.c | 25 +++++++++++++++++++++++-- include/linux/fs.h | 3 +++ 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index 6533807..afcf9be 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking @@ -61,6 +61,7 @@ ata *); int (*removexattr) (struct dentry *, const char *); void (*truncate_range)(struct inode *, loff_t, loff_t); int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start, u64 len); + struct file *(*open)(struct dentry *,struct file *,const struct cred *); locking rules: all may block @@ -88,6 +89,7 @@ listxattr: no removexattr: yes truncate_range: yes fiemap: no +open: no Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_mutex on victim. cross-directory ->rename() has (per-superblock) ->s_vfs_rename_sem. diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt index 52d8fb8..ea20354 100644 --- a/Documentation/filesystems/vfs.txt +++ b/Documentation/filesystems/vfs.txt @@ -364,6 +364,8 @@ struct inode_operations { ssize_t (*listxattr) (struct dentry *, char *, size_t); int (*removexattr) (struct dentry *, const char *); void (*truncate_range)(struct inode *, loff_t, loff_t); + struct file *(*open) (struct dentry *, struct file *, + const struct cred *); }; Again, all methods are called without any locks being held, unless @@ -475,6 +477,12 @@ otherwise noted. truncate_range: a method provided by the underlying filesystem to truncate a range of blocks , i.e. punch a hole somewhere in a file. + open: this is an alternative to f_op->open(), the difference is that this + method may return any open file, not necessarily originating from the + same filesystem as the one i_op->open() was called on. It may be useful + for stacking filesystems which want to allow native I/O directly on + underlying files. + The Address Space Object ======================== diff --git a/fs/open.c b/fs/open.c index fe635fa..254098e 100644 --- a/fs/open.c +++ b/fs/open.c @@ -795,7 +795,7 @@ struct file *nameidata_to_filp(struct nameidata *nd) /* Has the filesystem initialised the file for us? */ if (filp->f_path.dentry == NULL) - filp = __dentry_open(&nd->path, filp, NULL, cred); + filp = vfs_open(&nd->path, filp, cred); return filp; } @@ -820,7 +820,7 @@ struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags, f = get_empty_filp(); if (f != NULL) { f->f_flags = flags; - ret = __dentry_open(&path, f, NULL, cred); + ret = vfs_open(&path, f, cred); } path_put(&path); @@ -828,6 +828,27 @@ struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags, } EXPORT_SYMBOL(dentry_open); +/** + * vfs_open - open the file at the given path + * @path: path to open + * @filp: newly allocated file with f_flag initialized + * @cred: credentials to use + * + * Open the file. If successful, the returned file will have acquired + * an additional reference for path. + */ +struct file *vfs_open(struct path *path, struct file *filp, + const struct cred *cred) +{ + struct inode *inode = path->dentry->d_inode; + + if (inode->i_op->open) + return inode->i_op->open(path->dentry, filp, cred); + else + return __dentry_open(path, filp, NULL, cred); +} +EXPORT_SYMBOL(vfs_open); + static void __put_unused_fd(struct files_struct *files, unsigned int fd) { struct fdtable *fdt = files_fdtable(files); diff --git a/include/linux/fs.h b/include/linux/fs.h index cf7bc25..95ae38e 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1618,6 +1618,8 @@ struct inode_operations { void (*truncate_range)(struct inode *, loff_t, loff_t); int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start, u64 len); + struct file *(*open) (struct dentry *, struct file *, + const struct cred *); } ____cacheline_aligned; struct seq_file; @@ -2023,6 +2025,7 @@ extern long do_sys_open(int dfd, const char __user *filename, int flags, extern struct file *filp_open(const char *, int, int); extern struct file *file_open_root(struct dentry *, struct vfsmount *, const char *, int); +extern struct file *vfs_open(struct path *, struct file *, const struct cred *); extern struct file * dentry_open(struct dentry *, struct vfsmount *, int, const struct cred *); extern int filp_close(struct file *, fl_owner_t id);