From patchwork Mon Dec 21 19:50:53 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vivek Goyal X-Patchwork-Id: 11985287 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3BEA6C433DB for ; Mon, 21 Dec 2020 19:53:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id F263122BF3 for ; Mon, 21 Dec 2020 19:53:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726701AbgLUTw4 (ORCPT ); Mon, 21 Dec 2020 14:52:56 -0500 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:45261 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726518AbgLUTwq (ORCPT ); Mon, 21 Dec 2020 14:52:46 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1608580279; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=g4Ccy5Y/+A40pLTl1bTQK9IV0EnfnxjPgBUXKnkaryk=; b=ACtsS70JbZhAo5MRc9zKj6hOeOF3iuT++BJyo8MZPLHzEW8fWeQfJyMGetoL82N/pApSqw h0imva2cLkxpHUg3ZIN1PDy/9c2hKlYO5RXJ6/fC94JtOVL5W8plyVc4rdwh4QwPWCryKR oDtBS2cnMUuXaX5be1R3Fvb8d88CD+I= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-53--Anbpx-pNXyaD1agiUIXow-1; Mon, 21 Dec 2020 14:51:15 -0500 X-MC-Unique: -Anbpx-pNXyaD1agiUIXow-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 754FE425CB; Mon, 21 Dec 2020 19:51:13 +0000 (UTC) Received: from horse.redhat.com (ovpn-114-244.rdu2.redhat.com [10.10.114.244]) by smtp.corp.redhat.com (Postfix) with ESMTP id 959C860C0F; Mon, 21 Dec 2020 19:51:11 +0000 (UTC) Received: by horse.redhat.com (Postfix, from userid 10451) id 296A0223D98; Mon, 21 Dec 2020 14:51:11 -0500 (EST) From: Vivek Goyal To: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-unionfs@vger.kernel.org Cc: jlayton@kernel.org, vgoyal@redhat.com, amir73il@gmail.com, sargun@sargun.me, miklos@szeredi.hu, willy@infradead.org, jack@suse.cz, neilb@suse.com, viro@zeniv.linux.org.uk, hch@lst.de Subject: [PATCH 1/3] vfs: Do not ignore return code from s_op->sync_fs Date: Mon, 21 Dec 2020 14:50:53 -0500 Message-Id: <20201221195055.35295-2-vgoyal@redhat.com> In-Reply-To: <20201221195055.35295-1-vgoyal@redhat.com> References: <20201221195055.35295-1-vgoyal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Current implementation of __sync_filesystem() ignores the return code from ->sync_fs(). I am not sure why that's the case. Ignoring ->sync_fs() return code is problematic for overlayfs where it can return error if sync_filesystem() on upper super block failed. That error will simply be lost and sycnfs(overlay_fd), will get success (despite the fact it failed). Al Viro noticed that there are other filesystems which can sometimes return error in ->sync_fs() and these errors will be ignored too. fs/btrfs/super.c:2412: .sync_fs = btrfs_sync_fs, fs/exfat/super.c:204: .sync_fs = exfat_sync_fs, fs/ext4/super.c:1674: .sync_fs = ext4_sync_fs, fs/f2fs/super.c:2480: .sync_fs = f2fs_sync_fs, fs/gfs2/super.c:1600: .sync_fs = gfs2_sync_fs, fs/hfsplus/super.c:368: .sync_fs = hfsplus_sync_fs, fs/nilfs2/super.c:689: .sync_fs = nilfs_sync_fs, fs/ocfs2/super.c:139: .sync_fs = ocfs2_sync_fs, fs/overlayfs/super.c:399: .sync_fs = ovl_sync_fs, fs/ubifs/super.c:2052: .sync_fs = ubifs_sync_fs, Hence, this patch tries to fix it and capture error returned by ->sync_fs() and return to caller. I am specifically interested in syncfs() path and return error to user. I am assuming that we want to continue to call __sync_blockdev() despite the fact that there have been errors reported from ->sync_fs(). So this patch continues to call __sync_blockdev() even if ->sync_fs() returns an error. Al noticed that there are few other callsites where ->sync_fs() error code is being ignored. sync_fs_one_sb(): For this it seems desirable to ignore the return code. dquot_disable(): Jan Kara mentioned that ignoring return code here is fine because we don't want to fail dquot_disable() just beacuse caches might be incoherent. dquot_quota_sync(): Jan thinks that it might make some sense to capture return code here. But I am leaving it untouched for now. When somebody needs it, they can easily fix it. Signed-off-by: Vivek Goyal Signed-off-by: Vivek Goyal --- fs/sync.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/fs/sync.c b/fs/sync.c index 1373a610dc78..b5fb83a734cd 100644 --- a/fs/sync.c +++ b/fs/sync.c @@ -30,14 +30,18 @@ */ static int __sync_filesystem(struct super_block *sb, int wait) { + int ret, ret2; + if (wait) sync_inodes_sb(sb); else writeback_inodes_sb(sb, WB_REASON_SYNC); if (sb->s_op->sync_fs) - sb->s_op->sync_fs(sb, wait); - return __sync_blockdev(sb->s_bdev, wait); + ret = sb->s_op->sync_fs(sb, wait); + ret2 = __sync_blockdev(sb->s_bdev, wait); + + return ret ? ret : ret2; } /* From patchwork Mon Dec 21 19:50:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vivek Goyal X-Patchwork-Id: 11985285 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id DED08C4332B for ; Mon, 21 Dec 2020 19:53:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id ACBCD22CA1 for ; Mon, 21 Dec 2020 19:53:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726567AbgLUTwq (ORCPT ); Mon, 21 Dec 2020 14:52:46 -0500 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:25888 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726547AbgLUTwq (ORCPT ); Mon, 21 Dec 2020 14:52:46 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1608580280; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=i+Wu06QQA8V7H5DaVe6ll9ITIbYelVgG1MNXlVmRWcw=; b=MLsjyUQW18vxgNcolQMv24EuJ8gKU9DNjk813qR/otgRjZVJieUa0at5JcrX6ilgrk0L3Y M4ItrihH/q2dDXULi+DGnzvAlso6j/SVV1JbkF+HDQ1dUqap9OShWDw9bdMiCIuevoPv6T MSDRJS2wt7mnDAj1na8+ag+Of9embA0= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-181-GHupDSMONC-1jwPNcKH0XA-1; Mon, 21 Dec 2020 14:51:15 -0500 X-MC-Unique: GHupDSMONC-1jwPNcKH0XA-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 556BF801817; Mon, 21 Dec 2020 19:51:13 +0000 (UTC) Received: from horse.redhat.com (ovpn-114-244.rdu2.redhat.com [10.10.114.244]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9ED9619D9C; Mon, 21 Dec 2020 19:51:11 +0000 (UTC) Received: by horse.redhat.com (Postfix, from userid 10451) id 30DA3223D99; Mon, 21 Dec 2020 14:51:11 -0500 (EST) From: Vivek Goyal To: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-unionfs@vger.kernel.org Cc: jlayton@kernel.org, vgoyal@redhat.com, amir73il@gmail.com, sargun@sargun.me, miklos@szeredi.hu, willy@infradead.org, jack@suse.cz, neilb@suse.com, viro@zeniv.linux.org.uk, hch@lst.de Subject: [PATCH 2/3] vfs: Add a super block operation to check for writeback errors Date: Mon, 21 Dec 2020 14:50:54 -0500 Message-Id: <20201221195055.35295-3-vgoyal@redhat.com> In-Reply-To: <20201221195055.35295-1-vgoyal@redhat.com> References: <20201221195055.35295-1-vgoyal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Right now we check for errors on super block in syncfs(). ret2 = errseq_check_and_advance(&sb->s_wb_err, &f.file->f_sb_err); overlayfs does not update sb->s_wb_err and it is tracked on upper filesystem. So provide a superblock operation to check errors so that filesystem can provide override generic method and provide its own method to check for writeback errors. Signed-off-by: Vivek Goyal --- fs/sync.c | 5 ++++- include/linux/fs.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/sync.c b/fs/sync.c index b5fb83a734cd..57e43a16dfca 100644 --- a/fs/sync.c +++ b/fs/sync.c @@ -176,7 +176,10 @@ SYSCALL_DEFINE1(syncfs, int, fd) ret = sync_filesystem(sb); up_read(&sb->s_umount); - ret2 = errseq_check_and_advance(&sb->s_wb_err, &f.file->f_sb_err); + if (sb->s_op->errseq_check_advance) + ret2 = sb->s_op->errseq_check_advance(sb, f.file); + else + ret2 = errseq_check_and_advance(&sb->s_wb_err, &f.file->f_sb_err); fdput(f); return ret ? ret : ret2; diff --git a/include/linux/fs.h b/include/linux/fs.h index 8667d0cdc71e..4297b6127adf 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1965,6 +1965,7 @@ struct super_operations { struct shrink_control *); long (*free_cached_objects)(struct super_block *, struct shrink_control *); + int (*errseq_check_advance)(struct super_block *, struct file *); }; /* From patchwork Mon Dec 21 19:50:55 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vivek Goyal X-Patchwork-Id: 11985283 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 83557C433DB for ; Mon, 21 Dec 2020 19:53:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3CF262310D for ; Mon, 21 Dec 2020 19:53:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726689AbgLUTwr (ORCPT ); Mon, 21 Dec 2020 14:52:47 -0500 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:20393 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726517AbgLUTwq (ORCPT ); Mon, 21 Dec 2020 14:52:46 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1608580279; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Aml02yYxR2r5UtIADXUcAHlj0J0r9Os28OjvX37LEzc=; b=VArg04SoZrQz9njufVGUhqKuMLhS0jHElSlqyIJeah72Q0QSgl8lCTx9EC859Tip81I0yq UYl4V2kMfJUzCI8sYCQ4D+R0UsS9UK5lcEY1MaYeUY6rWd1mnf2mc/UjbvxK41+UXTq6zX vckZVRpIHBzE+wcv/s5TDDFT3zaARrs= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-53-W4cEpUsdOWGcgyq1OUTOcw-1; Mon, 21 Dec 2020 14:51:15 -0500 X-MC-Unique: W4cEpUsdOWGcgyq1OUTOcw-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 58C61804002; Mon, 21 Dec 2020 19:51:12 +0000 (UTC) Received: from horse.redhat.com (ovpn-114-244.rdu2.redhat.com [10.10.114.244]) by smtp.corp.redhat.com (Postfix) with ESMTP id AEABE5C5E1; Mon, 21 Dec 2020 19:51:11 +0000 (UTC) Received: by horse.redhat.com (Postfix, from userid 10451) id 35680225FCD; Mon, 21 Dec 2020 14:51:11 -0500 (EST) From: Vivek Goyal To: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-unionfs@vger.kernel.org Cc: jlayton@kernel.org, vgoyal@redhat.com, amir73il@gmail.com, sargun@sargun.me, miklos@szeredi.hu, willy@infradead.org, jack@suse.cz, neilb@suse.com, viro@zeniv.linux.org.uk, hch@lst.de Subject: [PATCH 3/3] overlayfs: Report writeback errors on upper Date: Mon, 21 Dec 2020 14:50:55 -0500 Message-Id: <20201221195055.35295-4-vgoyal@redhat.com> In-Reply-To: <20201221195055.35295-1-vgoyal@redhat.com> References: <20201221195055.35295-1-vgoyal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Currently syncfs() and fsync() seem to be two interfaces which check and return writeback errors on superblock to user space. fsync() should work fine with overlayfs as it relies on underlying filesystem to do the check and return error. For example, if ext4 is on upper filesystem, then ext4_sync_file() calls file_check_and_advance_wb_err(file) on upper file and returns error. So overlayfs does not have to do anything special. But with syncfs(), error check happens in vfs in syncfs() w.r.t overlay_sb->s_wb_err. Given overlayfs is stacked filesystem, it does not do actual writeback and all writeback errors are recorded on underlying filesystem. So sb->s_wb_err is never updated hence syncfs() does not work with overlay. Jeff suggested that instead of trying to propagate errors to overlay super block, why not simply check for errors against upper filesystem super block. I implemented this idea. Overlay file has "since" value which needs to be initialized at open time. Overlay overrides VFS initialization and re-initializes f->f_sb_err w.r.t upper super block. Later when ovl_sb->errseq_check_advance() is called, f->f_sb_err is used as since value to figure out if any error on upper sb has happened since then. Note, Right now this patch only deals with regular file and directories. Yet to deal with special files like device inodes, socket, fifo etc. Suggested-by: Jeff Layton Signed-off-by: Vivek Goyal --- fs/overlayfs/file.c | 1 + fs/overlayfs/overlayfs.h | 1 + fs/overlayfs/readdir.c | 1 + fs/overlayfs/super.c | 23 +++++++++++++++++++++++ fs/overlayfs/util.c | 13 +++++++++++++ 5 files changed, 39 insertions(+) diff --git a/fs/overlayfs/file.c b/fs/overlayfs/file.c index efccb7c1f9bc..7b58a44dcb71 100644 --- a/fs/overlayfs/file.c +++ b/fs/overlayfs/file.c @@ -163,6 +163,7 @@ static int ovl_open(struct inode *inode, struct file *file) return PTR_ERR(realfile); file->private_data = realfile; + ovl_init_file_errseq(file); return 0; } diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h index f8880aa2ba0e..47838abbfb3d 100644 --- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h @@ -322,6 +322,7 @@ int ovl_check_metacopy_xattr(struct ovl_fs *ofs, struct dentry *dentry); bool ovl_is_metacopy_dentry(struct dentry *dentry); char *ovl_get_redirect_xattr(struct ovl_fs *ofs, struct dentry *dentry, int padding); +void ovl_init_file_errseq(struct file *file); static inline bool ovl_is_impuredir(struct super_block *sb, struct dentry *dentry) diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c index 01620ebae1bd..0c48f1545483 100644 --- a/fs/overlayfs/readdir.c +++ b/fs/overlayfs/readdir.c @@ -960,6 +960,7 @@ static int ovl_dir_open(struct inode *inode, struct file *file) od->is_real = ovl_dir_is_real(file->f_path.dentry); od->is_upper = OVL_TYPE_UPPER(type); file->private_data = od; + ovl_init_file_errseq(file); return 0; } diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index 290983bcfbb3..d99867983722 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c @@ -390,6 +390,28 @@ static int ovl_remount(struct super_block *sb, int *flags, char *data) return ret; } +static int ovl_errseq_check_advance(struct super_block *sb, struct file *file) +{ + struct ovl_fs *ofs = sb->s_fs_info; + struct super_block *upper_sb; + int ret; + + if (!ovl_upper_mnt(ofs)) + return 0; + + upper_sb = ovl_upper_mnt(ofs)->mnt_sb; + + if (!errseq_check(&upper_sb->s_wb_err, file->f_sb_err)) + return 0; + + /* Something changed, must use slow path */ + spin_lock(&file->f_lock); + ret = errseq_check_and_advance(&upper_sb->s_wb_err, &file->f_sb_err); + spin_unlock(&file->f_lock); + + return ret; +} + static const struct super_operations ovl_super_operations = { .alloc_inode = ovl_alloc_inode, .free_inode = ovl_free_inode, @@ -400,6 +422,7 @@ static const struct super_operations ovl_super_operations = { .statfs = ovl_statfs, .show_options = ovl_show_options, .remount_fs = ovl_remount, + .errseq_check_advance = ovl_errseq_check_advance, }; enum { diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c index 23f475627d07..a1742847f3a8 100644 --- a/fs/overlayfs/util.c +++ b/fs/overlayfs/util.c @@ -950,3 +950,16 @@ char *ovl_get_redirect_xattr(struct ovl_fs *ofs, struct dentry *dentry, kfree(buf); return ERR_PTR(res); } + +void ovl_init_file_errseq(struct file *file) +{ + struct super_block *sb = file_dentry(file)->d_sb; + struct ovl_fs *ofs = sb->s_fs_info; + struct super_block *upper_sb; + + if (!ovl_upper_mnt(ofs)) + return; + + upper_sb = ovl_upper_mnt(ofs)->mnt_sb; + file->f_sb_err = errseq_sample(&upper_sb->s_wb_err); +}