From patchwork Thu Jan 26 11:58:19 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Kirill A. Shutemov" X-Patchwork-Id: 9539055 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 5CB50601D7 for ; Thu, 26 Jan 2017 12:04:31 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 54DDC26E91 for ; Thu, 26 Jan 2017 12:04:31 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 497912818E; Thu, 26 Jan 2017 12:04:31 +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 D9C6726E91 for ; Thu, 26 Jan 2017 12:04:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752779AbdAZMEO (ORCPT ); Thu, 26 Jan 2017 07:04:14 -0500 Received: from mga07.intel.com ([134.134.136.100]:55662 "EHLO mga07.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753380AbdAZL7K (ORCPT ); Thu, 26 Jan 2017 06:59:10 -0500 Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga105.jf.intel.com with ESMTP; 26 Jan 2017 03:58:56 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.33,289,1477983600"; d="scan'208";a="813549870" Received: from black.fi.intel.com ([10.237.72.28]) by FMSMGA003.fm.intel.com with ESMTP; 26 Jan 2017 03:58:51 -0800 Received: by black.fi.intel.com (Postfix, from userid 1000) id D8E217BB; Thu, 26 Jan 2017 13:58:26 +0200 (EET) From: "Kirill A. Shutemov" To: "Theodore Ts'o" , Andreas Dilger , Jan Kara , Andrew Morton Cc: Alexander Viro , Hugh Dickins , Andrea Arcangeli , Dave Hansen , Vlastimil Babka , Matthew Wilcox , Ross Zwisler , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux-block@vger.kernel.org, "Kirill A. Shutemov" Subject: [PATCHv6 37/37] ext4, vfs: add huge= mount option Date: Thu, 26 Jan 2017 14:58:19 +0300 Message-Id: <20170126115819.58875-38-kirill.shutemov@linux.intel.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170126115819.58875-1-kirill.shutemov@linux.intel.com> References: <20170126115819.58875-1-kirill.shutemov@linux.intel.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 The same four values as in tmpfs case. Encyption code is not yet ready to handle huge page, so we disable huge pages support if the inode has EXT4_INODE_ENCRYPT. Signed-off-by: Kirill A. Shutemov --- fs/ext4/ext4.h | 5 +++++ fs/ext4/inode.c | 32 +++++++++++++++++++++++--------- fs/ext4/super.c | 24 ++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 9 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 2163c1e69f2a..19bb9995fa96 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -1134,6 +1134,11 @@ struct ext4_inode_info { #define EXT4_MOUNT_DIOREAD_NOLOCK 0x400000 /* Enable support for dio read nolocking */ #define EXT4_MOUNT_JOURNAL_CHECKSUM 0x800000 /* Journal checksums */ #define EXT4_MOUNT_JOURNAL_ASYNC_COMMIT 0x1000000 /* Journal Async Commit */ +#define EXT4_MOUNT_HUGE_MODE 0x6000000 /* Huge support mode: */ +#define EXT4_MOUNT_HUGE_NEVER 0x0000000 +#define EXT4_MOUNT_HUGE_ALWAYS 0x2000000 +#define EXT4_MOUNT_HUGE_WITHIN_SIZE 0x4000000 +#define EXT4_MOUNT_HUGE_ADVISE 0x6000000 #define EXT4_MOUNT_DELALLOC 0x8000000 /* Delalloc support */ #define EXT4_MOUNT_DATA_ERR_ABORT 0x10000000 /* Abort on file data write */ #define EXT4_MOUNT_BLOCK_VALIDITY 0x20000000 /* Block validity checking */ diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index e24ccf4c3694..120d32bcb6af 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -4481,7 +4481,7 @@ int ext4_get_inode_loc(struct inode *inode, struct ext4_iloc *iloc) void ext4_set_inode_flags(struct inode *inode) { unsigned int flags = EXT4_I(inode)->i_flags; - unsigned int new_fl = 0; + unsigned int mask, new_fl = 0; if (flags & EXT4_SYNC_FL) new_fl |= S_SYNC; @@ -4493,11 +4493,25 @@ void ext4_set_inode_flags(struct inode *inode) new_fl |= S_NOATIME; if (flags & EXT4_DIRSYNC_FL) new_fl |= S_DIRSYNC; - if (test_opt(inode->i_sb, DAX) && S_ISREG(inode->i_mode) && - !ext4_should_journal_data(inode) && !ext4_has_inline_data(inode) && - !ext4_encrypted_inode(inode)) - new_fl |= S_DAX; - + if (S_ISREG(inode->i_mode) && !ext4_encrypted_inode(inode)) { + if (test_opt(inode->i_sb, DAX) && + !ext4_should_journal_data(inode) && + !ext4_has_inline_data(inode)) + new_fl |= S_DAX; + switch (test_opt(inode->i_sb, HUGE_MODE)) { + case EXT4_MOUNT_HUGE_NEVER: + break; + case EXT4_MOUNT_HUGE_ALWAYS: + new_fl |= S_HUGE_ALWAYS; + break; + case EXT4_MOUNT_HUGE_WITHIN_SIZE: + new_fl |= S_HUGE_WITHIN_SIZE; + break; + case EXT4_MOUNT_HUGE_ADVISE: + new_fl |= S_HUGE_ADVISE; + break; + } + } if ((new_fl & S_HUGE_MODE) != S_HUGE_NEVER && EXT4_JOURNAL(inode) != NULL) { int bpp = __ext4_journal_blocks_per_page(inode, true); @@ -4511,9 +4525,9 @@ void ext4_set_inode_flags(struct inode *inode) new_fl &= ~S_HUGE_MODE; } } - - inode_set_flags(inode, new_fl, - S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC|S_DAX); + mask = S_SYNC | S_APPEND | S_IMMUTABLE | S_NOATIME | + S_DIRSYNC | S_DAX | S_HUGE_MODE; + inode_set_flags(inode, new_fl, mask); } /* Propagate flags from i_flags to EXT4_I(inode)->i_flags */ diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 66845a08a87a..13376a72050c 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1296,6 +1296,7 @@ enum { Opt_dioread_nolock, Opt_dioread_lock, Opt_discard, Opt_nodiscard, Opt_init_itable, Opt_noinit_itable, Opt_max_dir_size_kb, Opt_nojournal_checksum, + Opt_huge_never, Opt_huge_always, Opt_huge_within_size, Opt_huge_advise, }; static const match_table_t tokens = { @@ -1376,6 +1377,10 @@ static const match_table_t tokens = { {Opt_init_itable, "init_itable"}, {Opt_noinit_itable, "noinit_itable"}, {Opt_max_dir_size_kb, "max_dir_size_kb=%u"}, + {Opt_huge_never, "huge=never"}, + {Opt_huge_always, "huge=always"}, + {Opt_huge_within_size, "huge=within_size"}, + {Opt_huge_advise, "huge=advise"}, {Opt_test_dummy_encryption, "test_dummy_encryption"}, {Opt_removed, "check=none"}, /* mount option from ext2/3 */ {Opt_removed, "nocheck"}, /* mount option from ext2/3 */ @@ -1494,6 +1499,11 @@ static int clear_qf_name(struct super_block *sb, int qtype) #define MOPT_NO_EXT3 0x0200 #define MOPT_EXT4_ONLY (MOPT_NO_EXT2 | MOPT_NO_EXT3) #define MOPT_STRING 0x0400 +#ifdef CONFIG_TRANSPARENT_HUGE_PAGECACHE +#define MOPT_HUGE 0x1000 +#else +#define MOPT_HUGE MOPT_NOSUPPORT +#endif static const struct mount_opts { int token; @@ -1581,6 +1591,10 @@ static const struct mount_opts { {Opt_jqfmt_vfsv0, QFMT_VFS_V0, MOPT_QFMT}, {Opt_jqfmt_vfsv1, QFMT_VFS_V1, MOPT_QFMT}, {Opt_max_dir_size_kb, 0, MOPT_GTE0}, + {Opt_huge_never, EXT4_MOUNT_HUGE_NEVER, MOPT_HUGE}, + {Opt_huge_always, EXT4_MOUNT_HUGE_ALWAYS, MOPT_HUGE}, + {Opt_huge_within_size, EXT4_MOUNT_HUGE_WITHIN_SIZE, MOPT_HUGE}, + {Opt_huge_advise, EXT4_MOUNT_HUGE_ADVISE, MOPT_HUGE}, {Opt_test_dummy_encryption, 0, MOPT_GTE0}, {Opt_err, 0, 0} }; @@ -1662,6 +1676,16 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token, } else return -1; } + if (MOPT_HUGE != MOPT_NOSUPPORT && m->flags & MOPT_HUGE) { + sbi->s_mount_opt &= ~EXT4_MOUNT_HUGE_MODE; + sbi->s_mount_opt |= m->mount_opt; + if (m->mount_opt) { + ext4_msg(sb, KERN_WARNING, "Warning: " + "Support of huge pages is EXPERIMENTAL," + " use at your own risk"); + } + return 1; + } if (m->flags & MOPT_CLEAR_ERR) clear_opt(sb, ERRORS_MASK); if (token == Opt_noquota && sb_any_quota_loaded(sb)) {