From patchwork Mon Apr 8 04:09:20 2024 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: 13620550 Received: from mx08-001d1705.pphosted.com (mx08-001d1705.pphosted.com [185.183.30.70]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9241A4A3F for ; Mon, 8 Apr 2024 04:10:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=185.183.30.70 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712549412; cv=fail; b=IssGYN755MscpJ/feeB/do1KYVOvw2D1l9Oa1seMTAHU+I7ZwyQse8HOLu9fIUD8XedcgFEwKtQ5whMm6b7sqnV6uG3+0uhRiwhSmSh8PNyiJFujSCgRovsPwIOlRQv+e6nQZcA5qzCy/UPn+cglWo1RyrF0Mi0VF8p3iUWPSos= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712549412; c=relaxed/simple; bh=R0U1P3qdFsuD1mNrfcio1HPf38qDE4YGSGblpXIo2/g=; h=From:To:CC:Subject:Date:Message-ID:MIME-Version:Content-Type; b=RTjeCRof+uz+WLSJeQqmldCgbzoqftcvOd4Cn5+TyK5Y4gLlpnE5XzGRV81u7Klrf76Gyjd597P4CH4FLarGym4ib62mWg/MIrxZq2R1mSqHhn3bM6XSKu206BHz+F1JJ6jow/ZBavEID8zTDoWKqyduyMP4SxzW3i4nJO5VYyw= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=sony.com; spf=pass smtp.mailfrom=sony.com; dkim=pass (2048-bit key) header.d=sony.com header.i=@sony.com header.b=G3yGJW20; arc=fail smtp.client-ip=185.183.30.70 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=sony.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=sony.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=sony.com header.i=@sony.com header.b="G3yGJW20" Received: from pps.filterd (m0209319.ppops.net [127.0.0.1]) by mx08-001d1705.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 4383iU06024381; Mon, 8 Apr 2024 04:09:31 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; s=S1; bh=U9aHz6qZwKJrL9z93sHZn6Hzuhqkmkzrhk0lTGGIm0g=; b=G3yGJW20veQudnWnZZdR0tH+0j9ib5tkRFJ1UMXyLn0E/7SPD6wlLka665MEN16jwL4S ReVdgAxFBU4xeKFWLyD6zgnXfbOlEI/EZs0AHDwDtcOL/ssvht0ObktNY+bfFxTiz5w/ gjsUnDY0GNJF/oSOO1l3jUy+yf7+cJnYChfqS6Jx2yiJfemjALPMBDsAQn4XXIt23szA K0A+xfuXgk74UFADwh8JEBpdgxC2xgiuC9AKUWFyMihgV8plR7D171lOXvitARZ7xneU GX338VH86Xc5PtxCLM9JQto/P9qE7STRRKb3M602TNhJ4BFnpjhadbeHuBCilDdzVbSP Vg== Received: from sg2pr03cu006.outbound.protection.outlook.com (mail-southeastasiaazlp17010000.outbound.protection.outlook.com [40.93.129.0]) by mx08-001d1705.pphosted.com (PPS) with ESMTPS id 3xaxst17u8-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 08 Apr 2024 04:09:30 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=naH/Rgl6s5k+c8bJFRccRb6vlw6/n1XD3cI7zuGoSsqTzw78Cs2ZYhYS7P7fsDxcXua8pxxay6QcAYnveSi50GuOeMNipZDrzTnX8OmOjI3xtT3R4b4fwFmeVaYAgiFVdKGYyALAKJ9QKAztyXb0v9OaGLnoYgM5Ti4UwxjuOwC220chTJiQC1SndSeRWeXqgkqpC1owRFCgUdCfqj4tQzfe/5rkoCVyQXGTk6oV12na/0Wt8BI0F3KRzGKYbOa/hKi3S5CGXWq8DK2QymL14SeRm8/Z9BWOHg1WTLlSLN4u2AGoXUjAuhwRMl36QHkJnDl2IsBdqiohPGwYG39rXg== 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=U9aHz6qZwKJrL9z93sHZn6Hzuhqkmkzrhk0lTGGIm0g=; b=liAC3i62z04fqeUqbY83Ezf/Bp4iO40M4PjtFnvwaKyGF1fixtaIBvhNGpar3FewYUP/Pn5e3ejCb/QVtg4z6q+l4JiRSRD4QcMQjMA3Z9cs0eOuaWLKF37xjN49LJ0tDcTxsBiwDcWw4qARn8baU1TccCxJBfN5PzIrMLdF+CkS6znFktHCqZy4KS2yZtcNo5UXY3thP+ov11c/DqSASWfuqB6rCFgjFyIdxuoyHqfmEHbTkO4IUtElMXphykYVjMVF4jc8Ub3n5AvjRgMT1kDz6y/58mgh0BFeXbJM9gZDKttbh963W9PMKaSZonXE7aHBpqaxNzaH1/7GHKnWBA== 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 SG2PR04MB5769.apcprd04.prod.outlook.com (2603:1096:4:1d6::13) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7409.46; Mon, 8 Apr 2024 04:09:20 +0000 Received: from PUZPR04MB6316.apcprd04.prod.outlook.com ([fe80::b59d:42cd:35d:351e]) by PUZPR04MB6316.apcprd04.prod.outlook.com ([fe80::b59d:42cd:35d:351e%4]) with mapi id 15.20.7409.042; Mon, 8 Apr 2024 04:09:20 +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" , Matthew Wilcox , "dchinner@redhat.com" Subject: [PATCH v2] exfat: move extend valid_size into ->page_mkwrite() Thread-Topic: [PATCH v2] exfat: move extend valid_size into ->page_mkwrite() Thread-Index: AQHaiWnQ7a+r99yPRUWKkEXVY33clw== Date: Mon, 8 Apr 2024 04:09:20 +0000 Message-ID: Accept-Language: en-US, zh-CN Content-Language: en-US X-MS-Has-Attach: yes X-MS-TNEF-Correlator: msip_labels: x-ms-publictraffictype: Email x-ms-traffictypediagnostic: PUZPR04MB6316:EE_|SG2PR04MB5769:EE_ x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: EF+lgK9KZ2B1AkiwNtyS7ZNYcpgWqIwLSlUWJMWHYrELdvov0hbfqVdOMZJYgiPyJh2z5uRi+n+0U00LW1908MY/ADr17xYHPPyiCJme7zRZ7GMB9DzEf8o3s8QGPsDUs+TK8c4/1hMkFA6MyUPgYTFDshtKqOnXzwYqu5GUdUkWYkbLK1dxSiwNiXF4yB8vRF76hQEWm33gmABDjSXF8g/n6sFrsnFdTj7w0IUSG6Sm9lhVeBZXG0pmn40pTsS28/aF/S+z30Anl7j3Ueb7Q2cVwjIxqUsnjWkAk7gjMMoKX5D9KKZ19mpjyC1FJdjZlQm/cgx8+6TbJNpL4wNkcK/sStrTrikEnz9wSne8rGNWa/IEgWcf0WdhA67scXIFmXbIWO90kd5l//eFG7PQFmGGl12GRnMZpa/qu8hpiIkPqGlGjb6oDxeH4zrjLAAtf1CbgdQy83fJUjIA7SlPyCyVugt8GBVW5F+g0rv1ncPdCe+RarbbPCz6HhbxKykUYVWFqeZPL6mAvTpn0No9JyRngFcNs+WIDSbzLBJYceH6cy/wUJvIey40MkN0po7eDJwFe/h6hFCPmSTIIwGM1PrgrG6lzimgGxWimzARL3TYYav5Bq25LiFP2fBHZx6r0/rbnwhqQd0+2MYlGhe8YGiH8l/3L/psRkGkSkaBXgs= 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)(366007)(1800799015)(376005);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?iso-8859-1?q?bZc0EXGHCm5qMsOkql8m1XP?= =?iso-8859-1?q?c1Sy3Zf3xYR5TOKgnMdt0TVeACGncJZYBHNdNgqEDWV/bF7dmGHD6wd0NqSn?= =?iso-8859-1?q?VYA9VBIdgmCsqyYHX/RWJuDxjHb9xOANe+WHy4mCyHYRNtun1IZjTt1BUeNC?= =?iso-8859-1?q?AkjCBAEpEnYbjF6+4PaQlpWLd2pREwkGIyuprgxO6tYiA+BabAxa80T5Uhum?= =?iso-8859-1?q?cLzOCtKjzdKVIxQ/V+YXtuCb7H9zCPtjvRbftVkufKgLq3BSKF+WfU8zLtVV?= =?iso-8859-1?q?3vG4OTCDlBb6c8Sxaj7rS0FGvcNCMzoMos6e9LO2h9YviFqEwKnzK+NreRG7?= =?iso-8859-1?q?yO/TBYikx8hMyEVLCwp74s0Kp07uuovGJj8yoKDWCE+trsyRXz3eAbj6uV8C?= =?iso-8859-1?q?BFZlt8TAu0foVR25qvmSk4KA+du7n7KSfRDAKcyC2fhyHu1hKJGHz3zsCcxw?= =?iso-8859-1?q?n1HK7yEiB+5/EBkgg+/Ki5lXZyUczJfn0POJADoCE+G2K6GHczagGeg0h3cr?= =?iso-8859-1?q?2KGN2kJhyqpC6b25w4K4O9jkej6PRevve6m5p+LpVdevMtmQl6S0fqV726Hz?= =?iso-8859-1?q?Kx1UKzroVD4XUsAF+eQw1pcZd8c4dxX+GuCeN7aeqoLC+N9yxbtQr4LkGfLu?= =?iso-8859-1?q?32c/5XiR7VHzrM3rTmhgXTpndVXxk+TumNuTMEd/GARrx2HqGNdF9PADMDFz?= =?iso-8859-1?q?d6UzxXoYlEKfIkBS3SN4LxYdV4q76nXybjEg/k7ukL+AXuL1nKFnjJfGYa/K?= =?iso-8859-1?q?99EQ4DJezazy9KB8fs+qiZHRIGRsVWvGT0sOSJN8o+t+RpBbw+IDWfHpm5IY?= =?iso-8859-1?q?9FouFhpvgXf6jRvJVR+moVhiPaa+6vHQOQv9MgdrR2ytP35umf+Xt3s3uora?= =?iso-8859-1?q?nfeW0fRh4hv+m1z9pSjT1HZSQ4CMAU9iGcCmc1E9uC8rkBcAtfFmPjGdYtMr?= =?iso-8859-1?q?uZcQebSUosNrdgYdDfSUrIImCa5uBwV7fmfD1cdtlA/Q19TKoHoV1PXo9ShI?= =?iso-8859-1?q?gIJ+i+ac1AFpSNRY2u8sleG9xYTITFlZDPNCP+a9m4wAL5N39UF7d4ekbZWh?= =?iso-8859-1?q?IajT5tUondhuTngktWnXKlppQOjgb07glgjvvB6RCOu6qtatXhbQIGFTltoq?= =?iso-8859-1?q?0gL1XKTCOm50zcRDbwUEMCYhm6SXRkJYehGbTdtxCp07neja9mAdyn9lpAsD?= =?iso-8859-1?q?LlhOUC8CBo4uL6vm0bTP2PqPV203V0fAVvA52iOliF7u4/QgZQx8IkPRX6kZ?= =?iso-8859-1?q?SZhDFrzJ4eDD0eQSHFzijFLbTwdkG7n6K/rcWKWC3crG+c4XYtQSzgHLElNj?= =?iso-8859-1?q?5T8JXwbiKgli0DU1/I4nyMg0+uYtSbpogKywuhQaCtoq9f2Jlz9iuzrHlCuT?= =?iso-8859-1?q?l9uvXDlMcezeKemJoSbjkmsNAdvz9Oo5h2BBzLkjBtLA+hMQ7CWyQMKQk8VP?= =?iso-8859-1?q?VIbyKRU6P8u80Uj1pAJ/M98FBflz60Rw14r5W68AUQBTe8845WxaNVwS9Jja?= =?iso-8859-1?q?vsOzhJanPAlGiJdXvpbdJyt3Ckd6an057XlmVPkKnz/vmeloicgFSuGxhHnJ?= =?iso-8859-1?q?hXABYFH+QjP/HQwvCNk9zm8dsVZUjUp9Q9vFoOwGgqHqCeFLWAJ17B3ah3RB?= =?iso-8859-1?q?elefTfplWxGZnjk9UhDvBLVHRRa+WxTkLVmkAqq9EkVRgclFJjmpLu348N8U?= =?iso-8859-1?q?=3D?= Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-Exchange-AntiSpam-ExternalHop-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-ExternalHop-MessageData-0: 7+fz8RyxZHmTfTSyUYSGQrbLW6BKnhMRnm1LgZa+NGWqTC0a1PjOageNtf6BqDnKJ3ZeVYyhcjn0gF7RH8u6NZnCd1vGmr51Acn5Z6l7MtmmDqwa6uLT6IsPrUAsbMmbCfhwEGY6LbL10JSq/tUulcJHdJB4M6m0HX4OmWwv8K3fmvOKEd/Zb8sRQa+KUfVIJ36Dvgr3V8NmaJFcEBiFRgGCeS7/uIKxg1OlJBR1ICcQIN86AD9Jou8W3O68rUKdsHAOU7XNtqYbErKylDpiGgDYgllFdM81WIxy/J77tVCvSa0omFmDWbJqU+BRgle0796wFKP6Puvle6jwvP5/svzfiddqjvXOEfl1lB+WoBHZR1ezKOvKRaSZUuV/CEDm3oehUOCMybEGWbw1q3Jn4LGjpaP/dnDDL77i8tV9FpZslj57RMkM7z/xYB95UK1CPofpllwEdTZY1RzfoS0FzyNC5ZVRALk+iY1+OYCwQKauLr3AHsZAZWWkTonMPCq4XnNBEggnkNSbp9L8mXHkNBQENRESoN+WlDFrq1ao6MRRmkYYDsW4zE4WOfmyjSVtXsSOALUliqIaVP5RYs5Z7GlTjiz+djmRvLeC73CrkAk6ATxOOv7YtZaoTYyO9epe 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: 6af557c7-922d-4b81-725e-08dc5781aa62 X-MS-Exchange-CrossTenant-originalarrivaltime: 08 Apr 2024 04:09:20.0489 (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: NmoEVfmXBKpK0Kd0IZsXiPQPHzO3Qspz9U+8DzHKNMdSvqkNwuH/4xZvLFz4YWs3rR64NP+hiyz8ZYk0fDhjMQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: SG2PR04MB5769 X-Proofpoint-ORIG-GUID: XyxtheQlFkrRKEu7Kn5vvVt8q9XFLvp5 X-Proofpoint-GUID: XyxtheQlFkrRKEu7Kn5vvVt8q9XFLvp5 X-Sony-Outbound-GUID: XyxtheQlFkrRKEu7Kn5vvVt8q9XFLvp5 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.1011,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-04-08_01,2024-04-05_02,2023-05-22_02 It is not a good way to extend valid_size to the end of the mmap area by writing zeros in mmap. Because after calling mmap, no data may be written, or only a small amount of data may be written to the head of the mmap area. This commit moves extending valid_size to exfat_page_mkwrite(). In exfat_page_mkwrite() only extend valid_size to the starting position of new data writing, which reduces unnecessary writing of zeros. If the block is not mapped and is marked as new after being mapped for writing, block_write_begin() will zero the page cache corresponding to the block, so there is no need to call zero_user_segment() in exfat_file_zeroed_range(). And after moving extending valid_size to exfat_page_mkwrite(), the data written by mmap will be copied to the page cache but the page cache may be not mapped to the disk. Calling zero_user_segment() will cause the data written by mmap to be cleared. So this commit removes calling zero_user_segment() from exfat_file_zeroed_range() and renames exfat_file_zeroed_range() to exfat_extend_valid_size(). Signed-off-by: Yuezhang Mo Changes for v2: - Remove a unnecessary check from exfat_file_mmap() --- fs/exfat/exfat_fs.h | 1 + fs/exfat/file.c | 97 +++++++++++++++++++++++++++++++++++---------- fs/exfat/inode.c | 5 +++ 3 files changed, 83 insertions(+), 20 deletions(-) From 9c86704ab9babe373bbe431f8eff6c8cb565b6bf Mon Sep 17 00:00:00 2001 From: Yuezhang Mo Date: Fri, 8 Mar 2024 14:03:46 +0800 Subject: [PATCH v2] exfat: move extend valid_size into ->page_mkwrite() It is not a good way to extend valid_size to the end of the mmap area by writing zeros in mmap. Because after calling mmap, no data may be written, or only a small amount of data may be written to the head of the mmap area. This commit moves extending valid_size to exfat_page_mkwrite(). In exfat_page_mkwrite() only extend valid_size to the starting position of new data writing, which reduces unnecessary writing of zeros. If the block is not mapped and is marked as new after being mapped for writing, block_write_begin() will zero the page cache corresponding to the block, so there is no need to call zero_user_segment() in exfat_file_zeroed_range(). And after moving extending valid_size to exfat_page_mkwrite(), the data written by mmap will be copied to the page cache but the page cache may be not mapped to the disk. Calling zero_user_segment() will cause the data written by mmap to be cleared. So this commit removes calling zero_user_segment() from exfat_file_zeroed_range() and renames exfat_file_zeroed_range() to exfat_extend_valid_size(). Signed-off-by: Yuezhang Mo Changes for v2: - Remove a unnecessary check from exfat_file_mmap() --- fs/exfat/exfat_fs.h | 1 + fs/exfat/file.c | 97 +++++++++++++++++++++++++++++++++++---------- fs/exfat/inode.c | 5 +++ 3 files changed, 83 insertions(+), 20 deletions(-) diff --git a/fs/exfat/exfat_fs.h b/fs/exfat/exfat_fs.h index ecc5db952deb..1d207eee3197 100644 --- a/fs/exfat/exfat_fs.h +++ b/fs/exfat/exfat_fs.h @@ -516,6 +516,7 @@ 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_block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf); /* 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 cc00f1a7a1e1..95d3e7f8b911 100644 --- a/fs/exfat/file.c +++ b/fs/exfat/file.c @@ -523,7 +523,7 @@ 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) +static int exfat_extend_valid_size(struct file *file, loff_t start, loff_t end) { int err; struct inode *inode = file_inode(file); @@ -531,11 +531,10 @@ static int exfat_file_zeroed_range(struct file *file, loff_t start, loff_t end) const struct address_space_operations *ops = mapping->a_ops; while (start < end) { - u32 zerofrom, len; + u32 len; struct page *page = NULL; - zerofrom = start & (PAGE_SIZE - 1); - len = PAGE_SIZE - zerofrom; + len = PAGE_SIZE - (start & (PAGE_SIZE - 1)); if (start + len > end) len = end - start; @@ -543,8 +542,6 @@ static int exfat_file_zeroed_range(struct file *file, loff_t start, loff_t end) 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; @@ -576,7 +573,7 @@ static ssize_t exfat_file_write_iter(struct kiocb *iocb, struct iov_iter *iter) goto unlock; if (pos > valid_size) { - ret = exfat_file_zeroed_range(file, valid_size, pos); + ret = exfat_extend_valid_size(file, valid_size, pos); if (ret < 0 && ret != -ENOSPC) { exfat_err(inode->i_sb, "write: fail to zero from %llu to %llu(%zd)", @@ -610,26 +607,86 @@ static ssize_t exfat_file_write_iter(struct kiocb *iocb, struct iov_iter *iter) return ret; } -static int exfat_file_mmap(struct file *file, struct vm_area_struct *vma) +static vm_fault_t exfat_page_mkwrite(struct vm_fault *vmf) { - int ret; + int err; + struct vm_area_struct *vma = vmf->vma; + struct file *file = vma->vm_file; 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); + struct folio *folio = page_folio(vmf->page); + vm_fault_t ret = VM_FAULT_LOCKED; + + sb_start_pagefault(inode->i_sb); + file_update_time(file); + folio_lock(folio); + if (folio->mapping != file->f_mapping) { + folio_unlock(folio); + ret = VM_FAULT_NOPAGE; + goto out; + } - 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; + if (ei->valid_size < folio_pos(folio)) { + inode_lock(inode); + err = exfat_extend_valid_size(file, ei->valid_size, folio_pos(folio)); + inode_unlock(inode); + if (err < 0) { + ret = vmf_fs_error(err); + goto out; } } - return generic_file_mmap(file, vma); + /* + * check if the folio is mapped already (Whether ei->valid_size + * has been extended to folio_pos(folio)+folio_len(folio)) + */ + if (!folio_test_mappedtodisk(folio)) { + struct buffer_head *head = folio_buffers(folio); + + if (head) { + int fully_mapped = 1; + struct buffer_head *bh = head; + + do { + if (!buffer_mapped(bh)) { + fully_mapped = 0; + break; + } + } while (bh = bh->b_this_page, bh != head); + + if (fully_mapped) + folio_set_mappedtodisk(folio); + } + } + + if (folio_test_mappedtodisk(folio)) { + folio_mark_dirty(folio); + folio_wait_stable(folio); + goto out; + } + + folio_unlock(folio); + + err = exfat_block_page_mkwrite(vma, vmf); + if (err) + ret = vmf_fs_error(err); + +out: + sb_end_pagefault(inode->i_sb); + return ret; +} + +static const struct vm_operations_struct exfat_file_vm_ops = { + .fault = filemap_fault, + .map_pages = filemap_map_pages, + .page_mkwrite = exfat_page_mkwrite, +}; + +static int exfat_file_mmap(struct file *file, struct vm_area_struct *vma) +{ + file_accessed(file); + vma->vm_ops = &exfat_file_vm_ops; + return 0; } const struct file_operations exfat_file_operations = { diff --git a/fs/exfat/inode.c b/fs/exfat/inode.c index dd894e558c91..804de7496a7f 100644 --- a/fs/exfat/inode.c +++ b/fs/exfat/inode.c @@ -564,6 +564,11 @@ int exfat_block_truncate_page(struct inode *inode, loff_t from) return block_truncate_page(inode->i_mapping, from, exfat_get_block); } +int exfat_block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) +{ + return block_page_mkwrite(vma, vmf, exfat_get_block); +} + static const struct address_space_operations exfat_aops = { .dirty_folio = block_dirty_folio, .invalidate_folio = block_invalidate_folio, -- 2.34.1