From nobody Fri Sep 12 00:29:39 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 68870C4167B for ; Wed, 6 Dec 2023 15:11:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1379165AbjLFPLl (ORCPT ); Wed, 6 Dec 2023 10:11:41 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48964 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1379090AbjLFPLi (ORCPT ); Wed, 6 Dec 2023 10:11:38 -0500 Received: from relayaws-01.paragon-software.com (relayaws-01.paragon-software.com [35.157.23.187]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F1F6F112; Wed, 6 Dec 2023 07:11:42 -0800 (PST) Received: from dlg2.mail.paragon-software.com (vdlg-exch-02.paragon-software.com [172.30.1.105]) by relayaws-01.paragon-software.com (Postfix) with ESMTPS id C6A3D212D; Wed, 6 Dec 2023 15:05:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=paragon-software.com; s=mail; t=1701875116; bh=RexGtu8XWQhs4tm8penzzSeBhtaDj8gNGca25jwrs2M=; h=Date:Subject:From:To:CC:References:In-Reply-To; b=hXLqwnBonYPKS90AP/XXpXvpg5+f5SWde19cling7MoZ4UnWwskiL/hAMPHubIxpw Of4FcC2fjOf/dQzXu8I2+vhD8p4R9EntgiXK60JCya/xpV8K9VtmMDipKLzh3QLjox JsiEpCgDcYrptLa+d6fhqSCIT7nICinhP97CaNZM= Received: from [172.16.192.129] (192.168.211.144) by vdlg-exch-02.paragon-software.com (172.30.1.105) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.7; Wed, 6 Dec 2023 18:11:40 +0300 Message-ID: <17bac290-26bf-484d-bcf2-9a65e93add78@paragon-software.com> Date: Wed, 6 Dec 2023 18:11:40 +0300 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: [PATCH 06/16] fs/ntfs3: Reduce stack usage Content-Language: en-US From: Konstantin Komarovc To: CC: , References: <00fd1558-fda5-421b-be43-7de69e32cb4e@paragon-software.com> In-Reply-To: <00fd1558-fda5-421b-be43-7de69e32cb4e@paragon-software.com> Content-Type: text/plain; charset="utf-8"; format="flowed" Content-Transfer-Encoding: quoted-printable X-Originating-IP: [192.168.211.144] X-ClientProxiedBy: vobn-exch-01.paragon-software.com (172.30.72.13) To vdlg-exch-02.paragon-software.com (172.30.1.105) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Signed-off-by: Konstantin Komarov --- =C2=A0fs/ntfs3/fslog.c | 218 +++++++++++++++++++++------------------------= -- =C2=A01 file changed, 98 insertions(+), 120 deletions(-) diff --git a/fs/ntfs3/fslog.c b/fs/ntfs3/fslog.c index 98ccb6650858..7dbb000fc691 100644 --- a/fs/ntfs3/fslog.c +++ b/fs/ntfs3/fslog.c @@ -974,6 +974,16 @@ static inline void *alloc_rsttbl_from_idx(struct=20 RESTART_TABLE **tbl, u32 vbo) =C2=A0=C2=A0=C2=A0 =C2=A0return e; =C2=A0} +struct restart_info { +=C2=A0=C2=A0 =C2=A0u64 last_lsn; +=C2=A0=C2=A0 =C2=A0struct RESTART_HDR *r_page; +=C2=A0=C2=A0 =C2=A0u32 vbo; +=C2=A0=C2=A0 =C2=A0bool chkdsk_was_run; +=C2=A0=C2=A0 =C2=A0bool valid_page; +=C2=A0=C2=A0 =C2=A0bool initialized; +=C2=A0=C2=A0 =C2=A0bool restart; +}; + =C2=A0#define RESTART_SINGLE_PAGE_IO cpu_to_le16(0x0001) =C2=A0#define NTFSLOG_WRAPPED 0x00000001 @@ -987,6 +997,7 @@ struct ntfs_log { =C2=A0=C2=A0=C2=A0 =C2=A0struct ntfs_inode *ni; =C2=A0=C2=A0=C2=A0 =C2=A0u32 l_size; +=C2=A0=C2=A0 =C2=A0u32 orig_file_size; =C2=A0=C2=A0=C2=A0 =C2=A0u32 sys_page_size; =C2=A0=C2=A0=C2=A0 =C2=A0u32 sys_page_mask; =C2=A0=C2=A0=C2=A0 =C2=A0u32 page_size; @@ -1040,6 +1051,8 @@ struct ntfs_log { =C2=A0=C2=A0=C2=A0 =C2=A0struct CLIENT_ID client_id; =C2=A0=C2=A0=C2=A0 =C2=A0u32 client_undo_commit; + +=C2=A0=C2=A0 =C2=A0struct restart_info rst_info, rst_info2; =C2=A0}; =C2=A0static inline u32 lsn_to_vbo(struct ntfs_log *log, const u64 lsn) @@ -1105,16 +1118,6 @@ static inline bool verify_client_lsn(struct=20 ntfs_log *log, =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 lsn <=3D le6= 4_to_cpu(log->ra->current_lsn) && lsn; =C2=A0} -struct restart_info { -=C2=A0=C2=A0 =C2=A0u64 last_lsn; -=C2=A0=C2=A0 =C2=A0struct RESTART_HDR *r_page; -=C2=A0=C2=A0 =C2=A0u32 vbo; -=C2=A0=C2=A0 =C2=A0bool chkdsk_was_run; -=C2=A0=C2=A0 =C2=A0bool valid_page; -=C2=A0=C2=A0 =C2=A0bool initialized; -=C2=A0=C2=A0 =C2=A0bool restart; -}; - =C2=A0static int read_log_page(struct ntfs_log *log, u32 vbo, =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 struct REC= ORD_PAGE_HDR **buffer, bool *usa_error) =C2=A0{ @@ -1176,7 +1179,7 @@ static int read_log_page(struct ntfs_log *log, u32=20 vbo, =C2=A0 * restart page header. It will stop the first time we find a =C2=A0 * valid page header. =C2=A0 */ -static int log_read_rst(struct ntfs_log *log, u32 l_size, bool first, +static int log_read_rst(struct ntfs_log *log, bool first, =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0struct rest= art_info *info) =C2=A0{ =C2=A0=C2=A0=C2=A0 =C2=A0u32 skip, vbo; @@ -1192,7 +1195,7 @@ static int log_read_rst(struct ntfs_log *log, u32=20 l_size, bool first, =C2=A0=C2=A0=C2=A0 =C2=A0} =C2=A0=C2=A0=C2=A0 =C2=A0/* Loop continuously until we succeed. */ -=C2=A0=C2=A0 =C2=A0for (; vbo < l_size; vbo =3D 2 * vbo + skip, skip =3D 0= ) { +=C2=A0=C2=A0 =C2=A0for (; vbo < log->l_size; vbo =3D 2 * vbo + skip, skip = =3D 0) { =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0bool usa_error; =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0bool brst, bchk; =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0struct RESTART_AREA *ra; @@ -1285,22 +1288,17 @@ static int log_read_rst(struct ntfs_log *log,=20 u32 l_size, bool first, =C2=A0/* =C2=A0 * Ilog_init_pg_hdr - Init @log from restart page header. =C2=A0 */ -static void log_init_pg_hdr(struct ntfs_log *log, u32 sys_page_size, -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=C2= =A0 u32 page_size, u16 major_ver, u16 minor_ver) +static void log_init_pg_hdr(struct ntfs_log *log, u16 major_ver, u16=20 minor_ver) =C2=A0{ -=C2=A0=C2=A0 =C2=A0log->sys_page_size =3D sys_page_size; -=C2=A0=C2=A0 =C2=A0log->sys_page_mask =3D sys_page_size - 1; -=C2=A0=C2=A0 =C2=A0log->page_size =3D page_size; -=C2=A0=C2=A0 =C2=A0log->page_mask =3D page_size - 1; -=C2=A0=C2=A0 =C2=A0log->page_bits =3D blksize_bits(page_size); +=C2=A0=C2=A0 =C2=A0log->sys_page_size =3D log->page_size; +=C2=A0=C2=A0 =C2=A0log->sys_page_mask =3D log->page_mask; =C2=A0=C2=A0=C2=A0 =C2=A0log->clst_per_page =3D log->page_size >> log->ni-= >mi.sbi->cluster_bits; =C2=A0=C2=A0=C2=A0 =C2=A0if (!log->clst_per_page) =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0log->clst_per_page =3D 1; -=C2=A0=C2=A0 =C2=A0log->first_page =3D major_ver >=3D 2 ? -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2= =A0=C2=A0 0x22 * page_size : -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2= =A0=C2=A0 ((sys_page_size << 1) + (page_size << 1)); +=C2=A0=C2=A0 =C2=A0log->first_page =3D major_ver >=3D 2 ? 0x22 * log->page= _size : +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2= =A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 4 * log->page_size; =C2=A0=C2=A0=C2=A0 =C2=A0log->major_ver =3D major_ver; =C2=A0=C2=A0=C2=A0 =C2=A0log->minor_ver =3D minor_ver; =C2=A0} @@ -1308,12 +1306,11 @@ static void log_init_pg_hdr(struct ntfs_log=20 *log, u32 sys_page_size, =C2=A0/* =C2=A0 * log_create - Init @log in cases when we don't have a restart area=20 to use. =C2=A0 */ -static void log_create(struct ntfs_log *log, u32 l_size, const u64=20 last_lsn, +static void log_create(struct ntfs_log *log, const u64 last_lsn, =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0 u32 open_log_count, bool wrapped, bool use_multi_page) =C2=A0{ -=C2=A0=C2=A0 =C2=A0log->l_size =3D l_size; =C2=A0=C2=A0=C2=A0 =C2=A0/* All file offsets must be quadword aligned. */ -=C2=A0=C2=A0 =C2=A0log->file_data_bits =3D blksize_bits(l_size) - 3; +=C2=A0=C2=A0 =C2=A0log->file_data_bits =3D blksize_bits(log->l_size) - 3; =C2=A0=C2=A0=C2=A0 =C2=A0log->seq_num_mask =3D (8 << log->file_data_bits) = - 1; =C2=A0=C2=A0=C2=A0 =C2=A0log->seq_num_bits =3D sizeof(u64) * 8 - log->file= _data_bits; =C2=A0=C2=A0=C2=A0 =C2=A0log->seq_num =3D (last_lsn >> log->file_data_bits= ) + 2; @@ -3720,10 +3717,8 @@ int log_replay(struct ntfs_inode *ni, bool=20 *initialized) =C2=A0=C2=A0=C2=A0 =C2=A0struct ntfs_sb_info *sbi =3D ni->mi.sbi; =C2=A0=C2=A0=C2=A0 =C2=A0struct ntfs_log *log; -=C2=A0=C2=A0 =C2=A0struct restart_info rst_info, rst_info2; -=C2=A0=C2=A0 =C2=A0u64 rec_lsn, ra_lsn, checkpt_lsn =3D 0, rlsn =3D 0; +=C2=A0=C2=A0 =C2=A0u64 rec_lsn, checkpt_lsn =3D 0, rlsn =3D 0; =C2=A0=C2=A0=C2=A0 =C2=A0struct ATTR_NAME_ENTRY *attr_names =3D NULL; -=C2=A0=C2=A0 =C2=A0struct ATTR_NAME_ENTRY *ane; =C2=A0=C2=A0=C2=A0 =C2=A0struct RESTART_TABLE *dptbl =3D NULL; =C2=A0=C2=A0=C2=A0 =C2=A0struct RESTART_TABLE *trtbl =3D NULL; =C2=A0=C2=A0=C2=A0 =C2=A0const struct RESTART_TABLE *rt; @@ -3741,9 +3736,7 @@ int log_replay(struct ntfs_inode *ni, bool=20 *initialized) =C2=A0=C2=A0=C2=A0 =C2=A0struct TRANSACTION_ENTRY *tr; =C2=A0=C2=A0=C2=A0 =C2=A0struct DIR_PAGE_ENTRY *dp; =C2=A0=C2=A0=C2=A0 =C2=A0u32 i, bytes_per_attr_entry; -=C2=A0=C2=A0 =C2=A0u32 l_size =3D ni->vfs_inode.i_size; -=C2=A0=C2=A0 =C2=A0u32 orig_file_size =3D l_size; -=C2=A0=C2=A0 =C2=A0u32 page_size, vbo, tail, off, dlen; +=C2=A0=C2=A0 =C2=A0u32 vbo, tail, off, dlen; =C2=A0=C2=A0=C2=A0 =C2=A0u32 saved_len, rec_len, transact_id; =C2=A0=C2=A0=C2=A0 =C2=A0bool use_second_page; =C2=A0=C2=A0=C2=A0 =C2=A0struct RESTART_AREA *ra2, *ra =3D NULL; @@ -3758,52 +3751,50 @@ int log_replay(struct ntfs_inode *ni, bool=20 *initialized) =C2=A0=C2=A0=C2=A0 =C2=A0u16 t16; =C2=A0=C2=A0=C2=A0 =C2=A0u32 t32; -=C2=A0=C2=A0 =C2=A0/* Get the size of page. NOTE: To replay we can use def= ault page. */ -#if PAGE_SIZE >=3D DefaultLogPageSize && PAGE_SIZE <=3D DefaultLogPageSize= * 2 -=C2=A0=C2=A0 =C2=A0page_size =3D norm_file_page(PAGE_SIZE, &l_size, true); -#else -=C2=A0=C2=A0 =C2=A0page_size =3D norm_file_page(PAGE_SIZE, &l_size, false); -#endif -=C2=A0=C2=A0 =C2=A0if (!page_size) -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0return -EINVAL; - =C2=A0=C2=A0=C2=A0 =C2=A0log =3D kzalloc(sizeof(struct ntfs_log), GFP_NOFS= ); =C2=A0=C2=A0=C2=A0 =C2=A0if (!log) =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0return -ENOMEM; =C2=A0=C2=A0=C2=A0 =C2=A0log->ni =3D ni; -=C2=A0=C2=A0 =C2=A0log->l_size =3D l_size; -=C2=A0=C2=A0 =C2=A0log->one_page_buf =3D kmalloc(page_size, GFP_NOFS); +=C2=A0=C2=A0 =C2=A0log->l_size =3D log->orig_file_size =3D ni->vfs_inode.i= _size; + +=C2=A0=C2=A0 =C2=A0/* Get the size of page. NOTE: To replay we can use def= ault page. */ +#if PAGE_SIZE >=3D DefaultLogPageSize && PAGE_SIZE <=3D DefaultLogPageSize= * 2 +=C2=A0=C2=A0 =C2=A0log->page_size =3D norm_file_page(PAGE_SIZE, &log->l_si= ze, true); +#else +=C2=A0=C2=A0 =C2=A0log->page_size =3D norm_file_page(PAGE_SIZE, &log->l_si= ze, false); +#endif +=C2=A0=C2=A0 =C2=A0if (!log->page_size) { +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0err =3D -EINVAL; +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0goto out; +=C2=A0=C2=A0 =C2=A0} +=C2=A0=C2=A0 =C2=A0log->one_page_buf =3D kmalloc(log->page_size, GFP_NOFS); =C2=A0=C2=A0=C2=A0 =C2=A0if (!log->one_page_buf) { =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0err =3D -ENOMEM; =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0goto out; =C2=A0=C2=A0=C2=A0 =C2=A0} -=C2=A0=C2=A0 =C2=A0log->page_size =3D page_size; -=C2=A0=C2=A0 =C2=A0log->page_mask =3D page_size - 1; -=C2=A0=C2=A0 =C2=A0log->page_bits =3D blksize_bits(page_size); +=C2=A0=C2=A0 =C2=A0log->page_mask =3D log->page_size - 1; +=C2=A0=C2=A0 =C2=A0log->page_bits =3D blksize_bits(log->page_size); =C2=A0=C2=A0=C2=A0 =C2=A0/* Look for a restart area on the disk. */ -=C2=A0=C2=A0 =C2=A0memset(&rst_info, 0, sizeof(struct restart_info)); -=C2=A0=C2=A0 =C2=A0err =3D log_read_rst(log, l_size, true, &rst_info); +=C2=A0=C2=A0 =C2=A0err =3D log_read_rst(log, true, &log->rst_info); =C2=A0=C2=A0=C2=A0 =C2=A0if (err) =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0goto out; =C2=A0=C2=A0=C2=A0 =C2=A0/* remember 'initialized' */ -=C2=A0=C2=A0 =C2=A0*initialized =3D rst_info.initialized; +=C2=A0=C2=A0 =C2=A0*initialized =3D log->rst_info.initialized; -=C2=A0=C2=A0 =C2=A0if (!rst_info.restart) { -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0if (rst_info.initialized) { +=C2=A0=C2=A0 =C2=A0if (!log->rst_info.restart) { +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0if (log->rst_info.initialized) { =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0/* No resta= rt area but the file is not initialized. */ =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0err =3D -EI= NVAL; =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0goto out; =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0} -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0log_init_pg_hdr(log, page_size, page= _size, 1, 1); -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0log_create(log, l_size, 0, get_rando= m_u32(), false, false); - -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0log->ra =3D ra; +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0log_init_pg_hdr(log, 1, 1); +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0log_create(log, 0, get_random_u32(),= false, false); =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0ra =3D log_create_ra(log); =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0if (!ra) { @@ -3820,25 +3811,26 @@ int log_replay(struct ntfs_inode *ni, bool=20 *initialized) =C2=A0=C2=A0=C2=A0 =C2=A0 * If the restart offset above wasn't zero then w= e won't =C2=A0=C2=A0=C2=A0 =C2=A0 * look for a second restart. =C2=A0=C2=A0=C2=A0 =C2=A0 */ -=C2=A0=C2=A0 =C2=A0if (rst_info.vbo) +=C2=A0=C2=A0 =C2=A0if (log->rst_info.vbo) =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0goto check_restart_area; -=C2=A0=C2=A0 =C2=A0memset(&rst_info2, 0, sizeof(struct restart_info)); -=C2=A0=C2=A0 =C2=A0err =3D log_read_rst(log, l_size, false, &rst_info2); +=C2=A0=C2=A0 =C2=A0err =3D log_read_rst(log, false, &log->rst_info2); =C2=A0=C2=A0=C2=A0 =C2=A0if (err) =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0goto out; =C2=A0=C2=A0=C2=A0 =C2=A0/* Determine which restart area to use. */ -=C2=A0=C2=A0 =C2=A0if (!rst_info2.restart || rst_info2.last_lsn <=3D rst_i= nfo.last_lsn) +=C2=A0=C2=A0 =C2=A0if (!log->rst_info2.restart || +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=C2=A0 log->rst_info2.last_lsn <=3D log->rs= t_info.last_lsn) =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0goto use_first_page; =C2=A0=C2=A0=C2=A0 =C2=A0use_second_page =3D true; -=C2=A0=C2=A0 =C2=A0if (rst_info.chkdsk_was_run && page_size !=3D rst_info.= vbo) { +=C2=A0=C2=A0 =C2=A0if (log->rst_info.chkdsk_was_run && +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=C2=A0 log->page_size !=3D log->rst_info.vb= o) { =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0struct RECORD_PAGE_HDR *sp =3D= NULL; =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0bool usa_error; -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0if (!read_log_page(log, page_size, &= sp, &usa_error) && +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0if (!read_log_page(log, log->page_si= ze, &sp, &usa_error) && =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=C2=A0 sp->rhdr.si= gn =3D=3D NTFS_CHKD_SIGNATURE) { =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0use_second_= page =3D false; =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0} @@ -3846,52 +3838,43 @@ int log_replay(struct ntfs_inode *ni, bool=20 *initialized) =C2=A0=C2=A0=C2=A0 =C2=A0} =C2=A0=C2=A0=C2=A0 =C2=A0if (use_second_page) { -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0kfree(rst_info.r_page); -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0memcpy(&rst_info, &rst_info2, sizeof= (struct restart_info)); -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0rst_info2.r_page =3D NULL; +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0kfree(log->rst_info.r_page); +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0memcpy(&log->rst_info, &log->rst_inf= o2, +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= sizeof(struct restart_info)); +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0log->rst_info2.r_page =3D NULL; =C2=A0=C2=A0=C2=A0 =C2=A0} =C2=A0use_first_page: -=C2=A0=C2=A0 =C2=A0kfree(rst_info2.r_page); +=C2=A0=C2=A0 =C2=A0kfree(log->rst_info2.r_page); =C2=A0check_restart_area: =C2=A0=C2=A0=C2=A0 =C2=A0/* =C2=A0=C2=A0=C2=A0 =C2=A0 * If the restart area is at offset 0, we want =C2=A0=C2=A0=C2=A0 =C2=A0 * to write the second restart area first. =C2=A0=C2=A0=C2=A0 =C2=A0 */ -=C2=A0=C2=A0 =C2=A0log->init_ra =3D !!rst_info.vbo; +=C2=A0=C2=A0 =C2=A0log->init_ra =3D !!log->rst_info.vbo; =C2=A0=C2=A0=C2=A0 =C2=A0/* If we have a valid page then grab a pointer to= the restart area. */ -=C2=A0=C2=A0 =C2=A0ra2 =3D rst_info.valid_page ? -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Add2P= tr(rst_info.r_page, -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0 le16_to_cpu(rst_info.r_page->ra_off)) : +=C2=A0=C2=A0 =C2=A0ra2 =3D log->rst_info.valid_page ? +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Add2P= tr(log->rst_info.r_page, +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0 le16_to_cpu(log->rst_info.r_page->ra_off)) : =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= NULL; -=C2=A0=C2=A0 =C2=A0if (rst_info.chkdsk_was_run || +=C2=A0=C2=A0 =C2=A0if (log->rst_info.chkdsk_was_run || =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=C2=A0 (ra2 && ra2->client_idx[1] =3D= =3D LFS_NO_CLIENT_LE)) { =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0bool wrapped =3D false; =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0bool use_multi_page =3D false; =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0u32 open_log_count; =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0/* Do some checks based on whe= ther we have a valid log page. */ -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0if (!rst_info.valid_page) { -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0open_log_count = =3D get_random_u32(); -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0goto init_log_ins= tance; -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0} -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0open_log_count =3D le32_to_cpu(ra2->= open_log_count); - -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0/* -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 * If the restart page size isn't ch= anging then we want to -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 * check how much work we need to do. -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 */ -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0if (page_size !=3D le32_to_cpu(rst_i= nfo.r_page->sys_page_size)) -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0goto init_log_ins= tance; +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0open_log_count =3D log->rst_info.val= id_page ? +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2= =A0=C2=A0=C2=A0 =C2=A0 le32_to_cpu(ra2->open_log_count) : +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2= =A0=C2=A0=C2=A0 =C2=A0 get_random_u32(); -init_log_instance: -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0log_init_pg_hdr(log, page_size, page= _size, 1, 1); +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0log_init_pg_hdr(log, 1, 1); -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0log_create(log, l_size, rst_info.las= t_lsn, open_log_count, -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 wrap= ped, use_multi_page); +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0log_create(log, log->rst_info.last_l= sn, open_log_count, wrapped, +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 use_= multi_page); =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0ra =3D log_create_ra(log); =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0if (!ra) { @@ -3916,28 +3899,27 @@ int log_replay(struct ntfs_inode *ni, bool=20 *initialized) =C2=A0=C2=A0=C2=A0 =C2=A0 * use the log file. We must use the system page = size instead of the =C2=A0=C2=A0=C2=A0 =C2=A0 * default size if there is not a clean shutdown. =C2=A0=C2=A0=C2=A0 =C2=A0 */ -=C2=A0=C2=A0 =C2=A0t32 =3D le32_to_cpu(rst_info.r_page->sys_page_size); -=C2=A0=C2=A0 =C2=A0if (page_size !=3D t32) { -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0l_size =3D orig_file_size; -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0page_size =3D -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0norm_file_page(t3= 2, &l_size, t32 =3D=3D DefaultLogPageSize); +=C2=A0=C2=A0 =C2=A0t32 =3D le32_to_cpu(log->rst_info.r_page->sys_page_size= ); +=C2=A0=C2=A0 =C2=A0if (log->page_size !=3D t32) { +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0log->l_size =3D log->orig_file_size; +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0log->page_size =3D norm_file_page(t3= 2, &log->l_size, +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2= =A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0t32 =3D=3D DefaultLogPageSize); =C2=A0=C2=A0=C2=A0 =C2=A0} -=C2=A0=C2=A0 =C2=A0if (page_size !=3D t32 || -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=C2=A0 page_size !=3D le32_to_cpu(rst_info.= r_page->page_size)) { +=C2=A0=C2=A0 =C2=A0if (log->page_size !=3D t32 || +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=C2=A0 log->page_size !=3D le32_to_cpu(log-= >rst_info.r_page->page_size)) { =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0err =3D -EINVAL; =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0goto out; =C2=A0=C2=A0=C2=A0 =C2=A0} =C2=A0=C2=A0=C2=A0 =C2=A0/* If the file size has shrunk then we won't moun= t it. */ -=C2=A0=C2=A0 =C2=A0if (l_size < le64_to_cpu(ra2->l_size)) { +=C2=A0=C2=A0 =C2=A0if (log->l_size < le64_to_cpu(ra2->l_size)) { =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0err =3D -EINVAL; =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0goto out; =C2=A0=C2=A0=C2=A0 =C2=A0} -=C2=A0=C2=A0 =C2=A0log_init_pg_hdr(log, page_size, page_size, -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0le16_to_cpu(rst_i= nfo.r_page->major_ver), -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0le16_to_cpu(rst_i= nfo.r_page->minor_ver)); +=C2=A0=C2=A0 =C2=A0log_init_pg_hdr(log, le16_to_cpu(log->rst_info.r_page->= major_ver), +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0le16_to_cpu(log->= rst_info.r_page->minor_ver)); =C2=A0=C2=A0=C2=A0 =C2=A0log->l_size =3D le64_to_cpu(ra2->l_size); =C2=A0=C2=A0=C2=A0 =C2=A0log->seq_num_bits =3D le32_to_cpu(ra2->seq_num_bi= ts); @@ -3945,7 +3927,7 @@ int log_replay(struct ntfs_inode *ni, bool=20 *initialized) =C2=A0=C2=A0=C2=A0 =C2=A0log->seq_num_mask =3D (8 << log->file_data_bits) = - 1; =C2=A0=C2=A0=C2=A0 =C2=A0log->last_lsn =3D le64_to_cpu(ra2->current_lsn); =C2=A0=C2=A0=C2=A0 =C2=A0log->seq_num =3D log->last_lsn >> log->file_data_= bits; -=C2=A0=C2=A0 =C2=A0log->ra_off =3D le16_to_cpu(rst_info.r_page->ra_off); +=C2=A0=C2=A0 =C2=A0log->ra_off =3D le16_to_cpu(log->rst_info.r_page->ra_of= f); =C2=A0=C2=A0=C2=A0 =C2=A0log->restart_size =3D log->sys_page_size - log->r= a_off; =C2=A0=C2=A0=C2=A0 =C2=A0log->record_header_len =3D le16_to_cpu(ra2->rec_h= dr_len); =C2=A0=C2=A0=C2=A0 =C2=A0log->ra_size =3D le16_to_cpu(ra2->ra_len); @@ -4045,7 +4027,7 @@ int log_replay(struct ntfs_inode *ni, bool=20 *initialized) =C2=A0=C2=A0=C2=A0 =C2=A0log->current_avail =3D current_log_avail(log); =C2=A0=C2=A0=C2=A0 =C2=A0/* Remember which restart area to write first. */ -=C2=A0=C2=A0 =C2=A0log->init_ra =3D rst_info.vbo; +=C2=A0=C2=A0 =C2=A0log->init_ra =3D log->rst_info.vbo; =C2=A0process_log: =C2=A0=C2=A0=C2=A0 =C2=A0/* 1.0, 1.1, 2.0 log->major_ver/minor_ver - short= values. */ @@ -4105,7 +4087,7 @@ int log_replay(struct ntfs_inode *ni, bool=20 *initialized) =C2=A0=C2=A0=C2=A0 =C2=A0log->client_id.seq_num =3D cr->seq_num; =C2=A0=C2=A0=C2=A0 =C2=A0log->client_id.client_idx =3D client; -=C2=A0=C2=A0 =C2=A0err =3D read_rst_area(log, &rst, &ra_lsn); +=C2=A0=C2=A0 =C2=A0err =3D read_rst_area(log, &rst, &checkpt_lsn); =C2=A0=C2=A0=C2=A0 =C2=A0if (err) =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0goto out; @@ -4114,9 +4096,8 @@ int log_replay(struct ntfs_inode *ni, bool=20 *initialized) =C2=A0=C2=A0=C2=A0 =C2=A0bytes_per_attr_entry =3D !rst->major_ver ? 0x2C := 0x28; -=C2=A0=C2=A0 =C2=A0checkpt_lsn =3D le64_to_cpu(rst->check_point_start); -=C2=A0=C2=A0 =C2=A0if (!checkpt_lsn) -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0checkpt_lsn =3D ra_lsn; +=C2=A0=C2=A0 =C2=A0if (rst->check_point_start) +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0checkpt_lsn =3D le64_to_cpu(rst->che= ck_point_start); =C2=A0=C2=A0=C2=A0 =C2=A0/* Allocate and Read the Transaction Table. */ =C2=A0=C2=A0=C2=A0 =C2=A0if (!rst->transact_table_len) @@ -4330,23 +4311,20 @@ int log_replay(struct ntfs_inode *ni, bool=20 *initialized) =C2=A0=C2=A0=C2=A0 =C2=A0lcb =3D NULL; =C2=A0check_attribute_names2: -=C2=A0=C2=A0 =C2=A0if (!rst->attr_names_len) -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0goto trace_attribute_table; - -=C2=A0=C2=A0 =C2=A0ane =3D attr_names; -=C2=A0=C2=A0 =C2=A0if (!oatbl) -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0goto trace_attribute_table; -=C2=A0=C2=A0 =C2=A0while (ane->off) { -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0/* TODO: Clear table on exit! */ -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0oe =3D Add2Ptr(oatbl, le16_to_cpu(an= e->off)); -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0t16 =3D le16_to_cpu(ane->name_bytes); -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0oe->name_len =3D t16 / sizeof(short); -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0oe->ptr =3D ane->name; -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0oe->is_attr_name =3D 2; -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0ane =3D Add2Ptr(ane, sizeof(struct A= TTR_NAME_ENTRY) + t16); -=C2=A0=C2=A0 =C2=A0} - -trace_attribute_table: +=C2=A0=C2=A0 =C2=A0if (rst->attr_names_len && oatbl) { +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0struct ATTR_NAME_ENTRY *ane =3D attr= _names; +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0while (ane->off) { +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0/* TODO: Clear ta= ble on exit! */ +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0oe =3D Add2Ptr(oa= tbl, le16_to_cpu(ane->off)); +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0t16 =3D le16_to_c= pu(ane->name_bytes); +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0oe->name_len =3D = t16 / sizeof(short); +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0oe->ptr =3D ane->= name; +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0oe->is_attr_name = =3D 2; +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0ane =3D Add2Ptr(a= ne, +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 sizeof(struct ATTR_NAME_ENTRY) + t16); +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0} +=C2=A0=C2=A0 =C2=A0} + =C2=A0=C2=A0=C2=A0 =C2=A0/* =C2=A0=C2=A0=C2=A0 =C2=A0 * If the checkpt_lsn is zero, then this is a fre= shly =C2=A0=C2=A0=C2=A0 =C2=A0 * formatted disk and we have no work to do. @@ -5189,7 +5167,7 @@ int log_replay(struct ntfs_inode *ni, bool=20 *initialized) =C2=A0=C2=A0=C2=A0 =C2=A0kfree(oatbl); =C2=A0=C2=A0=C2=A0 =C2=A0kfree(dptbl); =C2=A0=C2=A0=C2=A0 =C2=A0kfree(attr_names); -=C2=A0=C2=A0 =C2=A0kfree(rst_info.r_page); +=C2=A0=C2=A0 =C2=A0kfree(log->rst_info.r_page); =C2=A0=C2=A0=C2=A0 =C2=A0kfree(ra); =C2=A0=C2=A0=C2=A0 =C2=A0kfree(log->one_page_buf); --=20 2.34.1