From patchwork Fri Feb 17 16:09:33 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miklos Szeredi X-Patchwork-Id: 9580353 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 CCCFD600F6 for ; Fri, 17 Feb 2017 16:11:41 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BEDD628343 for ; Fri, 17 Feb 2017 16:11:41 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B367D2871C; Fri, 17 Feb 2017 16:11:41 +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.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI 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 4C1A828343 for ; Fri, 17 Feb 2017 16:11:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934665AbdBQQJv (ORCPT ); Fri, 17 Feb 2017 11:09:51 -0500 Received: from mail-wm0-f52.google.com ([74.125.82.52]:32955 "EHLO mail-wm0-f52.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934592AbdBQQJt (ORCPT ); Fri, 17 Feb 2017 11:09:49 -0500 Received: by mail-wm0-f52.google.com with SMTP id t18so10511508wmt.0 for ; Fri, 17 Feb 2017 08:09:48 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=YGArTFfzpAiSC+i1yLDjufFNeLzB3RK5xPqcgRcQOUY=; b=sCEIhKQ897NosyQ/yocU80gNdr2bo63q7frTVUYOR4dVMmTRnPAes5HHw0n393SdeB 4Sxu87+xYwL5EyabDWXiY3CNI0MUrbAmtdrZrMr0IhVb4o5vZ+prUI4UHMsAVPENBj5O baB+zvl1eQ+Q7q7n338dEfofj0rLW5kgfFGdIgKVHQx7TPweu3pbUblE3/ztM0RTH/2H 9oaG7DJmnyo6xjHD3479+2MotSZxQkpXbI+cnt54BQ0py69arEslP4UXLhHB7rcgcPgr wn7bcDOsvUM6Wmyqhv+F1f3gIJ+8Li1YwT89Q/jVbsj5wjpV5jPbQVR1WsIc/+1u0RUB lWNw== X-Gm-Message-State: AMke39my3KHMpUrk+K++t8USBPCK3PxRH8yLgunrQo/qEXEe9bpR3zemQdN1EQ9OyCzKjF+W X-Received: by 10.28.174.14 with SMTP id x14mr4347189wme.75.1487347787446; Fri, 17 Feb 2017 08:09:47 -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 h23sm4538793wrc.48.2017.02.17.08.09.45 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 17 Feb 2017 08:09:46 -0800 (PST) From: Miklos Szeredi To: Al Viro Cc: linux-unionfs@vger.kernel.org, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH 4/9] vfs: intercept reads to overlay files Date: Fri, 17 Feb 2017 17:09:33 +0100 Message-Id: <1487347778-18596-5-git-send-email-mszeredi@redhat.com> X-Mailer: git-send-email 2.5.5 In-Reply-To: <1487347778-18596-1-git-send-email-mszeredi@redhat.com> References: <1487347778-18596-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 ...in order to handle the corner case when the file is copyied up after being opened read-only. Can be verified with the following script: - 8< - - - - - 8< - - - - - 8< - - - - - 8< - - - - cd / rm -rf /tmp/ovl-rorw-test mkdir /tmp/ovl-rorw-test cd /tmp/ovl-rorw-test mkdir -p mnt lower upper work echo baba > lower/foo mount -t overlay overlay -olowerdir=lower,upperdir=upper,workdir=work mnt exec 3< mnt/foo echo bubu > mnt/foo cat <&3 exec 3>&- umount mnt - 8< - - - - - 8< - - - - - 8< - - - - - 8< - - - - Correct output is "bubu", incorrect output is "baba". Signed-off-by: Miklos Szeredi --- fs/Makefile | 2 +- fs/open.c | 2 ++ fs/overlay_util.c | 39 +++++++++++++++++++++++++++++++++++++++ include/linux/fs.h | 13 +++++++++++++ include/linux/overlay_util.h | 13 +++++++++++++ 5 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 fs/overlay_util.c create mode 100644 include/linux/overlay_util.h diff --git a/fs/Makefile b/fs/Makefile index 7bbaca9c67b1..8c8f197d7c75 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -11,7 +11,7 @@ obj-y := open.o read_write.o file_table.o super.o \ attr.o bad_inode.o file.o filesystems.o namespace.o \ seq_file.o xattr.o libfs.o fs-writeback.o \ pnode.o splice.o sync.o utimes.o \ - stack.o fs_struct.o statfs.o fs_pin.o nsfs.o + stack.o fs_struct.o statfs.o fs_pin.o nsfs.o overlay_util.o ifeq ($(CONFIG_BLOCK),y) obj-y += buffer.o block_dev.o direct-io.o mpage.o diff --git a/fs/open.c b/fs/open.c index 9921f70bc5ca..4916ccff29f5 100644 --- a/fs/open.c +++ b/fs/open.c @@ -762,6 +762,8 @@ static int do_dentry_open(struct file *f, if ((f->f_mode & FMODE_WRITE) && likely(f->f_op->write || f->f_op->write_iter)) f->f_mode |= FMODE_CAN_WRITE; + if (unlikely(d_inode(f->f_path.dentry) != inode)) + f->f_mode |= FMODE_OVERLAY; f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC); diff --git a/fs/overlay_util.c b/fs/overlay_util.c new file mode 100644 index 000000000000..0daff19bad0b --- /dev/null +++ b/fs/overlay_util.c @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2017 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ +#if IS_ENABLED(CONFIG_OVERLAY_FS) + +#include +#include +#include +#include "internal.h" + +static bool overlay_file_consistent(struct file *file) +{ + return d_real_inode(file->f_path.dentry) == file_inode(file); +} + +ssize_t overlay_read_iter(struct file *file, struct kiocb *kio, + struct iov_iter *iter) +{ + ssize_t ret; + + if (likely(overlay_file_consistent(file))) + return file->f_op->read_iter(kio, iter); + + file = filp_clone_open(file); + if (IS_ERR(file)) + return PTR_ERR(file); + + ret = vfs_iter_read(file, iter, &kio->ki_pos); + fput(file); + + return ret; +} +EXPORT_SYMBOL(overlay_read_iter); + +#endif /* IS_ENABLED(CONFIG_OVERLAY_FS) */ diff --git a/include/linux/fs.h b/include/linux/fs.h index efdaad954b70..d186d5390e99 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -143,6 +144,9 @@ typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset, /* File was opened by fanotify and shouldn't generate fanotify events */ #define FMODE_NONOTIFY ((__force fmode_t)0x4000000) +/* File comes from overlay filesystem */ +#define FMODE_OVERLAY ((__force fmode_t)0x8000000) + /* * Flag for rw_copy_check_uvector and compat_rw_copy_check_uvector * that indicates that they should check the contents of the iovec are @@ -1712,9 +1716,18 @@ struct inode_operations { int (*set_acl)(struct inode *, struct posix_acl *, int); } ____cacheline_aligned; + +static inline bool is_overlay_file(struct file *file) +{ + return IS_ENABLED(CONFIG_OVERLAY_FS) && file->f_mode & FMODE_OVERLAY; +} + static inline ssize_t call_read_iter(struct file *file, struct kiocb *kio, struct iov_iter *iter) { + if (unlikely(is_overlay_file(file))) + return overlay_read_iter(file, kio, iter); + return file->f_op->read_iter(kio, iter); } diff --git a/include/linux/overlay_util.h b/include/linux/overlay_util.h new file mode 100644 index 000000000000..886be9003bf3 --- /dev/null +++ b/include/linux/overlay_util.h @@ -0,0 +1,13 @@ +#ifndef _LINUX_OVERLAY_FS_H +#define _LINUX_OVERLAY_FS_H + +#include + +struct file; +struct kiocb; +struct iov_iter; + +extern ssize_t overlay_read_iter(struct file *file, struct kiocb *kio, + struct iov_iter *iter); + +#endif /* _LINUX_OVERLAY_FS_H */