From patchwork Mon Sep 25 05:29:47 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Yuezhang.Mo@sony.com" X-Patchwork-Id: 13397277 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 98E36CE7A81 for ; Mon, 25 Sep 2023 06:44:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231993AbjIYGoz (ORCPT ); Mon, 25 Sep 2023 02:44:55 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40638 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229537AbjIYGoy (ORCPT ); Mon, 25 Sep 2023 02:44:54 -0400 Received: from mx07-001d1705.pphosted.com (mx07-001d1705.pphosted.com [185.132.183.11]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 11823C5 for ; Sun, 24 Sep 2023 23:44:45 -0700 (PDT) Received: from pps.filterd (m0209327.ppops.net [127.0.0.1]) by mx08-001d1705.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 38P54CUk009680; Mon, 25 Sep 2023 05:29:52 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sony.com; h=from : to : cc : subject : date : message-id : mime-version : content-type : content-transfer-encoding; s=S1; bh=A02ScO0nTvJLh39dwJgDtOqiRHux9ggMFDZbAHODmtE=; b=hUi0OmX86AkxHrJKw4Dza/mU/LPkfVWyt1xvFNn0y3B92mM98dYFwRDXteMAZNRhdjXI CM8zfnLKjBKuP5MjC2U6cXLdeVbmQ3Q1zy9odzGBhczcgBDqW3dVPuRMlJ+/DV4/n/kv UUkpwduWPij6lcYGDrHzhIUBbotIplnHnr1kaA3txRKrDKcndyScAvw8atsFW0+KRBDo s3P/obsCmfzGIsZTYLQQALmP7jujGZKgDM0m44rp4mbEzQyRX2K9Er5JQsLDo+DBHXe1 qM/RS460beO4uu9W8Gx+NukHV34QIkxuyoZnnlYE/9FE3U5pZioQMtZUrcmIweH9zbDb fg== Received: from apc01-psa-obe.outbound.protection.outlook.com (mail-psaapc01lp2047.outbound.protection.outlook.com [104.47.26.47]) by mx08-001d1705.pphosted.com (PPS) with ESMTPS id 3t9pw3sfb8-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 25 Sep 2023 05:29:52 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=NcF4gBQ8O7KrxEQM5E3EdeV1CshvfSTfZ6sUVZ+67FL/woOfGPLA1lWmpXsCRWy5vglC+qVwv6QTcm1miusvbH/6f0X3LPeEeru5EWAHcDInu0ayh3v0DWoibcB+xdze9dOwgK3s6nrINfV0SUTpc4e01Q2MNZ7XSZV9q8Vs3CQRaRKDDYDYjTGJigS7uuIi/6B5LcRfI7IWqD2vEKcroNNSZ8ZwsRO1pzwMS+oPf4qwck9JtzwIrXly1G9Pqdvikt/WQGncFJ+srTyP6LwHF1C820gFf8nydnO6Z5ihqAMi0w2x5w96AMLWvWOzNzdjkZyBCJRF9PbEaOlXmsx2Dg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=A02ScO0nTvJLh39dwJgDtOqiRHux9ggMFDZbAHODmtE=; b=TmwHTwy6xGpcTPOsBslWma+joPE9pEczQS27HOdbL0m0kVpnpbrqheoQB+0qSQNi+kJfN5BAKOPbkgq+rHVghNLtjE8LLlEodBn8VxeKrGtuYDjuNO8H/Wnr8BYZojVQwl+HIs76F8Z3c8QfDgn7+ba3oKTSDUnVyFFxEbYaKUtlZ62nq6Y+YwMpwH5+5fONmwvU6ZX8+xIlH2/A5NGehYhP/B7QLPJwSL3WnCkBsUgpS1wI43SpKpbWe42DiCAIcpYcGBdS0goPJOh67/ZmoufUMaY2V/4asBZsIeAOOhdj04ZrcXLYty4nQmI2Q6O0i6eHqFI93hQWeftVShBnIQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=sony.com; dmarc=pass action=none header.from=sony.com; dkim=pass header.d=sony.com; arc=none Received: from PUZPR04MB6316.apcprd04.prod.outlook.com (2603:1096:301:fc::7) by TYSPR04MB7081.apcprd04.prod.outlook.com (2603:1096:400:47d::8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6813.28; Mon, 25 Sep 2023 05:29:48 +0000 Received: from PUZPR04MB6316.apcprd04.prod.outlook.com ([fe80::f9d4:e3c8:e9c0:1ad]) by PUZPR04MB6316.apcprd04.prod.outlook.com ([fe80::f9d4:e3c8:e9c0:1ad%6]) with mapi id 15.20.6813.027; Mon, 25 Sep 2023 05:29:48 +0000 From: "Yuezhang.Mo@sony.com" To: "linkinjeon@kernel.org" , "sj1557.seo@samsung.com" CC: "linux-fsdevel@vger.kernel.org" , "Andy.Wu@sony.com" , "Wataru.Aoyama@sony.com" Subject: [PATCH v3 1/2] exfat: change to get file size from DataLength Thread-Topic: [PATCH v3 1/2] exfat: change to get file size from DataLength Thread-Index: AdnvcJ5Hu5/6OJRdRTGqnNdIG/us0w== Date: Mon, 25 Sep 2023 05:29:47 +0000 Message-ID: Accept-Language: zh-CN, en-US Content-Language: zh-CN X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-publictraffictype: Email x-ms-traffictypediagnostic: PUZPR04MB6316:EE_|TYSPR04MB7081:EE_ x-ms-office365-filtering-correlation-id: b96c5941-c180-4dca-0420-08dbbd886f17 x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: QXo5Qvgmg5X0KpwnvpnKD4HilNzVZv9iciP9ZMilebnksxaWRZwm9iFqsJ8DmtYTtXUxNHbMAgs6uE4g5xTiHb5Rpb5GjpHMtwI45Up/5OUVVtn5yhPUWsqlx6vCkw68Of7AgHt962muxNXqVPtnOOF91jJguIn5iORdQM7VZ0GcffEplLkz+aKvqvNfHQs8natbIbC4u43ayzhdBbfKqZ6EE9B0zlE2NcnTwieptPo94abHlClXBchTK19V+j2KRahIgf5wM+CkH/4wtrpO7L2H9vFtVtmEjj4UkjGUbolAnTZYGfUz/wAi9YY+qbCnrCAr4Wz4pf6knHpLfTEhgo4lsN5iojhKEA/pOLrn24Xm2Sls/HqmWDGGo6dZKp6mpDUws0JjEeINhoHZ+Ae3PZtZ/OxgqQFEcp8gdzwGmV8Bv67eYeJXZy+69mM393hZkEH1aSRKtOmjD7ADF2/ZRvVdwCu/gtRTuXTjDYzyx7c70V7y8kR6T/GKChhWgOZBlleXxnA2cyJVjNncWhWmJvxJlyMzng4bvrct39kQcyA72n7rLTqhprQwyy3LqKsqPzxQ+hiaZDr1eTgcM7SlAG4yMnRkL8jSkgoMO7Wqtqfr5eE/D63kaVNy9mMj3jj3 x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:PUZPR04MB6316.apcprd04.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230031)(39860400002)(396003)(136003)(366004)(346002)(376002)(230922051799003)(186009)(451199024)(1800799009)(30864003)(8936002)(4326008)(5660300002)(8676002)(2906002)(52536014)(316002)(41300700001)(66446008)(64756008)(66556008)(55016003)(66476007)(54906003)(110136005)(66946007)(76116006)(26005)(107886003)(33656002)(9686003)(71200400001)(38100700002)(82960400001)(122000001)(38070700005)(86362001)(478600001)(83380400001)(6506007)(7696005);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?utf-8?q?vPSe1c0FOtV6J7xTStqjH0o+up1d?= =?utf-8?q?eN3/mTjzYnSlFbaJP1QP81CRy4o1AxteAmefINWBNDeOzzx76HtZJno8pkNzdUckS?= =?utf-8?q?6A2/FDAqrXVz7pkD9uVNP/IULx8ZNulABlk+t/LZwNAXaz85sxEtpzBQvZmF0EMlg?= =?utf-8?q?zJw2hwgIIH6y/VpRMaCUIrSb1tR7u3ZLKrQSD9r/Tqqqsi2rSOf5UP4Xo432WhpPS?= =?utf-8?q?Tk19wVTmprIXvcCUVmd0WClO3iiGYRVEQgBZ0EqjqxVUPqLiiakfWM9IbxKP2cN9a?= =?utf-8?q?djKZNdXZH9xU/WZVyFOpDm1DcvQhUMQMN/A1glb6TLaTMhwfIQcKyV8s4K5X1jCDz?= =?utf-8?q?ZQWRYJe5t0AVirR2TjWswJ3/X9GCfywRtL5unF/aDM7l6xSqcwRf4meqVFWqowEF1?= =?utf-8?q?l9/8ZMFtyao9+KQk19r9DfvSMHYmshEfkERBIsc/lCuwPh85Wl9sL+fa5tNyI59df?= =?utf-8?q?8DA9l1RZ7eRBRjRBLaKLiOZzkmLs5xmNeAHfbo66bt0/YmO17EeRoOWVJ1yIXXyLe?= =?utf-8?q?Y7lIE/0HDNfp/hyE6snhjVBGJ0WG80+0k8OnBF06vM1d+3K+tUBjKdGiVJmGfWacJ?= =?utf-8?q?C3SumwiffLmET9v3PERj2J327XD1CcPH7Je6MREh9Rx6NX3R4k/iS9makwqFpHWpc?= =?utf-8?q?8ivGQtawwcEIVmwZe5JF92LW0pkuFrgxv8RhpAAhohGwmWZpUuu9tSzmCf+zbuCEj?= =?utf-8?q?+ZyTNMGNZMGN0WkSxMDDoSfBZrzUejcL9QFDIZ6Rmeiuk4i6/XPk99tZcEWx4+5pD?= =?utf-8?q?vTU6brSvJLGW7o9ipNjKEZzo3jfNwy37HOzts5y6EpdL8QlItdr8Kl6RIwhWjqNLh?= =?utf-8?q?blXg7IW3PI0VT8EkQWBeDhP3TS58pTiv7PBiYyAdigNJ/L9xQ9F8XeUSxBmlLquL5?= =?utf-8?q?b/0DdnG9ANWIxphX1ypnKxhPlkpwq/l1pE4A7kFFAU9Ye8BeaY2R0mfjbJ3iJu2s8?= =?utf-8?q?11yjaefW0OHgDbFJDkNNcYBj+kYTbL1oOcyoklxXBuhcTpXTxVIewYsbmqrdP5MXd?= =?utf-8?q?QgoWxg3qphFCYIVRiIOkFROgchiYWcPxl2vQk/FcAgq8DmsOhlVTkiIXgaYv+pwz5?= =?utf-8?q?3/FZNpmtbgB0AhXOMt2NxsvaKTmAXJhkWEC8IXTrVMAbsAyB8mROUX1MB8a7Xakjp?= =?utf-8?q?CMXvLo6QMGQi2nGu31R+TzpFb2hcAwYRYTCBLXQ7MKDlDtQLYrKj/ftx5XTqdM/r8?= =?utf-8?q?jAkKGOnAYJV4YLZwyZovNGq4spiFfg8JWBED3IaMw23lSnZ3mDLsWI4W/9uGxJ+0I?= =?utf-8?q?nIHAc9dmR24QqYVN9zlK4Z/BsW+0u2pjuVugr3XwWiT1x/vPoA/c3cHaWkOpDSLO9?= =?utf-8?q?kj0ZGVkjUq6kuy7f14chCTkhSLyjeuFf8uuDyyL6DBMNLcViSZbAeTcARnQ1xDqE3?= =?utf-8?q?N/SKgp1mr1htvn+McuPAF32+gsf03iUU/6n8UXnq2bjP3bfRkh3ujeedmOSdAnsOC?= =?utf-8?q?gUzOf+22QGsASeaDA02kVSeUpMGH3AwCU75+jX3WxTLxCXrMATD6sWKYyJr3uKAkH?= =?utf-8?q?dttV6I9X41B8?= MIME-Version: 1.0 X-MS-Exchange-AntiSpam-ExternalHop-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-ExternalHop-MessageData-0: /Nvenpfg4dSJCzXY8CQoB76fwsn5Yh52jbCS8krbD1aVrwLXcPk1YQIq77bQuFecw49BC9XHJw9Rjp0kCZD4UjvhJ/pyZpg/1rkCao/VVBPz4oEzfIloliyK5yMMiHRWvl+0Vw2VjhNANd2xmNCmStUBXPfRXoabCUhKZTfv+kGqG/Ljc1ktMrICiti+JL4cH4Fnq7dEQ9pi1gyzsnLjyIDJpZerl3UmpvWuHL/hSwMtX09wf4k3MlPJ9iYYpYyadQTKco6dkSbDTvGyhLBCWCiBsNgAkXpLgTvH7Vw6epU07ySWGqtCWhM3VljSDryKuFGiJalJGKVhObT1Id8Zk21Kv2TVZhtttinI76SoB2quRicVDD6JhUam1skHaU0eDQfCEQHgorRhQMY6oACAPADi0H0QATCv4NpcNAOFrGLL3rjAY3tNvDNdCu3QaWSTkWavROE3yiTnyUsOu09cG7C9EHVsEvjrR5O5JzD5/7EL/X3X1EHuA5EAQV/Pv00PM92FpXtONB0Snly7DjWoVvCgEJibpmsURKn5feFtyD/IcNlF6YIe55tjHVqVE2NuxkGxZkNGYZmvs62fjPmSUHVPZR3Jvp6f4drme7Duc1QH8RyEX723buQ97O3dLZo5FcYMPqs+jAd2MJuzZV6gFG93Ny50jJLunUaMwA2Bsp1kDFoLZUZpi2DlN+E24HhtwAJIKjspu0S6OmR7BY5vFwWc9UDKK8IXHNEJG2ceQn/rEqjQkBWVQPJmdiYgPC1v8IfOmFUmEqfpgElyGwGMEUhVmEa4V8HcuoDzeivq7t3oJe1hsuHvOch5cYeAbzD69Su0qvc0RluWqhWVDveaug== X-OriginatorOrg: sony.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: PUZPR04MB6316.apcprd04.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: b96c5941-c180-4dca-0420-08dbbd886f17 X-MS-Exchange-CrossTenant-originalarrivaltime: 25 Sep 2023 05:29:47.9393 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 66c65d8a-9158-4521-a2d8-664963db48e4 X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: 0Vbom3w/OAxu6aI3V2gDsLwKCYVtD1mC9nHE7QwvsZfrWu0eQYoUXTPRgJQdYjs27NVUnygamXa02ykb2xab2w== X-MS-Exchange-Transport-CrossTenantHeadersStamped: TYSPR04MB7081 X-Proofpoint-GUID: UAXq9L_wbxTIKT-3sdQ3S4UiliaHgjwL X-Proofpoint-ORIG-GUID: UAXq9L_wbxTIKT-3sdQ3S4UiliaHgjwL X-Sony-Outbound-GUID: UAXq9L_wbxTIKT-3sdQ3S4UiliaHgjwL X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.267,Aquarius:18.0.980,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2023-09-25_03,2023-09-21_01,2023-05-22_02 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org In stream extension directory entry, the ValidDataLength field describes how far into the data stream user data has been written, and the DataLength field describes the file size. Signed-off-by: Yuezhang Mo Reviewed-by: Andy Wu Reviewed-by: Aoyama Wataru --- fs/exfat/exfat_fs.h | 4 ++ fs/exfat/file.c | 123 +++++++++++++++++++++++++++++++++++++++++++- fs/exfat/inode.c | 94 +++++++++++++++++++++++++++------ fs/exfat/namei.c | 6 +++ 4 files changed, 210 insertions(+), 17 deletions(-) diff --git a/fs/exfat/exfat_fs.h b/fs/exfat/exfat_fs.h index 219b1cf9d041..041a5d0f51de 100644 --- a/fs/exfat/exfat_fs.h +++ b/fs/exfat/exfat_fs.h @@ -214,6 +214,7 @@ struct exfat_dir_entry { unsigned char flags; unsigned short attr; loff_t size; + loff_t valid_size; unsigned int num_subdirs; struct timespec64 atime; struct timespec64 mtime; @@ -323,6 +324,7 @@ struct exfat_inode_info { loff_t i_size_aligned; /* on-disk position of directory entry or 0 */ loff_t i_pos; + loff_t valid_size; /* hash by i_location */ struct hlist_node i_hash_fat; /* protect bmap against truncate */ @@ -521,6 +523,8 @@ int __exfat_write_inode(struct inode *inode, int sync); int exfat_write_inode(struct inode *inode, struct writeback_control *wbc); void exfat_evict_inode(struct inode *inode); int exfat_block_truncate_page(struct inode *inode, loff_t from); +int exfat_get_block(struct inode *inode, sector_t iblock, + struct buffer_head *bh_result, int create); /* exfat/nls.c */ unsigned short exfat_toupper(struct super_block *sb, unsigned short a); diff --git a/fs/exfat/file.c b/fs/exfat/file.c index f47620eef71b..8e45e782faff 100644 --- a/fs/exfat/file.c +++ b/fs/exfat/file.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "exfat_raw.h" #include "exfat_fs.h" @@ -25,6 +26,7 @@ static int exfat_cont_expand(struct inode *inode, loff_t size) return err; inode->i_mtime = inode_set_ctime_current(inode); + EXFAT_I(inode)->valid_size = size; mark_inode_dirty(inode); if (!IS_SYNC(inode)) @@ -145,6 +147,9 @@ int __exfat_truncate(struct inode *inode) ei->start_clu = EXFAT_EOF_CLUSTER; } + if (i_size_read(inode) < ei->valid_size) + ei->valid_size = i_size_read(inode); + if (ei->type == TYPE_FILE) ei->attr |= ATTR_ARCHIVE; @@ -472,15 +477,129 @@ int exfat_file_fsync(struct file *filp, loff_t start, loff_t end, int datasync) return blkdev_issue_flush(inode->i_sb->s_bdev); } +static int exfat_file_zeroed_range(struct file *file, loff_t start, loff_t end) +{ + int err; + struct inode *inode = file_inode(file); + struct exfat_inode_info *ei = EXFAT_I(inode); + struct address_space *mapping = inode->i_mapping; + const struct address_space_operations *ops = mapping->a_ops; + + while (start < end) { + u32 zerofrom, len; + struct page *page = NULL; + + zerofrom = start & (PAGE_SIZE - 1); + len = PAGE_SIZE - zerofrom; + if (start + len > end) + len = end - start; + + err = block_write_begin(mapping, start, len, &page, + exfat_get_block); + if (err) + goto out; + + zero_user_segment(page, zerofrom, zerofrom + len); + + err = ops->write_end(file, mapping, start, len, len, page, NULL); + if (err < 0) + goto out; + start += len; + + balance_dirty_pages_ratelimited(mapping); + cond_resched(); + } + + ei->valid_size = end; + mark_inode_dirty(inode); + +out: + return err; +} + +static ssize_t exfat_file_write_iter(struct kiocb *iocb, struct iov_iter *iter) +{ + ssize_t ret; + struct file *file = iocb->ki_filp; + struct inode *inode = file_inode(file); + struct exfat_inode_info *ei = EXFAT_I(inode); + loff_t pos = iocb->ki_pos; + loff_t valid_size; + + inode_lock(inode); + + valid_size = ei->valid_size; + + ret = generic_write_checks(iocb, iter); + if (ret < 0) + goto unlock; + + if (pos > valid_size) { + ret = exfat_file_zeroed_range(file, valid_size, pos); + if (ret < 0 && ret != -ENOSPC) { + exfat_err(inode->i_sb, + "write: fail to zero from %llu to %llu(%ld)", + valid_size, pos, ret); + } + if (ret < 0) + goto unlock; + } + + ret = __generic_file_write_iter(iocb, iter); + if (ret < 0) + goto unlock; + + inode_unlock(inode); + + if (pos > valid_size && iocb_is_dsync(iocb)) { + ssize_t err = vfs_fsync_range(file, valid_size, pos - 1, + iocb->ki_flags & IOCB_SYNC); + if (err < 0) + return err; + } + + if (ret) + ret = generic_write_sync(iocb, ret); + + return ret; + +unlock: + inode_unlock(inode); + + return ret; +} + +static int exfat_file_mmap(struct file *file, struct vm_area_struct *vma) +{ + int ret; + struct inode *inode = file_inode(file); + struct exfat_inode_info *ei = EXFAT_I(inode); + loff_t start = ((loff_t)vma->vm_pgoff << PAGE_SHIFT); + loff_t end = min_t(loff_t, i_size_read(inode), + start + vma->vm_end - vma->vm_start); + + if ((vma->vm_flags & VM_WRITE) && ei->valid_size < end) { + ret = exfat_file_zeroed_range(file, ei->valid_size, end); + if (ret < 0) { + exfat_err(inode->i_sb, + "mmap: fail to zero from %llu to %llu(%d)", + start, end, ret); + return ret; + } + } + + return generic_file_mmap(file, vma); +} + const struct file_operations exfat_file_operations = { .llseek = generic_file_llseek, .read_iter = generic_file_read_iter, - .write_iter = generic_file_write_iter, + .write_iter = exfat_file_write_iter, .unlocked_ioctl = exfat_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = exfat_compat_ioctl, #endif - .mmap = generic_file_mmap, + .mmap = exfat_file_mmap, .fsync = exfat_file_fsync, .splice_read = filemap_splice_read, .splice_write = iter_file_splice_write, diff --git a/fs/exfat/inode.c b/fs/exfat/inode.c index 13329baeafbc..fb8c17996b35 100644 --- a/fs/exfat/inode.c +++ b/fs/exfat/inode.c @@ -72,8 +72,7 @@ int __exfat_write_inode(struct inode *inode, int sync) if (ei->start_clu == EXFAT_EOF_CLUSTER) on_disk_size = 0; - ep2->dentry.stream.valid_size = cpu_to_le64(on_disk_size); - ep2->dentry.stream.size = ep2->dentry.stream.valid_size; + ep2->dentry.stream.size = cpu_to_le64(on_disk_size); if (on_disk_size) { ep2->dentry.stream.flags = ei->flags; ep2->dentry.stream.start_clu = cpu_to_le32(ei->start_clu); @@ -82,6 +81,8 @@ int __exfat_write_inode(struct inode *inode, int sync) ep2->dentry.stream.start_clu = EXFAT_FREE_CLUSTER; } + ep2->dentry.stream.valid_size = cpu_to_le64(ei->valid_size); + exfat_update_dir_chksum_with_entry_set(&es); return exfat_put_dentry_set(&es, sync); } @@ -263,7 +264,7 @@ static int exfat_map_new_buffer(struct exfat_inode_info *ei, return 0; } -static int exfat_get_block(struct inode *inode, sector_t iblock, +int exfat_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create) { struct exfat_inode_info *ei = EXFAT_I(inode); @@ -303,17 +304,25 @@ static int exfat_get_block(struct inode *inode, sector_t iblock, mapped_blocks = sbi->sect_per_clus - sec_offset; max_blocks = min(mapped_blocks, max_blocks); - /* Treat newly added block / cluster */ - if (iblock < last_block) - create = 0; - - if (create || buffer_delay(bh_result)) { - pos = EXFAT_BLK_TO_B((iblock + 1), sb); + pos = EXFAT_BLK_TO_B((iblock + 1), sb); + if ((create && iblock >= last_block) || buffer_delay(bh_result)) { if (ei->i_size_ondisk < pos) ei->i_size_ondisk = pos; } + map_bh(bh_result, sb, phys); + if (buffer_delay(bh_result)) + clear_buffer_delay(bh_result); + if (create) { + sector_t valid_blks; + + valid_blks = EXFAT_B_TO_BLK_ROUND_UP(ei->valid_size, sb); + if (iblock < valid_blks && iblock + max_blocks >= valid_blks) { + max_blocks = valid_blks - iblock; + goto done; + } + err = exfat_map_new_buffer(ei, bh_result, pos); if (err) { exfat_fs_error(sb, @@ -321,11 +330,35 @@ static int exfat_get_block(struct inode *inode, sector_t iblock, pos, ei->i_size_aligned); goto unlock_ret; } + } else { + size_t b_size = EXFAT_BLK_TO_B(max_blocks, sb); + + pos -= sb->s_blocksize; + if (pos >= ei->valid_size) { + /* Read out of valid data */ + clear_buffer_mapped(bh_result); + } else if (pos + b_size <= ei->valid_size) { + /* Normal read */ + } else if (pos + sb->s_blocksize <= ei->valid_size) { + /* Normal short read */ + max_blocks = 1; + } else { + /* Read across valid size */ + if (bh_result->b_folio) { + loff_t size = ei->valid_size - pos; + loff_t off = pos & (PAGE_SIZE - 1); + + folio_set_bh(bh_result, bh_result->b_folio, off); + err = bh_read(bh_result, 0); + if (err < 0) + goto unlock_ret; + + folio_zero_segment(bh_result->b_folio, off + size, + off + sb->s_blocksize); + } + max_blocks = 1; + } } - - if (buffer_delay(bh_result)) - clear_buffer_delay(bh_result); - map_bh(bh_result, sb, phys); done: bh_result->b_size = EXFAT_BLK_TO_B(max_blocks, sb); unlock_ret: @@ -340,6 +373,17 @@ static int exfat_read_folio(struct file *file, struct folio *folio) static void exfat_readahead(struct readahead_control *rac) { + struct address_space *mapping = rac->mapping; + struct inode *inode = mapping->host; + struct exfat_inode_info *ei = EXFAT_I(inode); + loff_t pos = readahead_pos(rac); + + /* Range cross valid_size, read it page by page. */ + if (ei->valid_size < i_size_read(inode) && + pos <= ei->valid_size && + ei->valid_size < pos + readahead_length(rac)) + return; + mpage_readahead(rac, exfat_get_block); } @@ -397,6 +441,11 @@ static int exfat_write_end(struct file *file, struct address_space *mapping, if (err < len) exfat_write_failed(mapping, pos+len); + if (!(err < 0) && pos + err > ei->valid_size) { + ei->valid_size = pos + err; + mark_inode_dirty(inode); + } + if (!(err < 0) && !(ei->attr & ATTR_ARCHIVE)) { inode->i_mtime = inode_set_ctime_current(inode); ei->attr |= ATTR_ARCHIVE; @@ -410,6 +459,8 @@ static ssize_t exfat_direct_IO(struct kiocb *iocb, struct iov_iter *iter) { struct address_space *mapping = iocb->ki_filp->f_mapping; struct inode *inode = mapping->host; + struct exfat_inode_info *ei = EXFAT_I(inode); + loff_t pos = iocb->ki_pos; loff_t size = iocb->ki_pos + iov_iter_count(iter); int rw = iov_iter_rw(iter); ssize_t ret; @@ -433,8 +484,20 @@ static ssize_t exfat_direct_IO(struct kiocb *iocb, struct iov_iter *iter) * condition of exfat_get_block() and ->truncate(). */ ret = blockdev_direct_IO(iocb, inode, iter, exfat_get_block); - if (ret < 0 && (rw & WRITE)) - exfat_write_failed(mapping, size); + if (ret < 0) { + if (rw & WRITE) + exfat_write_failed(mapping, size); + + if (ret != -EIOCBQUEUED) + return ret; + } else + size = pos + ret; + + if ((rw & READ) && pos < ei->valid_size && ei->valid_size < size) { + iov_iter_revert(iter, size - ei->valid_size); + iov_iter_zero(size - ei->valid_size, iter); + } + return ret; } @@ -534,6 +597,7 @@ static int exfat_fill_inode(struct inode *inode, struct exfat_dir_entry *info) ei->start_clu = info->start_clu; ei->flags = info->flags; ei->type = info->type; + ei->valid_size = info->valid_size; ei->version = 0; ei->hint_stat.eidx = 0; diff --git a/fs/exfat/namei.c b/fs/exfat/namei.c index 1e1ffda279cf..0c121f2ceaf5 100644 --- a/fs/exfat/namei.c +++ b/fs/exfat/namei.c @@ -406,6 +406,7 @@ static int exfat_find_empty_entry(struct inode *inode, i_size_write(inode, size); ei->i_size_ondisk += sbi->cluster_size; ei->i_size_aligned += sbi->cluster_size; + ei->valid_size += sbi->cluster_size; ei->flags = p_dir->flags; inode->i_blocks += sbi->cluster_size >> 9; } @@ -558,6 +559,8 @@ static int exfat_add_entry(struct inode *inode, const char *path, info->size = clu_size; info->num_subdirs = EXFAT_MIN_SUBDIR; } + info->valid_size = info->size; + memset(&info->crtime, 0, sizeof(info->crtime)); memset(&info->mtime, 0, sizeof(info->mtime)); memset(&info->atime, 0, sizeof(info->atime)); @@ -659,6 +662,8 @@ static int exfat_find(struct inode *dir, struct qstr *qname, info->type = exfat_get_entry_type(ep); info->attr = le16_to_cpu(ep->dentry.file.attr); info->size = le64_to_cpu(ep2->dentry.stream.valid_size); + info->valid_size = le64_to_cpu(ep2->dentry.stream.valid_size); + info->size = le64_to_cpu(ep2->dentry.stream.size); if (info->size == 0) { info->flags = ALLOC_NO_FAT_CHAIN; info->start_clu = EXFAT_EOF_CLUSTER; @@ -1287,6 +1292,7 @@ static int __exfat_rename(struct inode *old_parent_inode, } i_size_write(new_inode, 0); + new_ei->valid_size = 0; new_ei->start_clu = EXFAT_EOF_CLUSTER; new_ei->flags = ALLOC_NO_FAT_CHAIN; } From patchwork Mon Sep 25 05:29:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Yuezhang.Mo@sony.com" X-Patchwork-Id: 13397270 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 4159CCE7A81 for ; Mon, 25 Sep 2023 06:09:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229568AbjIYGJq (ORCPT ); Mon, 25 Sep 2023 02:09:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39300 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229511AbjIYGJp (ORCPT ); Mon, 25 Sep 2023 02:09:45 -0400 Received: from mx07-001d1705.pphosted.com (mx07-001d1705.pphosted.com [185.132.183.11]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 410A9C6 for ; Sun, 24 Sep 2023 23:09:39 -0700 (PDT) Received: from pps.filterd (m0209324.ppops.net [127.0.0.1]) by mx08-001d1705.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 38P4Aqww031121; Mon, 25 Sep 2023 05:29:57 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sony.com; h=from : to : cc : subject : date : message-id : mime-version : content-type : content-transfer-encoding; s=S1; bh=BU3AhuHw8m2VM06hpVFYbLasQYj1qqyB4L0hNgyJyXI=; b=Pf9Vv+EwmjxKdcU6GtMFn4cjh6LOCfcLL6+VU2RujH9E/+7ePy0HEdHisYSDBYrf3P9u H8/RojHaCSQmgQpsK2b8oh3sXwGZgCulwvmzG0ZzVqZlsvILzMaFdQzoBiudM0h/vTjt 5Ed5Ybw0pxVcKvMDo6Hd/62c2q9P9qBfuzjvndMaFSbNhQ3vhCYrCKkNf0bq9T/ZSDAP 3Tn7T56f5psiM7dbKgzt1G1JLjBDkb/5t4puMCg8zVQ7o698BWcMtMPl4AhD6GyYgAq3 zh/fUvoGJMZDx0aE+yg1+zFVTqw6IJ2+2AJOjnU86SMN5OCdR908wzFFILoHYR1JVmbV qw== Received: from apc01-psa-obe.outbound.protection.outlook.com (mail-psaapc01lp2045.outbound.protection.outlook.com [104.47.26.45]) by mx08-001d1705.pphosted.com (PPS) with ESMTPS id 3t9n669hcr-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 25 Sep 2023 05:29:57 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Q2t9BuKReXdN8d+fV4AyD7EcvHpdDbBerODJLGE/2ng+5kdZFXt5YiNfwWF2Ay/9Vx/QKiaVf7fH/H8U/k2ujfvyOof61s0FPw+6gwg29AGIlmG9IMjWw1yhOBiio8vuuoxWCNgz1WN8SZN8VNuUhQkKLvmyzovI/bIbHWaeX1C9Ltxg8nxuRlVEjBnZEUApXVzxpMeDtYjtmDBwXQk0wmnsJ81mwqMIe2WzpKjWzj6azKvM/LbsUL/RsZrCVNpYhril6RH+91lpE14WXeBc+8MYLVqKRoxwVCauJKV6UchfU3+FhZd+mPTORG2HcQ1j3dhhxOE/dhjWxvUi0Z+/iQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=BU3AhuHw8m2VM06hpVFYbLasQYj1qqyB4L0hNgyJyXI=; b=JM7l1DmaPuTaQyF58VexzrLQYvNCdRhdW2fwIKa7+g6MFxBQq2iHatbzRxRDpculfzXI1rXC8ipFsrNKGV9ooVXM269AC5daowrOzm7xEcL7OOyUHYl60CYqeFyHVZY2T6bL5de2SAS6jhQkwRJdE87hefVg4LXcyjX9sdc7Ua42jJoPy3gRfItNmbPE6PY/ZoIMPzK1QVs3jOm5DZoALHYr7MDwcGKsU5TV0WodToTg1HgGHn2267/1c5uZ8ffmUpa5qMA3VofsHkU7jKkaZeWvuvCk4S7JU9RcJcuq/VSgT4uagdBcqHJ7Pc4tp/8AWqKo6Z09Ff/SeF3TVVuaJA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=sony.com; dmarc=pass action=none header.from=sony.com; dkim=pass header.d=sony.com; arc=none Received: from PUZPR04MB6316.apcprd04.prod.outlook.com (2603:1096:301:fc::7) by TYSPR04MB7081.apcprd04.prod.outlook.com (2603:1096:400:47d::8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6813.28; Mon, 25 Sep 2023 05:29:51 +0000 Received: from PUZPR04MB6316.apcprd04.prod.outlook.com ([fe80::f9d4:e3c8:e9c0:1ad]) by PUZPR04MB6316.apcprd04.prod.outlook.com ([fe80::f9d4:e3c8:e9c0:1ad%6]) with mapi id 15.20.6813.027; Mon, 25 Sep 2023 05:29:51 +0000 From: "Yuezhang.Mo@sony.com" To: "linkinjeon@kernel.org" , "sj1557.seo@samsung.com" CC: "linux-fsdevel@vger.kernel.org" , "Andy.Wu@sony.com" , "Wataru.Aoyama@sony.com" Subject: [PATCH v3 2/2] exfat: do not zeroed the extended part Thread-Topic: [PATCH v3 2/2] exfat: do not zeroed the extended part Thread-Index: AdnvcNO4U5DLWxY2QtuDuNbPCCrffQ== Date: Mon, 25 Sep 2023 05:29:51 +0000 Message-ID: Accept-Language: zh-CN, en-US Content-Language: zh-CN X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-publictraffictype: Email x-ms-traffictypediagnostic: PUZPR04MB6316:EE_|TYSPR04MB7081:EE_ x-ms-office365-filtering-correlation-id: c0f3caa9-2c8c-4e6a-1ea8-08dbbd887134 x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: GWBErNzrHeraK48ol12iDJbanv5/9UHFSMKnXHPHvQsAv3qEe/1vQxY6d6wL1pHFpkZ+VapSXfl7DI4HsWK2uD9vNyXF7C4ev5Tgli9DyUSog4NDRo8TAJ4edlRmLlczh0VHSbqUnhHGTVRdDQENiAdxQ9zG/L4NxDhc0GtL+8tFQ7xG3mhuPdrQcKqHxxs7drC7Ra3IwY8J0jhYF0QSYhczcH0QzifExswpoC9zRPfipqLaZ/5MbY6N97tfaolH/Nvg+/uqQ94Rbm6N6Sy/nGVrpxwePS+l6ftXHQbYcKjfb6DzH7FlV0R6JkC0s3fe+IoU4nr3u0FUF0IETi0iwHOZKCsiqVscAqmktrlhAdiQQL+vsOy8ULYsWG/jQZJbGfryn0M4GBS5ArVVrU0DNqJYgeGuQCrYN8SuZyuQny8Gn4B1lqeO7vb8HUQUYvWmb3QgclDUR0ofxKIyLYVCJGimKuS1Qw2IDi1v0Jw7EpXAwNzHpR6xUJEGNU5biBPsjP67Brg5lR52Z25RKDmhVRuyWmcAZPNMPTa4jFvY0afoofMg/CGDS7hnWcHYNogkrq5gaINOuDFa2NOaYvcOa0OWVyTEyU2loEGKUMvwFciIM9gfRyegInnoJRlNKKWB x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:PUZPR04MB6316.apcprd04.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230031)(39860400002)(396003)(136003)(366004)(346002)(376002)(230922051799003)(186009)(451199024)(1800799009)(8936002)(4326008)(5660300002)(8676002)(2906002)(52536014)(316002)(41300700001)(66446008)(64756008)(66556008)(55016003)(66476007)(54906003)(110136005)(66946007)(76116006)(26005)(107886003)(33656002)(9686003)(71200400001)(38100700002)(82960400001)(122000001)(38070700005)(86362001)(478600001)(83380400001)(6506007)(7696005);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?utf-8?q?9EYqzZOwfOMXHYeiaLkuZy/tZMXd?= =?utf-8?q?Rhz306x+FDXzpCuOjbLIknALNvGAJ2oFmutOLtrJMhOh0A2rmCK3cSsTbXEZybbMr?= =?utf-8?q?KJ1kbzJwaAC1JpMmFtx3ds9kokipZnmLe3l68GwPmZ2z6iwsx/jEGBaSf0x1VUMaQ?= =?utf-8?q?w3viBpDll5aDZPtf/eHKIc0DohQ1d+LYgs0YHz45aVIZyHFIOgqTOPL71WpAEnyZp?= =?utf-8?q?byKzRzBBqEa/OqBwko/xP2EvgqekIvz842nF9cym6zziGCwtH5g8qgbm0FuIQs2nP?= =?utf-8?q?L5oPyiF0lxC0mTCaEMm1y+8/esEheJ9T0pYBIYbNaCDjdJx6na4mqOUJfojL3tf7h?= =?utf-8?q?ydU+Tz2asIpQVMHSqI2+OOo3pXWBg7MTC4EvhpLDBBEc9kVm3ZzG4A7Y2tJ1P/yZa?= =?utf-8?q?RxOvo5hM3tYrcKOCSghklwx8IicJ1oaGosb6w3APIexhtovuMVuvoLbET95fq9tbQ?= =?utf-8?q?2d6pjSUqd+v1Cq92mkyRVV+8T8o3P9WpUhR4+7wk/UEXZwGauXBrZNWOaw/8LjC2H?= =?utf-8?q?I+N7XWfRXCdGVkT13coTipCTuOYBm6e2hb5YvfL79RwHByuhfdn1BhTES55oGFkGA?= =?utf-8?q?Gy8AQ8CyhT4Ebpz+pNJoxYHKXJAyJMnjWHhUwd5TFJvDTO4xOs08JAlegXKDZmqx6?= =?utf-8?q?A3FbZpyM0O60TzI+va9H+U2Yvegj1r4VEP+C79sk64j5l8HiawrlFrx0pa2uVFVCw?= =?utf-8?q?fVmMnq6M2xnAh70yJ+Qp/bTn0AM3wufYp8tfpajsPDs6WWf42/V/qvNHIJQjBMas9?= =?utf-8?q?6EoJLhAYKbiR43CIQ1yBCrWJRU6IUoHY6F6057ThriaGh4yzf6lnt3OvSM4ykjY4l?= =?utf-8?q?okhKjX6Iq/ajgpPCymg6S2tJpoLDP6FEmXnUeAu3XiyHlqq4IjBFHF/T1uyu6lxAe?= =?utf-8?q?sV8iFAGTFRYhDTVobfVomGOjJy3wKU4AAmFshO9lhGh+jdPw/DnZ7vXQ7ravz+7vG?= =?utf-8?q?7+Mvf8dHUa1QIv+B42HVO+li/DOo6JiGHj1rL+HBrj8ffP3gAFObQ9ljVYPdtW0Hs?= =?utf-8?q?P03736TessIFEMPff+FcRRoM6Dslqb1JLyUTLna37MF+AfQXEGyPywrC7RRv+U4EV?= =?utf-8?q?BRdNxotoiubuJBREBmWgu4yQZvYJknxwkr7GC+HmUvGLbYK2qStQur3+R1DE75E0F?= =?utf-8?q?kRJiEOcJ6JWj7tiuMtlsNDOJfckBCsgbjxpgdP0XCdQDzPf4cZ+oGkV3qZRXoqKn3?= =?utf-8?q?p9jjSaMCx9Najv4Ec3wujzq5ytdvCZt4mQkeDtB+jJLoAbXNOpoacVG2jpPk2Brsz?= =?utf-8?q?J0jdJhZS2LEdFIbQtW5GZLCk1xdHpvAwuOG6PaN7IIem7bnjoatE33UIWBSkQka1T?= =?utf-8?q?aoyNtzoNFuUEHFR86Y5a+v7IjiexmrVH6W1d3PsH/4PVvu6mCH0rELYcs03OFZ80s?= =?utf-8?q?cgNCiTush6cIZvUNeghw/8aF5CzAUTlEGEA6RylBfxxy6vKw3icxpdZdXxQ4zcqlk?= =?utf-8?q?Kn+sPAYBCaGLlVwv23kWlqRsvT5LhBGkgx0XV+doqb5PDEj0VrMa9kGc2jTcbBSP6?= =?utf-8?q?cJRtRaDDFm+f?= MIME-Version: 1.0 X-MS-Exchange-AntiSpam-ExternalHop-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-ExternalHop-MessageData-0: OYMOyfv+o5yaCDSPK2PLScAY6ah3YrELSYZ1ejXjwX+Cm1HF+bpvOmuIvt/haC87xhbYMerZo9oOIee7qWicoUdWt8aVXZJHGmyEseagntFLlFt1AbyXDqMkMzyLK71vZoVt/9yUYpd+yeHbUWnrfHrna4VhbcNUA3ExT4ap1u1qibIR6GM5XHf5E2b9ZnlWenGBICLVKT3El/f1E3M31BlmWJWKRqwoIhWwHzOi1DAsOTMFS4IV0QBn1RiRGCARaTEj0fOEE0V3MlVvQJRNISNK+J5Fml51EeLNWp1HjvR9ZwZIyFb3MqgtfFrBxwNYVpcqVaJAu8cR6jddLbuLlD86+GZ6avx1Xpy2Ne5XAUmlEdKct+uXOdIF4UFsSjew6xH37Vm0Zg6Bq6Zm31WeGE4QbhHCfesNuC4LZp+w7FheP93T7YM6a9qyTaxlZ18PgnffrBpAlgh3U3ftoQOY67+CLeE0sE8TsutijLLW29WNfEth7bcOuqsnFsx3J4BSVn+amyj1D2WvBDOF2mLiZi6zLoGFcld8vy27hSsNG61nGhG/AaGVApEzfaL0tVB6zeLNmKCSIUeG17xOr6HioPmnPtYbaoMTP23jERHaDHbtw+c5GlFkGNZaYvDGjaNprF+aIe8W1LotkUybAGOeq72OqDuVtMR9g6Ii+GNE6N31ZnRujJ5RgzeHu723HPgkINc83oLa6OvRVTGRMCuf1388PoPI14iW9YYn84hJCoTrbYvObMlPsFViSOg9w60KcSrrtkuha8Wxv4UztqJQeiijc7HawpVIA987GgJaZsTCcuNpfwAiTi1u1aOCPt9I9RhQ5rdwf9uJupqT9hf+ew== X-OriginatorOrg: sony.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: PUZPR04MB6316.apcprd04.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: c0f3caa9-2c8c-4e6a-1ea8-08dbbd887134 X-MS-Exchange-CrossTenant-originalarrivaltime: 25 Sep 2023 05:29:51.5317 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 66c65d8a-9158-4521-a2d8-664963db48e4 X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: W7eSPV0zz9SQspJ1F4Ee36ldIhHNxw2zOLAGymmj0aoL2HGu196UMI6B/17ByUmWVEOwGtUdykvCHcWCSWysdA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: TYSPR04MB7081 X-Proofpoint-ORIG-GUID: rTImMq_AvDZ7WHA-p9FWQhGdGJ53V0js X-Proofpoint-GUID: rTImMq_AvDZ7WHA-p9FWQhGdGJ53V0js X-Sony-Outbound-GUID: rTImMq_AvDZ7WHA-p9FWQhGdGJ53V0js X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.267,Aquarius:18.0.980,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2023-09-25_03,2023-09-21_01,2023-05-22_02 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Since the read operation beyond the ValidDataLength returns zero, if we just extend the size of the file, we don't need to zero the extended part, but only change the DataLength without changing the ValidDataLength. Signed-off-by: Yuezhang Mo Reviewed-by: Andy Wu Reviewed-by: Aoyama Wataru --- fs/exfat/file.c | 77 +++++++++++++++++++++++++++++++++++------------- fs/exfat/inode.c | 16 +++++++++- 2 files changed, 72 insertions(+), 21 deletions(-) diff --git a/fs/exfat/file.c b/fs/exfat/file.c index 8e45e782faff..390fef888df5 100644 --- a/fs/exfat/file.c +++ b/fs/exfat/file.c @@ -17,32 +17,69 @@ static int exfat_cont_expand(struct inode *inode, loff_t size) { - struct address_space *mapping = inode->i_mapping; - loff_t start = i_size_read(inode), count = size - i_size_read(inode); - int err, err2; + int ret; + unsigned int num_clusters, new_num_clusters, last_clu; + struct exfat_inode_info *ei = EXFAT_I(inode); + struct super_block *sb = inode->i_sb; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + struct exfat_chain clu; - err = generic_cont_expand_simple(inode, size); - if (err) - return err; + ret = inode_newsize_ok(inode, size); + if (ret) + return ret; + + num_clusters = EXFAT_B_TO_CLU_ROUND_UP(i_size_read(inode), sbi); + new_num_clusters = EXFAT_B_TO_CLU_ROUND_UP(size, sbi); + + if (new_num_clusters == num_clusters) + goto out; + + exfat_chain_set(&clu, ei->start_clu, num_clusters, ei->flags); + ret = exfat_find_last_cluster(sb, &clu, &last_clu); + if (ret) + return ret; + clu.dir = (last_clu == EXFAT_EOF_CLUSTER) ? + EXFAT_EOF_CLUSTER : last_clu + 1; + clu.size = 0; + clu.flags = ei->flags; + + ret = exfat_alloc_cluster(inode, new_num_clusters - num_clusters, + &clu, IS_DIRSYNC(inode)); + if (ret) + return ret; + + /* Append new clusters to chain */ + if (clu.flags != ei->flags) { + exfat_chain_cont_cluster(sb, ei->start_clu, num_clusters); + ei->flags = ALLOC_FAT_CHAIN; + } + if (clu.flags == ALLOC_FAT_CHAIN) + if (exfat_ent_set(sb, last_clu, clu.dir)) + goto free_clu; + + if (num_clusters == 0) + ei->start_clu = clu.dir; + +out: inode->i_mtime = inode_set_ctime_current(inode); - EXFAT_I(inode)->valid_size = size; - mark_inode_dirty(inode); + /* Expanded range not zeroed, do not update valid_size */ + i_size_write(inode, size); - if (!IS_SYNC(inode)) - return 0; + ei->i_size_aligned = round_up(size, sb->s_blocksize); + ei->i_size_ondisk = ei->i_size_aligned; + inode->i_blocks = round_up(size, sbi->cluster_size) >> 9; - err = filemap_fdatawrite_range(mapping, start, start + count - 1); - err2 = sync_mapping_buffers(mapping); - if (!err) - err = err2; - err2 = write_inode_now(inode, 1); - if (!err) - err = err2; - if (err) - return err; + if (IS_DIRSYNC(inode)) + return write_inode_now(inode, 1); + + mark_inode_dirty(inode); + + return 0; - return filemap_fdatawait_range(mapping, start, start + count - 1); +free_clu: + exfat_free_cluster(inode, &clu); + return -EIO; } static bool exfat_allow_set_time(struct exfat_sb_info *sbi, struct inode *inode) diff --git a/fs/exfat/inode.c b/fs/exfat/inode.c index fb8c17996b35..aba4d9ec9d52 100644 --- a/fs/exfat/inode.c +++ b/fs/exfat/inode.c @@ -81,7 +81,15 @@ int __exfat_write_inode(struct inode *inode, int sync) ep2->dentry.stream.start_clu = EXFAT_FREE_CLUSTER; } - ep2->dentry.stream.valid_size = cpu_to_le64(ei->valid_size); + /* + * mmap write does not use exfat_write_end(), valid_size may be + * extended to the sector-aligned length in exfat_get_block(). + * So we need to fixup valid_size to the writren length. + */ + if (on_disk_size < ei->valid_size) + ep2->dentry.stream.valid_size = ep2->dentry.stream.size; + else + ep2->dentry.stream.valid_size = cpu_to_le64(ei->valid_size); exfat_update_dir_chksum_with_entry_set(&es); return exfat_put_dentry_set(&es, sync); @@ -330,6 +338,12 @@ int exfat_get_block(struct inode *inode, sector_t iblock, pos, ei->i_size_aligned); goto unlock_ret; } + + pos -= sb->s_blocksize; + if (pos + bh_result->b_size > ei->valid_size) { + ei->valid_size = pos + bh_result->b_size; + mark_inode_dirty(inode); + } } else { size_t b_size = EXFAT_BLK_TO_B(max_blocks, sb);