From patchwork Thu Nov 24 10:55:38 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miklos Szeredi X-Patchwork-Id: 9445185 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 029FF6075F for ; Thu, 24 Nov 2016 10:56:50 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0C3D7269A3 for ; Thu, 24 Nov 2016 10:56:50 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0109C27C14; Thu, 24 Nov 2016 10:56:49 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.4 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A164F269A3 for ; Thu, 24 Nov 2016 10:56:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S964912AbcKXKzz (ORCPT ); Thu, 24 Nov 2016 05:55:55 -0500 Received: from mail-wm0-f45.google.com ([74.125.82.45]:38045 "EHLO mail-wm0-f45.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S964851AbcKXKzv (ORCPT ); Thu, 24 Nov 2016 05:55:51 -0500 Received: by mail-wm0-f45.google.com with SMTP id f82so56378871wmf.1 for ; Thu, 24 Nov 2016 02:55:50 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=SElWhlhRXVTr2ND91O8hxLH9pzXRBX0D9ps+6rqWH0M=; b=HpEFUVMbNNBmedF5oQ347i4UxWR8eue/0Lc7Fq6fqb4GXYkrxDYA8d4LYqmQEvfW8M c6LlkjecxvqR7MJdK/UQN+KvnyNBRKZBzkj2JQoFE9yxtb5AbHeawhbFTWKPAV/h5R5M GIFwE9b40ZV/RIBHmsz2JcST3jQCLrTYHvd/bbSdSk1BjPNsg8VVuuGB2w+qXv34RaxG M1ocuNnLDAYkyE2rxRD+/1RKxZqqsQpCB1vQ+GaeC1cWwyZr22p3w0FP/e5Ph38FcMTs MFCHzA/7RG8Zz9dVPV7bnxJvciCJxz7Seykr4+ischQhKlbesqBM9o+/gfA0a+Q36PwP VeeA== X-Gm-Message-State: AKaTC02c/joJttAqOZgl7/95MoVoBhhUgMff3fFL2YdRx69H6QyWKfOx69ioWo2P8b2GWXhz X-Received: by 10.28.166.20 with SMTP id p20mr1762897wme.87.1479984949719; Thu, 24 Nov 2016 02:55:49 -0800 (PST) Received: from veci.piliscsaba.szeredi.hu (pool-dsl-2c-0018.externet.hu. [217.173.44.24]) by smtp.gmail.com with ESMTPSA id g73sm7587416wme.16.2016.11.24.02.55.48 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 24 Nov 2016 02:55:48 -0800 (PST) From: Miklos Szeredi To: linux-unionfs@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 1/7] vfs: allow overlayfs to intercept file ops Date: Thu, 24 Nov 2016 11:55:38 +0100 Message-Id: <1479984944-1017-3-git-send-email-mszeredi@redhat.com> X-Mailer: git-send-email 2.5.5 In-Reply-To: <1479984944-1017-1-git-send-email-mszeredi@redhat.com> References: <1479984944-1017-1-git-send-email-mszeredi@redhat.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 Almost all of the time overlayfs just wants to let underlying filesystems handle file operations on regular files. There is a rare corner case, namely when a file residing a read-only (lower) layer is: - opened for O_RDONLY - opened for O_WRONLY - contents modified - contents read back though O_RDONLY fd Currently overlayfs gives inconsistent result in this case, since the O_RDONLY file refers to the lower, unmodified file, even after the copy up has happened. This happens very rarely, so a) we want the normal cases (when no copy up happens) still go as fast as possible; b) we can let the corner case go slow. The proposed solution is to allow overlayfs to intercept file operations if it wants (O_RDONLY open of file on lower layer), but still let the file be owned by the underlying layer. This means everything in filp, including the private_data, is controlled by the underlying layer (as it has been until now) with the exception of f_op, which comes from overlayfs. This patch doesn't change the actual behavior, it just adds the vfs change necessary and then unconditionally sets the f_op back to the underlying file's ops. For non-overlayfs, this doesn't change anything. Signed-off-by: Miklos Szeredi --- fs/open.c | 2 +- fs/overlayfs/inode.c | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/fs/open.c b/fs/open.c index 8a0254b56780..453ef5581389 100644 --- a/fs/open.c +++ b/fs/open.c @@ -734,7 +734,7 @@ static int do_dentry_open(struct file *f, if (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)) f->f_mode |= FMODE_ATOMIC_POS; - f->f_op = fops_get(inode->i_fop); + f->f_op = fops_get(f->f_path.dentry->d_inode->i_fop); if (unlikely(WARN_ON(!f->f_op))) { error = -ENODEV; goto cleanup_all; diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c index a10e948d24fa..1981a5514f51 100644 --- a/fs/overlayfs/inode.c +++ b/fs/overlayfs/inode.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "overlayfs.h" static int ovl_copy_up_truncate(struct dentry *dentry) @@ -333,6 +334,22 @@ static const struct inode_operations ovl_symlink_inode_operations = { .update_time = ovl_update_time, }; +static int ovl_open(struct inode *inode, struct file *file) +{ + int ret = 0; + + /* Want fops from real inode */ + replace_fops(file, inode->i_fop); + if (file->f_op->open) + ret = file->f_op->open(inode, file); + + return ret; +} + +static const struct file_operations ovl_file_operations = { + .open = ovl_open, +}; + static void ovl_fill_inode(struct inode *inode, umode_t mode, dev_t rdev) { inode->i_ino = get_next_ino(); @@ -345,6 +362,7 @@ static void ovl_fill_inode(struct inode *inode, umode_t mode, dev_t rdev) switch (mode & S_IFMT) { case S_IFREG: inode->i_op = &ovl_file_inode_operations; + inode->i_fop = &ovl_file_operations; break; case S_IFDIR: