From patchwork Thu Sep 9 20:22:22 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mauricio Faria de Oliveira X-Patchwork-Id: 1526284 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=canonical.com header.i=@canonical.com header.a=rsa-sha256 header.s=20210705 header.b=Rtg+Reab; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4H59RT4mddz9sXS; Fri, 10 Sep 2021 06:22:44 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1mOQZD-0001rK-L6; Thu, 09 Sep 2021 20:22:39 +0000 Received: from smtp-relay-internal-0.internal ([10.131.114.225] helo=smtp-relay-internal-0.canonical.com) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1mOQZA-0001qj-Nc for kernel-team@lists.ubuntu.com; Thu, 09 Sep 2021 20:22:36 +0000 Received: from mail-qt1-f200.google.com (mail-qt1-f200.google.com [209.85.160.200]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id 87B0040265 for ; Thu, 9 Sep 2021 20:22:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1631218956; bh=vmoT4LD8Q4NHZg9wNoReZ5kQqdZdkl9rFmuzvCiapxA=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Rtg+ReabIQJbklJuuiKTyPGuQCCRvzbjftxbVV/s3/wnnMTXm0T6AZhuyVT/T54qr YMiQ/+kyr/8An/9ZCIVGuLMS+vQdiJBrTwY81G8VfOJDCyKNXFaIN13h4GKPWHKPvk U0ntvCQuJL0sbpIjIBZHiv1hMoCZq2iOzYAMadYUOQZcAerGYbeOrt9HQ0oVPmeiek N06FvC+nj4BQfEYlSn85q7l6ikG5pG/Es2GHoVwlY6OxtLbD/4P9WogDneWy26qUDW UO1NZYbnI14MdexIn92aUcLlW0L5q+6fvwUzjSxgXDFHS/8CoXS44DkdUishq7Jp3l yKv7dmzLdVCzw== Received: by mail-qt1-f200.google.com with SMTP id a22-20020ac86116000000b002a1463f30ddso9494554qtm.17 for ; Thu, 09 Sep 2021 13:22:36 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=vmoT4LD8Q4NHZg9wNoReZ5kQqdZdkl9rFmuzvCiapxA=; b=B53qfJemoAi198KjH0gXW0tMiHKL2eUem9lEomWNQ8DyAqnfG2Nvf9vyYAMEcZLKFJ DfImWjkSIWekQLNPtE7CYtHIknBTVa2gkS9DcZDr6cGGTPnFQNPnzfFyRHjLJ3yXE9Q0 3ukEcreWzk7TI2w3Ty33DIkju9hDM0zYWk1Vnaf2WBqP6mjXYxogiQ+iKxi8kLcHDtf8 0KVxqOP+2/ciB9dt3j0aF+yW1TpTGMv8xWf1eZPyKJURcs3CPLWI+JDmW8zVrAZ2e9iX zFRM1QNrLyG6sd1VpxY5sp/EM5AlO8bY2IjGrHRNDdfxcT7SwrgRZtuPf2bWAQL2GYdH yM0Q== X-Gm-Message-State: AOAM532jy/Hs97WplZQ8DRzxR8ySed2p2fuTCKXIP/fvLo3bK7GOF44F z6SAxbUm1B8WUkBmhlOJeqjuvRCLuJYjZxI5RAmaiBLmv1Jztt02AFyMUiILdNJi9tzxij9CfbT qbhXnxGM01t32Gbag+hCzVZp0WI1Yl/y4R2/2FNOTNA== X-Received: by 2002:a05:620a:110d:: with SMTP id o13mr4662996qkk.108.1631218955264; Thu, 09 Sep 2021 13:22:35 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxjqHwXIvIJTuwYzRhv9uVhAeZPtmwrXPTsn8oJrUdlcfRYJ29LQ9fIxxNtgKsFf6cHMpP1Ag== X-Received: by 2002:a05:620a:110d:: with SMTP id o13mr4662985qkk.108.1631218955042; Thu, 09 Sep 2021 13:22:35 -0700 (PDT) Received: from mfo-t470.. ([2804:14c:4e1:8732:e256:1fca:b0d8:d6a8]) by smtp.gmail.com with ESMTPSA id t64sm2172210qkd.71.2021.09.09.13.22.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Sep 2021 13:22:34 -0700 (PDT) From: Mauricio Faria de Oliveira To: kernel-team@lists.ubuntu.com Subject: [F][PATCH 1/5] jbd2: introduce/export functions jbd2_journal_submit|finish_inode_data_buffers() Date: Thu, 9 Sep 2021 17:22:22 -0300 Message-Id: <20210909202230.886329-2-mfo@canonical.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210909202230.886329-1-mfo@canonical.com> References: <20210909202230.886329-1-mfo@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" BugLink: https://bugs.launchpad.net/bugs/1847340 Export functions that implement the current behavior done for an inode in journal_submit|finish_inode_data_buffers(). No functional change. Signed-off-by: Mauricio Faria de Oliveira Suggested-by: Jan Kara Reviewed-by: Jan Kara Reviewed-by: Andreas Dilger Link: https://lore.kernel.org/r/20201006004841.600488-2-mfo@canonical.com Signed-off-by: Theodore Ts'o (cherry picked from commit aa3c0c61f62d682259e3e66cdc01846290f9cd6c) Signed-off-by: Mauricio Faria de Oliveira --- fs/jbd2/commit.c | 36 ++++++++++++++++-------------------- fs/jbd2/journal.c | 2 ++ include/linux/jbd2.h | 4 ++++ 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index 88146008b3e3..70cb8420636c 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c @@ -187,19 +187,17 @@ static int journal_wait_on_commit_record(journal_t *journal, * use writepages() because with delayed allocation we may be doing * block allocation in writepages(). */ -static int journal_submit_inode_data_buffers(struct address_space *mapping, - loff_t dirty_start, loff_t dirty_end) +int jbd2_journal_submit_inode_data_buffers(struct jbd2_inode *jinode) { - int ret; + struct address_space *mapping = jinode->i_vfs_inode->i_mapping; struct writeback_control wbc = { .sync_mode = WB_SYNC_ALL, .nr_to_write = mapping->nrpages * 2, - .range_start = dirty_start, - .range_end = dirty_end, + .range_start = jinode->i_dirty_start, + .range_end = jinode->i_dirty_end, }; - ret = generic_writepages(mapping, &wbc); - return ret; + return generic_writepages(mapping, &wbc); } /* @@ -215,16 +213,11 @@ static int journal_submit_data_buffers(journal_t *journal, { struct jbd2_inode *jinode; int err, ret = 0; - struct address_space *mapping; spin_lock(&journal->j_list_lock); list_for_each_entry(jinode, &commit_transaction->t_inode_list, i_list) { - loff_t dirty_start = jinode->i_dirty_start; - loff_t dirty_end = jinode->i_dirty_end; - if (!(jinode->i_flags & JI_WRITE_DATA)) continue; - mapping = jinode->i_vfs_inode->i_mapping; jinode->i_flags |= JI_COMMIT_RUNNING; spin_unlock(&journal->j_list_lock); /* @@ -234,8 +227,7 @@ static int journal_submit_data_buffers(journal_t *journal, * only allocated blocks here. */ trace_jbd2_submit_inode_data(jinode->i_vfs_inode); - err = journal_submit_inode_data_buffers(mapping, dirty_start, - dirty_end); + err = jbd2_journal_submit_inode_data_buffers(jinode); if (!ret) ret = err; spin_lock(&journal->j_list_lock); @@ -248,6 +240,15 @@ static int journal_submit_data_buffers(journal_t *journal, return ret; } +int jbd2_journal_finish_inode_data_buffers(struct jbd2_inode *jinode) +{ + struct address_space *mapping = jinode->i_vfs_inode->i_mapping; + + return filemap_fdatawait_range_keep_errors(mapping, + jinode->i_dirty_start, + jinode->i_dirty_end); +} + /* * Wait for data submitted for writeout, refile inodes to proper * transaction if needed. @@ -262,16 +263,11 @@ static int journal_finish_inode_data_buffers(journal_t *journal, /* For locking, see the comment in journal_submit_data_buffers() */ spin_lock(&journal->j_list_lock); list_for_each_entry(jinode, &commit_transaction->t_inode_list, i_list) { - loff_t dirty_start = jinode->i_dirty_start; - loff_t dirty_end = jinode->i_dirty_end; - if (!(jinode->i_flags & JI_WAIT_DATA)) continue; jinode->i_flags |= JI_COMMIT_RUNNING; spin_unlock(&journal->j_list_lock); - err = filemap_fdatawait_range_keep_errors( - jinode->i_vfs_inode->i_mapping, dirty_start, - dirty_end); + err = jbd2_journal_finish_inode_data_buffers(jinode); if (!ret) ret = err; spin_lock(&journal->j_list_lock); diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index b7c5819bfc41..6d2f70da7d16 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c @@ -91,6 +91,8 @@ EXPORT_SYMBOL(jbd2_journal_try_to_free_buffers); EXPORT_SYMBOL(jbd2_journal_force_commit); EXPORT_SYMBOL(jbd2_journal_inode_ranged_write); EXPORT_SYMBOL(jbd2_journal_inode_ranged_wait); +EXPORT_SYMBOL(jbd2_journal_submit_inode_data_buffers); +EXPORT_SYMBOL(jbd2_journal_finish_inode_data_buffers); EXPORT_SYMBOL(jbd2_journal_init_jbd_inode); EXPORT_SYMBOL(jbd2_journal_release_jbd_inode); EXPORT_SYMBOL(jbd2_journal_begin_ordered_truncate); diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h index b0e97e5de8ca..41ab7b9240b4 100644 --- a/include/linux/jbd2.h +++ b/include/linux/jbd2.h @@ -1415,6 +1415,10 @@ extern int jbd2_journal_inode_ranged_write(handle_t *handle, extern int jbd2_journal_inode_ranged_wait(handle_t *handle, struct jbd2_inode *inode, loff_t start_byte, loff_t length); +extern int jbd2_journal_submit_inode_data_buffers( + struct jbd2_inode *jinode); +extern int jbd2_journal_finish_inode_data_buffers( + struct jbd2_inode *jinode); extern int jbd2_journal_begin_ordered_truncate(journal_t *journal, struct jbd2_inode *inode, loff_t new_size); extern void jbd2_journal_init_jbd_inode(struct jbd2_inode *jinode, struct inode *inode); From patchwork Thu Sep 9 20:22:23 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mauricio Faria de Oliveira X-Patchwork-Id: 1526286 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=canonical.com header.i=@canonical.com header.a=rsa-sha256 header.s=20210705 header.b=uessMqUR; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4H59RT5Fkwz9ssP; Fri, 10 Sep 2021 06:22:44 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1mOQZE-0001rs-SO; Thu, 09 Sep 2021 20:22:40 +0000 Received: from smtp-relay-internal-1.internal ([10.131.114.114] helo=smtp-relay-internal-1.canonical.com) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1mOQZC-0001r3-46 for kernel-team@lists.ubuntu.com; Thu, 09 Sep 2021 20:22:38 +0000 Received: from mail-qt1-f198.google.com (mail-qt1-f198.google.com [209.85.160.198]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id D886D3F302 for ; Thu, 9 Sep 2021 20:22:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1631218957; bh=+8oFbyGOFQko/xwNYKIMpgiyahTRjfKHrVZyBCxXmHk=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=uessMqURRQET094OaxQiU9mh27bjx3yBDoNPKi0dkAlLzNanel0O/ywlQidSVexlJ zrMBvUQrQX7Z31m0dZyzcGbo8bgfNmDYEwS8LFumKsg1RB4QWig+l0MJSELI1PR+4G zDQPDANsqy/ZTcvsxUhn1fCUG9VTgyb7vF9O4QB0Vh7LbfBgKkBU391tEO6Y6jgvN9 v8XLjEveLcGeLtrFBmjtVUn+2CuM89oDd6dN42+HZuEh9OxG/+fGBYO+SR3Cf8udH0 NWhLsiRVeZLMY2tmlMDolRwCNz8lvt1MUMSpTahvu+FIIKAoVMvcDdH3l6pKF0jC0W GFSdnBZl+6sVw== Received: by mail-qt1-f198.google.com with SMTP id z16-20020ac86b90000000b0029eec160182so9575877qts.9 for ; Thu, 09 Sep 2021 13:22:37 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=+8oFbyGOFQko/xwNYKIMpgiyahTRjfKHrVZyBCxXmHk=; b=VasXtTqDznniYlYXBFmt1BhxtOUFVbR7cn2dOv2zDAu+zeWK0wN2v6cuzTwuu9+ZQd PXYzhOhofWz1Hh/3eQDrNgnmj79BcCG0rF4jCSZMu5nlsnBQ3Vti4Y8EdFUkvvOhwhbc 99YSx4dRRWGswXIzfXa86zlUk8I2YFxFqT3nK1i22fu5BWgFtPdo9C5CNtihyDSLcI1r sGQOcGyjzEqQg976Gs6T4de+unYXhtL7sENDApU+a8dm9r6Ak+dNaipKeoiLMoJT7ATt ieSTL+U0DFe0FqSf01QWb0abbQ9BeGZh6bYAETi5A0E6NdX8N+OEGJGypOyoQy1bzcYK TIvg== X-Gm-Message-State: AOAM533vYLFdeWC7g/oUpVxE7G+Kv2P6UooG6fVMMoS8C9/suIJpC23P xexjyoMorI7/T8MFZkSO5v+LBUqkmOWgU32BjZ/lrJ1MarXQHQ2UVnrj0y/Hyy2qDTb8R7dkGMD vRoLXQHWCs8DjAbgx4JN6wFzW947O8g4C5myys8jwBQ== X-Received: by 2002:a37:8a44:: with SMTP id m65mr4617863qkd.72.1631218956580; Thu, 09 Sep 2021 13:22:36 -0700 (PDT) X-Google-Smtp-Source: ABdhPJw+UKEMWQZQUg/QZiaV/vr6tN28MDm3c5kqY7mi2Fp4wX9k8+YLJ2Dg/0ep+Fg+pVRowuwCWA== X-Received: by 2002:a37:8a44:: with SMTP id m65mr4617847qkd.72.1631218956358; Thu, 09 Sep 2021 13:22:36 -0700 (PDT) Received: from mfo-t470.. ([2804:14c:4e1:8732:e256:1fca:b0d8:d6a8]) by smtp.gmail.com with ESMTPSA id t64sm2172210qkd.71.2021.09.09.13.22.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Sep 2021 13:22:36 -0700 (PDT) From: Mauricio Faria de Oliveira To: kernel-team@lists.ubuntu.com Subject: [B/F][PATCH 2/5] jbd2, ext4, ocfs2: introduce/use journal callbacks j_submit|finish_inode_data_buffers() Date: Thu, 9 Sep 2021 17:22:23 -0300 Message-Id: <20210909202230.886329-3-mfo@canonical.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210909202230.886329-1-mfo@canonical.com> References: <20210909202230.886329-1-mfo@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" BugLink: https://bugs.launchpad.net/bugs/1847340 Introduce journal callbacks to allow different behaviors for an inode in journal_submit|finish_inode_data_buffers(). The existing users of the current behavior (ext4, ocfs2) are adapted to use the previously exported functions that implement the current behavior. Users are callers of jbd2_journal_inode_ranged_write|wait(), which adds the inode to the transaction's inode list with the JI_WRITE|WAIT_DATA flags. Only ext4 and ocfs2 in-tree. Both CONFIG_EXT4_FS and CONFIG_OCSFS2_FS select CONFIG_JBD2, which builds fs/jbd2/commit.c and journal.c that define and export the functions, so we can call directly in ext4/ocfs2. Signed-off-by: Mauricio Faria de Oliveira Suggested-by: Jan Kara Reviewed-by: Jan Kara Reviewed-by: Andreas Dilger Link: https://lore.kernel.org/r/20201006004841.600488-3-mfo@canonical.com Signed-off-by: Theodore Ts'o (cherry picked from commit 342af94ec6c02aa478fe2adcd41b950e154b03ba) Signed-off-by: Mauricio Faria de Oliveira --- fs/ext4/super.c | 4 ++++ fs/jbd2/commit.c | 30 ++++++++++++++++++------------ fs/ocfs2/journal.c | 4 ++++ include/linux/jbd2.h | 25 ++++++++++++++++++++++++- 4 files changed, 50 insertions(+), 13 deletions(-) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index ce8372ceaa43..dda9df956505 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -4465,6 +4465,10 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) set_task_ioprio(sbi->s_journal->j_task, journal_ioprio); sbi->s_journal->j_commit_callback = ext4_journal_commit_callback; + sbi->s_journal->j_submit_inode_data_buffers = + jbd2_journal_submit_inode_data_buffers; + sbi->s_journal->j_finish_inode_data_buffers = + jbd2_journal_finish_inode_data_buffers; no_journal: if (!test_opt(sb, NO_MBCACHE)) { diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index 70cb8420636c..15665086e1c8 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c @@ -197,6 +197,12 @@ int jbd2_journal_submit_inode_data_buffers(struct jbd2_inode *jinode) .range_end = jinode->i_dirty_end, }; + /* + * submit the inode data buffers. We use writepage + * instead of writepages. Because writepages can do + * block allocation with delalloc. We need to write + * only allocated blocks here. + */ return generic_writepages(mapping, &wbc); } @@ -220,16 +226,13 @@ static int journal_submit_data_buffers(journal_t *journal, continue; jinode->i_flags |= JI_COMMIT_RUNNING; spin_unlock(&journal->j_list_lock); - /* - * submit the inode data buffers. We use writepage - * instead of writepages. Because writepages can do - * block allocation with delalloc. We need to write - * only allocated blocks here. - */ + /* submit the inode data buffers. */ trace_jbd2_submit_inode_data(jinode->i_vfs_inode); - err = jbd2_journal_submit_inode_data_buffers(jinode); - if (!ret) - ret = err; + if (journal->j_submit_inode_data_buffers) { + err = journal->j_submit_inode_data_buffers(jinode); + if (!ret) + ret = err; + } spin_lock(&journal->j_list_lock); J_ASSERT(jinode->i_transaction == commit_transaction); jinode->i_flags &= ~JI_COMMIT_RUNNING; @@ -267,9 +270,12 @@ static int journal_finish_inode_data_buffers(journal_t *journal, continue; jinode->i_flags |= JI_COMMIT_RUNNING; spin_unlock(&journal->j_list_lock); - err = jbd2_journal_finish_inode_data_buffers(jinode); - if (!ret) - ret = err; + /* wait for the inode data buffers writeout. */ + if (journal->j_finish_inode_data_buffers) { + err = journal->j_finish_inode_data_buffers(jinode); + if (!ret) + ret = err; + } spin_lock(&journal->j_list_lock); jinode->i_flags &= ~JI_COMMIT_RUNNING; smp_mb(); diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c index 900e4ef686bf..bba30d4a8c49 100644 --- a/fs/ocfs2/journal.c +++ b/fs/ocfs2/journal.c @@ -883,6 +883,10 @@ int ocfs2_journal_init(struct ocfs2_journal *journal, int *dirty) OCFS2_JOURNAL_DIRTY_FL); journal->j_journal = j_journal; + journal->j_journal->j_submit_inode_data_buffers = + jbd2_journal_submit_inode_data_buffers; + journal->j_journal->j_finish_inode_data_buffers = + jbd2_journal_finish_inode_data_buffers; journal->j_inode = inode; journal->j_bh = bh; diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h index 41ab7b9240b4..339550f6db2d 100644 --- a/include/linux/jbd2.h +++ b/include/linux/jbd2.h @@ -644,7 +644,9 @@ struct transaction_s struct journal_head *t_shadow_list; /* - * List of inodes whose data we've modified in data=ordered mode. + * List of inodes associated with the transaction; e.g., ext4 uses + * this to track inodes in data=ordered and data=journal mode that + * need special handling on transaction commit; also used by ocfs2. * [j_list_lock] */ struct list_head t_inode_list; @@ -1106,6 +1108,27 @@ struct journal_s void (*j_commit_callback)(journal_t *, transaction_t *); + /** + * @j_submit_inode_data_buffers: + * + * This function is called for all inodes associated with the + * committing transaction marked with JI_WRITE_DATA flag + * before we start to write out the transaction to the journal. + */ + int (*j_submit_inode_data_buffers) + (struct jbd2_inode *); + + /** + * @j_finish_inode_data_buffers: + * + * This function is called for all inodes associated with the + * committing transaction marked with JI_WAIT_DATA flag + * after we have written the transaction to the journal + * but before we write out the commit block. + */ + int (*j_finish_inode_data_buffers) + (struct jbd2_inode *); + /* * Journal statistics */ From patchwork Thu Sep 9 20:22:24 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mauricio Faria de Oliveira X-Patchwork-Id: 1526287 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=canonical.com header.i=@canonical.com header.a=rsa-sha256 header.s=20210705 header.b=Ym9UTJye; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4H59RT6Ccvz9t14; Fri, 10 Sep 2021 06:22:45 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1mOQZG-0001sb-Cq; Thu, 09 Sep 2021 20:22:42 +0000 Received: from smtp-relay-internal-0.internal ([10.131.114.225] helo=smtp-relay-internal-0.canonical.com) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1mOQZD-0001rE-Fq for kernel-team@lists.ubuntu.com; Thu, 09 Sep 2021 20:22:39 +0000 Received: from mail-qv1-f71.google.com (mail-qv1-f71.google.com [209.85.219.71]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id 3DC2E4025C for ; Thu, 9 Sep 2021 20:22:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1631218959; bh=O0SCW1ZIMlyR+tmpqPQsn23zsBMCCGGQxpN3a8Oj2OY=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Ym9UTJye+OPHqBnYlUTg9sKc7ox+B2o0zd2PgXu1xQHsmEtQqUTattSdyIYHSUoWo C1oHKOdrb8sfmgXpbi81OKaQIWgUMkicxm/CWWL5T8MMJ2w9nVtAMM0n4+zI6vQCN4 YEEcmzOyrRpAhhZtVJdLvFce7qOWcnID7kvdWoD/PiGbg8/kiOKfAZIjk44rCuh7GV eldracpQbJfZ2b0nHbyYKgxUIeW4202qTji0tsZ8sku7m95Qf+7xGQSFV+5wjeSp8B WKnTNO7Qo0E3QnHXIl8UJxBHrgXRUJ7QY5DvmUD14gig0DXxM9rYtzKwLBCIBzK57w 7kQuX2Y8F42FQ== Received: by mail-qv1-f71.google.com with SMTP id z6-20020a056214060600b0037a3f6bd9abso7220255qvw.3 for ; Thu, 09 Sep 2021 13:22:39 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=O0SCW1ZIMlyR+tmpqPQsn23zsBMCCGGQxpN3a8Oj2OY=; b=uadmmln27ZvsA2xFha6AyhqbcER2bLYZ+a9pAIS/rkGsOl2HrWy5edejYvBMG8ssgy xGdCgmAHm73mRU6exPBqM1Wp+jlh2g2Sr4eo5CIVyNEWEBx3W9bWeNa8UHkslWqLc0a6 p8LNxs3jssxTNzSIo7eIxf4JAYPiI1ZL7+Sjh4vM5y11nN3GwU7Yaqb1uzuYZEIFP7b3 9Y9icwrwdv3EJIcuIS3X/M5b9mYEL19BwMuviELbJQGoURENrWs8igLAV7tGLw7p9sLf NMYmMbIrpBvY73iw0KMsat6reIua+4EPakQkjgo+dCw5tCIvvjs2UpnMjAmYoD8Q8Xrb YKxA== X-Gm-Message-State: AOAM532eHKtVbSmXdwWC0yRQ3+AkplGHu0Qn89OFClrNtiIRYVTxskqK 7eksU+mdqBeyq9PlVGx1EH6hiiMB1WQdjtJgneCaNTB8+RZk6iasYBzZ+d72CIRxO3ez+WVh80T OZM6JToFx8OrqiFuqbE5bvSJcwx/Waq8GK/4jSJ8SZQ== X-Received: by 2002:a37:8183:: with SMTP id c125mr4763514qkd.134.1631218957889; Thu, 09 Sep 2021 13:22:37 -0700 (PDT) X-Google-Smtp-Source: ABdhPJynex82AP7n8aF0DGuJZHMelAmhmSbf88xEgdV6AJGVb/v5cCOrqBRxVRtdWDsuB5rExpPVxg== X-Received: by 2002:a37:8183:: with SMTP id c125mr4763497qkd.134.1631218957623; Thu, 09 Sep 2021 13:22:37 -0700 (PDT) Received: from mfo-t470.. ([2804:14c:4e1:8732:e256:1fca:b0d8:d6a8]) by smtp.gmail.com with ESMTPSA id t64sm2172210qkd.71.2021.09.09.13.22.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Sep 2021 13:22:37 -0700 (PDT) From: Mauricio Faria de Oliveira To: kernel-team@lists.ubuntu.com Subject: [F][PATCH 3/5] ext4: data=journal: fixes for ext4_page_mkwrite() Date: Thu, 9 Sep 2021 17:22:24 -0300 Message-Id: <20210909202230.886329-4-mfo@canonical.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210909202230.886329-1-mfo@canonical.com> References: <20210909202230.886329-1-mfo@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" BugLink: https://bugs.launchpad.net/bugs/1847340 These are two fixes for data journalling required by the next patch, discovered while testing it. First, the optimization to return early if all buffers are mapped is not appropriate for the next patch: The inode _must_ be added to the transaction's list in data=journal mode (so to write-protect pages on commit) thus we cannot return early there. Second, once that optimization to reduce transactions was disabled for data=journal mode, more transactions happened, and occasionally hit this warning message: 'JBD2: Spotted dirty metadata buffer'. Reason is, block_page_mkwrite() will set_buffer_dirty() before do_journal_get_write_access() that is there to prevent it. This issue was masked by the optimization. So, on data=journal use __block_write_begin() instead. This also requires page locking and len recalculation. (see block_page_mkwrite() for implementation details.) Finally, as Jan noted there is little sharing between data=journal and other modes in ext4_page_mkwrite(). However, a prototype of ext4_journalled_page_mkwrite() showed there still would be lots of duplicated lines (tens of) that didn't seem worth it. Thus this patch ends up with an ugly goto to skip all non-data journalling code (to avoid long indentations, but that can be changed..) in the beginning, and just a conditional in the transaction section. Well, we skip a common part to data journalling which is the page truncated check, but we do it again after ext4_journal_start() when we re-acquire the page lock (so not to acquire the page lock twice needlessly for data journalling.) Signed-off-by: Mauricio Faria de Oliveira Suggested-by: Jan Kara Reviewed-by: Jan Kara Reviewed-by: Andreas Dilger Link: https://lore.kernel.org/r/20201006004841.600488-4-mfo@canonical.com Signed-off-by: Theodore Ts'o (cherry picked from commit 64a9f1449950c774743420cf374047043e32fde4) Signed-off-by: Mauricio Faria de Oliveira --- fs/ext4/inode.c | 51 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 1429d01d836b..fa283bcdd762 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -6276,9 +6276,17 @@ vm_fault_t ext4_page_mkwrite(struct vm_fault *vmf) if (err) goto out_ret; + /* + * On data journalling we skip straight to the transaction handle: + * there's no delalloc; page truncated will be checked later; the + * early return w/ all buffers mapped (calculates size/len) can't + * be used; and there's no dioread_nolock, so only ext4_get_block. + */ + if (ext4_should_journal_data(inode)) + goto retry_alloc; + /* Delalloc case is easy... */ if (test_opt(inode->i_sb, DELALLOC) && - !ext4_should_journal_data(inode) && !ext4_nonda_switch(inode->i_sb)) { do { err = block_page_mkwrite(vma, vmf, @@ -6304,6 +6312,9 @@ vm_fault_t ext4_page_mkwrite(struct vm_fault *vmf) /* * Return if we have all the buffers mapped. This avoids the need to do * journal_start/journal_stop which can block and take a long time + * + * This cannot be done for data journalling, as we have to add the + * inode to the transaction's list to writeprotect pages on commit. */ if (page_has_buffers(page)) { if (!ext4_walk_page_buffers(NULL, page_buffers(page), @@ -6328,16 +6339,42 @@ vm_fault_t ext4_page_mkwrite(struct vm_fault *vmf) ret = VM_FAULT_SIGBUS; goto out; } - err = block_page_mkwrite(vma, vmf, get_block); - if (!err && ext4_should_journal_data(inode)) { - if (ext4_walk_page_buffers(handle, page_buffers(page), 0, - PAGE_SIZE, NULL, do_journal_get_write_access)) { + /* + * Data journalling can't use block_page_mkwrite() because it + * will set_buffer_dirty() before do_journal_get_write_access() + * thus might hit warning messages for dirty metadata buffers. + */ + if (!ext4_should_journal_data(inode)) { + err = block_page_mkwrite(vma, vmf, get_block); + } else { + lock_page(page); + size = i_size_read(inode); + /* Page got truncated from under us? */ + if (page->mapping != mapping || page_offset(page) > size) { unlock_page(page); - ret = VM_FAULT_SIGBUS; + ret = VM_FAULT_NOPAGE; ext4_journal_stop(handle); goto out; } - ext4_set_inode_state(inode, EXT4_STATE_JDATA); + + if (page->index == size >> PAGE_SHIFT) + len = size & ~PAGE_MASK; + else + len = PAGE_SIZE; + + err = __block_write_begin(page, 0, len, ext4_get_block); + if (!err) { + if (ext4_walk_page_buffers(handle, page_buffers(page), + 0, len, NULL, do_journal_get_write_access)) { + unlock_page(page); + ret = VM_FAULT_SIGBUS; + ext4_journal_stop(handle); + goto out; + } + ext4_set_inode_state(inode, EXT4_STATE_JDATA); + } else { + unlock_page(page); + } } ext4_journal_stop(handle); if (err == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) From patchwork Thu Sep 9 20:22:25 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mauricio Faria de Oliveira X-Patchwork-Id: 1526288 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=canonical.com header.i=@canonical.com header.a=rsa-sha256 header.s=20210705 header.b=rNPjsNEO; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4H59RX1szFz9t1Q; Fri, 10 Sep 2021 06:22:47 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1mOQZH-0001tM-M6; Thu, 09 Sep 2021 20:22:43 +0000 Received: from smtp-relay-internal-1.internal ([10.131.114.114] helo=smtp-relay-internal-1.canonical.com) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1mOQZE-0001rh-RC for kernel-team@lists.ubuntu.com; Thu, 09 Sep 2021 20:22:40 +0000 Received: from mail-qv1-f70.google.com (mail-qv1-f70.google.com [209.85.219.70]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id A2AC83F302 for ; Thu, 9 Sep 2021 20:22:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1631218960; bh=57Hia0ThN7SAd4b9TtrfCRrMj/WGATB5qJIqg8+tz7c=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=rNPjsNEOOfuDa/r1Qk10gF3zNQNRcWV9AY4zVL9DMf9fX/QgA7S0rwfTMbeOzJ5z3 0ZOWV292BQhpPvJ7r5Cu+gN1dtFUtEH5rDOBFewe5o8YHoqwEvG3rSDHfoih4/Bu9P F2fJzOprReLhFlNGBHDkIM8eQumh1a6+aucCmQErfTRkzio8UpzNe0Vf18FX7k0Vkn c6V3URKmn10a2xSo05Qkv/5m1u1hTRn27XksWlDa+kMkUeij1DYktkDJPccTKVR7W7 5I76GFt1Dceo2/eDhONqkPe1RoopvjrGXkTZEveZmDokRWZVQ5mplMTcGs0tGH9rIT MmHE7BB+1uyiQ== Received: by mail-qv1-f70.google.com with SMTP id a10-20020ad45c4a000000b0037774ba4e8bso11601931qva.5 for ; Thu, 09 Sep 2021 13:22:40 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=57Hia0ThN7SAd4b9TtrfCRrMj/WGATB5qJIqg8+tz7c=; b=xOSnAfWTRNOuG9kd5pPefScf5mw22LCKj6kJpwTYPBoQ3qEG5LFxxNbQ/KQ/trJzf8 WiQLj+ngcqwZB4AJtZQB4pG29xGQF4YRv51O12gX3EMNbkMrsbfLUfdgO5aHkmLh4xQb MFu0w01sXzfUHWZ8norcYpO1ausgFhSqVoz+ilSDkPiquF0SJO1qLqPNFrgJh4PXa42K 96dS93mO2U31/chTXHM2YklT3LMWYCXADcpBDsvY+t5ehjmDm6535mWDasFaP5zlDeqV B2ssq7oMR0rQ+dxrKwTQiF9bXSV0aw1GLa7YLu3LpwFqvcoXM5moFo0mdcJwgecnmow7 OrYA== X-Gm-Message-State: AOAM530YhOuNY5tDVpPVc49eS/dx5OQPomxfiT5eIRcoKQhXrD0To7gA P/BPqEjwIAG2kqC+YICFjukX0BcN0nD6ZgPyombA8iO7io4QHhkBXji4R5ZH8pixr6PDMCFtcll ynCNlW/0Pgro3AgN9QxSu7PLWGrKro35PjMJasu3G6g== X-Received: by 2002:ac8:6786:: with SMTP id b6mr4763148qtp.201.1631218959338; Thu, 09 Sep 2021 13:22:39 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyoH062DwDWE1GPG/0Q3pzLYMCOw4i17v/acy28KH4Wnmt/fV2ev5vzTw9yKf2hT92NZ/1FqQ== X-Received: by 2002:ac8:6786:: with SMTP id b6mr4763122qtp.201.1631218959040; Thu, 09 Sep 2021 13:22:39 -0700 (PDT) Received: from mfo-t470.. ([2804:14c:4e1:8732:e256:1fca:b0d8:d6a8]) by smtp.gmail.com with ESMTPSA id t64sm2172210qkd.71.2021.09.09.13.22.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Sep 2021 13:22:38 -0700 (PDT) From: Mauricio Faria de Oliveira To: kernel-team@lists.ubuntu.com Subject: [F][PATCH 4/5] ext4: data=journal: write-protect pages on j_submit_inode_data_buffers() Date: Thu, 9 Sep 2021 17:22:25 -0300 Message-Id: <20210909202230.886329-5-mfo@canonical.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210909202230.886329-1-mfo@canonical.com> References: <20210909202230.886329-1-mfo@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" BugLink: https://bugs.launchpad.net/bugs/1847340 This implements journal callbacks j_submit|finish_inode_data_buffers() with different behavior for data=journal: to write-protect pages under commit, preventing changes to buffers writeably mapped to userspace. If a buffer's content changes between commit's checksum calculation and write-out to disk, it can cause journal recovery/mount failures upon a kernel crash or power loss. [ 27.334874] EXT4-fs: Warning: mounting with data=journal disables delayed allocation, dioread_nolock, and O_DIRECT support! [ 27.339492] JBD2: Invalid checksum recovering data block 8705 in log [ 27.342716] JBD2: recovery failed [ 27.343316] EXT4-fs (loop0): error loading journal mount: /ext4: can't read superblock on /dev/loop0. In j_submit_inode_data_buffers() we write-protect the inode's pages with write_cache_pages() and redirty w/ writepage callback if needed. In j_finish_inode_data_buffers() there is nothing do to. And in order to use the callbacks, inodes are added to the inode list in transaction in __ext4_journalled_writepage() and ext4_page_mkwrite(). In ext4_page_mkwrite() we must make sure that the buffers are attached to the transaction as jbddirty with write_end_fn(), as already done in __ext4_journalled_writepage(). Signed-off-by: Mauricio Faria de Oliveira Reported-by: Dann Frazier Reported-by: kernel test robot # wbc.nr_to_write Suggested-by: Jan Kara Reviewed-by: Jan Kara Link: https://lore.kernel.org/r/20201006004841.600488-5-mfo@canonical.com Signed-off-by: Theodore Ts'o (cherry picked from commit afb585a97f81899e39c14658789f02259d8c306a) Signed-off-by: Mauricio Faria de Oliveira --- fs/ext4/inode.c | 25 +++++++++----- fs/ext4/super.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 101 insertions(+), 11 deletions(-) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index fa283bcdd762..0fd8b033bbbe 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -2069,6 +2069,9 @@ static int __ext4_journalled_writepage(struct page *page, err = ext4_walk_page_buffers(handle, page_bufs, 0, len, NULL, write_end_fn); } + if (ret == 0) + ret = err; + err = ext4_jbd2_inode_add_write(handle, inode, 0, len); if (ret == 0) ret = err; EXT4_I(inode)->i_datasync_tid = handle->h_transaction->t_tid; @@ -6351,10 +6354,8 @@ vm_fault_t ext4_page_mkwrite(struct vm_fault *vmf) size = i_size_read(inode); /* Page got truncated from under us? */ if (page->mapping != mapping || page_offset(page) > size) { - unlock_page(page); ret = VM_FAULT_NOPAGE; - ext4_journal_stop(handle); - goto out; + goto out_error; } if (page->index == size >> PAGE_SHIFT) @@ -6364,13 +6365,15 @@ vm_fault_t ext4_page_mkwrite(struct vm_fault *vmf) err = __block_write_begin(page, 0, len, ext4_get_block); if (!err) { + ret = VM_FAULT_SIGBUS; if (ext4_walk_page_buffers(handle, page_buffers(page), - 0, len, NULL, do_journal_get_write_access)) { - unlock_page(page); - ret = VM_FAULT_SIGBUS; - ext4_journal_stop(handle); - goto out; - } + 0, len, NULL, do_journal_get_write_access)) + goto out_error; + if (ext4_walk_page_buffers(handle, page_buffers(page), + 0, len, NULL, write_end_fn)) + goto out_error; + if (ext4_jbd2_inode_add_write(handle, inode, 0, len)) + goto out_error; ext4_set_inode_state(inode, EXT4_STATE_JDATA); } else { unlock_page(page); @@ -6385,6 +6388,10 @@ vm_fault_t ext4_page_mkwrite(struct vm_fault *vmf) up_read(&EXT4_I(inode)->i_mmap_sem); sb_end_pagefault(inode->i_sb); return ret; +out_error: + unlock_page(page); + ext4_journal_stop(handle); + goto out; } vm_fault_t ext4_filemap_fault(struct vm_fault *vmf) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index dda9df956505..a29ec0fa3d71 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -432,6 +432,89 @@ static void ext4_journal_commit_callback(journal_t *journal, transaction_t *txn) spin_unlock(&sbi->s_md_lock); } +/* + * This writepage callback for write_cache_pages() + * takes care of a few cases after page cleaning. + * + * write_cache_pages() already checks for dirty pages + * and calls clear_page_dirty_for_io(), which we want, + * to write protect the pages. + * + * However, we may have to redirty a page (see below.) + */ +static int ext4_journalled_writepage_callback(struct page *page, + struct writeback_control *wbc, + void *data) +{ + transaction_t *transaction = (transaction_t *) data; + struct buffer_head *bh, *head; + struct journal_head *jh; + + bh = head = page_buffers(page); + do { + /* + * We have to redirty a page in these cases: + * 1) If buffer is dirty, it means the page was dirty because it + * contains a buffer that needs checkpointing. So the dirty bit + * needs to be preserved so that checkpointing writes the buffer + * properly. + * 2) If buffer is not part of the committing transaction + * (we may have just accidentally come across this buffer because + * inode range tracking is not exact) or if the currently running + * transaction already contains this buffer as well, dirty bit + * needs to be preserved so that the buffer gets writeprotected + * properly on running transaction's commit. + */ + jh = bh2jh(bh); + if (buffer_dirty(bh) || + (jh && (jh->b_transaction != transaction || + jh->b_next_transaction))) { + redirty_page_for_writepage(wbc, page); + goto out; + } + } while ((bh = bh->b_this_page) != head); + +out: + return AOP_WRITEPAGE_ACTIVATE; +} + +static int ext4_journalled_submit_inode_data_buffers(struct jbd2_inode *jinode) +{ + struct address_space *mapping = jinode->i_vfs_inode->i_mapping; + struct writeback_control wbc = { + .sync_mode = WB_SYNC_ALL, + .nr_to_write = LONG_MAX, + .range_start = jinode->i_dirty_start, + .range_end = jinode->i_dirty_end, + }; + + return write_cache_pages(mapping, &wbc, + ext4_journalled_writepage_callback, + jinode->i_transaction); +} + +static int ext4_journal_submit_inode_data_buffers(struct jbd2_inode *jinode) +{ + int ret; + + if (ext4_should_journal_data(jinode->i_vfs_inode)) + ret = ext4_journalled_submit_inode_data_buffers(jinode); + else + ret = jbd2_journal_submit_inode_data_buffers(jinode); + + return ret; +} + +static int ext4_journal_finish_inode_data_buffers(struct jbd2_inode *jinode) +{ + int ret = 0; + + if (!ext4_should_journal_data(jinode->i_vfs_inode)) + ret = jbd2_journal_finish_inode_data_buffers(jinode); + + return ret; +} + static bool system_going_down(void) { return system_state == SYSTEM_HALT || system_state == SYSTEM_POWER_OFF @@ -4466,9 +4549,9 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) sbi->s_journal->j_commit_callback = ext4_journal_commit_callback; sbi->s_journal->j_submit_inode_data_buffers = - jbd2_journal_submit_inode_data_buffers; + ext4_journal_submit_inode_data_buffers; sbi->s_journal->j_finish_inode_data_buffers = - jbd2_journal_finish_inode_data_buffers; + ext4_journal_finish_inode_data_buffers; no_journal: if (!test_opt(sb, NO_MBCACHE)) { From patchwork Thu Sep 9 20:22:26 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mauricio Faria de Oliveira X-Patchwork-Id: 1526290 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=canonical.com header.i=@canonical.com header.a=rsa-sha256 header.s=20210705 header.b=hl87p1eN; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4H59Rd6TDwz9ssP; Fri, 10 Sep 2021 06:22:53 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1mOQZN-0001xU-4h; Thu, 09 Sep 2021 20:22:49 +0000 Received: from smtp-relay-internal-1.internal ([10.131.114.114] helo=smtp-relay-internal-1.canonical.com) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1mOQZG-0001sU-3S for kernel-team@lists.ubuntu.com; Thu, 09 Sep 2021 20:22:42 +0000 Received: from mail-qk1-f198.google.com (mail-qk1-f198.google.com [209.85.222.198]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id E36B43F338 for ; Thu, 9 Sep 2021 20:22:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1631218961; bh=4F1pcn4Bavi6f5N9ddtsOgY1XopdThTye1gNdQuWYWE=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=hl87p1eNO3/eyrqxWXmm+euUEl1cgb6WKSHbjWOstKpo/cTFmctLaYG1dz1odz7F3 PZBUomeVjGcCUWCwFlwEhB2h4EwxZMm/1VtqRw1tXm5HLAopG6a75CA9GrDJpvhSHm lXFFmUJkkAzxghdGStOJHyjohxlNPmY1cjm4/Or2VcFontl2L8ihy4CoDZdwqrpf/l 0Ymg3hIqNpIyfIvTCb/ajXCKnWuBA281/6te83aHhlWMU8HE3KMNMxLPUdb5ehoQ1W Hkv3uOlTCBGT7sXIhkPNxtx201Lvx31L3NOoxQeL6RiytlWE/jZy/0uRAT+jbdlULW ZtQhjhlQWjOzw== Received: by mail-qk1-f198.google.com with SMTP id v21-20020a05620a0a9500b003d5c1e2f277so8543312qkg.13 for ; Thu, 09 Sep 2021 13:22:41 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=4F1pcn4Bavi6f5N9ddtsOgY1XopdThTye1gNdQuWYWE=; b=V7eHuemWJi7Mr+q8MIvfN5H/VESYLFNPAMgZiS/dyAY7SGmPNudydFCEaNaK+A9Lyc OdNWw5HkIlMSfFQzJhkVwvUyrEjQeU1KgX2CAjHj6IgU9EMbR1gqlqnxFNagHQCv2BP3 6ijdeYuhQNAYzVEE8bzc6gW860T06pyGP0DMHwx2SERO0w71P/o6HjsyJXo4fisJJyGB z2eG9LTmvv6P2fzTQQtgr0glwzEtJ3bk7eyQADTqasNDL5/ktXqnmwB7FAfRUXmDIFCq ngZvmu0iMGhJdjzlqWF/BIIAGqdYmaNNaZfCBOiiMkC1rwGtJAF3FPD7C7gSklQR9+e6 4Zgw== X-Gm-Message-State: AOAM533zoNXeofE8UCaT1y+VfTfY64ZhWHd5E8ExXoMxI+NICK28SM9Q VXmrKJWWYUDw2CgkbIOSLxpCedHD8mgMLuaM9hcdk3Qo6tAua+23D8MnV6xMs9hs3BXDoRxFlHT a4P4H5LU32H70HoHd7gYtxePi7tnhowyozvfoX75gCA== X-Received: by 2002:ac8:6b82:: with SMTP id z2mr4706680qts.52.1631218960683; Thu, 09 Sep 2021 13:22:40 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyQ+6hJdJ3/scjwZLQBfamO8C8HqnqVjpz0Lrf20WsBu/mmjjsDaYGWS0W3GoWfYwrKOELp+w== X-Received: by 2002:ac8:6b82:: with SMTP id z2mr4706660qts.52.1631218960480; Thu, 09 Sep 2021 13:22:40 -0700 (PDT) Received: from mfo-t470.. ([2804:14c:4e1:8732:e256:1fca:b0d8:d6a8]) by smtp.gmail.com with ESMTPSA id t64sm2172210qkd.71.2021.09.09.13.22.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Sep 2021 13:22:40 -0700 (PDT) From: Mauricio Faria de Oliveira To: kernel-team@lists.ubuntu.com Subject: [F][PATCH 5/5] ext4: fix mmap write protection for data=journal mode Date: Thu, 9 Sep 2021 17:22:26 -0300 Message-Id: <20210909202230.886329-6-mfo@canonical.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210909202230.886329-1-mfo@canonical.com> References: <20210909202230.886329-1-mfo@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Jan Kara BugLink: https://bugs.launchpad.net/bugs/1847340 Commit afb585a97f81 "ext4: data=journal: write-protect pages on j_submit_inode_data_buffers()") added calls ext4_jbd2_inode_add_write() to track inode ranges whose mappings need to get write-protected during transaction commits. However the added calls use wrong start of a range (0 instead of page offset) and so write protection is not necessarily effective. Use correct range start to fix the problem. Fixes: afb585a97f81 ("ext4: data=journal: write-protect pages on j_submit_inode_data_buffers()") Signed-off-by: Jan Kara Link: https://lore.kernel.org/r/20201027132751.29858-1-jack@suse.cz Signed-off-by: Theodore Ts'o (cherry picked from commit b5b18160a3e7a9f55e3528d77051670cca6d9314) Signed-off-by: Mauricio Faria de Oliveira --- fs/ext4/inode.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 0fd8b033bbbe..4ff06480dcac 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -2071,7 +2071,7 @@ static int __ext4_journalled_writepage(struct page *page, } if (ret == 0) ret = err; - err = ext4_jbd2_inode_add_write(handle, inode, 0, len); + err = ext4_jbd2_inode_add_write(handle, inode, page_offset(page), len); if (ret == 0) ret = err; EXT4_I(inode)->i_datasync_tid = handle->h_transaction->t_tid; @@ -6372,7 +6372,8 @@ vm_fault_t ext4_page_mkwrite(struct vm_fault *vmf) if (ext4_walk_page_buffers(handle, page_buffers(page), 0, len, NULL, write_end_fn)) goto out_error; - if (ext4_jbd2_inode_add_write(handle, inode, 0, len)) + if (ext4_jbd2_inode_add_write(handle, inode, + page_offset(page), len)) goto out_error; ext4_set_inode_state(inode, EXT4_STATE_JDATA); } else {