Received: by 10.192.165.148 with SMTP id m20csp2830000imm; Mon, 7 May 2018 01:48:19 -0700 (PDT) X-Google-Smtp-Source: AB8JxZp6R7t69c4hpY3uUyHz3Nd6IH9zFD7ZEEq3M4t5e+DbFzzMwhx9nT3m5iKd/52bRz47iYzR X-Received: by 2002:a17:902:822:: with SMTP id 31-v6mr37793075plk.172.1525682899161; Mon, 07 May 2018 01:48:19 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1525682899; cv=none; d=google.com; s=arc-20160816; b=qNhkFmI69ZyQozxavRhq6QuzP2S6pp5yXM7+anYZeJQvYPqc3h+0bzJ76PiQbrwwKg t8Hz0XI8td3S6Tlwbif5kmb28t+ZtASF68avC31Ypmj89t3Y0juffuJIO48qxev4CtD0 hKpuOuRYFDbVpvpV8MfSMoxp9a9LeDH8ZUut/e7IKNxXUVBq97Mz6NNoAlIN+jsUPJwz lGmZdIwa6U7Tg8qtgLKdNAHXp3Z3FELVlNJjpBFvtaMawF3a1r9MbtqJqEN9FtkUIQGX DQbjH/19bBggoYitzndipUNf77uy/X8/M53Anh0Q6EIASv/xdxCbUvpBIssVHZvMVTAg Ya5A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=LwsJTSUT2RemjBhJkpSIUg+cLBfUDr1+MvgYud7NBTY=; b=zwtXxZGAZN9L4+qpLQWqQs+cBFfQZ3K9a5Qxa8kdqosCipep1kXcWq3r/FJ5fSWoLR DUlFX2p95S4z+GEylPY3E5Zp2xXESr+zR4f7ykew5Q73ipowxQJYUAjFw3dL0NDUM17U EX73Q8/5leYfG+88tyrCnlj8TS6jJFLUArGb0TdoDft5LghvVtxtl3nXuIuxKagofr6C dyfqFxWa+VtUzRkWcrX0dW0dzZD5DUteXtD+dPMnIn5cKaRGr08IEVe4ABJOH2FPrZZS dVcWiT+629ga4DY3QuWg+jAFFiVhMsJrfMLe3vc4Wxq1wo7UeOOTbkhI1CXvilhRoKLZ s7KA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 3-v6si21732032plv.323.2018.05.07.01.48.05; Mon, 07 May 2018 01:48:19 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752624AbeEGIrl (ORCPT + 99 others); Mon, 7 May 2018 04:47:41 -0400 Received: from mail-wm0-f68.google.com ([74.125.82.68]:55809 "EHLO mail-wm0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752131AbeEGIi2 (ORCPT ); Mon, 7 May 2018 04:38:28 -0400 Received: by mail-wm0-f68.google.com with SMTP id a8so12016988wmg.5 for ; Mon, 07 May 2018 01:38:27 -0700 (PDT) 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=LwsJTSUT2RemjBhJkpSIUg+cLBfUDr1+MvgYud7NBTY=; b=mYuwJRcEef8nDAU5e8R61QFaCDn6hEa6ygWOe8d9QYzybCb+L37Fhih1oUbdYdR/+H 4mJQu4ZCc7o9cqgjFnNHq0clFqK3B4EIOjLEBXExkg1Dm0RXN79j8HRTWJK3ewNZ7pCz 058vBELJEgBuM/Ko26xLrepjmnl243Nt5h0cZAKG95LlQw/Xm0kKjOkeucminjzhs3x7 4q+0Ns5/zwcvhEWJBZU081DhclEHvuHo4uVeRcSfIzEe0554cRzEFByUxgdKal5SGtsC lpDXYlhjdQ+cbOxskmfXHOk0cgqSeq4mCu3v3fYJ5o62afpHLBv8Fj57I9HrVMmjmGkI F8ow== X-Gm-Message-State: ALQs6tAA8VF8OXh3fwnMB7ir9/68hsDicpGxMrr8hUs/z+d/VrLmN+H0 Lhy/pO1F/yJ+YYHIJUTeO+8Oaw== X-Received: by 2002:a1c:e696:: with SMTP id e22-v6mr170908wmi.118.1525682306944; Mon, 07 May 2018 01:38:26 -0700 (PDT) Received: from veci.piliscsaba.redhat.com (C2B0E321.catv.pool.telekom.hu. [194.176.227.33]) by smtp.gmail.com with ESMTPSA id h8-v6sm5908050wmc.16.2018.05.07.01.38.25 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 07 May 2018 01:38:26 -0700 (PDT) From: Miklos Szeredi To: linux-unionfs@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 12/35] ovl: add helper to return real file Date: Mon, 7 May 2018 10:37:44 +0200 Message-Id: <20180507083807.28792-13-mszeredi@redhat.com> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180507083807.28792-1-mszeredi@redhat.com> References: <20180507083807.28792-1-mszeredi@redhat.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org In the common case we can just use the real file cached in file->private_data. There are two exceptions: 1) File has been copied up since open: in this unlikely corner case just use a throwaway real file for the operation. If ever this becomes a perfomance problem (very unlikely, since overlayfs has been doing most fine without correctly handling this case at all), then we can deal with that by updating the cached real file. 2) File's f_flags have changed since open: no need to reopen the cached real file, we can just change the flags there as well. Signed-off-by: Miklos Szeredi --- fs/overlayfs/file.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/fs/overlayfs/file.c b/fs/overlayfs/file.c index a0b606885c41..db8778e7c37a 100644 --- a/fs/overlayfs/file.c +++ b/fs/overlayfs/file.c @@ -31,6 +31,66 @@ static struct file *ovl_open_realfile(const struct file *file) return realfile; } +#define OVL_SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT) + +static int ovl_change_flags(struct file *file, unsigned int flags) +{ + struct inode *inode = file_inode(file); + int err; + + /* No atime modificaton on underlying */ + flags |= O_NOATIME; + + /* If some flag changed that cannot be changed then something's amiss */ + if (WARN_ON((file->f_flags ^ flags) & ~OVL_SETFL_MASK)) + return -EIO; + + flags &= OVL_SETFL_MASK; + + if (((flags ^ file->f_flags) & O_APPEND) && IS_APPEND(inode)) + return -EPERM; + + if (flags & O_DIRECT) { + if (!file->f_mapping->a_ops || + !file->f_mapping->a_ops->direct_IO) + return -EINVAL; + } + + if (file->f_op->check_flags) { + err = file->f_op->check_flags(flags); + if (err) + return err; + } + + spin_lock(&file->f_lock); + file->f_flags = (file->f_flags & ~OVL_SETFL_MASK) | flags; + spin_unlock(&file->f_lock); + + return 0; +} + +static int ovl_real_fdget(const struct file *file, struct fd *real) +{ + struct inode *inode = file_inode(file); + + real->flags = 0; + real->file = file->private_data; + + /* Has it been copied up since we'd opened it? */ + if (unlikely(file_inode(real->file) != ovl_inode_real(inode))) { + real->flags = FDPUT_FPUT; + real->file = ovl_open_realfile(file); + + return PTR_ERR_OR_ZERO(real->file); + } + + /* Did the flags change since open? */ + if (unlikely((file->f_flags ^ real->file->f_flags) & ~O_NOATIME)) + return ovl_change_flags(real->file, file->f_flags); + + return 0; +} + static int ovl_open(struct inode *inode, struct file *file) { struct dentry *dentry = file_dentry(file); -- 2.14.3