Message ID | 20221115160155.1037163-1-shengyong@oppo.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:6687:0:0:0:0:0 with SMTP id l7csp2816025wru; Tue, 15 Nov 2022 08:13:34 -0800 (PST) X-Google-Smtp-Source: AA0mqf4wyNaM79qIgeysTWJmWDYe9QBNd3+ni83smNQrw19kRZ+Z6YBdCqiSDIFu2f5RimN1D6ly X-Received: by 2002:a63:ed18:0:b0:45c:eb5a:3361 with SMTP id d24-20020a63ed18000000b0045ceb5a3361mr16083357pgi.346.1668528814478; Tue, 15 Nov 2022 08:13:34 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1668528814; cv=pass; d=google.com; s=arc-20160816; b=LR55+dfJcryedAVYH14JxBqrQMXGYDcVHKURp8aS3EvBgo2Y2+2QS+ikMEPJTjOQrj WMdWNuas0RuqMYany+hbwdwIOIMWH/xnsTFw31bb1Y1JqU7A+XjNEfSC/Pz8KEAZMrrw QPpyeO+Yc8DU6uKUj4dREj/0riSGjbn1rXe9bRIVWXV9K41q0RcFivzAr0GkX3wynYRM beHTGgpMqt+xiwR3VeNoggZ7Td4ii6qc1YO5+ixL+tGfzKDTPHtUdLddGPbe+CJExQNw iQDh+nLasJphjc8whFJmCSb7aIKHJW0TsJo67r3/hGVsuwyvxq0i2qlOV2dN7T/GOrRN 1Jzg== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:content-transfer-encoding :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=4d3B/PGtTQYXHQ7OKboe22V9b3Gf8sq3dbcehpWreHY=; b=unPZub1FahKG2KhtVmXi0RfJencsXMx5uoxD/xhdv22qyVeF/JwNG4o7RTpu454a/f SXBxEDjUvt6PmUW+ytdtxX90LeCVBX6qGujHYx4EgTRuhTSZ7JkQEPjQ6G5pgQWvFeSe pnZx1vdEugd4u042nsZ2amP/wrqIGV8/HVczKwx0dCBRd1f8Xi0OgMcwTxWRfXUjz7XM D6fOO74DOE0U3KcWLNVKx7PVo0BGy/L0f6tLeoEgExCpInhUFLVSCZyAphnGLeKWOz+b t8rHwgFcwDDGLtABXUodesoetRSEVbztv2LlrBIWo3cJo4UZlf2BpvKXtALvgHZQYVMW 0O5w== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@oppo.com header.s=selector1 header.b=h3waAbtv; arc=pass (i=1 spf=pass spfdomain=oppo.com dkim=pass dkdomain=oppo.com dmarc=pass fromdomain=oppo.com); spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=oppo.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id y4-20020a170902cac400b00186ba56bda8si11088900pld.61.2022.11.15.08.13.16; Tue, 15 Nov 2022 08:13:34 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@oppo.com header.s=selector1 header.b=h3waAbtv; arc=pass (i=1 spf=pass spfdomain=oppo.com dkim=pass dkdomain=oppo.com dmarc=pass fromdomain=oppo.com); spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=oppo.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238005AbiKOQDn (ORCPT <rfc822;maxim.cournoyer@gmail.com> + 99 others); Tue, 15 Nov 2022 11:03:43 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56932 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232197AbiKOQDa (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Tue, 15 Nov 2022 11:03:30 -0500 Received: from APC01-SG2-obe.outbound.protection.outlook.com (mail-sgaapc01on2080.outbound.protection.outlook.com [40.107.215.80]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 88DEF1000 for <linux-kernel@vger.kernel.org>; Tue, 15 Nov 2022 08:03:25 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=nNjpofMxR9/+cJ3X0rmERLvA56pfjGT//mNeou+pD86LeHP4lskx/dMJkWqU+p9WC54N5ZO56iaIBaAoWxgESpMOc83huOhGrhelx4/31ZDg9azcVV+bHrXVEdgnJNSiAXf3CcQK0pLoiikqPis3CeanaMxJUfJidWLYaG3X3sLd6olF78JaYXxpQT7FDr17Bz50fIIhIJvp8uLscC7KvDA8HOE2Aq6ABKum4vg3/wWqxGa27Oq8mtshGIvfEWXCUHA1tZ0Uypn45CpFjWOcZhbvWViUNFb8ukP2Zz2RVFu6BjB2ROhEXv7CNla3Y1Z4hWCWS/ZznMQekmgAfZtjUg== 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=4d3B/PGtTQYXHQ7OKboe22V9b3Gf8sq3dbcehpWreHY=; b=ZvVzH8Ur7IMhNOKkpiqB8NqlYZx1lq5nEm0JTDGOHiMaCTqMHGES3C6uUVeYMyexLLcsNvdMLZvtk8vpbUUBy3cxRseQaTTRfDinlTdCuF3lD5uqrn+hYNup8zNP9AqR0MG1Qe0+EXYFMNwax/ARtqCEVC1ZuSvX572+oN4UuG1i5Bj2Q6oeRkWr3+HX5F0h9EKBCbbVvD55E/AE9LCYRw4MTty0YJUJT+fcQU/GfKtcftVPotRA/ZgZj2epb1SGMIlAtGy2hhOoHGR+EP0+mpjtMUtVkz2XmCXPaQqRKH3u9pk2X/yr6lvP2G5pMgOWBFQo0Y8Qf6uldVFU7fIfiw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=oppo.com; dmarc=pass action=none header.from=oppo.com; dkim=pass header.d=oppo.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oppo.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=4d3B/PGtTQYXHQ7OKboe22V9b3Gf8sq3dbcehpWreHY=; b=h3waAbtv0OQOwEzT9SqvlFgrUGq8giVPI53pwNE7Q9GozRC4nUD7h4niRDVnenNEAKT9of686Wxk3dKilPFYT6A8pX+kzEnqCsKTC/P6HGCkoHH2RbeW522Hz9pKSH9IYPi+epj7BiFY3evBLqNdJnX87Dsw6GnihR7FZF8fykM= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=oppo.com; Received: from SI2PR02MB5148.apcprd02.prod.outlook.com (2603:1096:4:153::6) by TY0PR02MB5765.apcprd02.prod.outlook.com (2603:1096:400:1b4::6) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5813.17; Tue, 15 Nov 2022 16:03:20 +0000 Received: from SI2PR02MB5148.apcprd02.prod.outlook.com ([fe80::2954:8e56:dcd1:452c]) by SI2PR02MB5148.apcprd02.prod.outlook.com ([fe80::2954:8e56:dcd1:452c%3]) with mapi id 15.20.5813.017; Tue, 15 Nov 2022 16:03:20 +0000 From: Sheng Yong <shengyong@oppo.com> To: jaegeuk@kernel.org, chao@kernel.org Cc: linux-f2fs-devel@lists.sourceforge.net, linux-kernel@vger.kernel.org, shengyong@oppo.com Subject: [PATCH v3] f2fs: fix to enable compress for newly created file if extension matches Date: Wed, 16 Nov 2022 00:01:55 +0800 Message-Id: <20221115160155.1037163-1-shengyong@oppo.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <f508dea8-5dc3-e29e-0d8b-4d64735817ac@kernel.org> References: <f508dea8-5dc3-e29e-0d8b-4d64735817ac@kernel.org> Content-Transfer-Encoding: 8bit Content-Type: text/plain X-ClientProxiedBy: SI1PR02CA0024.apcprd02.prod.outlook.com (2603:1096:4:1f4::12) To SI2PR02MB5148.apcprd02.prod.outlook.com (2603:1096:4:153::6) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SI2PR02MB5148:EE_|TY0PR02MB5765:EE_ X-MS-Office365-Filtering-Correlation-Id: 69757fa1-8061-4761-a11c-08dac722ea99 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: fUMRc9Il0z6uAJkqERNY6+gMDk9QIOPNL/EpAfMLDyNTGWMuP6O332EZYGyP8Q6/lFICvyAcWYLjntMsp+CjPqc3aXcJMmzH0S398m2bMPABmFlr6bQj20yumxACuPMb8Dsji1yr0BQ9v9939AMNfOTK4Anx9f93bHx+Pwt7sQMsbUH0KKeHmDuZSCKDFnvw18gLx9JwapAducczFnWNjDpVC3SB5o822GXH4ionnz9G6vr+D92jNKCs9hTyePMGxUKlB+DN+4gO+rriozPqP5nRKWLf8D6G86p4Rggbq0sdycZxOVuuL1kINPiSTvXph1qLOYNyi9YbXJl6i1QpYJ6th/yvo61vy5zv89KrKh2lKKO+jlV3Z9ogb4XAXkXjzN6cBkZK4h9w4GAm445V5V0YkldSssDuWli4zlCzUF6bGATGo50oeX2A2L8ytlhhTg1bnY3wsEt7MzlwNmJ7BcttKMsfZAxeA0cg8FCpddp2IyKYmeHjWQ1B1opPDLsXzwQgTEBNlkdqx/KxOKAv+CJIc4NKsJSciMjhDMZIZBOArHwaqKoiD7TyNexlCtdXk7zcQmOuhPIlDJoehHPXtYN/XQiKZc/t5J0Wc8cb47A+PZtJoIebpD90bkvfqRVGHVRXgyM7PtNxqcuhl9QbNlLTO/3P/6VkkS6Zof0Ryl1atYqY050vtwGfLE3volhxaUh6DzTW7WmUlnhzAfqwsbMf8H3xT3q45c4fXJcDt2v4fjUJhBFSpZ2YMhZb2j7p X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:SI2PR02MB5148.apcprd02.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230022)(4636009)(136003)(396003)(366004)(346002)(39860400002)(376002)(451199015)(6486002)(52116002)(6666004)(107886003)(478600001)(66476007)(316002)(66946007)(66556008)(6512007)(26005)(6506007)(8676002)(41300700001)(4326008)(86362001)(38100700002)(38350700002)(186003)(2616005)(83380400001)(1076003)(8936002)(2906002)(5660300002)(36756003)(30864003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: 2AaElL+qqPCs+nDYDln7uxaT9rHV3wPW5Z46jRx3LUGLRd17ov/PhICVYOVQcgXS8DFpSRCiKb0QDIc78J6zq0VXtDgtGHT7nVx9HGBp+bW94XjD59jJ1H+V4UMwjjrc78WBfZel+xigaMes/kWw5SY0mQ/13fJ5mEg2u21HMj7vLfqmKZ5nnCW603wZwXSlO6GC2XmPFVP2bl+DuMC8vDDiwgVBBm4gBtpd9d1T4NC+3H3zAmNh791yNlU5eZKxkDNTUVd597pvJcbAVzjTqgz+xXaV2juhhdpZBH2cdbUk/jO/A9TJpLyhEzKWJ3QcXsJjpXTuYtQXYvq/zPa47W++nIGsgy+LGl5NZUqXt7dkNXysyriEsjSDnmrJ8Eox3VlzIkh4F8A9FqzZFE/zLp+M0zZiJOSsCsLmVUJhfH6Bo0wpagZH3S+KHwOlW3JTTzrbvmxlrJ6Mfh6QVxXf6LoaG6pkg9XzydwD/FY3fd7IAo+dNtHJDArsKR4ht40/DBwklCt1Ra2B/aPtSDRTxsm0yf7xXcNm8Bt5u5AH7dc9E/w1moeKdN40yqj7NTAB8FHN2v9gJxIeiVACvTlcOaVWl5UO+LvRcl+Ap/CGpM0JLB8bYahEuRUofs5bgGmQXYSK8sHIjJjhPOrk5XnBUnkiFQRxadC+oPBzWI7qTUi5msdsxyEWR9YSdU/uyA4idqhkKkKeRTBbJ6TUSzZi255BVlM8WSfieIOb9X3N+aDES4t1x4Yw3y20W7B1q5WPgMxSPUwXYeq3Zx4BTuk7B8iGePRBwbEAUIshHV+4svkTivm5n5nOX0BhT2pqDVegl7kSp9CY50Nd0DIAASFBFGZoOWbM92BYluKQLYy+o8hL8isqaoA1ulh2aZdsIa92PoEfiYLAvo/+RTErnxvl/Y3QxnmOHDed4qHse4eIRr7untA+LalnrqA7vNcUxuWB+6SYM8sQ34Dc1w9icBRO4ixNPFYWAvI2l9pY8r0SI63XKi0GmzUZaPjqc8bkknxCct2JGBwzqXhsop0FARqN6Y+Qg/apVzAWfeNviLbASJyyJNGG0jotb9SVb0P6iIF1kRAoMEvmjT1TuGMZHOXlGRUTKrebMAfpg2WQwQ42R/mp4ZW3zX3uQ2/zkz/gC4xYqP01aiAHpGE9D23EzB69dUuSTTfZuQesRt2FRGvRH5F7yVMFGsqn2E8BsiJn44Dant9e+TZuAFZ1gMy3nkRFFdgmipc8wwKkr+7ha6GFnuJ36xbt+UAGpXF9qwdvvAK7sLmVgXdhyZYF3hmFrWt+g8SWl3U1VYVTLK2k0vFDTWK9eC4Xibnte2SK3ZkLJVlvI+R3eUb21L9qA6NN73sZnR0t3DYSl7SsDUKYy008YVdKqzb4r85PvLYc7D8HCqE4yOwy6HVBEc0PsYhkrHNPDaVBbQ9/b/q/q5qNG4coJCSuVnOg5x2FTRfAy8HW7WoOBTbewBhi98WrFKSf7uYLYlXPm7uaZcULe0ApVo8udt/XVcQAPIy26OmRAzobGf2jh3K6TRCnLi55gmAFA71DLsBGwjkk3cTgIBhMOYp2lH2IJRZ4XGpTC6w5bIr5e+DK X-OriginatorOrg: oppo.com X-MS-Exchange-CrossTenant-Network-Message-Id: 69757fa1-8061-4761-a11c-08dac722ea99 X-MS-Exchange-CrossTenant-AuthSource: SI2PR02MB5148.apcprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 15 Nov 2022 16:03:20.7285 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f1905eb1-c353-41c5-9516-62b4a54b5ee6 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: ReeByN0GveTnIiJ7ZpCj2htj2rDuDPdfvEydh3d3aeD3QEuObiRsSQwjum+4Mv+FZcA3vI0WiMCjnQu+DzlvsQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: TY0PR02MB5765 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2,SPF_HELO_PASS,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1749194512625242599?= X-GMAIL-MSGID: =?utf-8?q?1749579270256050372?= |
Series |
[v3] f2fs: fix to enable compress for newly created file if extension matches
|
|
Commit Message
Sheng Yong
Nov. 15, 2022, 4:01 p.m. UTC
If compress_extension is set, and a newly created file matches the extension, the file could be marked as compression file. However, if inline_data is also enabled, there is no chance to check its extension since f2fs_should_compress() always returns false. This patch moves set_compress_inode(), which do extension check, in f2fs_should_compress() to check extensions before setting inline data flag. Fixes: 7165841d578e ("f2fs: fix to check inline_data during compressed inode conversion") Signed-off-by: Sheng Yong <shengyong@oppo.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org> --- fs/f2fs/f2fs.h | 1 + fs/f2fs/namei.c | 336 ++++++++++++++++++++++++------------------------ 2 files changed, 171 insertions(+), 166 deletions(-) --- Hi, Jaegeuk, Chao, How about adding a bool `may_compress' in set_compress_new_inode, set `my_compress` according to several conditions. If it is false, clear F2FS_COMPR_FL. And set_compress_context is also changed to clear F2FS_NOCOMP_FL, otherwise, if F2FS_NOCOMP_FL is inherited from parent and hit compress_extension, both F2FS_NOCOMP_FL and F2FS_COMPR_FL are set.
Comments
On 11/16, Sheng Yong wrote: > If compress_extension is set, and a newly created file matches the > extension, the file could be marked as compression file. However, > if inline_data is also enabled, there is no chance to check its > extension since f2fs_should_compress() always returns false. > > This patch moves set_compress_inode(), which do extension check, in > f2fs_should_compress() to check extensions before setting inline > data flag. > > Fixes: 7165841d578e ("f2fs: fix to check inline_data during compressed inode conversion") > Signed-off-by: Sheng Yong <shengyong@oppo.com> > Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org> > --- > fs/f2fs/f2fs.h | 1 + > fs/f2fs/namei.c | 336 ++++++++++++++++++++++++------------------------ > 2 files changed, 171 insertions(+), 166 deletions(-) > --- > > Hi, Jaegeuk, Chao, > > How about adding a bool `may_compress' in set_compress_new_inode, set > `my_compress` according to several conditions. If it is false, clear > F2FS_COMPR_FL. > > And set_compress_context is also changed to clear F2FS_NOCOMP_FL, > otherwise, if F2FS_NOCOMP_FL is inherited from parent and hit > compress_extension, both F2FS_NOCOMP_FL and F2FS_COMPR_FL are set. > > diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h > index 6a8cbf5bb1871..a3420fbb29214 100644 > --- a/fs/f2fs/f2fs.h > +++ b/fs/f2fs/f2fs.h > @@ -4355,6 +4355,7 @@ static inline int set_compress_context(struct inode *inode) > F2FS_I(inode)->i_compress_flag |= > F2FS_OPTION(sbi).compress_level << > COMPRESS_LEVEL_OFFSET; > + F2FS_I(inode)->i_flags &= ~F2FS_NOCOMP_FL; > F2FS_I(inode)->i_flags |= F2FS_COMPR_FL; > set_inode_flag(inode, FI_COMPRESSED_FILE); > stat_inc_compr_inode(inode); > diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c > index e104409c3a0e5..36ec5cf7cf859 100644 > --- a/fs/f2fs/namei.c > +++ b/fs/f2fs/namei.c > @@ -22,8 +22,170 @@ > #include "acl.h" > #include <trace/events/f2fs.h> > > +static inline int is_extension_exist(const unsigned char *s, const char *sub, > + bool tmp_ext) > +{ > + size_t slen = strlen(s); > + size_t sublen = strlen(sub); > + int i; > + > + if (sublen == 1 && *sub == '*') > + return 1; > + > + /* > + * filename format of multimedia file should be defined as: > + * "filename + '.' + extension + (optional: '.' + temp extension)". > + */ > + if (slen < sublen + 2) > + return 0; > + > + if (!tmp_ext) { > + /* file has no temp extension */ > + if (s[slen - sublen - 1] != '.') > + return 0; > + return !strncasecmp(s + slen - sublen, sub, sublen); > + } > + > + for (i = 1; i < slen - sublen; i++) { > + if (s[i] != '.') > + continue; > + if (!strncasecmp(s + i + 1, sub, sublen)) > + return 1; > + } > + > + return 0; > +} > + > +int f2fs_update_extension_list(struct f2fs_sb_info *sbi, const char *name, > + bool hot, bool set) > +{ > + __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; > + int cold_count = le32_to_cpu(sbi->raw_super->extension_count); > + int hot_count = sbi->raw_super->hot_ext_count; > + int total_count = cold_count + hot_count; > + int start, count; > + int i; > + > + if (set) { > + if (total_count == F2FS_MAX_EXTENSION) > + return -EINVAL; > + } else { > + if (!hot && !cold_count) > + return -EINVAL; > + if (hot && !hot_count) > + return -EINVAL; > + } > + > + if (hot) { > + start = cold_count; > + count = total_count; > + } else { > + start = 0; > + count = cold_count; > + } > + > + for (i = start; i < count; i++) { > + if (strcmp(name, extlist[i])) > + continue; > + > + if (set) > + return -EINVAL; > + > + memcpy(extlist[i], extlist[i + 1], > + F2FS_EXTENSION_LEN * (total_count - i - 1)); > + memset(extlist[total_count - 1], 0, F2FS_EXTENSION_LEN); > + if (hot) > + sbi->raw_super->hot_ext_count = hot_count - 1; > + else > + sbi->raw_super->extension_count = > + cpu_to_le32(cold_count - 1); > + return 0; > + } > + > + if (!set) > + return -EINVAL; > + > + if (hot) { > + memcpy(extlist[count], name, strlen(name)); > + sbi->raw_super->hot_ext_count = hot_count + 1; > + } else { > + char buf[F2FS_MAX_EXTENSION][F2FS_EXTENSION_LEN]; > + > + memcpy(buf, &extlist[cold_count], > + F2FS_EXTENSION_LEN * hot_count); > + memset(extlist[cold_count], 0, F2FS_EXTENSION_LEN); > + memcpy(extlist[cold_count], name, strlen(name)); > + memcpy(&extlist[cold_count + 1], buf, > + F2FS_EXTENSION_LEN * hot_count); > + sbi->raw_super->extension_count = cpu_to_le32(cold_count + 1); > + } > + return 0; > +} > + > +static void set_compress_new_inode(struct f2fs_sb_info *sbi, struct inode *dir, > + struct inode *inode, const unsigned char *name) > +{ > + struct f2fs_inode_info *fi = F2FS_I(inode); > + __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; > + unsigned char (*noext)[F2FS_EXTENSION_LEN] = > + F2FS_OPTION(sbi).noextensions; > + unsigned char (*ext)[F2FS_EXTENSION_LEN] = F2FS_OPTION(sbi).extensions; > + unsigned char ext_cnt = F2FS_OPTION(sbi).compress_ext_cnt; > + unsigned char noext_cnt = F2FS_OPTION(sbi).nocompress_ext_cnt; > + bool may_compress = false; > + int i, cold_count, hot_count; > + > + if (!f2fs_sb_has_compression(sbi) || !name) > + return; > + if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode)) > + return; > + > + /* Inherit the compression flag in directory */ > + if (fi->i_flags & FS_COMPR_FL) > + may_compress = true; > + > + /* Start to check extension list for regular file */ > + if ((!ext_cnt && !noext_cnt) || S_ISDIR(inode->i_mode)) This doesn't address the Chao's point. It seems not much motivation to add may_compress. Let me try to combine some with the previous patch. > + goto set_compress; > + > + /* Don't compress hot files. */ > + f2fs_down_read(&sbi->sb_lock); > + cold_count = le32_to_cpu(sbi->raw_super->extension_count); > + hot_count = sbi->raw_super->hot_ext_count; > + for (i = cold_count; i < cold_count + hot_count; i++) > + if (is_extension_exist(name, extlist[i], false)) { > + may_compress = false; > + f2fs_up_read(&sbi->sb_lock); > + goto set_compress; > + } > + f2fs_up_read(&sbi->sb_lock); > + > + /* Don't compress unallowed extension. */ > + for (i = 0; i < noext_cnt; i++) { > + if (is_extension_exist(name, noext[i], false)) { > + may_compress = false; > + goto set_compress; > + } > + } > + > + /* Compress wanting extension. */ > + for (i = 0; i < ext_cnt; i++) { > + if (is_extension_exist(name, ext[i], false)) { > + may_compress = true; > + goto set_compress; > + } > + } > + > +set_compress: > + if (may_compress) > + set_compress_context(inode); > + else if (fi->i_flags & F2FS_COMPR_FL) > + fi->i_flags &= ~F2FS_COMPR_FL; > +} > + > static struct inode *f2fs_new_inode(struct user_namespace *mnt_userns, > - struct inode *dir, umode_t mode) > + struct inode *dir, umode_t mode, > + const char *name) > { > struct f2fs_sb_info *sbi = F2FS_I_SB(dir); > nid_t ino; > @@ -114,12 +276,8 @@ static struct inode *f2fs_new_inode(struct user_namespace *mnt_userns, > if (F2FS_I(inode)->i_flags & F2FS_PROJINHERIT_FL) > set_inode_flag(inode, FI_PROJ_INHERIT); > > - if (f2fs_sb_has_compression(sbi)) { > - /* Inherit the compression flag in directory */ > - if ((F2FS_I(dir)->i_flags & F2FS_COMPR_FL) && > - f2fs_may_compress(inode)) > - set_compress_context(inode); > - } > + /* Check compression first. */ > + set_compress_new_inode(sbi, dir, inode, name); > > /* Should enable inline_data after compression set */ > if (test_opt(sbi, INLINE_DATA) && f2fs_may_inline_data(inode)) > @@ -153,40 +311,6 @@ static struct inode *f2fs_new_inode(struct user_namespace *mnt_userns, > return ERR_PTR(err); > } > > -static inline int is_extension_exist(const unsigned char *s, const char *sub, > - bool tmp_ext) > -{ > - size_t slen = strlen(s); > - size_t sublen = strlen(sub); > - int i; > - > - if (sublen == 1 && *sub == '*') > - return 1; > - > - /* > - * filename format of multimedia file should be defined as: > - * "filename + '.' + extension + (optional: '.' + temp extension)". > - */ > - if (slen < sublen + 2) > - return 0; > - > - if (!tmp_ext) { > - /* file has no temp extension */ > - if (s[slen - sublen - 1] != '.') > - return 0; > - return !strncasecmp(s + slen - sublen, sub, sublen); > - } > - > - for (i = 1; i < slen - sublen; i++) { > - if (s[i] != '.') > - continue; > - if (!strncasecmp(s + i + 1, sub, sublen)) > - return 1; > - } > - > - return 0; > -} > - > /* > * Set file's temperature for hot/cold data separation > */ > @@ -217,124 +341,6 @@ static inline void set_file_temperature(struct f2fs_sb_info *sbi, struct inode * > file_set_hot(inode); > } > > -int f2fs_update_extension_list(struct f2fs_sb_info *sbi, const char *name, > - bool hot, bool set) > -{ > - __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; > - int cold_count = le32_to_cpu(sbi->raw_super->extension_count); > - int hot_count = sbi->raw_super->hot_ext_count; > - int total_count = cold_count + hot_count; > - int start, count; > - int i; > - > - if (set) { > - if (total_count == F2FS_MAX_EXTENSION) > - return -EINVAL; > - } else { > - if (!hot && !cold_count) > - return -EINVAL; > - if (hot && !hot_count) > - return -EINVAL; > - } > - > - if (hot) { > - start = cold_count; > - count = total_count; > - } else { > - start = 0; > - count = cold_count; > - } > - > - for (i = start; i < count; i++) { > - if (strcmp(name, extlist[i])) > - continue; > - > - if (set) > - return -EINVAL; > - > - memcpy(extlist[i], extlist[i + 1], > - F2FS_EXTENSION_LEN * (total_count - i - 1)); > - memset(extlist[total_count - 1], 0, F2FS_EXTENSION_LEN); > - if (hot) > - sbi->raw_super->hot_ext_count = hot_count - 1; > - else > - sbi->raw_super->extension_count = > - cpu_to_le32(cold_count - 1); > - return 0; > - } > - > - if (!set) > - return -EINVAL; > - > - if (hot) { > - memcpy(extlist[count], name, strlen(name)); > - sbi->raw_super->hot_ext_count = hot_count + 1; > - } else { > - char buf[F2FS_MAX_EXTENSION][F2FS_EXTENSION_LEN]; > - > - memcpy(buf, &extlist[cold_count], > - F2FS_EXTENSION_LEN * hot_count); > - memset(extlist[cold_count], 0, F2FS_EXTENSION_LEN); > - memcpy(extlist[cold_count], name, strlen(name)); > - memcpy(&extlist[cold_count + 1], buf, > - F2FS_EXTENSION_LEN * hot_count); > - sbi->raw_super->extension_count = cpu_to_le32(cold_count + 1); > - } > - return 0; > -} > - > -static void set_compress_inode(struct f2fs_sb_info *sbi, struct inode *inode, > - const unsigned char *name) > -{ > - __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; > - unsigned char (*noext)[F2FS_EXTENSION_LEN] = F2FS_OPTION(sbi).noextensions; > - unsigned char (*ext)[F2FS_EXTENSION_LEN] = F2FS_OPTION(sbi).extensions; > - unsigned char ext_cnt = F2FS_OPTION(sbi).compress_ext_cnt; > - unsigned char noext_cnt = F2FS_OPTION(sbi).nocompress_ext_cnt; > - int i, cold_count, hot_count; > - > - if (!f2fs_sb_has_compression(sbi) || > - F2FS_I(inode)->i_flags & F2FS_NOCOMP_FL || > - !f2fs_may_compress(inode) || > - (!ext_cnt && !noext_cnt)) > - return; > - > - f2fs_down_read(&sbi->sb_lock); > - > - cold_count = le32_to_cpu(sbi->raw_super->extension_count); > - hot_count = sbi->raw_super->hot_ext_count; > - > - for (i = cold_count; i < cold_count + hot_count; i++) { > - if (is_extension_exist(name, extlist[i], false)) { > - f2fs_up_read(&sbi->sb_lock); > - return; > - } > - } > - > - f2fs_up_read(&sbi->sb_lock); > - > - for (i = 0; i < noext_cnt; i++) { > - if (is_extension_exist(name, noext[i], false)) { > - f2fs_disable_compressed_file(inode); > - return; > - } > - } > - > - if (is_inode_flag_set(inode, FI_COMPRESSED_FILE)) > - return; > - > - for (i = 0; i < ext_cnt; i++) { > - if (!is_extension_exist(name, ext[i], false)) > - continue; > - > - /* Do not use inline_data with compression */ > - stat_dec_inline_inode(inode); > - clear_inode_flag(inode, FI_INLINE_DATA); > - set_compress_context(inode); > - return; > - } > -} > - > static int f2fs_create(struct user_namespace *mnt_userns, struct inode *dir, > struct dentry *dentry, umode_t mode, bool excl) > { > @@ -352,15 +358,13 @@ static int f2fs_create(struct user_namespace *mnt_userns, struct inode *dir, > if (err) > return err; > > - inode = f2fs_new_inode(mnt_userns, dir, mode); > + inode = f2fs_new_inode(mnt_userns, dir, mode, dentry->d_name.name); > if (IS_ERR(inode)) > return PTR_ERR(inode); > > if (!test_opt(sbi, DISABLE_EXT_IDENTIFY)) > set_file_temperature(sbi, inode, dentry->d_name.name); > > - set_compress_inode(sbi, inode, dentry->d_name.name); > - > inode->i_op = &f2fs_file_inode_operations; > inode->i_fop = &f2fs_file_operations; > inode->i_mapping->a_ops = &f2fs_dblock_aops; > @@ -689,7 +693,7 @@ static int f2fs_symlink(struct user_namespace *mnt_userns, struct inode *dir, > if (err) > return err; > > - inode = f2fs_new_inode(mnt_userns, dir, S_IFLNK | S_IRWXUGO); > + inode = f2fs_new_inode(mnt_userns, dir, S_IFLNK | S_IRWXUGO, NULL); > if (IS_ERR(inode)) > return PTR_ERR(inode); > > @@ -760,7 +764,7 @@ static int f2fs_mkdir(struct user_namespace *mnt_userns, struct inode *dir, > if (err) > return err; > > - inode = f2fs_new_inode(mnt_userns, dir, S_IFDIR | mode); > + inode = f2fs_new_inode(mnt_userns, dir, S_IFDIR | mode, dentry->d_name.name); > if (IS_ERR(inode)) > return PTR_ERR(inode); > > @@ -817,7 +821,7 @@ static int f2fs_mknod(struct user_namespace *mnt_userns, struct inode *dir, > if (err) > return err; > > - inode = f2fs_new_inode(mnt_userns, dir, mode); > + inode = f2fs_new_inode(mnt_userns, dir, mode, NULL); > if (IS_ERR(inode)) > return PTR_ERR(inode); > > @@ -856,7 +860,7 @@ static int __f2fs_tmpfile(struct user_namespace *mnt_userns, struct inode *dir, > if (err) > return err; > > - inode = f2fs_new_inode(mnt_userns, dir, mode); > + inode = f2fs_new_inode(mnt_userns, dir, mode, NULL); > if (IS_ERR(inode)) > return PTR_ERR(inode); > > -- > 2.25.1
On 11/16, Sheng Yong wrote: > If compress_extension is set, and a newly created file matches the > extension, the file could be marked as compression file. However, > if inline_data is also enabled, there is no chance to check its > extension since f2fs_should_compress() always returns false. > > This patch moves set_compress_inode(), which do extension check, in > f2fs_should_compress() to check extensions before setting inline > data flag. > > Fixes: 7165841d578e ("f2fs: fix to check inline_data during compressed inode conversion") > Signed-off-by: Sheng Yong <shengyong@oppo.com> > Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org> > --- > fs/f2fs/f2fs.h | 1 + > fs/f2fs/namei.c | 336 ++++++++++++++++++++++++------------------------ > 2 files changed, 171 insertions(+), 166 deletions(-) > --- > > Hi, Jaegeuk, Chao, > > How about adding a bool `may_compress' in set_compress_new_inode, set > `my_compress` according to several conditions. If it is false, clear > F2FS_COMPR_FL. > > And set_compress_context is also changed to clear F2FS_NOCOMP_FL, > otherwise, if F2FS_NOCOMP_FL is inherited from parent and hit > compress_extension, both F2FS_NOCOMP_FL and F2FS_COMPR_FL are set. > > diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h > index 6a8cbf5bb1871..a3420fbb29214 100644 > --- a/fs/f2fs/f2fs.h > +++ b/fs/f2fs/f2fs.h > @@ -4355,6 +4355,7 @@ static inline int set_compress_context(struct inode *inode) > F2FS_I(inode)->i_compress_flag |= > F2FS_OPTION(sbi).compress_level << > COMPRESS_LEVEL_OFFSET; > + F2FS_I(inode)->i_flags &= ~F2FS_NOCOMP_FL; > F2FS_I(inode)->i_flags |= F2FS_COMPR_FL; > set_inode_flag(inode, FI_COMPRESSED_FILE); > stat_inc_compr_inode(inode); > diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c > index e104409c3a0e5..36ec5cf7cf859 100644 > --- a/fs/f2fs/namei.c > +++ b/fs/f2fs/namei.c > @@ -22,8 +22,170 @@ > #include "acl.h" > #include <trace/events/f2fs.h> > > +static inline int is_extension_exist(const unsigned char *s, const char *sub, > + bool tmp_ext) > +{ > + size_t slen = strlen(s); > + size_t sublen = strlen(sub); > + int i; > + > + if (sublen == 1 && *sub == '*') > + return 1; > + > + /* > + * filename format of multimedia file should be defined as: > + * "filename + '.' + extension + (optional: '.' + temp extension)". > + */ > + if (slen < sublen + 2) > + return 0; > + > + if (!tmp_ext) { > + /* file has no temp extension */ > + if (s[slen - sublen - 1] != '.') > + return 0; > + return !strncasecmp(s + slen - sublen, sub, sublen); > + } > + > + for (i = 1; i < slen - sublen; i++) { > + if (s[i] != '.') > + continue; > + if (!strncasecmp(s + i + 1, sub, sublen)) > + return 1; > + } > + > + return 0; > +} > + > +int f2fs_update_extension_list(struct f2fs_sb_info *sbi, const char *name, > + bool hot, bool set) > +{ > + __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; > + int cold_count = le32_to_cpu(sbi->raw_super->extension_count); > + int hot_count = sbi->raw_super->hot_ext_count; > + int total_count = cold_count + hot_count; > + int start, count; > + int i; > + > + if (set) { > + if (total_count == F2FS_MAX_EXTENSION) > + return -EINVAL; > + } else { > + if (!hot && !cold_count) > + return -EINVAL; > + if (hot && !hot_count) > + return -EINVAL; > + } > + > + if (hot) { > + start = cold_count; > + count = total_count; > + } else { > + start = 0; > + count = cold_count; > + } > + > + for (i = start; i < count; i++) { > + if (strcmp(name, extlist[i])) > + continue; > + > + if (set) > + return -EINVAL; > + > + memcpy(extlist[i], extlist[i + 1], > + F2FS_EXTENSION_LEN * (total_count - i - 1)); > + memset(extlist[total_count - 1], 0, F2FS_EXTENSION_LEN); > + if (hot) > + sbi->raw_super->hot_ext_count = hot_count - 1; > + else > + sbi->raw_super->extension_count = > + cpu_to_le32(cold_count - 1); > + return 0; > + } > + > + if (!set) > + return -EINVAL; > + > + if (hot) { > + memcpy(extlist[count], name, strlen(name)); > + sbi->raw_super->hot_ext_count = hot_count + 1; > + } else { > + char buf[F2FS_MAX_EXTENSION][F2FS_EXTENSION_LEN]; > + > + memcpy(buf, &extlist[cold_count], > + F2FS_EXTENSION_LEN * hot_count); > + memset(extlist[cold_count], 0, F2FS_EXTENSION_LEN); > + memcpy(extlist[cold_count], name, strlen(name)); > + memcpy(&extlist[cold_count + 1], buf, > + F2FS_EXTENSION_LEN * hot_count); > + sbi->raw_super->extension_count = cpu_to_le32(cold_count + 1); > + } > + return 0; > +} > + > +static void set_compress_new_inode(struct f2fs_sb_info *sbi, struct inode *dir, > + struct inode *inode, const unsigned char *name) > +{ > + struct f2fs_inode_info *fi = F2FS_I(inode); > + __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; > + unsigned char (*noext)[F2FS_EXTENSION_LEN] = > + F2FS_OPTION(sbi).noextensions; > + unsigned char (*ext)[F2FS_EXTENSION_LEN] = F2FS_OPTION(sbi).extensions; > + unsigned char ext_cnt = F2FS_OPTION(sbi).compress_ext_cnt; > + unsigned char noext_cnt = F2FS_OPTION(sbi).nocompress_ext_cnt; > + bool may_compress = false; > + int i, cold_count, hot_count; > + > + if (!f2fs_sb_has_compression(sbi) || !name) > + return; > + if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode)) > + return; > + > + /* Inherit the compression flag in directory */ > + if (fi->i_flags & FS_COMPR_FL) > + may_compress = true; > + > + /* Start to check extension list for regular file */ > + if ((!ext_cnt && !noext_cnt) || S_ISDIR(inode->i_mode)) > + goto set_compress; > + > + /* Don't compress hot files. */ > + f2fs_down_read(&sbi->sb_lock); > + cold_count = le32_to_cpu(sbi->raw_super->extension_count); > + hot_count = sbi->raw_super->hot_ext_count; > + for (i = cold_count; i < cold_count + hot_count; i++) > + if (is_extension_exist(name, extlist[i], false)) { > + may_compress = false; > + f2fs_up_read(&sbi->sb_lock); > + goto set_compress; > + } > + f2fs_up_read(&sbi->sb_lock); > + > + /* Don't compress unallowed extension. */ > + for (i = 0; i < noext_cnt; i++) { > + if (is_extension_exist(name, noext[i], false)) { > + may_compress = false; > + goto set_compress; > + } > + } > + > + /* Compress wanting extension. */ > + for (i = 0; i < ext_cnt; i++) { > + if (is_extension_exist(name, ext[i], false)) { > + may_compress = true; > + goto set_compress; > + } > + } > + > +set_compress: > + if (may_compress) > + set_compress_context(inode); > + else if (fi->i_flags & F2FS_COMPR_FL) > + fi->i_flags &= ~F2FS_COMPR_FL; Let's inherit F2FS_COMPR_FL and F2FS_NOCOMP_FL here instead of getting it before. > +} > + > static struct inode *f2fs_new_inode(struct user_namespace *mnt_userns, > - struct inode *dir, umode_t mode) > + struct inode *dir, umode_t mode, > + const char *name) > { > struct f2fs_sb_info *sbi = F2FS_I_SB(dir); > nid_t ino; > @@ -114,12 +276,8 @@ static struct inode *f2fs_new_inode(struct user_namespace *mnt_userns, > if (F2FS_I(inode)->i_flags & F2FS_PROJINHERIT_FL) > set_inode_flag(inode, FI_PROJ_INHERIT); > > - if (f2fs_sb_has_compression(sbi)) { > - /* Inherit the compression flag in directory */ > - if ((F2FS_I(dir)->i_flags & F2FS_COMPR_FL) && > - f2fs_may_compress(inode)) > - set_compress_context(inode); > - } > + /* Check compression first. */ > + set_compress_new_inode(sbi, dir, inode, name); > > /* Should enable inline_data after compression set */ > if (test_opt(sbi, INLINE_DATA) && f2fs_may_inline_data(inode)) > @@ -153,40 +311,6 @@ static struct inode *f2fs_new_inode(struct user_namespace *mnt_userns, > return ERR_PTR(err); > } > > -static inline int is_extension_exist(const unsigned char *s, const char *sub, > - bool tmp_ext) > -{ > - size_t slen = strlen(s); > - size_t sublen = strlen(sub); > - int i; > - > - if (sublen == 1 && *sub == '*') > - return 1; > - > - /* > - * filename format of multimedia file should be defined as: > - * "filename + '.' + extension + (optional: '.' + temp extension)". > - */ > - if (slen < sublen + 2) > - return 0; > - > - if (!tmp_ext) { > - /* file has no temp extension */ > - if (s[slen - sublen - 1] != '.') > - return 0; > - return !strncasecmp(s + slen - sublen, sub, sublen); > - } > - > - for (i = 1; i < slen - sublen; i++) { > - if (s[i] != '.') > - continue; > - if (!strncasecmp(s + i + 1, sub, sublen)) > - return 1; > - } > - > - return 0; > -} > - > /* > * Set file's temperature for hot/cold data separation > */ > @@ -217,124 +341,6 @@ static inline void set_file_temperature(struct f2fs_sb_info *sbi, struct inode * > file_set_hot(inode); > } > > -int f2fs_update_extension_list(struct f2fs_sb_info *sbi, const char *name, > - bool hot, bool set) > -{ > - __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; > - int cold_count = le32_to_cpu(sbi->raw_super->extension_count); > - int hot_count = sbi->raw_super->hot_ext_count; > - int total_count = cold_count + hot_count; > - int start, count; > - int i; > - > - if (set) { > - if (total_count == F2FS_MAX_EXTENSION) > - return -EINVAL; > - } else { > - if (!hot && !cold_count) > - return -EINVAL; > - if (hot && !hot_count) > - return -EINVAL; > - } > - > - if (hot) { > - start = cold_count; > - count = total_count; > - } else { > - start = 0; > - count = cold_count; > - } > - > - for (i = start; i < count; i++) { > - if (strcmp(name, extlist[i])) > - continue; > - > - if (set) > - return -EINVAL; > - > - memcpy(extlist[i], extlist[i + 1], > - F2FS_EXTENSION_LEN * (total_count - i - 1)); > - memset(extlist[total_count - 1], 0, F2FS_EXTENSION_LEN); > - if (hot) > - sbi->raw_super->hot_ext_count = hot_count - 1; > - else > - sbi->raw_super->extension_count = > - cpu_to_le32(cold_count - 1); > - return 0; > - } > - > - if (!set) > - return -EINVAL; > - > - if (hot) { > - memcpy(extlist[count], name, strlen(name)); > - sbi->raw_super->hot_ext_count = hot_count + 1; > - } else { > - char buf[F2FS_MAX_EXTENSION][F2FS_EXTENSION_LEN]; > - > - memcpy(buf, &extlist[cold_count], > - F2FS_EXTENSION_LEN * hot_count); > - memset(extlist[cold_count], 0, F2FS_EXTENSION_LEN); > - memcpy(extlist[cold_count], name, strlen(name)); > - memcpy(&extlist[cold_count + 1], buf, > - F2FS_EXTENSION_LEN * hot_count); > - sbi->raw_super->extension_count = cpu_to_le32(cold_count + 1); > - } > - return 0; > -} > - > -static void set_compress_inode(struct f2fs_sb_info *sbi, struct inode *inode, > - const unsigned char *name) > -{ > - __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; > - unsigned char (*noext)[F2FS_EXTENSION_LEN] = F2FS_OPTION(sbi).noextensions; > - unsigned char (*ext)[F2FS_EXTENSION_LEN] = F2FS_OPTION(sbi).extensions; > - unsigned char ext_cnt = F2FS_OPTION(sbi).compress_ext_cnt; > - unsigned char noext_cnt = F2FS_OPTION(sbi).nocompress_ext_cnt; > - int i, cold_count, hot_count; > - > - if (!f2fs_sb_has_compression(sbi) || > - F2FS_I(inode)->i_flags & F2FS_NOCOMP_FL || > - !f2fs_may_compress(inode) || > - (!ext_cnt && !noext_cnt)) > - return; > - > - f2fs_down_read(&sbi->sb_lock); > - > - cold_count = le32_to_cpu(sbi->raw_super->extension_count); > - hot_count = sbi->raw_super->hot_ext_count; > - > - for (i = cold_count; i < cold_count + hot_count; i++) { > - if (is_extension_exist(name, extlist[i], false)) { > - f2fs_up_read(&sbi->sb_lock); > - return; > - } > - } > - > - f2fs_up_read(&sbi->sb_lock); > - > - for (i = 0; i < noext_cnt; i++) { > - if (is_extension_exist(name, noext[i], false)) { > - f2fs_disable_compressed_file(inode); > - return; > - } > - } > - > - if (is_inode_flag_set(inode, FI_COMPRESSED_FILE)) > - return; > - > - for (i = 0; i < ext_cnt; i++) { > - if (!is_extension_exist(name, ext[i], false)) > - continue; > - > - /* Do not use inline_data with compression */ > - stat_dec_inline_inode(inode); > - clear_inode_flag(inode, FI_INLINE_DATA); > - set_compress_context(inode); > - return; > - } > -} > - > static int f2fs_create(struct user_namespace *mnt_userns, struct inode *dir, > struct dentry *dentry, umode_t mode, bool excl) > { > @@ -352,15 +358,13 @@ static int f2fs_create(struct user_namespace *mnt_userns, struct inode *dir, > if (err) > return err; > > - inode = f2fs_new_inode(mnt_userns, dir, mode); > + inode = f2fs_new_inode(mnt_userns, dir, mode, dentry->d_name.name); > if (IS_ERR(inode)) > return PTR_ERR(inode); > > if (!test_opt(sbi, DISABLE_EXT_IDENTIFY)) > set_file_temperature(sbi, inode, dentry->d_name.name); > > - set_compress_inode(sbi, inode, dentry->d_name.name); > - > inode->i_op = &f2fs_file_inode_operations; > inode->i_fop = &f2fs_file_operations; > inode->i_mapping->a_ops = &f2fs_dblock_aops; > @@ -689,7 +693,7 @@ static int f2fs_symlink(struct user_namespace *mnt_userns, struct inode *dir, > if (err) > return err; > > - inode = f2fs_new_inode(mnt_userns, dir, S_IFLNK | S_IRWXUGO); > + inode = f2fs_new_inode(mnt_userns, dir, S_IFLNK | S_IRWXUGO, NULL); > if (IS_ERR(inode)) > return PTR_ERR(inode); > > @@ -760,7 +764,7 @@ static int f2fs_mkdir(struct user_namespace *mnt_userns, struct inode *dir, > if (err) > return err; > > - inode = f2fs_new_inode(mnt_userns, dir, S_IFDIR | mode); > + inode = f2fs_new_inode(mnt_userns, dir, S_IFDIR | mode, dentry->d_name.name); > if (IS_ERR(inode)) > return PTR_ERR(inode); > > @@ -817,7 +821,7 @@ static int f2fs_mknod(struct user_namespace *mnt_userns, struct inode *dir, > if (err) > return err; > > - inode = f2fs_new_inode(mnt_userns, dir, mode); > + inode = f2fs_new_inode(mnt_userns, dir, mode, NULL); > if (IS_ERR(inode)) > return PTR_ERR(inode); > > @@ -856,7 +860,7 @@ static int __f2fs_tmpfile(struct user_namespace *mnt_userns, struct inode *dir, > if (err) > return err; > > - inode = f2fs_new_inode(mnt_userns, dir, mode); > + inode = f2fs_new_inode(mnt_userns, dir, mode, NULL); > if (IS_ERR(inode)) > return PTR_ERR(inode); > > -- > 2.25.1
If compress_extension is set, and a newly created file matches the extension, the file could be marked as compression file. However, if inline_data is also enabled, there is no chance to check its extension since f2fs_should_compress() always returns false. This patch moves set_compress_inode(), which do extension check, in f2fs_should_compress() to check extensions before setting inline data flag. Fixes: 7165841d578e ("f2fs: fix to check inline_data during compressed inode conversion") Signed-off-by: Sheng Yong <shengyong@oppo.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org> --- Checking this version. fs/f2fs/f2fs.h | 2 +- fs/f2fs/namei.c | 328 ++++++++++++++++++++++++------------------------ 2 files changed, 163 insertions(+), 167 deletions(-) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index b89b5d755ce0..dedac413bf64 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -2980,7 +2980,7 @@ static inline void f2fs_change_bit(unsigned int nr, char *addr) /* Flags that should be inherited by new inodes from their parent. */ #define F2FS_FL_INHERITED (F2FS_SYNC_FL | F2FS_NODUMP_FL | F2FS_NOATIME_FL | \ F2FS_DIRSYNC_FL | F2FS_PROJINHERIT_FL | \ - F2FS_CASEFOLD_FL | F2FS_COMPR_FL | F2FS_NOCOMP_FL) + F2FS_CASEFOLD_FL) /* Flags that are appropriate for regular files (all but dir-specific ones). */ #define F2FS_REG_FLMASK (~(F2FS_DIRSYNC_FL | F2FS_PROJINHERIT_FL | \ diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index e104409c3a0e..cb7441a19d22 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c @@ -22,8 +22,161 @@ #include "acl.h" #include <trace/events/f2fs.h> +static inline int is_extension_exist(const unsigned char *s, const char *sub, + bool tmp_ext) +{ + size_t slen = strlen(s); + size_t sublen = strlen(sub); + int i; + + if (sublen == 1 && *sub == '*') + return 1; + + /* + * filename format of multimedia file should be defined as: + * "filename + '.' + extension + (optional: '.' + temp extension)". + */ + if (slen < sublen + 2) + return 0; + + if (!tmp_ext) { + /* file has no temp extension */ + if (s[slen - sublen - 1] != '.') + return 0; + return !strncasecmp(s + slen - sublen, sub, sublen); + } + + for (i = 1; i < slen - sublen; i++) { + if (s[i] != '.') + continue; + if (!strncasecmp(s + i + 1, sub, sublen)) + return 1; + } + + return 0; +} + +int f2fs_update_extension_list(struct f2fs_sb_info *sbi, const char *name, + bool hot, bool set) +{ + __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; + int cold_count = le32_to_cpu(sbi->raw_super->extension_count); + int hot_count = sbi->raw_super->hot_ext_count; + int total_count = cold_count + hot_count; + int start, count; + int i; + + if (set) { + if (total_count == F2FS_MAX_EXTENSION) + return -EINVAL; + } else { + if (!hot && !cold_count) + return -EINVAL; + if (hot && !hot_count) + return -EINVAL; + } + + if (hot) { + start = cold_count; + count = total_count; + } else { + start = 0; + count = cold_count; + } + + for (i = start; i < count; i++) { + if (strcmp(name, extlist[i])) + continue; + + if (set) + return -EINVAL; + + memcpy(extlist[i], extlist[i + 1], + F2FS_EXTENSION_LEN * (total_count - i - 1)); + memset(extlist[total_count - 1], 0, F2FS_EXTENSION_LEN); + if (hot) + sbi->raw_super->hot_ext_count = hot_count - 1; + else + sbi->raw_super->extension_count = + cpu_to_le32(cold_count - 1); + return 0; + } + + if (!set) + return -EINVAL; + + if (hot) { + memcpy(extlist[count], name, strlen(name)); + sbi->raw_super->hot_ext_count = hot_count + 1; + } else { + char buf[F2FS_MAX_EXTENSION][F2FS_EXTENSION_LEN]; + + memcpy(buf, &extlist[cold_count], + F2FS_EXTENSION_LEN * hot_count); + memset(extlist[cold_count], 0, F2FS_EXTENSION_LEN); + memcpy(extlist[cold_count], name, strlen(name)); + memcpy(&extlist[cold_count + 1], buf, + F2FS_EXTENSION_LEN * hot_count); + sbi->raw_super->extension_count = cpu_to_le32(cold_count + 1); + } + return 0; +} + +static void set_compress_new_inode(struct f2fs_sb_info *sbi, struct inode *dir, + struct inode *inode, const unsigned char *name) +{ + __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; + unsigned char (*noext)[F2FS_EXTENSION_LEN] = + F2FS_OPTION(sbi).noextensions; + unsigned char (*ext)[F2FS_EXTENSION_LEN] = F2FS_OPTION(sbi).extensions; + unsigned char ext_cnt = F2FS_OPTION(sbi).compress_ext_cnt; + unsigned char noext_cnt = F2FS_OPTION(sbi).nocompress_ext_cnt; + int i, cold_count, hot_count; + + /* Caller should give the name of regular file or directory. */ + if (!f2fs_sb_has_compression(sbi) || !name) + return; + + if (S_ISDIR(inode->i_mode)) + goto inherit_comp; + + /* Don't compress hot files. */ + f2fs_down_read(&sbi->sb_lock); + cold_count = le32_to_cpu(sbi->raw_super->extension_count); + hot_count = sbi->raw_super->hot_ext_count; + for (i = cold_count; i < cold_count + hot_count; i++) + if (is_extension_exist(name, extlist[i], false)) + break; + f2fs_up_read(&sbi->sb_lock); + if (i < (cold_count + hot_count)) + return; + + /* Don't compress unallowed extension. */ + for (i = 0; i < noext_cnt; i++) + if (is_extension_exist(name, noext[i], false)) + return; +inherit_comp: + /* Inherit the {no-}compression flag in directory */ + if (F2FS_I(dir)->i_flags & F2FS_NOCOMP_FL) { + F2FS_I(inode)->i_flags |= F2FS_NOCOMP_FL; + return; + } else if (F2FS_I(dir)->i_flags & F2FS_COMPR_FL) { + set_compress_context(inode); + return; + } + + /* Compress wanting extension. */ + for (i = 0; i < ext_cnt; i++) { + if (is_extension_exist(name, ext[i], false)) { + set_compress_context(inode); + return; + } + } +} + static struct inode *f2fs_new_inode(struct user_namespace *mnt_userns, - struct inode *dir, umode_t mode) + struct inode *dir, umode_t mode, + const char *name) { struct f2fs_sb_info *sbi = F2FS_I_SB(dir); nid_t ino; @@ -114,12 +267,8 @@ static struct inode *f2fs_new_inode(struct user_namespace *mnt_userns, if (F2FS_I(inode)->i_flags & F2FS_PROJINHERIT_FL) set_inode_flag(inode, FI_PROJ_INHERIT); - if (f2fs_sb_has_compression(sbi)) { - /* Inherit the compression flag in directory */ - if ((F2FS_I(dir)->i_flags & F2FS_COMPR_FL) && - f2fs_may_compress(inode)) - set_compress_context(inode); - } + /* Check compression first. */ + set_compress_new_inode(sbi, dir, inode, name); /* Should enable inline_data after compression set */ if (test_opt(sbi, INLINE_DATA) && f2fs_may_inline_data(inode)) @@ -153,40 +302,6 @@ static struct inode *f2fs_new_inode(struct user_namespace *mnt_userns, return ERR_PTR(err); } -static inline int is_extension_exist(const unsigned char *s, const char *sub, - bool tmp_ext) -{ - size_t slen = strlen(s); - size_t sublen = strlen(sub); - int i; - - if (sublen == 1 && *sub == '*') - return 1; - - /* - * filename format of multimedia file should be defined as: - * "filename + '.' + extension + (optional: '.' + temp extension)". - */ - if (slen < sublen + 2) - return 0; - - if (!tmp_ext) { - /* file has no temp extension */ - if (s[slen - sublen - 1] != '.') - return 0; - return !strncasecmp(s + slen - sublen, sub, sublen); - } - - for (i = 1; i < slen - sublen; i++) { - if (s[i] != '.') - continue; - if (!strncasecmp(s + i + 1, sub, sublen)) - return 1; - } - - return 0; -} - /* * Set file's temperature for hot/cold data separation */ @@ -217,124 +332,6 @@ static inline void set_file_temperature(struct f2fs_sb_info *sbi, struct inode * file_set_hot(inode); } -int f2fs_update_extension_list(struct f2fs_sb_info *sbi, const char *name, - bool hot, bool set) -{ - __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; - int cold_count = le32_to_cpu(sbi->raw_super->extension_count); - int hot_count = sbi->raw_super->hot_ext_count; - int total_count = cold_count + hot_count; - int start, count; - int i; - - if (set) { - if (total_count == F2FS_MAX_EXTENSION) - return -EINVAL; - } else { - if (!hot && !cold_count) - return -EINVAL; - if (hot && !hot_count) - return -EINVAL; - } - - if (hot) { - start = cold_count; - count = total_count; - } else { - start = 0; - count = cold_count; - } - - for (i = start; i < count; i++) { - if (strcmp(name, extlist[i])) - continue; - - if (set) - return -EINVAL; - - memcpy(extlist[i], extlist[i + 1], - F2FS_EXTENSION_LEN * (total_count - i - 1)); - memset(extlist[total_count - 1], 0, F2FS_EXTENSION_LEN); - if (hot) - sbi->raw_super->hot_ext_count = hot_count - 1; - else - sbi->raw_super->extension_count = - cpu_to_le32(cold_count - 1); - return 0; - } - - if (!set) - return -EINVAL; - - if (hot) { - memcpy(extlist[count], name, strlen(name)); - sbi->raw_super->hot_ext_count = hot_count + 1; - } else { - char buf[F2FS_MAX_EXTENSION][F2FS_EXTENSION_LEN]; - - memcpy(buf, &extlist[cold_count], - F2FS_EXTENSION_LEN * hot_count); - memset(extlist[cold_count], 0, F2FS_EXTENSION_LEN); - memcpy(extlist[cold_count], name, strlen(name)); - memcpy(&extlist[cold_count + 1], buf, - F2FS_EXTENSION_LEN * hot_count); - sbi->raw_super->extension_count = cpu_to_le32(cold_count + 1); - } - return 0; -} - -static void set_compress_inode(struct f2fs_sb_info *sbi, struct inode *inode, - const unsigned char *name) -{ - __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; - unsigned char (*noext)[F2FS_EXTENSION_LEN] = F2FS_OPTION(sbi).noextensions; - unsigned char (*ext)[F2FS_EXTENSION_LEN] = F2FS_OPTION(sbi).extensions; - unsigned char ext_cnt = F2FS_OPTION(sbi).compress_ext_cnt; - unsigned char noext_cnt = F2FS_OPTION(sbi).nocompress_ext_cnt; - int i, cold_count, hot_count; - - if (!f2fs_sb_has_compression(sbi) || - F2FS_I(inode)->i_flags & F2FS_NOCOMP_FL || - !f2fs_may_compress(inode) || - (!ext_cnt && !noext_cnt)) - return; - - f2fs_down_read(&sbi->sb_lock); - - cold_count = le32_to_cpu(sbi->raw_super->extension_count); - hot_count = sbi->raw_super->hot_ext_count; - - for (i = cold_count; i < cold_count + hot_count; i++) { - if (is_extension_exist(name, extlist[i], false)) { - f2fs_up_read(&sbi->sb_lock); - return; - } - } - - f2fs_up_read(&sbi->sb_lock); - - for (i = 0; i < noext_cnt; i++) { - if (is_extension_exist(name, noext[i], false)) { - f2fs_disable_compressed_file(inode); - return; - } - } - - if (is_inode_flag_set(inode, FI_COMPRESSED_FILE)) - return; - - for (i = 0; i < ext_cnt; i++) { - if (!is_extension_exist(name, ext[i], false)) - continue; - - /* Do not use inline_data with compression */ - stat_dec_inline_inode(inode); - clear_inode_flag(inode, FI_INLINE_DATA); - set_compress_context(inode); - return; - } -} - static int f2fs_create(struct user_namespace *mnt_userns, struct inode *dir, struct dentry *dentry, umode_t mode, bool excl) { @@ -352,15 +349,13 @@ static int f2fs_create(struct user_namespace *mnt_userns, struct inode *dir, if (err) return err; - inode = f2fs_new_inode(mnt_userns, dir, mode); + inode = f2fs_new_inode(mnt_userns, dir, mode, dentry->d_name.name); if (IS_ERR(inode)) return PTR_ERR(inode); if (!test_opt(sbi, DISABLE_EXT_IDENTIFY)) set_file_temperature(sbi, inode, dentry->d_name.name); - set_compress_inode(sbi, inode, dentry->d_name.name); - inode->i_op = &f2fs_file_inode_operations; inode->i_fop = &f2fs_file_operations; inode->i_mapping->a_ops = &f2fs_dblock_aops; @@ -689,7 +684,7 @@ static int f2fs_symlink(struct user_namespace *mnt_userns, struct inode *dir, if (err) return err; - inode = f2fs_new_inode(mnt_userns, dir, S_IFLNK | S_IRWXUGO); + inode = f2fs_new_inode(mnt_userns, dir, S_IFLNK | S_IRWXUGO, NULL); if (IS_ERR(inode)) return PTR_ERR(inode); @@ -760,7 +755,8 @@ static int f2fs_mkdir(struct user_namespace *mnt_userns, struct inode *dir, if (err) return err; - inode = f2fs_new_inode(mnt_userns, dir, S_IFDIR | mode); + inode = f2fs_new_inode(mnt_userns, dir, S_IFDIR | mode, + dentry->d_name.name); if (IS_ERR(inode)) return PTR_ERR(inode); @@ -817,7 +813,7 @@ static int f2fs_mknod(struct user_namespace *mnt_userns, struct inode *dir, if (err) return err; - inode = f2fs_new_inode(mnt_userns, dir, mode); + inode = f2fs_new_inode(mnt_userns, dir, mode, NULL); if (IS_ERR(inode)) return PTR_ERR(inode); @@ -856,7 +852,7 @@ static int __f2fs_tmpfile(struct user_namespace *mnt_userns, struct inode *dir, if (err) return err; - inode = f2fs_new_inode(mnt_userns, dir, mode); + inode = f2fs_new_inode(mnt_userns, dir, mode, NULL); if (IS_ERR(inode)) return PTR_ERR(inode);
On 2022/11/16 7:00, Jaegeuk Kim wrote: > If compress_extension is set, and a newly created file matches the > extension, the file could be marked as compression file. However, > if inline_data is also enabled, there is no chance to check its > extension since f2fs_should_compress() always returns false. > > This patch moves set_compress_inode(), which do extension check, in > f2fs_should_compress() to check extensions before setting inline > data flag. > > Fixes: 7165841d578e ("f2fs: fix to check inline_data during compressed inode conversion") > Signed-off-by: Sheng Yong <shengyong@oppo.com> > Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org> > --- > > Checking this version. > > fs/f2fs/f2fs.h | 2 +- > fs/f2fs/namei.c | 328 ++++++++++++++++++++++++------------------------ > 2 files changed, 163 insertions(+), 167 deletions(-) > > diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h > index b89b5d755ce0..dedac413bf64 100644 > --- a/fs/f2fs/f2fs.h > +++ b/fs/f2fs/f2fs.h > @@ -2980,7 +2980,7 @@ static inline void f2fs_change_bit(unsigned int nr, char *addr) > /* Flags that should be inherited by new inodes from their parent. */ > #define F2FS_FL_INHERITED (F2FS_SYNC_FL | F2FS_NODUMP_FL | F2FS_NOATIME_FL | \ > F2FS_DIRSYNC_FL | F2FS_PROJINHERIT_FL | \ > - F2FS_CASEFOLD_FL | F2FS_COMPR_FL | F2FS_NOCOMP_FL) > + F2FS_CASEFOLD_FL) > > /* Flags that are appropriate for regular files (all but dir-specific ones). */ > #define F2FS_REG_FLMASK (~(F2FS_DIRSYNC_FL | F2FS_PROJINHERIT_FL | \ > diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c > index e104409c3a0e..cb7441a19d22 100644 > --- a/fs/f2fs/namei.c > +++ b/fs/f2fs/namei.c > @@ -22,8 +22,161 @@ > #include "acl.h" > #include <trace/events/f2fs.h> > > +static inline int is_extension_exist(const unsigned char *s, const char *sub, > + bool tmp_ext) > +{ > + size_t slen = strlen(s); > + size_t sublen = strlen(sub); > + int i; > + > + if (sublen == 1 && *sub == '*') > + return 1; > + > + /* > + * filename format of multimedia file should be defined as: > + * "filename + '.' + extension + (optional: '.' + temp extension)". > + */ > + if (slen < sublen + 2) > + return 0; > + > + if (!tmp_ext) { > + /* file has no temp extension */ > + if (s[slen - sublen - 1] != '.') > + return 0; > + return !strncasecmp(s + slen - sublen, sub, sublen); > + } > + > + for (i = 1; i < slen - sublen; i++) { > + if (s[i] != '.') > + continue; > + if (!strncasecmp(s + i + 1, sub, sublen)) > + return 1; > + } > + > + return 0; > +} > + > +int f2fs_update_extension_list(struct f2fs_sb_info *sbi, const char *name, > + bool hot, bool set) > +{ > + __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; > + int cold_count = le32_to_cpu(sbi->raw_super->extension_count); > + int hot_count = sbi->raw_super->hot_ext_count; > + int total_count = cold_count + hot_count; > + int start, count; > + int i; > + > + if (set) { > + if (total_count == F2FS_MAX_EXTENSION) > + return -EINVAL; > + } else { > + if (!hot && !cold_count) > + return -EINVAL; > + if (hot && !hot_count) > + return -EINVAL; > + } > + > + if (hot) { > + start = cold_count; > + count = total_count; > + } else { > + start = 0; > + count = cold_count; > + } > + > + for (i = start; i < count; i++) { > + if (strcmp(name, extlist[i])) > + continue; > + > + if (set) > + return -EINVAL; > + > + memcpy(extlist[i], extlist[i + 1], > + F2FS_EXTENSION_LEN * (total_count - i - 1)); > + memset(extlist[total_count - 1], 0, F2FS_EXTENSION_LEN); > + if (hot) > + sbi->raw_super->hot_ext_count = hot_count - 1; > + else > + sbi->raw_super->extension_count = > + cpu_to_le32(cold_count - 1); > + return 0; > + } > + > + if (!set) > + return -EINVAL; > + > + if (hot) { > + memcpy(extlist[count], name, strlen(name)); > + sbi->raw_super->hot_ext_count = hot_count + 1; > + } else { > + char buf[F2FS_MAX_EXTENSION][F2FS_EXTENSION_LEN]; > + > + memcpy(buf, &extlist[cold_count], > + F2FS_EXTENSION_LEN * hot_count); > + memset(extlist[cold_count], 0, F2FS_EXTENSION_LEN); > + memcpy(extlist[cold_count], name, strlen(name)); > + memcpy(&extlist[cold_count + 1], buf, > + F2FS_EXTENSION_LEN * hot_count); > + sbi->raw_super->extension_count = cpu_to_le32(cold_count + 1); > + } > + return 0; > +} > + > +static void set_compress_new_inode(struct f2fs_sb_info *sbi, struct inode *dir, > + struct inode *inode, const unsigned char *name) > +{ > + __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; > + unsigned char (*noext)[F2FS_EXTENSION_LEN] = > + F2FS_OPTION(sbi).noextensions; > + unsigned char (*ext)[F2FS_EXTENSION_LEN] = F2FS_OPTION(sbi).extensions; > + unsigned char ext_cnt = F2FS_OPTION(sbi).compress_ext_cnt; > + unsigned char noext_cnt = F2FS_OPTION(sbi).nocompress_ext_cnt; > + int i, cold_count, hot_count; > + > + /* Caller should give the name of regular file or directory. */ > + if (!f2fs_sb_has_compression(sbi) || !name) > + return; > + > + if (S_ISDIR(inode->i_mode)) > + goto inherit_comp; > + > + /* Don't compress hot files. */ > + f2fs_down_read(&sbi->sb_lock); > + cold_count = le32_to_cpu(sbi->raw_super->extension_count); > + hot_count = sbi->raw_super->hot_ext_count; > + for (i = cold_count; i < cold_count + hot_count; i++) > + if (is_extension_exist(name, extlist[i], false)) > + break; > + f2fs_up_read(&sbi->sb_lock); > + if (i < (cold_count + hot_count)) > + return; > + > + /* Don't compress unallowed extension. */ > + for (i = 0; i < noext_cnt; i++) > + if (is_extension_exist(name, noext[i], false)) > + return; > +inherit_comp: > + /* Inherit the {no-}compression flag in directory */ > + if (F2FS_I(dir)->i_flags & F2FS_NOCOMP_FL) { > + F2FS_I(inode)->i_flags |= F2FS_NOCOMP_FL; > + return; Hi, Jaegeuk, It should not return immediately here. The scenario here is: mount -o compress_extension=txt,compress_mode=user mkdir dir f2fs_io setflags nocompression dir # set dir nocompression touch dir/file.txt f2fs_io getflags compression dir/file.txt # file.txt should have compression flag According to f2fs.rst, if dir is set as nocompression, but file's extension hit compress_extension, then the file should be compressed. And before set_compress_context later, F2FS_NOCOMP_FL should be cleared first. thanks, shengyong > + } else if (F2FS_I(dir)->i_flags & F2FS_COMPR_FL) { > + set_compress_context(inode); > + return; > + } > + > + /* Compress wanting extension. */ > + for (i = 0; i < ext_cnt; i++) { > + if (is_extension_exist(name, ext[i], false)) { > + set_compress_context(inode); > + return; > + } > + } > +} > + > static struct inode *f2fs_new_inode(struct user_namespace *mnt_userns, > - struct inode *dir, umode_t mode) > + struct inode *dir, umode_t mode, > + const char *name) > { > struct f2fs_sb_info *sbi = F2FS_I_SB(dir); > nid_t ino; > @@ -114,12 +267,8 @@ static struct inode *f2fs_new_inode(struct user_namespace *mnt_userns, > if (F2FS_I(inode)->i_flags & F2FS_PROJINHERIT_FL) > set_inode_flag(inode, FI_PROJ_INHERIT); > > - if (f2fs_sb_has_compression(sbi)) { > - /* Inherit the compression flag in directory */ > - if ((F2FS_I(dir)->i_flags & F2FS_COMPR_FL) && > - f2fs_may_compress(inode)) > - set_compress_context(inode); > - } > + /* Check compression first. */ > + set_compress_new_inode(sbi, dir, inode, name); > > /* Should enable inline_data after compression set */ > if (test_opt(sbi, INLINE_DATA) && f2fs_may_inline_data(inode)) > @@ -153,40 +302,6 @@ static struct inode *f2fs_new_inode(struct user_namespace *mnt_userns, > return ERR_PTR(err); > } > > -static inline int is_extension_exist(const unsigned char *s, const char *sub, > - bool tmp_ext) > -{ > - size_t slen = strlen(s); > - size_t sublen = strlen(sub); > - int i; > - > - if (sublen == 1 && *sub == '*') > - return 1; > - > - /* > - * filename format of multimedia file should be defined as: > - * "filename + '.' + extension + (optional: '.' + temp extension)". > - */ > - if (slen < sublen + 2) > - return 0; > - > - if (!tmp_ext) { > - /* file has no temp extension */ > - if (s[slen - sublen - 1] != '.') > - return 0; > - return !strncasecmp(s + slen - sublen, sub, sublen); > - } > - > - for (i = 1; i < slen - sublen; i++) { > - if (s[i] != '.') > - continue; > - if (!strncasecmp(s + i + 1, sub, sublen)) > - return 1; > - } > - > - return 0; > -} > - > /* > * Set file's temperature for hot/cold data separation > */ > @@ -217,124 +332,6 @@ static inline void set_file_temperature(struct f2fs_sb_info *sbi, struct inode * > file_set_hot(inode); > } > > -int f2fs_update_extension_list(struct f2fs_sb_info *sbi, const char *name, > - bool hot, bool set) > -{ > - __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; > - int cold_count = le32_to_cpu(sbi->raw_super->extension_count); > - int hot_count = sbi->raw_super->hot_ext_count; > - int total_count = cold_count + hot_count; > - int start, count; > - int i; > - > - if (set) { > - if (total_count == F2FS_MAX_EXTENSION) > - return -EINVAL; > - } else { > - if (!hot && !cold_count) > - return -EINVAL; > - if (hot && !hot_count) > - return -EINVAL; > - } > - > - if (hot) { > - start = cold_count; > - count = total_count; > - } else { > - start = 0; > - count = cold_count; > - } > - > - for (i = start; i < count; i++) { > - if (strcmp(name, extlist[i])) > - continue; > - > - if (set) > - return -EINVAL; > - > - memcpy(extlist[i], extlist[i + 1], > - F2FS_EXTENSION_LEN * (total_count - i - 1)); > - memset(extlist[total_count - 1], 0, F2FS_EXTENSION_LEN); > - if (hot) > - sbi->raw_super->hot_ext_count = hot_count - 1; > - else > - sbi->raw_super->extension_count = > - cpu_to_le32(cold_count - 1); > - return 0; > - } > - > - if (!set) > - return -EINVAL; > - > - if (hot) { > - memcpy(extlist[count], name, strlen(name)); > - sbi->raw_super->hot_ext_count = hot_count + 1; > - } else { > - char buf[F2FS_MAX_EXTENSION][F2FS_EXTENSION_LEN]; > - > - memcpy(buf, &extlist[cold_count], > - F2FS_EXTENSION_LEN * hot_count); > - memset(extlist[cold_count], 0, F2FS_EXTENSION_LEN); > - memcpy(extlist[cold_count], name, strlen(name)); > - memcpy(&extlist[cold_count + 1], buf, > - F2FS_EXTENSION_LEN * hot_count); > - sbi->raw_super->extension_count = cpu_to_le32(cold_count + 1); > - } > - return 0; > -} > - > -static void set_compress_inode(struct f2fs_sb_info *sbi, struct inode *inode, > - const unsigned char *name) > -{ > - __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; > - unsigned char (*noext)[F2FS_EXTENSION_LEN] = F2FS_OPTION(sbi).noextensions; > - unsigned char (*ext)[F2FS_EXTENSION_LEN] = F2FS_OPTION(sbi).extensions; > - unsigned char ext_cnt = F2FS_OPTION(sbi).compress_ext_cnt; > - unsigned char noext_cnt = F2FS_OPTION(sbi).nocompress_ext_cnt; > - int i, cold_count, hot_count; > - > - if (!f2fs_sb_has_compression(sbi) || > - F2FS_I(inode)->i_flags & F2FS_NOCOMP_FL || > - !f2fs_may_compress(inode) || > - (!ext_cnt && !noext_cnt)) > - return; > - > - f2fs_down_read(&sbi->sb_lock); > - > - cold_count = le32_to_cpu(sbi->raw_super->extension_count); > - hot_count = sbi->raw_super->hot_ext_count; > - > - for (i = cold_count; i < cold_count + hot_count; i++) { > - if (is_extension_exist(name, extlist[i], false)) { > - f2fs_up_read(&sbi->sb_lock); > - return; > - } > - } > - > - f2fs_up_read(&sbi->sb_lock); > - > - for (i = 0; i < noext_cnt; i++) { > - if (is_extension_exist(name, noext[i], false)) { > - f2fs_disable_compressed_file(inode); > - return; > - } > - } > - > - if (is_inode_flag_set(inode, FI_COMPRESSED_FILE)) > - return; > - > - for (i = 0; i < ext_cnt; i++) { > - if (!is_extension_exist(name, ext[i], false)) > - continue; > - > - /* Do not use inline_data with compression */ > - stat_dec_inline_inode(inode); > - clear_inode_flag(inode, FI_INLINE_DATA); > - set_compress_context(inode); > - return; > - } > -} > - > static int f2fs_create(struct user_namespace *mnt_userns, struct inode *dir, > struct dentry *dentry, umode_t mode, bool excl) > { > @@ -352,15 +349,13 @@ static int f2fs_create(struct user_namespace *mnt_userns, struct inode *dir, > if (err) > return err; > > - inode = f2fs_new_inode(mnt_userns, dir, mode); > + inode = f2fs_new_inode(mnt_userns, dir, mode, dentry->d_name.name); > if (IS_ERR(inode)) > return PTR_ERR(inode); > > if (!test_opt(sbi, DISABLE_EXT_IDENTIFY)) > set_file_temperature(sbi, inode, dentry->d_name.name); > > - set_compress_inode(sbi, inode, dentry->d_name.name); > - > inode->i_op = &f2fs_file_inode_operations; > inode->i_fop = &f2fs_file_operations; > inode->i_mapping->a_ops = &f2fs_dblock_aops; > @@ -689,7 +684,7 @@ static int f2fs_symlink(struct user_namespace *mnt_userns, struct inode *dir, > if (err) > return err; > > - inode = f2fs_new_inode(mnt_userns, dir, S_IFLNK | S_IRWXUGO); > + inode = f2fs_new_inode(mnt_userns, dir, S_IFLNK | S_IRWXUGO, NULL); > if (IS_ERR(inode)) > return PTR_ERR(inode); > > @@ -760,7 +755,8 @@ static int f2fs_mkdir(struct user_namespace *mnt_userns, struct inode *dir, > if (err) > return err; > > - inode = f2fs_new_inode(mnt_userns, dir, S_IFDIR | mode); > + inode = f2fs_new_inode(mnt_userns, dir, S_IFDIR | mode, > + dentry->d_name.name); > if (IS_ERR(inode)) > return PTR_ERR(inode); > > @@ -817,7 +813,7 @@ static int f2fs_mknod(struct user_namespace *mnt_userns, struct inode *dir, > if (err) > return err; > > - inode = f2fs_new_inode(mnt_userns, dir, mode); > + inode = f2fs_new_inode(mnt_userns, dir, mode, NULL); > if (IS_ERR(inode)) > return PTR_ERR(inode); > > @@ -856,7 +852,7 @@ static int __f2fs_tmpfile(struct user_namespace *mnt_userns, struct inode *dir, > if (err) > return err; > > - inode = f2fs_new_inode(mnt_userns, dir, mode); > + inode = f2fs_new_inode(mnt_userns, dir, mode, NULL); > if (IS_ERR(inode)) > return PTR_ERR(inode); >
If compress_extension is set, and a newly created file matches the extension, the file could be marked as compression file. However, if inline_data is also enabled, there is no chance to check its extension since f2fs_should_compress() always returns false. This patch moves set_compress_inode(), which do extension check, in f2fs_should_compress() to check extensions before setting inline data flag. Fixes: 7165841d578e ("f2fs: fix to check inline_data during compressed inode conversion") Signed-off-by: Sheng Yong <shengyong@oppo.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org> --- fs/f2fs/f2fs.h | 2 +- fs/f2fs/namei.c | 325 +++++++++++++++++++++++------------------------- 2 files changed, 160 insertions(+), 167 deletions(-) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index b89b5d755ce0..dedac413bf64 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -2980,7 +2980,7 @@ static inline void f2fs_change_bit(unsigned int nr, char *addr) /* Flags that should be inherited by new inodes from their parent. */ #define F2FS_FL_INHERITED (F2FS_SYNC_FL | F2FS_NODUMP_FL | F2FS_NOATIME_FL | \ F2FS_DIRSYNC_FL | F2FS_PROJINHERIT_FL | \ - F2FS_CASEFOLD_FL | F2FS_COMPR_FL | F2FS_NOCOMP_FL) + F2FS_CASEFOLD_FL) /* Flags that are appropriate for regular files (all but dir-specific ones). */ #define F2FS_REG_FLMASK (~(F2FS_DIRSYNC_FL | F2FS_PROJINHERIT_FL | \ diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index e104409c3a0e..c25009bb72f2 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c @@ -22,8 +22,158 @@ #include "acl.h" #include <trace/events/f2fs.h> +static inline int is_extension_exist(const unsigned char *s, const char *sub, + bool tmp_ext) +{ + size_t slen = strlen(s); + size_t sublen = strlen(sub); + int i; + + if (sublen == 1 && *sub == '*') + return 1; + + /* + * filename format of multimedia file should be defined as: + * "filename + '.' + extension + (optional: '.' + temp extension)". + */ + if (slen < sublen + 2) + return 0; + + if (!tmp_ext) { + /* file has no temp extension */ + if (s[slen - sublen - 1] != '.') + return 0; + return !strncasecmp(s + slen - sublen, sub, sublen); + } + + for (i = 1; i < slen - sublen; i++) { + if (s[i] != '.') + continue; + if (!strncasecmp(s + i + 1, sub, sublen)) + return 1; + } + + return 0; +} + +int f2fs_update_extension_list(struct f2fs_sb_info *sbi, const char *name, + bool hot, bool set) +{ + __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; + int cold_count = le32_to_cpu(sbi->raw_super->extension_count); + int hot_count = sbi->raw_super->hot_ext_count; + int total_count = cold_count + hot_count; + int start, count; + int i; + + if (set) { + if (total_count == F2FS_MAX_EXTENSION) + return -EINVAL; + } else { + if (!hot && !cold_count) + return -EINVAL; + if (hot && !hot_count) + return -EINVAL; + } + + if (hot) { + start = cold_count; + count = total_count; + } else { + start = 0; + count = cold_count; + } + + for (i = start; i < count; i++) { + if (strcmp(name, extlist[i])) + continue; + + if (set) + return -EINVAL; + + memcpy(extlist[i], extlist[i + 1], + F2FS_EXTENSION_LEN * (total_count - i - 1)); + memset(extlist[total_count - 1], 0, F2FS_EXTENSION_LEN); + if (hot) + sbi->raw_super->hot_ext_count = hot_count - 1; + else + sbi->raw_super->extension_count = + cpu_to_le32(cold_count - 1); + return 0; + } + + if (!set) + return -EINVAL; + + if (hot) { + memcpy(extlist[count], name, strlen(name)); + sbi->raw_super->hot_ext_count = hot_count + 1; + } else { + char buf[F2FS_MAX_EXTENSION][F2FS_EXTENSION_LEN]; + + memcpy(buf, &extlist[cold_count], + F2FS_EXTENSION_LEN * hot_count); + memset(extlist[cold_count], 0, F2FS_EXTENSION_LEN); + memcpy(extlist[cold_count], name, strlen(name)); + memcpy(&extlist[cold_count + 1], buf, + F2FS_EXTENSION_LEN * hot_count); + sbi->raw_super->extension_count = cpu_to_le32(cold_count + 1); + } + return 0; +} + +static void set_compress_new_inode(struct f2fs_sb_info *sbi, struct inode *dir, + struct inode *inode, const unsigned char *name) +{ + __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; + unsigned char (*noext)[F2FS_EXTENSION_LEN] = + F2FS_OPTION(sbi).noextensions; + unsigned char (*ext)[F2FS_EXTENSION_LEN] = F2FS_OPTION(sbi).extensions; + unsigned char ext_cnt = F2FS_OPTION(sbi).compress_ext_cnt; + unsigned char noext_cnt = F2FS_OPTION(sbi).nocompress_ext_cnt; + int i, cold_count, hot_count; + + /* Caller should give the name of regular file or directory. */ + if (!f2fs_sb_has_compression(sbi) || !name) + return; + + if (S_ISDIR(inode->i_mode)) + goto inherit_comp; + + /* Don't compress hot files. */ + f2fs_down_read(&sbi->sb_lock); + cold_count = le32_to_cpu(sbi->raw_super->extension_count); + hot_count = sbi->raw_super->hot_ext_count; + for (i = cold_count; i < cold_count + hot_count; i++) + if (is_extension_exist(name, extlist[i], false)) + break; + f2fs_up_read(&sbi->sb_lock); + if (i < (cold_count + hot_count)) + return; + + /* Don't compress unallowed extension. */ + for (i = 0; i < noext_cnt; i++) + if (is_extension_exist(name, noext[i], false)) + return; + + /* Compress wanting extension. */ + for (i = 0; i < ext_cnt; i++) { + if (is_extension_exist(name, ext[i], false)) { + set_compress_context(inode); + return; + } + } +inherit_comp: + /* Inherit the {no-}compression flag in directory */ + if (F2FS_I(dir)->i_flags & F2FS_NOCOMP_FL) + F2FS_I(inode)->i_flags |= F2FS_NOCOMP_FL; + else if (F2FS_I(dir)->i_flags & F2FS_COMPR_FL) + set_compress_context(inode); +} + static struct inode *f2fs_new_inode(struct user_namespace *mnt_userns, - struct inode *dir, umode_t mode) + struct inode *dir, umode_t mode, + const char *name) { struct f2fs_sb_info *sbi = F2FS_I_SB(dir); nid_t ino; @@ -114,12 +264,8 @@ static struct inode *f2fs_new_inode(struct user_namespace *mnt_userns, if (F2FS_I(inode)->i_flags & F2FS_PROJINHERIT_FL) set_inode_flag(inode, FI_PROJ_INHERIT); - if (f2fs_sb_has_compression(sbi)) { - /* Inherit the compression flag in directory */ - if ((F2FS_I(dir)->i_flags & F2FS_COMPR_FL) && - f2fs_may_compress(inode)) - set_compress_context(inode); - } + /* Check compression first. */ + set_compress_new_inode(sbi, dir, inode, name); /* Should enable inline_data after compression set */ if (test_opt(sbi, INLINE_DATA) && f2fs_may_inline_data(inode)) @@ -153,40 +299,6 @@ static struct inode *f2fs_new_inode(struct user_namespace *mnt_userns, return ERR_PTR(err); } -static inline int is_extension_exist(const unsigned char *s, const char *sub, - bool tmp_ext) -{ - size_t slen = strlen(s); - size_t sublen = strlen(sub); - int i; - - if (sublen == 1 && *sub == '*') - return 1; - - /* - * filename format of multimedia file should be defined as: - * "filename + '.' + extension + (optional: '.' + temp extension)". - */ - if (slen < sublen + 2) - return 0; - - if (!tmp_ext) { - /* file has no temp extension */ - if (s[slen - sublen - 1] != '.') - return 0; - return !strncasecmp(s + slen - sublen, sub, sublen); - } - - for (i = 1; i < slen - sublen; i++) { - if (s[i] != '.') - continue; - if (!strncasecmp(s + i + 1, sub, sublen)) - return 1; - } - - return 0; -} - /* * Set file's temperature for hot/cold data separation */ @@ -217,124 +329,6 @@ static inline void set_file_temperature(struct f2fs_sb_info *sbi, struct inode * file_set_hot(inode); } -int f2fs_update_extension_list(struct f2fs_sb_info *sbi, const char *name, - bool hot, bool set) -{ - __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; - int cold_count = le32_to_cpu(sbi->raw_super->extension_count); - int hot_count = sbi->raw_super->hot_ext_count; - int total_count = cold_count + hot_count; - int start, count; - int i; - - if (set) { - if (total_count == F2FS_MAX_EXTENSION) - return -EINVAL; - } else { - if (!hot && !cold_count) - return -EINVAL; - if (hot && !hot_count) - return -EINVAL; - } - - if (hot) { - start = cold_count; - count = total_count; - } else { - start = 0; - count = cold_count; - } - - for (i = start; i < count; i++) { - if (strcmp(name, extlist[i])) - continue; - - if (set) - return -EINVAL; - - memcpy(extlist[i], extlist[i + 1], - F2FS_EXTENSION_LEN * (total_count - i - 1)); - memset(extlist[total_count - 1], 0, F2FS_EXTENSION_LEN); - if (hot) - sbi->raw_super->hot_ext_count = hot_count - 1; - else - sbi->raw_super->extension_count = - cpu_to_le32(cold_count - 1); - return 0; - } - - if (!set) - return -EINVAL; - - if (hot) { - memcpy(extlist[count], name, strlen(name)); - sbi->raw_super->hot_ext_count = hot_count + 1; - } else { - char buf[F2FS_MAX_EXTENSION][F2FS_EXTENSION_LEN]; - - memcpy(buf, &extlist[cold_count], - F2FS_EXTENSION_LEN * hot_count); - memset(extlist[cold_count], 0, F2FS_EXTENSION_LEN); - memcpy(extlist[cold_count], name, strlen(name)); - memcpy(&extlist[cold_count + 1], buf, - F2FS_EXTENSION_LEN * hot_count); - sbi->raw_super->extension_count = cpu_to_le32(cold_count + 1); - } - return 0; -} - -static void set_compress_inode(struct f2fs_sb_info *sbi, struct inode *inode, - const unsigned char *name) -{ - __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; - unsigned char (*noext)[F2FS_EXTENSION_LEN] = F2FS_OPTION(sbi).noextensions; - unsigned char (*ext)[F2FS_EXTENSION_LEN] = F2FS_OPTION(sbi).extensions; - unsigned char ext_cnt = F2FS_OPTION(sbi).compress_ext_cnt; - unsigned char noext_cnt = F2FS_OPTION(sbi).nocompress_ext_cnt; - int i, cold_count, hot_count; - - if (!f2fs_sb_has_compression(sbi) || - F2FS_I(inode)->i_flags & F2FS_NOCOMP_FL || - !f2fs_may_compress(inode) || - (!ext_cnt && !noext_cnt)) - return; - - f2fs_down_read(&sbi->sb_lock); - - cold_count = le32_to_cpu(sbi->raw_super->extension_count); - hot_count = sbi->raw_super->hot_ext_count; - - for (i = cold_count; i < cold_count + hot_count; i++) { - if (is_extension_exist(name, extlist[i], false)) { - f2fs_up_read(&sbi->sb_lock); - return; - } - } - - f2fs_up_read(&sbi->sb_lock); - - for (i = 0; i < noext_cnt; i++) { - if (is_extension_exist(name, noext[i], false)) { - f2fs_disable_compressed_file(inode); - return; - } - } - - if (is_inode_flag_set(inode, FI_COMPRESSED_FILE)) - return; - - for (i = 0; i < ext_cnt; i++) { - if (!is_extension_exist(name, ext[i], false)) - continue; - - /* Do not use inline_data with compression */ - stat_dec_inline_inode(inode); - clear_inode_flag(inode, FI_INLINE_DATA); - set_compress_context(inode); - return; - } -} - static int f2fs_create(struct user_namespace *mnt_userns, struct inode *dir, struct dentry *dentry, umode_t mode, bool excl) { @@ -352,15 +346,13 @@ static int f2fs_create(struct user_namespace *mnt_userns, struct inode *dir, if (err) return err; - inode = f2fs_new_inode(mnt_userns, dir, mode); + inode = f2fs_new_inode(mnt_userns, dir, mode, dentry->d_name.name); if (IS_ERR(inode)) return PTR_ERR(inode); if (!test_opt(sbi, DISABLE_EXT_IDENTIFY)) set_file_temperature(sbi, inode, dentry->d_name.name); - set_compress_inode(sbi, inode, dentry->d_name.name); - inode->i_op = &f2fs_file_inode_operations; inode->i_fop = &f2fs_file_operations; inode->i_mapping->a_ops = &f2fs_dblock_aops; @@ -689,7 +681,7 @@ static int f2fs_symlink(struct user_namespace *mnt_userns, struct inode *dir, if (err) return err; - inode = f2fs_new_inode(mnt_userns, dir, S_IFLNK | S_IRWXUGO); + inode = f2fs_new_inode(mnt_userns, dir, S_IFLNK | S_IRWXUGO, NULL); if (IS_ERR(inode)) return PTR_ERR(inode); @@ -760,7 +752,8 @@ static int f2fs_mkdir(struct user_namespace *mnt_userns, struct inode *dir, if (err) return err; - inode = f2fs_new_inode(mnt_userns, dir, S_IFDIR | mode); + inode = f2fs_new_inode(mnt_userns, dir, S_IFDIR | mode, + dentry->d_name.name); if (IS_ERR(inode)) return PTR_ERR(inode); @@ -817,7 +810,7 @@ static int f2fs_mknod(struct user_namespace *mnt_userns, struct inode *dir, if (err) return err; - inode = f2fs_new_inode(mnt_userns, dir, mode); + inode = f2fs_new_inode(mnt_userns, dir, mode, NULL); if (IS_ERR(inode)) return PTR_ERR(inode); @@ -856,7 +849,7 @@ static int __f2fs_tmpfile(struct user_namespace *mnt_userns, struct inode *dir, if (err) return err; - inode = f2fs_new_inode(mnt_userns, dir, mode); + inode = f2fs_new_inode(mnt_userns, dir, mode, NULL); if (IS_ERR(inode)) return PTR_ERR(inode);
On 11/16, Sheng Yong wrote: > > > On 2022/11/16 7:00, Jaegeuk Kim wrote: > > If compress_extension is set, and a newly created file matches the > > extension, the file could be marked as compression file. However, > > if inline_data is also enabled, there is no chance to check its > > extension since f2fs_should_compress() always returns false. > > > > This patch moves set_compress_inode(), which do extension check, in > > f2fs_should_compress() to check extensions before setting inline > > data flag. > > > > Fixes: 7165841d578e ("f2fs: fix to check inline_data during compressed inode conversion") > > Signed-off-by: Sheng Yong <shengyong@oppo.com> > > Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org> > > --- > > > > Checking this version. > > > > fs/f2fs/f2fs.h | 2 +- > > fs/f2fs/namei.c | 328 ++++++++++++++++++++++++------------------------ > > 2 files changed, 163 insertions(+), 167 deletions(-) > > > > diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h > > index b89b5d755ce0..dedac413bf64 100644 > > --- a/fs/f2fs/f2fs.h > > +++ b/fs/f2fs/f2fs.h > > @@ -2980,7 +2980,7 @@ static inline void f2fs_change_bit(unsigned int nr, char *addr) > > /* Flags that should be inherited by new inodes from their parent. */ > > #define F2FS_FL_INHERITED (F2FS_SYNC_FL | F2FS_NODUMP_FL | F2FS_NOATIME_FL | \ > > F2FS_DIRSYNC_FL | F2FS_PROJINHERIT_FL | \ > > - F2FS_CASEFOLD_FL | F2FS_COMPR_FL | F2FS_NOCOMP_FL) > > + F2FS_CASEFOLD_FL) > > /* Flags that are appropriate for regular files (all but dir-specific ones). */ > > #define F2FS_REG_FLMASK (~(F2FS_DIRSYNC_FL | F2FS_PROJINHERIT_FL | \ > > diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c > > index e104409c3a0e..cb7441a19d22 100644 > > --- a/fs/f2fs/namei.c > > +++ b/fs/f2fs/namei.c > > @@ -22,8 +22,161 @@ > > #include "acl.h" > > #include <trace/events/f2fs.h> > > +static inline int is_extension_exist(const unsigned char *s, const char *sub, > > + bool tmp_ext) > > +{ > > + size_t slen = strlen(s); > > + size_t sublen = strlen(sub); > > + int i; > > + > > + if (sublen == 1 && *sub == '*') > > + return 1; > > + > > + /* > > + * filename format of multimedia file should be defined as: > > + * "filename + '.' + extension + (optional: '.' + temp extension)". > > + */ > > + if (slen < sublen + 2) > > + return 0; > > + > > + if (!tmp_ext) { > > + /* file has no temp extension */ > > + if (s[slen - sublen - 1] != '.') > > + return 0; > > + return !strncasecmp(s + slen - sublen, sub, sublen); > > + } > > + > > + for (i = 1; i < slen - sublen; i++) { > > + if (s[i] != '.') > > + continue; > > + if (!strncasecmp(s + i + 1, sub, sublen)) > > + return 1; > > + } > > + > > + return 0; > > +} > > + > > +int f2fs_update_extension_list(struct f2fs_sb_info *sbi, const char *name, > > + bool hot, bool set) > > +{ > > + __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; > > + int cold_count = le32_to_cpu(sbi->raw_super->extension_count); > > + int hot_count = sbi->raw_super->hot_ext_count; > > + int total_count = cold_count + hot_count; > > + int start, count; > > + int i; > > + > > + if (set) { > > + if (total_count == F2FS_MAX_EXTENSION) > > + return -EINVAL; > > + } else { > > + if (!hot && !cold_count) > > + return -EINVAL; > > + if (hot && !hot_count) > > + return -EINVAL; > > + } > > + > > + if (hot) { > > + start = cold_count; > > + count = total_count; > > + } else { > > + start = 0; > > + count = cold_count; > > + } > > + > > + for (i = start; i < count; i++) { > > + if (strcmp(name, extlist[i])) > > + continue; > > + > > + if (set) > > + return -EINVAL; > > + > > + memcpy(extlist[i], extlist[i + 1], > > + F2FS_EXTENSION_LEN * (total_count - i - 1)); > > + memset(extlist[total_count - 1], 0, F2FS_EXTENSION_LEN); > > + if (hot) > > + sbi->raw_super->hot_ext_count = hot_count - 1; > > + else > > + sbi->raw_super->extension_count = > > + cpu_to_le32(cold_count - 1); > > + return 0; > > + } > > + > > + if (!set) > > + return -EINVAL; > > + > > + if (hot) { > > + memcpy(extlist[count], name, strlen(name)); > > + sbi->raw_super->hot_ext_count = hot_count + 1; > > + } else { > > + char buf[F2FS_MAX_EXTENSION][F2FS_EXTENSION_LEN]; > > + > > + memcpy(buf, &extlist[cold_count], > > + F2FS_EXTENSION_LEN * hot_count); > > + memset(extlist[cold_count], 0, F2FS_EXTENSION_LEN); > > + memcpy(extlist[cold_count], name, strlen(name)); > > + memcpy(&extlist[cold_count + 1], buf, > > + F2FS_EXTENSION_LEN * hot_count); > > + sbi->raw_super->extension_count = cpu_to_le32(cold_count + 1); > > + } > > + return 0; > > +} > > + > > +static void set_compress_new_inode(struct f2fs_sb_info *sbi, struct inode *dir, > > + struct inode *inode, const unsigned char *name) > > +{ > > + __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; > > + unsigned char (*noext)[F2FS_EXTENSION_LEN] = > > + F2FS_OPTION(sbi).noextensions; > > + unsigned char (*ext)[F2FS_EXTENSION_LEN] = F2FS_OPTION(sbi).extensions; > > + unsigned char ext_cnt = F2FS_OPTION(sbi).compress_ext_cnt; > > + unsigned char noext_cnt = F2FS_OPTION(sbi).nocompress_ext_cnt; > > + int i, cold_count, hot_count; > > + > > + /* Caller should give the name of regular file or directory. */ > > + if (!f2fs_sb_has_compression(sbi) || !name) > > + return; > > + > > + if (S_ISDIR(inode->i_mode)) > > + goto inherit_comp; > > + > > + /* Don't compress hot files. */ > > + f2fs_down_read(&sbi->sb_lock); > > + cold_count = le32_to_cpu(sbi->raw_super->extension_count); > > + hot_count = sbi->raw_super->hot_ext_count; > > + for (i = cold_count; i < cold_count + hot_count; i++) > > + if (is_extension_exist(name, extlist[i], false)) > > + break; > > + f2fs_up_read(&sbi->sb_lock); > > + if (i < (cold_count + hot_count)) > > + return; > > + > > + /* Don't compress unallowed extension. */ > > + for (i = 0; i < noext_cnt; i++) > > + if (is_extension_exist(name, noext[i], false)) > > + return; > > +inherit_comp: > > + /* Inherit the {no-}compression flag in directory */ > > + if (F2FS_I(dir)->i_flags & F2FS_NOCOMP_FL) { > > + F2FS_I(inode)->i_flags |= F2FS_NOCOMP_FL; > > + return; > > Hi, Jaegeuk, > It should not return immediately here. The scenario here is: > > mount -o compress_extension=txt,compress_mode=user > mkdir dir > f2fs_io setflags nocompression dir # set dir nocompression > touch dir/file.txt > f2fs_io getflags compression dir/file.txt # file.txt should have > compression flag I see. Sent out v4. > > According to f2fs.rst, if dir is set as nocompression, but file's > extension hit compress_extension, then the file should be compressed. > And before set_compress_context later, F2FS_NOCOMP_FL should be > cleared first. > > thanks, > shengyong > > > + } else if (F2FS_I(dir)->i_flags & F2FS_COMPR_FL) { > > + set_compress_context(inode); > > + return; > > + } > > + > > + /* Compress wanting extension. */ > > + for (i = 0; i < ext_cnt; i++) { > > + if (is_extension_exist(name, ext[i], false)) { > > + set_compress_context(inode); > > + return; > > + } > > + } > > +} > > + > > static struct inode *f2fs_new_inode(struct user_namespace *mnt_userns, > > - struct inode *dir, umode_t mode) > > + struct inode *dir, umode_t mode, > > + const char *name) > > { > > struct f2fs_sb_info *sbi = F2FS_I_SB(dir); > > nid_t ino; > > @@ -114,12 +267,8 @@ static struct inode *f2fs_new_inode(struct user_namespace *mnt_userns, > > if (F2FS_I(inode)->i_flags & F2FS_PROJINHERIT_FL) > > set_inode_flag(inode, FI_PROJ_INHERIT); > > - if (f2fs_sb_has_compression(sbi)) { > > - /* Inherit the compression flag in directory */ > > - if ((F2FS_I(dir)->i_flags & F2FS_COMPR_FL) && > > - f2fs_may_compress(inode)) > > - set_compress_context(inode); > > - } > > + /* Check compression first. */ > > + set_compress_new_inode(sbi, dir, inode, name); > > /* Should enable inline_data after compression set */ > > if (test_opt(sbi, INLINE_DATA) && f2fs_may_inline_data(inode)) > > @@ -153,40 +302,6 @@ static struct inode *f2fs_new_inode(struct user_namespace *mnt_userns, > > return ERR_PTR(err); > > } > > -static inline int is_extension_exist(const unsigned char *s, const char *sub, > > - bool tmp_ext) > > -{ > > - size_t slen = strlen(s); > > - size_t sublen = strlen(sub); > > - int i; > > - > > - if (sublen == 1 && *sub == '*') > > - return 1; > > - > > - /* > > - * filename format of multimedia file should be defined as: > > - * "filename + '.' + extension + (optional: '.' + temp extension)". > > - */ > > - if (slen < sublen + 2) > > - return 0; > > - > > - if (!tmp_ext) { > > - /* file has no temp extension */ > > - if (s[slen - sublen - 1] != '.') > > - return 0; > > - return !strncasecmp(s + slen - sublen, sub, sublen); > > - } > > - > > - for (i = 1; i < slen - sublen; i++) { > > - if (s[i] != '.') > > - continue; > > - if (!strncasecmp(s + i + 1, sub, sublen)) > > - return 1; > > - } > > - > > - return 0; > > -} > > - > > /* > > * Set file's temperature for hot/cold data separation > > */ > > @@ -217,124 +332,6 @@ static inline void set_file_temperature(struct f2fs_sb_info *sbi, struct inode * > > file_set_hot(inode); > > } > > -int f2fs_update_extension_list(struct f2fs_sb_info *sbi, const char *name, > > - bool hot, bool set) > > -{ > > - __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; > > - int cold_count = le32_to_cpu(sbi->raw_super->extension_count); > > - int hot_count = sbi->raw_super->hot_ext_count; > > - int total_count = cold_count + hot_count; > > - int start, count; > > - int i; > > - > > - if (set) { > > - if (total_count == F2FS_MAX_EXTENSION) > > - return -EINVAL; > > - } else { > > - if (!hot && !cold_count) > > - return -EINVAL; > > - if (hot && !hot_count) > > - return -EINVAL; > > - } > > - > > - if (hot) { > > - start = cold_count; > > - count = total_count; > > - } else { > > - start = 0; > > - count = cold_count; > > - } > > - > > - for (i = start; i < count; i++) { > > - if (strcmp(name, extlist[i])) > > - continue; > > - > > - if (set) > > - return -EINVAL; > > - > > - memcpy(extlist[i], extlist[i + 1], > > - F2FS_EXTENSION_LEN * (total_count - i - 1)); > > - memset(extlist[total_count - 1], 0, F2FS_EXTENSION_LEN); > > - if (hot) > > - sbi->raw_super->hot_ext_count = hot_count - 1; > > - else > > - sbi->raw_super->extension_count = > > - cpu_to_le32(cold_count - 1); > > - return 0; > > - } > > - > > - if (!set) > > - return -EINVAL; > > - > > - if (hot) { > > - memcpy(extlist[count], name, strlen(name)); > > - sbi->raw_super->hot_ext_count = hot_count + 1; > > - } else { > > - char buf[F2FS_MAX_EXTENSION][F2FS_EXTENSION_LEN]; > > - > > - memcpy(buf, &extlist[cold_count], > > - F2FS_EXTENSION_LEN * hot_count); > > - memset(extlist[cold_count], 0, F2FS_EXTENSION_LEN); > > - memcpy(extlist[cold_count], name, strlen(name)); > > - memcpy(&extlist[cold_count + 1], buf, > > - F2FS_EXTENSION_LEN * hot_count); > > - sbi->raw_super->extension_count = cpu_to_le32(cold_count + 1); > > - } > > - return 0; > > -} > > - > > -static void set_compress_inode(struct f2fs_sb_info *sbi, struct inode *inode, > > - const unsigned char *name) > > -{ > > - __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; > > - unsigned char (*noext)[F2FS_EXTENSION_LEN] = F2FS_OPTION(sbi).noextensions; > > - unsigned char (*ext)[F2FS_EXTENSION_LEN] = F2FS_OPTION(sbi).extensions; > > - unsigned char ext_cnt = F2FS_OPTION(sbi).compress_ext_cnt; > > - unsigned char noext_cnt = F2FS_OPTION(sbi).nocompress_ext_cnt; > > - int i, cold_count, hot_count; > > - > > - if (!f2fs_sb_has_compression(sbi) || > > - F2FS_I(inode)->i_flags & F2FS_NOCOMP_FL || > > - !f2fs_may_compress(inode) || > > - (!ext_cnt && !noext_cnt)) > > - return; > > - > > - f2fs_down_read(&sbi->sb_lock); > > - > > - cold_count = le32_to_cpu(sbi->raw_super->extension_count); > > - hot_count = sbi->raw_super->hot_ext_count; > > - > > - for (i = cold_count; i < cold_count + hot_count; i++) { > > - if (is_extension_exist(name, extlist[i], false)) { > > - f2fs_up_read(&sbi->sb_lock); > > - return; > > - } > > - } > > - > > - f2fs_up_read(&sbi->sb_lock); > > - > > - for (i = 0; i < noext_cnt; i++) { > > - if (is_extension_exist(name, noext[i], false)) { > > - f2fs_disable_compressed_file(inode); > > - return; > > - } > > - } > > - > > - if (is_inode_flag_set(inode, FI_COMPRESSED_FILE)) > > - return; > > - > > - for (i = 0; i < ext_cnt; i++) { > > - if (!is_extension_exist(name, ext[i], false)) > > - continue; > > - > > - /* Do not use inline_data with compression */ > > - stat_dec_inline_inode(inode); > > - clear_inode_flag(inode, FI_INLINE_DATA); > > - set_compress_context(inode); > > - return; > > - } > > -} > > - > > static int f2fs_create(struct user_namespace *mnt_userns, struct inode *dir, > > struct dentry *dentry, umode_t mode, bool excl) > > { > > @@ -352,15 +349,13 @@ static int f2fs_create(struct user_namespace *mnt_userns, struct inode *dir, > > if (err) > > return err; > > - inode = f2fs_new_inode(mnt_userns, dir, mode); > > + inode = f2fs_new_inode(mnt_userns, dir, mode, dentry->d_name.name); > > if (IS_ERR(inode)) > > return PTR_ERR(inode); > > if (!test_opt(sbi, DISABLE_EXT_IDENTIFY)) > > set_file_temperature(sbi, inode, dentry->d_name.name); > > - set_compress_inode(sbi, inode, dentry->d_name.name); > > - > > inode->i_op = &f2fs_file_inode_operations; > > inode->i_fop = &f2fs_file_operations; > > inode->i_mapping->a_ops = &f2fs_dblock_aops; > > @@ -689,7 +684,7 @@ static int f2fs_symlink(struct user_namespace *mnt_userns, struct inode *dir, > > if (err) > > return err; > > - inode = f2fs_new_inode(mnt_userns, dir, S_IFLNK | S_IRWXUGO); > > + inode = f2fs_new_inode(mnt_userns, dir, S_IFLNK | S_IRWXUGO, NULL); > > if (IS_ERR(inode)) > > return PTR_ERR(inode); > > @@ -760,7 +755,8 @@ static int f2fs_mkdir(struct user_namespace *mnt_userns, struct inode *dir, > > if (err) > > return err; > > - inode = f2fs_new_inode(mnt_userns, dir, S_IFDIR | mode); > > + inode = f2fs_new_inode(mnt_userns, dir, S_IFDIR | mode, > > + dentry->d_name.name); > > if (IS_ERR(inode)) > > return PTR_ERR(inode); > > @@ -817,7 +813,7 @@ static int f2fs_mknod(struct user_namespace *mnt_userns, struct inode *dir, > > if (err) > > return err; > > - inode = f2fs_new_inode(mnt_userns, dir, mode); > > + inode = f2fs_new_inode(mnt_userns, dir, mode, NULL); > > if (IS_ERR(inode)) > > return PTR_ERR(inode); > > @@ -856,7 +852,7 @@ static int __f2fs_tmpfile(struct user_namespace *mnt_userns, struct inode *dir, > > if (err) > > return err; > > - inode = f2fs_new_inode(mnt_userns, dir, mode); > > + inode = f2fs_new_inode(mnt_userns, dir, mode, NULL); > > if (IS_ERR(inode)) > > return PTR_ERR(inode);
On 2022/11/17 9:12, Jaegeuk Kim wrote: > If compress_extension is set, and a newly created file matches the > extension, the file could be marked as compression file. However, > if inline_data is also enabled, there is no chance to check its > extension since f2fs_should_compress() always returns false. > > This patch moves set_compress_inode(), which do extension check, in > f2fs_should_compress() to check extensions before setting inline > data flag. > > Fixes: 7165841d578e ("f2fs: fix to check inline_data during compressed inode conversion") > Signed-off-by: Sheng Yong <shengyong@oppo.com> > Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org> > --- > fs/f2fs/f2fs.h | 2 +- > fs/f2fs/namei.c | 325 +++++++++++++++++++++++------------------------- > 2 files changed, 160 insertions(+), 167 deletions(-) > > diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h > index b89b5d755ce0..dedac413bf64 100644 > --- a/fs/f2fs/f2fs.h > +++ b/fs/f2fs/f2fs.h > @@ -2980,7 +2980,7 @@ static inline void f2fs_change_bit(unsigned int nr, char *addr) > /* Flags that should be inherited by new inodes from their parent. */ > #define F2FS_FL_INHERITED (F2FS_SYNC_FL | F2FS_NODUMP_FL | F2FS_NOATIME_FL | \ > F2FS_DIRSYNC_FL | F2FS_PROJINHERIT_FL | \ > - F2FS_CASEFOLD_FL | F2FS_COMPR_FL | F2FS_NOCOMP_FL) > + F2FS_CASEFOLD_FL) > > /* Flags that are appropriate for regular files (all but dir-specific ones). */ > #define F2FS_REG_FLMASK (~(F2FS_DIRSYNC_FL | F2FS_PROJINHERIT_FL | \ > diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c > index e104409c3a0e..c25009bb72f2 100644 > --- a/fs/f2fs/namei.c > +++ b/fs/f2fs/namei.c > @@ -22,8 +22,158 @@ > #include "acl.h" > #include <trace/events/f2fs.h> > > +static inline int is_extension_exist(const unsigned char *s, const char *sub, > + bool tmp_ext) > +{ > + size_t slen = strlen(s); > + size_t sublen = strlen(sub); > + int i; > + > + if (sublen == 1 && *sub == '*') > + return 1; > + > + /* > + * filename format of multimedia file should be defined as: > + * "filename + '.' + extension + (optional: '.' + temp extension)". > + */ > + if (slen < sublen + 2) > + return 0; > + > + if (!tmp_ext) { > + /* file has no temp extension */ > + if (s[slen - sublen - 1] != '.') > + return 0; > + return !strncasecmp(s + slen - sublen, sub, sublen); > + } > + > + for (i = 1; i < slen - sublen; i++) { > + if (s[i] != '.') > + continue; > + if (!strncasecmp(s + i + 1, sub, sublen)) > + return 1; > + } > + > + return 0; > +} > + > +int f2fs_update_extension_list(struct f2fs_sb_info *sbi, const char *name, > + bool hot, bool set) > +{ > + __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; > + int cold_count = le32_to_cpu(sbi->raw_super->extension_count); > + int hot_count = sbi->raw_super->hot_ext_count; > + int total_count = cold_count + hot_count; > + int start, count; > + int i; > + > + if (set) { > + if (total_count == F2FS_MAX_EXTENSION) > + return -EINVAL; > + } else { > + if (!hot && !cold_count) > + return -EINVAL; > + if (hot && !hot_count) > + return -EINVAL; > + } > + > + if (hot) { > + start = cold_count; > + count = total_count; > + } else { > + start = 0; > + count = cold_count; > + } > + > + for (i = start; i < count; i++) { > + if (strcmp(name, extlist[i])) > + continue; > + > + if (set) > + return -EINVAL; > + > + memcpy(extlist[i], extlist[i + 1], > + F2FS_EXTENSION_LEN * (total_count - i - 1)); > + memset(extlist[total_count - 1], 0, F2FS_EXTENSION_LEN); > + if (hot) > + sbi->raw_super->hot_ext_count = hot_count - 1; > + else > + sbi->raw_super->extension_count = > + cpu_to_le32(cold_count - 1); > + return 0; > + } > + > + if (!set) > + return -EINVAL; > + > + if (hot) { > + memcpy(extlist[count], name, strlen(name)); > + sbi->raw_super->hot_ext_count = hot_count + 1; > + } else { > + char buf[F2FS_MAX_EXTENSION][F2FS_EXTENSION_LEN]; > + > + memcpy(buf, &extlist[cold_count], > + F2FS_EXTENSION_LEN * hot_count); > + memset(extlist[cold_count], 0, F2FS_EXTENSION_LEN); > + memcpy(extlist[cold_count], name, strlen(name)); > + memcpy(&extlist[cold_count + 1], buf, > + F2FS_EXTENSION_LEN * hot_count); > + sbi->raw_super->extension_count = cpu_to_le32(cold_count + 1); > + } > + return 0; > +} > + > +static void set_compress_new_inode(struct f2fs_sb_info *sbi, struct inode *dir, > + struct inode *inode, const unsigned char *name) > +{ > + __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; > + unsigned char (*noext)[F2FS_EXTENSION_LEN] = > + F2FS_OPTION(sbi).noextensions; > + unsigned char (*ext)[F2FS_EXTENSION_LEN] = F2FS_OPTION(sbi).extensions; > + unsigned char ext_cnt = F2FS_OPTION(sbi).compress_ext_cnt; > + unsigned char noext_cnt = F2FS_OPTION(sbi).nocompress_ext_cnt; > + int i, cold_count, hot_count; > + > + /* Caller should give the name of regular file or directory. */ > + if (!f2fs_sb_has_compression(sbi) || !name) > + return; > + > + if (S_ISDIR(inode->i_mode)) > + goto inherit_comp; Documentation/filesystems/f2fs.rst - Priority in between FS_COMPR_FL, FS_NOCOMP_FS, extensions: * compress_extension=so; nocompress_extension=zip; chattr +c dir; touch dir/foo.so; touch dir/bar.zip; touch dir/baz.txt; then foo.so and baz.txt should be compresse, bar.zip should be non-compressed. chattr +c dir/bar.zip can enable compress on bar.zip. It looks nocompress_extension has higher priority than flag inheriting? > + > + /* Don't compress hot files. */ > + f2fs_down_read(&sbi->sb_lock); > + cold_count = le32_to_cpu(sbi->raw_super->extension_count); > + hot_count = sbi->raw_super->hot_ext_count; > + for (i = cold_count; i < cold_count + hot_count; i++) > + if (is_extension_exist(name, extlist[i], false)) > + break; > + f2fs_up_read(&sbi->sb_lock); > + if (i < (cold_count + hot_count)) > + return; > + > + /* Don't compress unallowed extension. */ > + for (i = 0; i < noext_cnt; i++) > + if (is_extension_exist(name, noext[i], false)) > + return; > + > + /* Compress wanting extension. */ > + for (i = 0; i < ext_cnt; i++) { > + if (is_extension_exist(name, ext[i], false)) { > + set_compress_context(inode); > + return; > + } > + } > +inherit_comp: > + /* Inherit the {no-}compression flag in directory */ > + if (F2FS_I(dir)->i_flags & F2FS_NOCOMP_FL) > + F2FS_I(inode)->i_flags |= F2FS_NOCOMP_FL; f2fs_mark_inode_dirty_sync(, true)? > + else if (F2FS_I(dir)->i_flags & F2FS_COMPR_FL) > + set_compress_context(inode); > +} > + > static struct inode *f2fs_new_inode(struct user_namespace *mnt_userns, > - struct inode *dir, umode_t mode) > + struct inode *dir, umode_t mode, > + const char *name) > { > struct f2fs_sb_info *sbi = F2FS_I_SB(dir); > nid_t ino; > @@ -114,12 +264,8 @@ static struct inode *f2fs_new_inode(struct user_namespace *mnt_userns, > if (F2FS_I(inode)->i_flags & F2FS_PROJINHERIT_FL) > set_inode_flag(inode, FI_PROJ_INHERIT); > > - if (f2fs_sb_has_compression(sbi)) { > - /* Inherit the compression flag in directory */ > - if ((F2FS_I(dir)->i_flags & F2FS_COMPR_FL) && > - f2fs_may_compress(inode)) > - set_compress_context(inode); > - } > + /* Check compression first. */ > + set_compress_new_inode(sbi, dir, inode, name); > > /* Should enable inline_data after compression set */ > if (test_opt(sbi, INLINE_DATA) && f2fs_may_inline_data(inode)) > @@ -153,40 +299,6 @@ static struct inode *f2fs_new_inode(struct user_namespace *mnt_userns, > return ERR_PTR(err); > } > > -static inline int is_extension_exist(const unsigned char *s, const char *sub, > - bool tmp_ext) > -{ > - size_t slen = strlen(s); > - size_t sublen = strlen(sub); > - int i; > - > - if (sublen == 1 && *sub == '*') > - return 1; > - > - /* > - * filename format of multimedia file should be defined as: > - * "filename + '.' + extension + (optional: '.' + temp extension)". > - */ > - if (slen < sublen + 2) > - return 0; > - > - if (!tmp_ext) { > - /* file has no temp extension */ > - if (s[slen - sublen - 1] != '.') > - return 0; > - return !strncasecmp(s + slen - sublen, sub, sublen); > - } > - > - for (i = 1; i < slen - sublen; i++) { > - if (s[i] != '.') > - continue; > - if (!strncasecmp(s + i + 1, sub, sublen)) > - return 1; > - } > - > - return 0; > -} > - > /* > * Set file's temperature for hot/cold data separation > */ > @@ -217,124 +329,6 @@ static inline void set_file_temperature(struct f2fs_sb_info *sbi, struct inode * > file_set_hot(inode); > } > > -int f2fs_update_extension_list(struct f2fs_sb_info *sbi, const char *name, > - bool hot, bool set) > -{ > - __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; > - int cold_count = le32_to_cpu(sbi->raw_super->extension_count); > - int hot_count = sbi->raw_super->hot_ext_count; > - int total_count = cold_count + hot_count; > - int start, count; > - int i; > - > - if (set) { > - if (total_count == F2FS_MAX_EXTENSION) > - return -EINVAL; > - } else { > - if (!hot && !cold_count) > - return -EINVAL; > - if (hot && !hot_count) > - return -EINVAL; > - } > - > - if (hot) { > - start = cold_count; > - count = total_count; > - } else { > - start = 0; > - count = cold_count; > - } > - > - for (i = start; i < count; i++) { > - if (strcmp(name, extlist[i])) > - continue; > - > - if (set) > - return -EINVAL; > - > - memcpy(extlist[i], extlist[i + 1], > - F2FS_EXTENSION_LEN * (total_count - i - 1)); > - memset(extlist[total_count - 1], 0, F2FS_EXTENSION_LEN); > - if (hot) > - sbi->raw_super->hot_ext_count = hot_count - 1; > - else > - sbi->raw_super->extension_count = > - cpu_to_le32(cold_count - 1); > - return 0; > - } > - > - if (!set) > - return -EINVAL; > - > - if (hot) { > - memcpy(extlist[count], name, strlen(name)); > - sbi->raw_super->hot_ext_count = hot_count + 1; > - } else { > - char buf[F2FS_MAX_EXTENSION][F2FS_EXTENSION_LEN]; > - > - memcpy(buf, &extlist[cold_count], > - F2FS_EXTENSION_LEN * hot_count); > - memset(extlist[cold_count], 0, F2FS_EXTENSION_LEN); > - memcpy(extlist[cold_count], name, strlen(name)); > - memcpy(&extlist[cold_count + 1], buf, > - F2FS_EXTENSION_LEN * hot_count); > - sbi->raw_super->extension_count = cpu_to_le32(cold_count + 1); > - } > - return 0; > -} > - > -static void set_compress_inode(struct f2fs_sb_info *sbi, struct inode *inode, > - const unsigned char *name) > -{ > - __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; > - unsigned char (*noext)[F2FS_EXTENSION_LEN] = F2FS_OPTION(sbi).noextensions; > - unsigned char (*ext)[F2FS_EXTENSION_LEN] = F2FS_OPTION(sbi).extensions; > - unsigned char ext_cnt = F2FS_OPTION(sbi).compress_ext_cnt; > - unsigned char noext_cnt = F2FS_OPTION(sbi).nocompress_ext_cnt; > - int i, cold_count, hot_count; > - > - if (!f2fs_sb_has_compression(sbi) || > - F2FS_I(inode)->i_flags & F2FS_NOCOMP_FL || > - !f2fs_may_compress(inode) || > - (!ext_cnt && !noext_cnt)) > - return; > - > - f2fs_down_read(&sbi->sb_lock); > - > - cold_count = le32_to_cpu(sbi->raw_super->extension_count); > - hot_count = sbi->raw_super->hot_ext_count; > - > - for (i = cold_count; i < cold_count + hot_count; i++) { > - if (is_extension_exist(name, extlist[i], false)) { > - f2fs_up_read(&sbi->sb_lock); > - return; > - } > - } > - > - f2fs_up_read(&sbi->sb_lock); > - > - for (i = 0; i < noext_cnt; i++) { > - if (is_extension_exist(name, noext[i], false)) { > - f2fs_disable_compressed_file(inode); > - return; > - } > - } > - > - if (is_inode_flag_set(inode, FI_COMPRESSED_FILE)) > - return; > - > - for (i = 0; i < ext_cnt; i++) { > - if (!is_extension_exist(name, ext[i], false)) > - continue; > - > - /* Do not use inline_data with compression */ > - stat_dec_inline_inode(inode); > - clear_inode_flag(inode, FI_INLINE_DATA); > - set_compress_context(inode); > - return; > - } > -} > - > static int f2fs_create(struct user_namespace *mnt_userns, struct inode *dir, > struct dentry *dentry, umode_t mode, bool excl) > { > @@ -352,15 +346,13 @@ static int f2fs_create(struct user_namespace *mnt_userns, struct inode *dir, > if (err) > return err; > > - inode = f2fs_new_inode(mnt_userns, dir, mode); > + inode = f2fs_new_inode(mnt_userns, dir, mode, dentry->d_name.name); > if (IS_ERR(inode)) > return PTR_ERR(inode); > > if (!test_opt(sbi, DISABLE_EXT_IDENTIFY)) > set_file_temperature(sbi, inode, dentry->d_name.name); > > - set_compress_inode(sbi, inode, dentry->d_name.name); > - > inode->i_op = &f2fs_file_inode_operations; > inode->i_fop = &f2fs_file_operations; > inode->i_mapping->a_ops = &f2fs_dblock_aops; > @@ -689,7 +681,7 @@ static int f2fs_symlink(struct user_namespace *mnt_userns, struct inode *dir, > if (err) > return err; > > - inode = f2fs_new_inode(mnt_userns, dir, S_IFLNK | S_IRWXUGO); > + inode = f2fs_new_inode(mnt_userns, dir, S_IFLNK | S_IRWXUGO, NULL); > if (IS_ERR(inode)) > return PTR_ERR(inode); > > @@ -760,7 +752,8 @@ static int f2fs_mkdir(struct user_namespace *mnt_userns, struct inode *dir, > if (err) > return err; > > - inode = f2fs_new_inode(mnt_userns, dir, S_IFDIR | mode); > + inode = f2fs_new_inode(mnt_userns, dir, S_IFDIR | mode, > + dentry->d_name.name); Why we need to pass directory's name to set_compress_new_inode()? Could we just check S_IFDIR in child inode? Thanks, > if (IS_ERR(inode)) > return PTR_ERR(inode); > > @@ -817,7 +810,7 @@ static int f2fs_mknod(struct user_namespace *mnt_userns, struct inode *dir, > if (err) > return err; > > - inode = f2fs_new_inode(mnt_userns, dir, mode); > + inode = f2fs_new_inode(mnt_userns, dir, mode, NULL); > if (IS_ERR(inode)) > return PTR_ERR(inode); > > @@ -856,7 +849,7 @@ static int __f2fs_tmpfile(struct user_namespace *mnt_userns, struct inode *dir, > if (err) > return err; > > - inode = f2fs_new_inode(mnt_userns, dir, mode); > + inode = f2fs_new_inode(mnt_userns, dir, mode, NULL); > if (IS_ERR(inode)) > return PTR_ERR(inode); >
On 2022/11/23 22:54, Chao Yu wrote: > On 2022/11/17 9:12, Jaegeuk Kim wrote: >> If compress_extension is set, and a newly created file matches the >> extension, the file could be marked as compression file. However, >> if inline_data is also enabled, there is no chance to check its >> extension since f2fs_should_compress() always returns false. >> >> This patch moves set_compress_inode(), which do extension check, in >> f2fs_should_compress() to check extensions before setting inline >> data flag. >> >> Fixes: 7165841d578e ("f2fs: fix to check inline_data during compressed inode conversion") >> Signed-off-by: Sheng Yong <shengyong@oppo.com> >> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org> >> --- >>  fs/f2fs/f2fs.h |  2 +- >>  fs/f2fs/namei.c | 325 +++++++++++++++++++++++------------------------- >>  2 files changed, 160 insertions(+), 167 deletions(-) >> >> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h >> index b89b5d755ce0..dedac413bf64 100644 >> --- a/fs/f2fs/f2fs.h >> +++ b/fs/f2fs/f2fs.h >> @@ -2980,7 +2980,7 @@ static inline void f2fs_change_bit(unsigned int nr, char *addr) >>  /* Flags that should be inherited by new inodes from their parent. */ >>  #define F2FS_FL_INHERITED (F2FS_SYNC_FL | F2FS_NODUMP_FL | F2FS_NOATIME_FL | \ >>                 F2FS_DIRSYNC_FL | F2FS_PROJINHERIT_FL | \ >> -              F2FS_CASEFOLD_FL | F2FS_COMPR_FL | F2FS_NOCOMP_FL) >> +              F2FS_CASEFOLD_FL) >>  /* Flags that are appropriate for regular files (all but dir-specific ones). */ >>  #define F2FS_REG_FLMASK       (~(F2FS_DIRSYNC_FL | F2FS_PROJINHERIT_FL | \ >> diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c >> index e104409c3a0e..c25009bb72f2 100644 >> --- a/fs/f2fs/namei.c >> +++ b/fs/f2fs/namei.c >> @@ -22,8 +22,158 @@ >>  #include "acl.h" >>  #include <trace/events/f2fs.h> >> +static inline int is_extension_exist(const unsigned char *s, const char *sub, >> +                       bool tmp_ext) >> +{ >> +   size_t slen = strlen(s); >> +   size_t sublen = strlen(sub); >> +   int i; >> + >> +   if (sublen == 1 && *sub == '*') >> +       return 1; >> + >> +   /* >> +    * filename format of multimedia file should be defined as: >> +    * "filename + '.' + extension + (optional: '.' + temp extension)". >> +    */ >> +   if (slen < sublen + 2) >> +       return 0; >> + >> +   if (!tmp_ext) { >> +       /* file has no temp extension */ >> +       if (s[slen - sublen - 1] != '.') >> +           return 0; >> +       return !strncasecmp(s + slen - sublen, sub, sublen); >> +   } >> + >> +   for (i = 1; i < slen - sublen; i++) { >> +       if (s[i] != '.') >> +           continue; >> +       if (!strncasecmp(s + i + 1, sub, sublen)) >> +           return 1; >> +   } >> + >> +   return 0; >> +} >> + >> +int f2fs_update_extension_list(struct f2fs_sb_info *sbi, const char *name, >> +                           bool hot, bool set) >> +{ >> +   __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; >> +   int cold_count = le32_to_cpu(sbi->raw_super->extension_count); >> +   int hot_count = sbi->raw_super->hot_ext_count; >> +   int total_count = cold_count + hot_count; >> +   int start, count; >> +   int i; >> + >> +   if (set) { >> +       if (total_count == F2FS_MAX_EXTENSION) >> +           return -EINVAL; >> +   } else { >> +       if (!hot && !cold_count) >> +           return -EINVAL; >> +       if (hot && !hot_count) >> +           return -EINVAL; >> +   } >> + >> +   if (hot) { >> +       start = cold_count; >> +       count = total_count; >> +   } else { >> +       start = 0; >> +       count = cold_count; >> +   } >> + >> +   for (i = start; i < count; i++) { >> +       if (strcmp(name, extlist[i])) >> +           continue; >> + >> +       if (set) >> +           return -EINVAL; >> + >> +       memcpy(extlist[i], extlist[i + 1], >> +               F2FS_EXTENSION_LEN * (total_count - i - 1)); >> +       memset(extlist[total_count - 1], 0, F2FS_EXTENSION_LEN); >> +       if (hot) >> +           sbi->raw_super->hot_ext_count = hot_count - 1; >> +       else >> +           sbi->raw_super->extension_count = >> +                       cpu_to_le32(cold_count - 1); >> +       return 0; >> +   } >> + >> +   if (!set) >> +       return -EINVAL; >> + >> +   if (hot) { >> +       memcpy(extlist[count], name, strlen(name)); >> +       sbi->raw_super->hot_ext_count = hot_count + 1; >> +   } else { >> +       char buf[F2FS_MAX_EXTENSION][F2FS_EXTENSION_LEN]; >> + >> +       memcpy(buf, &extlist[cold_count], >> +               F2FS_EXTENSION_LEN * hot_count); >> +       memset(extlist[cold_count], 0, F2FS_EXTENSION_LEN); >> +       memcpy(extlist[cold_count], name, strlen(name)); >> +       memcpy(&extlist[cold_count + 1], buf, >> +               F2FS_EXTENSION_LEN * hot_count); >> +       sbi->raw_super->extension_count = cpu_to_le32(cold_count + 1); >> +   } >> +   return 0; >> +} >> + >> +static void set_compress_new_inode(struct f2fs_sb_info *sbi, struct inode *dir, >> +               struct inode *inode, const unsigned char *name) >> +{ >> +   __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; >> +   unsigned char (*noext)[F2FS_EXTENSION_LEN] = >> +                       F2FS_OPTION(sbi).noextensions; >> +   unsigned char (*ext)[F2FS_EXTENSION_LEN] = F2FS_OPTION(sbi).extensions; >> +   unsigned char ext_cnt = F2FS_OPTION(sbi).compress_ext_cnt; >> +   unsigned char noext_cnt = F2FS_OPTION(sbi).nocompress_ext_cnt; >> +   int i, cold_count, hot_count; >> + >> +   /* Caller should give the name of regular file or directory. */ >> +   if (!f2fs_sb_has_compression(sbi) || !name) >> +       return; >> + >> +   if (S_ISDIR(inode->i_mode)) >> +       goto inherit_comp; > > Documentation/filesystems/f2fs.rst > > - Priority in between FS_COMPR_FL, FS_NOCOMP_FS, extensions: > >  * compress_extension=so; nocompress_extension=zip; chattr +c dir; touch >    dir/foo.so; touch dir/bar.zip; touch dir/baz.txt; then foo.so and baz.txt >    should be compresse, bar.zip should be non-compressed. chattr +c dir/bar.zip >    can enable compress on bar.zip. > > It looks nocompress_extension has higher priority than flag inheriting? Hi, Chao, Yes, nocompress_extension has higher priority for regular files. The following code checks ext[] and noext[] before setting compression flag. While for directories, we skip checking ext and noext. So the above `if (S_ISDIR(inode)) goto inherit_comp` does not break the rule. thanks, shengyong > >> + >> +   /* Don't compress hot files. */ >> +   f2fs_down_read(&sbi->sb_lock); >> +   cold_count = le32_to_cpu(sbi->raw_super->extension_count); >> +   hot_count = sbi->raw_super->hot_ext_count; >> +   for (i = cold_count; i < cold_count + hot_count; i++) >> +       if (is_extension_exist(name, extlist[i], false)) >> +           break; >> +   f2fs_up_read(&sbi->sb_lock); >> +   if (i < (cold_count + hot_count)) >> +       return; >> + >> +   /* Don't compress unallowed extension. */ >> +   for (i = 0; i < noext_cnt; i++) >> +       if (is_extension_exist(name, noext[i], false)) >> +           return; >> + >> +   /* Compress wanting extension. */ >> +   for (i = 0; i < ext_cnt; i++) { >> +       if (is_extension_exist(name, ext[i], false)) { >> +           set_compress_context(inode); >> +           return; >> +       } >> +   } >> +inherit_comp: >> +   /* Inherit the {no-}compression flag in directory */ >> +   if (F2FS_I(dir)->i_flags & F2FS_NOCOMP_FL) >> +       F2FS_I(inode)->i_flags |= F2FS_NOCOMP_FL; > > f2fs_mark_inode_dirty_sync(, true)? > >> +   else if (F2FS_I(dir)->i_flags & F2FS_COMPR_FL) >> +       set_compress_context(inode); >> +} >> + >>  static struct inode *f2fs_new_inode(struct user_namespace *mnt_userns, >> -                       struct inode *dir, umode_t mode) >> +                       struct inode *dir, umode_t mode, >> +                       const char *name) >>  { >>      struct f2fs_sb_info *sbi = F2FS_I_SB(dir); >>      nid_t ino; >> @@ -114,12 +264,8 @@ static struct inode *f2fs_new_inode(struct user_namespace *mnt_userns, >>      if (F2FS_I(inode)->i_flags & F2FS_PROJINHERIT_FL) >>          set_inode_flag(inode, FI_PROJ_INHERIT); >> -   if (f2fs_sb_has_compression(sbi)) { >> -       /* Inherit the compression flag in directory */ >> -       if ((F2FS_I(dir)->i_flags & F2FS_COMPR_FL) && >> -                   f2fs_may_compress(inode)) >> -           set_compress_context(inode); >> -   } >> +   /* Check compression first. */ >> +   set_compress_new_inode(sbi, dir, inode, name); >>      /* Should enable inline_data after compression set */ >>      if (test_opt(sbi, INLINE_DATA) && f2fs_may_inline_data(inode)) >> @@ -153,40 +299,6 @@ static struct inode *f2fs_new_inode(struct user_namespace *mnt_userns, >>      return ERR_PTR(err); >>  } >> -static inline int is_extension_exist(const unsigned char *s, const char *sub, >> -                       bool tmp_ext) >> -{ >> -   size_t slen = strlen(s); >> -   size_t sublen = strlen(sub); >> -   int i; >> - >> -   if (sublen == 1 && *sub == '*') >> -       return 1; >> - >> -   /* >> -    * filename format of multimedia file should be defined as: >> -    * "filename + '.' + extension + (optional: '.' + temp extension)". >> -    */ >> -   if (slen < sublen + 2) >> -       return 0; >> - >> -   if (!tmp_ext) { >> -       /* file has no temp extension */ >> -       if (s[slen - sublen - 1] != '.') >> -           return 0; >> -       return !strncasecmp(s + slen - sublen, sub, sublen); >> -   } >> - >> -   for (i = 1; i < slen - sublen; i++) { >> -       if (s[i] != '.') >> -           continue; >> -       if (!strncasecmp(s + i + 1, sub, sublen)) >> -           return 1; >> -   } >> - >> -   return 0; >> -} >> - >>  /* >>   * Set file's temperature for hot/cold data separation >>   */ >> @@ -217,124 +329,6 @@ static inline void set_file_temperature(struct f2fs_sb_info *sbi, struct inode * >>          file_set_hot(inode); >>  } >> -int f2fs_update_extension_list(struct f2fs_sb_info *sbi, const char *name, >> -                           bool hot, bool set) >> -{ >> -   __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; >> -   int cold_count = le32_to_cpu(sbi->raw_super->extension_count); >> -   int hot_count = sbi->raw_super->hot_ext_count; >> -   int total_count = cold_count + hot_count; >> -   int start, count; >> -   int i; >> - >> -   if (set) { >> -       if (total_count == F2FS_MAX_EXTENSION) >> -           return -EINVAL; >> -   } else { >> -       if (!hot && !cold_count) >> -           return -EINVAL; >> -       if (hot && !hot_count) >> -           return -EINVAL; >> -   } >> - >> -   if (hot) { >> -       start = cold_count; >> -       count = total_count; >> -   } else { >> -       start = 0; >> -       count = cold_count; >> -   } >> - >> -   for (i = start; i < count; i++) { >> -       if (strcmp(name, extlist[i])) >> -           continue; >> - >> -       if (set) >> -           return -EINVAL; >> - >> -       memcpy(extlist[i], extlist[i + 1], >> -               F2FS_EXTENSION_LEN * (total_count - i - 1)); >> -       memset(extlist[total_count - 1], 0, F2FS_EXTENSION_LEN); >> -       if (hot) >> -           sbi->raw_super->hot_ext_count = hot_count - 1; >> -       else >> -           sbi->raw_super->extension_count = >> -                       cpu_to_le32(cold_count - 1); >> -       return 0; >> -   } >> - >> -   if (!set) >> -       return -EINVAL; >> - >> -   if (hot) { >> -       memcpy(extlist[count], name, strlen(name)); >> -       sbi->raw_super->hot_ext_count = hot_count + 1; >> -   } else { >> -       char buf[F2FS_MAX_EXTENSION][F2FS_EXTENSION_LEN]; >> - >> -       memcpy(buf, &extlist[cold_count], >> -               F2FS_EXTENSION_LEN * hot_count); >> -       memset(extlist[cold_count], 0, F2FS_EXTENSION_LEN); >> -       memcpy(extlist[cold_count], name, strlen(name)); >> -       memcpy(&extlist[cold_count + 1], buf, >> -               F2FS_EXTENSION_LEN * hot_count); >> -       sbi->raw_super->extension_count = cpu_to_le32(cold_count + 1); >> -   } >> -   return 0; >> -} >> - >> -static void set_compress_inode(struct f2fs_sb_info *sbi, struct inode *inode, >> -                       const unsigned char *name) >> -{ >> -   __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; >> -   unsigned char (*noext)[F2FS_EXTENSION_LEN] = F2FS_OPTION(sbi).noextensions; >> -   unsigned char (*ext)[F2FS_EXTENSION_LEN] = F2FS_OPTION(sbi).extensions; >> -   unsigned char ext_cnt = F2FS_OPTION(sbi).compress_ext_cnt; >> -   unsigned char noext_cnt = F2FS_OPTION(sbi).nocompress_ext_cnt; >> -   int i, cold_count, hot_count; >> - >> -   if (!f2fs_sb_has_compression(sbi) || >> -           F2FS_I(inode)->i_flags & F2FS_NOCOMP_FL || >> -           !f2fs_may_compress(inode) || >> -           (!ext_cnt && !noext_cnt)) >> -       return; >> - >> -   f2fs_down_read(&sbi->sb_lock); >> - >> -   cold_count = le32_to_cpu(sbi->raw_super->extension_count); >> -   hot_count = sbi->raw_super->hot_ext_count; >> - >> -   for (i = cold_count; i < cold_count + hot_count; i++) { >> -       if (is_extension_exist(name, extlist[i], false)) { >> -           f2fs_up_read(&sbi->sb_lock); >> -           return; >> -       } >> -   } >> - >> -   f2fs_up_read(&sbi->sb_lock); >> - >> -   for (i = 0; i < noext_cnt; i++) { >> -       if (is_extension_exist(name, noext[i], false)) { >> -           f2fs_disable_compressed_file(inode); >> -           return; >> -       } >> -   } >> - >> -   if (is_inode_flag_set(inode, FI_COMPRESSED_FILE)) >> -       return; >> - >> -   for (i = 0; i < ext_cnt; i++) { >> -       if (!is_extension_exist(name, ext[i], false)) >> -           continue; >> - >> -       /* Do not use inline_data with compression */ >> -       stat_dec_inline_inode(inode); >> -       clear_inode_flag(inode, FI_INLINE_DATA); >> -       set_compress_context(inode); >> -       return; >> -   } >> -} >> - >>  static int f2fs_create(struct user_namespace *mnt_userns, struct inode *dir, >>                 struct dentry *dentry, umode_t mode, bool excl) >>  { >> @@ -352,15 +346,13 @@ static int f2fs_create(struct user_namespace *mnt_userns, struct inode *dir, >>      if (err) >>          return err; >> -   inode = f2fs_new_inode(mnt_userns, dir, mode); >> +   inode = f2fs_new_inode(mnt_userns, dir, mode, dentry->d_name.name); >>      if (IS_ERR(inode)) >>          return PTR_ERR(inode); >>      if (!test_opt(sbi, DISABLE_EXT_IDENTIFY)) >>          set_file_temperature(sbi, inode, dentry->d_name.name); >> -   set_compress_inode(sbi, inode, dentry->d_name.name); >> - >>      inode->i_op = &f2fs_file_inode_operations; >>      inode->i_fop = &f2fs_file_operations; >>      inode->i_mapping->a_ops = &f2fs_dblock_aops; >> @@ -689,7 +681,7 @@ static int f2fs_symlink(struct user_namespace *mnt_userns, struct inode *dir, >>      if (err) >>          return err; >> -   inode = f2fs_new_inode(mnt_userns, dir, S_IFLNK | S_IRWXUGO); >> +   inode = f2fs_new_inode(mnt_userns, dir, S_IFLNK | S_IRWXUGO, NULL); >>      if (IS_ERR(inode)) >>          return PTR_ERR(inode); >> @@ -760,7 +752,8 @@ static int f2fs_mkdir(struct user_namespace *mnt_userns, struct inode *dir, >>      if (err) >>          return err; >> -   inode = f2fs_new_inode(mnt_userns, dir, S_IFDIR | mode); >> +   inode = f2fs_new_inode(mnt_userns, dir, S_IFDIR | mode, >> +                       dentry->d_name.name); > > Why we need to pass directory's name to set_compress_new_inode()? > > Could we just check S_IFDIR in child inode? > > Thanks, > >>      if (IS_ERR(inode)) >>          return PTR_ERR(inode); >> @@ -817,7 +810,7 @@ static int f2fs_mknod(struct user_namespace *mnt_userns, struct inode *dir, >>      if (err) >>          return err; >> -   inode = f2fs_new_inode(mnt_userns, dir, mode); >> +   inode = f2fs_new_inode(mnt_userns, dir, mode, NULL); >>      if (IS_ERR(inode)) >>          return PTR_ERR(inode); >> @@ -856,7 +849,7 @@ static int __f2fs_tmpfile(struct user_namespace *mnt_userns, struct inode *dir, >>      if (err) >>          return err; >> -   inode = f2fs_new_inode(mnt_userns, dir, mode); >> +   inode = f2fs_new_inode(mnt_userns, dir, mode, NULL); >>      if (IS_ERR(inode)) >>          return PTR_ERR(inode);
On 11/23, Chao Yu wrote: > On 2022/11/17 9:12, Jaegeuk Kim wrote: > > If compress_extension is set, and a newly created file matches the > > extension, the file could be marked as compression file. However, > > if inline_data is also enabled, there is no chance to check its > > extension since f2fs_should_compress() always returns false. > > > > This patch moves set_compress_inode(), which do extension check, in > > f2fs_should_compress() to check extensions before setting inline > > data flag. > > > > Fixes: 7165841d578e ("f2fs: fix to check inline_data during compressed inode conversion") > > Signed-off-by: Sheng Yong <shengyong@oppo.com> > > Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org> > > --- > > fs/f2fs/f2fs.h | 2 +- > > fs/f2fs/namei.c | 325 +++++++++++++++++++++++------------------------- > > 2 files changed, 160 insertions(+), 167 deletions(-) > > > > diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h > > index b89b5d755ce0..dedac413bf64 100644 > > --- a/fs/f2fs/f2fs.h > > +++ b/fs/f2fs/f2fs.h > > @@ -2980,7 +2980,7 @@ static inline void f2fs_change_bit(unsigned int nr, char *addr) > > /* Flags that should be inherited by new inodes from their parent. */ > > #define F2FS_FL_INHERITED (F2FS_SYNC_FL | F2FS_NODUMP_FL | F2FS_NOATIME_FL | \ > > F2FS_DIRSYNC_FL | F2FS_PROJINHERIT_FL | \ > > - F2FS_CASEFOLD_FL | F2FS_COMPR_FL | F2FS_NOCOMP_FL) > > + F2FS_CASEFOLD_FL) > > /* Flags that are appropriate for regular files (all but dir-specific ones). */ > > #define F2FS_REG_FLMASK (~(F2FS_DIRSYNC_FL | F2FS_PROJINHERIT_FL | \ > > diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c > > index e104409c3a0e..c25009bb72f2 100644 > > --- a/fs/f2fs/namei.c > > +++ b/fs/f2fs/namei.c > > @@ -22,8 +22,158 @@ > > #include "acl.h" > > #include <trace/events/f2fs.h> > > +static inline int is_extension_exist(const unsigned char *s, const char *sub, > > + bool tmp_ext) > > +{ > > + size_t slen = strlen(s); > > + size_t sublen = strlen(sub); > > + int i; > > + > > + if (sublen == 1 && *sub == '*') > > + return 1; > > + > > + /* > > + * filename format of multimedia file should be defined as: > > + * "filename + '.' + extension + (optional: '.' + temp extension)". > > + */ > > + if (slen < sublen + 2) > > + return 0; > > + > > + if (!tmp_ext) { > > + /* file has no temp extension */ > > + if (s[slen - sublen - 1] != '.') > > + return 0; > > + return !strncasecmp(s + slen - sublen, sub, sublen); > > + } > > + > > + for (i = 1; i < slen - sublen; i++) { > > + if (s[i] != '.') > > + continue; > > + if (!strncasecmp(s + i + 1, sub, sublen)) > > + return 1; > > + } > > + > > + return 0; > > +} > > + > > +int f2fs_update_extension_list(struct f2fs_sb_info *sbi, const char *name, > > + bool hot, bool set) > > +{ > > + __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; > > + int cold_count = le32_to_cpu(sbi->raw_super->extension_count); > > + int hot_count = sbi->raw_super->hot_ext_count; > > + int total_count = cold_count + hot_count; > > + int start, count; > > + int i; > > + > > + if (set) { > > + if (total_count == F2FS_MAX_EXTENSION) > > + return -EINVAL; > > + } else { > > + if (!hot && !cold_count) > > + return -EINVAL; > > + if (hot && !hot_count) > > + return -EINVAL; > > + } > > + > > + if (hot) { > > + start = cold_count; > > + count = total_count; > > + } else { > > + start = 0; > > + count = cold_count; > > + } > > + > > + for (i = start; i < count; i++) { > > + if (strcmp(name, extlist[i])) > > + continue; > > + > > + if (set) > > + return -EINVAL; > > + > > + memcpy(extlist[i], extlist[i + 1], > > + F2FS_EXTENSION_LEN * (total_count - i - 1)); > > + memset(extlist[total_count - 1], 0, F2FS_EXTENSION_LEN); > > + if (hot) > > + sbi->raw_super->hot_ext_count = hot_count - 1; > > + else > > + sbi->raw_super->extension_count = > > + cpu_to_le32(cold_count - 1); > > + return 0; > > + } > > + > > + if (!set) > > + return -EINVAL; > > + > > + if (hot) { > > + memcpy(extlist[count], name, strlen(name)); > > + sbi->raw_super->hot_ext_count = hot_count + 1; > > + } else { > > + char buf[F2FS_MAX_EXTENSION][F2FS_EXTENSION_LEN]; > > + > > + memcpy(buf, &extlist[cold_count], > > + F2FS_EXTENSION_LEN * hot_count); > > + memset(extlist[cold_count], 0, F2FS_EXTENSION_LEN); > > + memcpy(extlist[cold_count], name, strlen(name)); > > + memcpy(&extlist[cold_count + 1], buf, > > + F2FS_EXTENSION_LEN * hot_count); > > + sbi->raw_super->extension_count = cpu_to_le32(cold_count + 1); > > + } > > + return 0; > > +} > > + > > +static void set_compress_new_inode(struct f2fs_sb_info *sbi, struct inode *dir, > > + struct inode *inode, const unsigned char *name) > > +{ > > + __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; > > + unsigned char (*noext)[F2FS_EXTENSION_LEN] = > > + F2FS_OPTION(sbi).noextensions; > > + unsigned char (*ext)[F2FS_EXTENSION_LEN] = F2FS_OPTION(sbi).extensions; > > + unsigned char ext_cnt = F2FS_OPTION(sbi).compress_ext_cnt; > > + unsigned char noext_cnt = F2FS_OPTION(sbi).nocompress_ext_cnt; > > + int i, cold_count, hot_count; > > + > > + /* Caller should give the name of regular file or directory. */ > > + if (!f2fs_sb_has_compression(sbi) || !name) > > + return; > > + > > + if (S_ISDIR(inode->i_mode)) > > + goto inherit_comp; > > Documentation/filesystems/f2fs.rst > > - Priority in between FS_COMPR_FL, FS_NOCOMP_FS, extensions: > > * compress_extension=so; nocompress_extension=zip; chattr +c dir; touch > dir/foo.so; touch dir/bar.zip; touch dir/baz.txt; then foo.so and baz.txt > should be compresse, bar.zip should be non-compressed. chattr +c dir/bar.zip > can enable compress on bar.zip. > > It looks nocompress_extension has higher priority than flag inheriting? I think so. > > > + > > + /* Don't compress hot files. */ > > + f2fs_down_read(&sbi->sb_lock); > > + cold_count = le32_to_cpu(sbi->raw_super->extension_count); > > + hot_count = sbi->raw_super->hot_ext_count; > > + for (i = cold_count; i < cold_count + hot_count; i++) > > + if (is_extension_exist(name, extlist[i], false)) > > + break; > > + f2fs_up_read(&sbi->sb_lock); > > + if (i < (cold_count + hot_count)) > > + return; > > + > > + /* Don't compress unallowed extension. */ > > + for (i = 0; i < noext_cnt; i++) > > + if (is_extension_exist(name, noext[i], false)) > > + return; > > + > > + /* Compress wanting extension. */ > > + for (i = 0; i < ext_cnt; i++) { > > + if (is_extension_exist(name, ext[i], false)) { > > + set_compress_context(inode); > > + return; > > + } > > + } > > +inherit_comp: > > + /* Inherit the {no-}compression flag in directory */ > > + if (F2FS_I(dir)->i_flags & F2FS_NOCOMP_FL) > > + F2FS_I(inode)->i_flags |= F2FS_NOCOMP_FL; > > f2fs_mark_inode_dirty_sync(, true)? Done. > > > + else if (F2FS_I(dir)->i_flags & F2FS_COMPR_FL) > > + set_compress_context(inode); > > +} > > + > > static struct inode *f2fs_new_inode(struct user_namespace *mnt_userns, > > - struct inode *dir, umode_t mode) > > + struct inode *dir, umode_t mode, > > + const char *name) > > { > > struct f2fs_sb_info *sbi = F2FS_I_SB(dir); > > nid_t ino; > > @@ -114,12 +264,8 @@ static struct inode *f2fs_new_inode(struct user_namespace *mnt_userns, > > if (F2FS_I(inode)->i_flags & F2FS_PROJINHERIT_FL) > > set_inode_flag(inode, FI_PROJ_INHERIT); > > - if (f2fs_sb_has_compression(sbi)) { > > - /* Inherit the compression flag in directory */ > > - if ((F2FS_I(dir)->i_flags & F2FS_COMPR_FL) && > > - f2fs_may_compress(inode)) > > - set_compress_context(inode); > > - } > > + /* Check compression first. */ > > + set_compress_new_inode(sbi, dir, inode, name); > > /* Should enable inline_data after compression set */ > > if (test_opt(sbi, INLINE_DATA) && f2fs_may_inline_data(inode)) > > @@ -153,40 +299,6 @@ static struct inode *f2fs_new_inode(struct user_namespace *mnt_userns, > > return ERR_PTR(err); > > } > > -static inline int is_extension_exist(const unsigned char *s, const char *sub, > > - bool tmp_ext) > > -{ > > - size_t slen = strlen(s); > > - size_t sublen = strlen(sub); > > - int i; > > - > > - if (sublen == 1 && *sub == '*') > > - return 1; > > - > > - /* > > - * filename format of multimedia file should be defined as: > > - * "filename + '.' + extension + (optional: '.' + temp extension)". > > - */ > > - if (slen < sublen + 2) > > - return 0; > > - > > - if (!tmp_ext) { > > - /* file has no temp extension */ > > - if (s[slen - sublen - 1] != '.') > > - return 0; > > - return !strncasecmp(s + slen - sublen, sub, sublen); > > - } > > - > > - for (i = 1; i < slen - sublen; i++) { > > - if (s[i] != '.') > > - continue; > > - if (!strncasecmp(s + i + 1, sub, sublen)) > > - return 1; > > - } > > - > > - return 0; > > -} > > - > > /* > > * Set file's temperature for hot/cold data separation > > */ > > @@ -217,124 +329,6 @@ static inline void set_file_temperature(struct f2fs_sb_info *sbi, struct inode * > > file_set_hot(inode); > > } > > -int f2fs_update_extension_list(struct f2fs_sb_info *sbi, const char *name, > > - bool hot, bool set) > > -{ > > - __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; > > - int cold_count = le32_to_cpu(sbi->raw_super->extension_count); > > - int hot_count = sbi->raw_super->hot_ext_count; > > - int total_count = cold_count + hot_count; > > - int start, count; > > - int i; > > - > > - if (set) { > > - if (total_count == F2FS_MAX_EXTENSION) > > - return -EINVAL; > > - } else { > > - if (!hot && !cold_count) > > - return -EINVAL; > > - if (hot && !hot_count) > > - return -EINVAL; > > - } > > - > > - if (hot) { > > - start = cold_count; > > - count = total_count; > > - } else { > > - start = 0; > > - count = cold_count; > > - } > > - > > - for (i = start; i < count; i++) { > > - if (strcmp(name, extlist[i])) > > - continue; > > - > > - if (set) > > - return -EINVAL; > > - > > - memcpy(extlist[i], extlist[i + 1], > > - F2FS_EXTENSION_LEN * (total_count - i - 1)); > > - memset(extlist[total_count - 1], 0, F2FS_EXTENSION_LEN); > > - if (hot) > > - sbi->raw_super->hot_ext_count = hot_count - 1; > > - else > > - sbi->raw_super->extension_count = > > - cpu_to_le32(cold_count - 1); > > - return 0; > > - } > > - > > - if (!set) > > - return -EINVAL; > > - > > - if (hot) { > > - memcpy(extlist[count], name, strlen(name)); > > - sbi->raw_super->hot_ext_count = hot_count + 1; > > - } else { > > - char buf[F2FS_MAX_EXTENSION][F2FS_EXTENSION_LEN]; > > - > > - memcpy(buf, &extlist[cold_count], > > - F2FS_EXTENSION_LEN * hot_count); > > - memset(extlist[cold_count], 0, F2FS_EXTENSION_LEN); > > - memcpy(extlist[cold_count], name, strlen(name)); > > - memcpy(&extlist[cold_count + 1], buf, > > - F2FS_EXTENSION_LEN * hot_count); > > - sbi->raw_super->extension_count = cpu_to_le32(cold_count + 1); > > - } > > - return 0; > > -} > > - > > -static void set_compress_inode(struct f2fs_sb_info *sbi, struct inode *inode, > > - const unsigned char *name) > > -{ > > - __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; > > - unsigned char (*noext)[F2FS_EXTENSION_LEN] = F2FS_OPTION(sbi).noextensions; > > - unsigned char (*ext)[F2FS_EXTENSION_LEN] = F2FS_OPTION(sbi).extensions; > > - unsigned char ext_cnt = F2FS_OPTION(sbi).compress_ext_cnt; > > - unsigned char noext_cnt = F2FS_OPTION(sbi).nocompress_ext_cnt; > > - int i, cold_count, hot_count; > > - > > - if (!f2fs_sb_has_compression(sbi) || > > - F2FS_I(inode)->i_flags & F2FS_NOCOMP_FL || > > - !f2fs_may_compress(inode) || > > - (!ext_cnt && !noext_cnt)) > > - return; > > - > > - f2fs_down_read(&sbi->sb_lock); > > - > > - cold_count = le32_to_cpu(sbi->raw_super->extension_count); > > - hot_count = sbi->raw_super->hot_ext_count; > > - > > - for (i = cold_count; i < cold_count + hot_count; i++) { > > - if (is_extension_exist(name, extlist[i], false)) { > > - f2fs_up_read(&sbi->sb_lock); > > - return; > > - } > > - } > > - > > - f2fs_up_read(&sbi->sb_lock); > > - > > - for (i = 0; i < noext_cnt; i++) { > > - if (is_extension_exist(name, noext[i], false)) { > > - f2fs_disable_compressed_file(inode); > > - return; > > - } > > - } > > - > > - if (is_inode_flag_set(inode, FI_COMPRESSED_FILE)) > > - return; > > - > > - for (i = 0; i < ext_cnt; i++) { > > - if (!is_extension_exist(name, ext[i], false)) > > - continue; > > - > > - /* Do not use inline_data with compression */ > > - stat_dec_inline_inode(inode); > > - clear_inode_flag(inode, FI_INLINE_DATA); > > - set_compress_context(inode); > > - return; > > - } > > -} > > - > > static int f2fs_create(struct user_namespace *mnt_userns, struct inode *dir, > > struct dentry *dentry, umode_t mode, bool excl) > > { > > @@ -352,15 +346,13 @@ static int f2fs_create(struct user_namespace *mnt_userns, struct inode *dir, > > if (err) > > return err; > > - inode = f2fs_new_inode(mnt_userns, dir, mode); > > + inode = f2fs_new_inode(mnt_userns, dir, mode, dentry->d_name.name); > > if (IS_ERR(inode)) > > return PTR_ERR(inode); > > if (!test_opt(sbi, DISABLE_EXT_IDENTIFY)) > > set_file_temperature(sbi, inode, dentry->d_name.name); > > - set_compress_inode(sbi, inode, dentry->d_name.name); > > - > > inode->i_op = &f2fs_file_inode_operations; > > inode->i_fop = &f2fs_file_operations; > > inode->i_mapping->a_ops = &f2fs_dblock_aops; > > @@ -689,7 +681,7 @@ static int f2fs_symlink(struct user_namespace *mnt_userns, struct inode *dir, > > if (err) > > return err; > > - inode = f2fs_new_inode(mnt_userns, dir, S_IFLNK | S_IRWXUGO); > > + inode = f2fs_new_inode(mnt_userns, dir, S_IFLNK | S_IRWXUGO, NULL); > > if (IS_ERR(inode)) > > return PTR_ERR(inode); > > @@ -760,7 +752,8 @@ static int f2fs_mkdir(struct user_namespace *mnt_userns, struct inode *dir, > > if (err) > > return err; > > - inode = f2fs_new_inode(mnt_userns, dir, S_IFDIR | mode); > > + inode = f2fs_new_inode(mnt_userns, dir, S_IFDIR | mode, > > + dentry->d_name.name); > > Why we need to pass directory's name to set_compress_new_inode()? > > Could we just check S_IFDIR in child inode? Yup, good point. Let me send v5. > > Thanks, > > > if (IS_ERR(inode)) > > return PTR_ERR(inode); > > @@ -817,7 +810,7 @@ static int f2fs_mknod(struct user_namespace *mnt_userns, struct inode *dir, > > if (err) > > return err; > > - inode = f2fs_new_inode(mnt_userns, dir, mode); > > + inode = f2fs_new_inode(mnt_userns, dir, mode, NULL); > > if (IS_ERR(inode)) > > return PTR_ERR(inode); > > @@ -856,7 +849,7 @@ static int __f2fs_tmpfile(struct user_namespace *mnt_userns, struct inode *dir, > > if (err) > > return err; > > - inode = f2fs_new_inode(mnt_userns, dir, mode); > > + inode = f2fs_new_inode(mnt_userns, dir, mode, NULL); > > if (IS_ERR(inode)) > > return PTR_ERR(inode);
If compress_extension is set, and a newly created file matches the extension, the file could be marked as compression file. However, if inline_data is also enabled, there is no chance to check its extension since f2fs_should_compress() always returns false. This patch moves set_compress_inode(), which do extension check, in f2fs_should_compress() to check extensions before setting inline data flag. Fixes: 7165841d578e ("f2fs: fix to check inline_data during compressed inode conversion") Signed-off-by: Sheng Yong <shengyong@oppo.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org> --- Change log from v4: - call f2fs_mark_inode_dirty_sync - remove name for directory fs/f2fs/f2fs.h | 2 +- fs/f2fs/namei.c | 329 ++++++++++++++++++++++++------------------------ 2 files changed, 164 insertions(+), 167 deletions(-) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 96bd3461c0bb..f0833638f59e 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -2980,7 +2980,7 @@ static inline void f2fs_change_bit(unsigned int nr, char *addr) /* Flags that should be inherited by new inodes from their parent. */ #define F2FS_FL_INHERITED (F2FS_SYNC_FL | F2FS_NODUMP_FL | F2FS_NOATIME_FL | \ F2FS_DIRSYNC_FL | F2FS_PROJINHERIT_FL | \ - F2FS_CASEFOLD_FL | F2FS_COMPR_FL | F2FS_NOCOMP_FL) + F2FS_CASEFOLD_FL) /* Flags that are appropriate for regular files (all but dir-specific ones). */ #define F2FS_REG_FLMASK (~(F2FS_DIRSYNC_FL | F2FS_PROJINHERIT_FL | \ diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index e104409c3a0e..54448dccbb6a 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c @@ -22,8 +22,163 @@ #include "acl.h" #include <trace/events/f2fs.h> +static inline int is_extension_exist(const unsigned char *s, const char *sub, + bool tmp_ext) +{ + size_t slen = strlen(s); + size_t sublen = strlen(sub); + int i; + + if (sublen == 1 && *sub == '*') + return 1; + + /* + * filename format of multimedia file should be defined as: + * "filename + '.' + extension + (optional: '.' + temp extension)". + */ + if (slen < sublen + 2) + return 0; + + if (!tmp_ext) { + /* file has no temp extension */ + if (s[slen - sublen - 1] != '.') + return 0; + return !strncasecmp(s + slen - sublen, sub, sublen); + } + + for (i = 1; i < slen - sublen; i++) { + if (s[i] != '.') + continue; + if (!strncasecmp(s + i + 1, sub, sublen)) + return 1; + } + + return 0; +} + +int f2fs_update_extension_list(struct f2fs_sb_info *sbi, const char *name, + bool hot, bool set) +{ + __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; + int cold_count = le32_to_cpu(sbi->raw_super->extension_count); + int hot_count = sbi->raw_super->hot_ext_count; + int total_count = cold_count + hot_count; + int start, count; + int i; + + if (set) { + if (total_count == F2FS_MAX_EXTENSION) + return -EINVAL; + } else { + if (!hot && !cold_count) + return -EINVAL; + if (hot && !hot_count) + return -EINVAL; + } + + if (hot) { + start = cold_count; + count = total_count; + } else { + start = 0; + count = cold_count; + } + + for (i = start; i < count; i++) { + if (strcmp(name, extlist[i])) + continue; + + if (set) + return -EINVAL; + + memcpy(extlist[i], extlist[i + 1], + F2FS_EXTENSION_LEN * (total_count - i - 1)); + memset(extlist[total_count - 1], 0, F2FS_EXTENSION_LEN); + if (hot) + sbi->raw_super->hot_ext_count = hot_count - 1; + else + sbi->raw_super->extension_count = + cpu_to_le32(cold_count - 1); + return 0; + } + + if (!set) + return -EINVAL; + + if (hot) { + memcpy(extlist[count], name, strlen(name)); + sbi->raw_super->hot_ext_count = hot_count + 1; + } else { + char buf[F2FS_MAX_EXTENSION][F2FS_EXTENSION_LEN]; + + memcpy(buf, &extlist[cold_count], + F2FS_EXTENSION_LEN * hot_count); + memset(extlist[cold_count], 0, F2FS_EXTENSION_LEN); + memcpy(extlist[cold_count], name, strlen(name)); + memcpy(&extlist[cold_count + 1], buf, + F2FS_EXTENSION_LEN * hot_count); + sbi->raw_super->extension_count = cpu_to_le32(cold_count + 1); + } + return 0; +} + +static void set_compress_new_inode(struct f2fs_sb_info *sbi, struct inode *dir, + struct inode *inode, const unsigned char *name) +{ + __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; + unsigned char (*noext)[F2FS_EXTENSION_LEN] = + F2FS_OPTION(sbi).noextensions; + unsigned char (*ext)[F2FS_EXTENSION_LEN] = F2FS_OPTION(sbi).extensions; + unsigned char ext_cnt = F2FS_OPTION(sbi).compress_ext_cnt; + unsigned char noext_cnt = F2FS_OPTION(sbi).nocompress_ext_cnt; + int i, cold_count, hot_count; + + if (!f2fs_sb_has_compression(sbi)) + return; + + if (S_ISDIR(inode->i_mode)) + goto inherit_comp; + + /* This name comes only from normal files. */ + if (!name) + return; + + /* Don't compress hot files. */ + f2fs_down_read(&sbi->sb_lock); + cold_count = le32_to_cpu(sbi->raw_super->extension_count); + hot_count = sbi->raw_super->hot_ext_count; + for (i = cold_count; i < cold_count + hot_count; i++) + if (is_extension_exist(name, extlist[i], false)) + break; + f2fs_up_read(&sbi->sb_lock); + if (i < (cold_count + hot_count)) + return; + + /* Don't compress unallowed extension. */ + for (i = 0; i < noext_cnt; i++) + if (is_extension_exist(name, noext[i], false)) + return; + + /* Compress wanting extension. */ + for (i = 0; i < ext_cnt; i++) { + if (is_extension_exist(name, ext[i], false)) { + set_compress_context(inode); + return; + } + } +inherit_comp: + /* Inherit the {no-}compression flag in directory */ + if (F2FS_I(dir)->i_flags & F2FS_NOCOMP_FL) { + F2FS_I(inode)->i_flags |= F2FS_NOCOMP_FL; + f2fs_mark_inode_dirty_sync(inode, true); + } else if (F2FS_I(dir)->i_flags & F2FS_COMPR_FL) { + set_compress_context(inode); + } +} + static struct inode *f2fs_new_inode(struct user_namespace *mnt_userns, - struct inode *dir, umode_t mode) + struct inode *dir, umode_t mode, + const char *name) { struct f2fs_sb_info *sbi = F2FS_I_SB(dir); nid_t ino; @@ -114,12 +269,8 @@ static struct inode *f2fs_new_inode(struct user_namespace *mnt_userns, if (F2FS_I(inode)->i_flags & F2FS_PROJINHERIT_FL) set_inode_flag(inode, FI_PROJ_INHERIT); - if (f2fs_sb_has_compression(sbi)) { - /* Inherit the compression flag in directory */ - if ((F2FS_I(dir)->i_flags & F2FS_COMPR_FL) && - f2fs_may_compress(inode)) - set_compress_context(inode); - } + /* Check compression first. */ + set_compress_new_inode(sbi, dir, inode, name); /* Should enable inline_data after compression set */ if (test_opt(sbi, INLINE_DATA) && f2fs_may_inline_data(inode)) @@ -153,40 +304,6 @@ static struct inode *f2fs_new_inode(struct user_namespace *mnt_userns, return ERR_PTR(err); } -static inline int is_extension_exist(const unsigned char *s, const char *sub, - bool tmp_ext) -{ - size_t slen = strlen(s); - size_t sublen = strlen(sub); - int i; - - if (sublen == 1 && *sub == '*') - return 1; - - /* - * filename format of multimedia file should be defined as: - * "filename + '.' + extension + (optional: '.' + temp extension)". - */ - if (slen < sublen + 2) - return 0; - - if (!tmp_ext) { - /* file has no temp extension */ - if (s[slen - sublen - 1] != '.') - return 0; - return !strncasecmp(s + slen - sublen, sub, sublen); - } - - for (i = 1; i < slen - sublen; i++) { - if (s[i] != '.') - continue; - if (!strncasecmp(s + i + 1, sub, sublen)) - return 1; - } - - return 0; -} - /* * Set file's temperature for hot/cold data separation */ @@ -217,124 +334,6 @@ static inline void set_file_temperature(struct f2fs_sb_info *sbi, struct inode * file_set_hot(inode); } -int f2fs_update_extension_list(struct f2fs_sb_info *sbi, const char *name, - bool hot, bool set) -{ - __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; - int cold_count = le32_to_cpu(sbi->raw_super->extension_count); - int hot_count = sbi->raw_super->hot_ext_count; - int total_count = cold_count + hot_count; - int start, count; - int i; - - if (set) { - if (total_count == F2FS_MAX_EXTENSION) - return -EINVAL; - } else { - if (!hot && !cold_count) - return -EINVAL; - if (hot && !hot_count) - return -EINVAL; - } - - if (hot) { - start = cold_count; - count = total_count; - } else { - start = 0; - count = cold_count; - } - - for (i = start; i < count; i++) { - if (strcmp(name, extlist[i])) - continue; - - if (set) - return -EINVAL; - - memcpy(extlist[i], extlist[i + 1], - F2FS_EXTENSION_LEN * (total_count - i - 1)); - memset(extlist[total_count - 1], 0, F2FS_EXTENSION_LEN); - if (hot) - sbi->raw_super->hot_ext_count = hot_count - 1; - else - sbi->raw_super->extension_count = - cpu_to_le32(cold_count - 1); - return 0; - } - - if (!set) - return -EINVAL; - - if (hot) { - memcpy(extlist[count], name, strlen(name)); - sbi->raw_super->hot_ext_count = hot_count + 1; - } else { - char buf[F2FS_MAX_EXTENSION][F2FS_EXTENSION_LEN]; - - memcpy(buf, &extlist[cold_count], - F2FS_EXTENSION_LEN * hot_count); - memset(extlist[cold_count], 0, F2FS_EXTENSION_LEN); - memcpy(extlist[cold_count], name, strlen(name)); - memcpy(&extlist[cold_count + 1], buf, - F2FS_EXTENSION_LEN * hot_count); - sbi->raw_super->extension_count = cpu_to_le32(cold_count + 1); - } - return 0; -} - -static void set_compress_inode(struct f2fs_sb_info *sbi, struct inode *inode, - const unsigned char *name) -{ - __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; - unsigned char (*noext)[F2FS_EXTENSION_LEN] = F2FS_OPTION(sbi).noextensions; - unsigned char (*ext)[F2FS_EXTENSION_LEN] = F2FS_OPTION(sbi).extensions; - unsigned char ext_cnt = F2FS_OPTION(sbi).compress_ext_cnt; - unsigned char noext_cnt = F2FS_OPTION(sbi).nocompress_ext_cnt; - int i, cold_count, hot_count; - - if (!f2fs_sb_has_compression(sbi) || - F2FS_I(inode)->i_flags & F2FS_NOCOMP_FL || - !f2fs_may_compress(inode) || - (!ext_cnt && !noext_cnt)) - return; - - f2fs_down_read(&sbi->sb_lock); - - cold_count = le32_to_cpu(sbi->raw_super->extension_count); - hot_count = sbi->raw_super->hot_ext_count; - - for (i = cold_count; i < cold_count + hot_count; i++) { - if (is_extension_exist(name, extlist[i], false)) { - f2fs_up_read(&sbi->sb_lock); - return; - } - } - - f2fs_up_read(&sbi->sb_lock); - - for (i = 0; i < noext_cnt; i++) { - if (is_extension_exist(name, noext[i], false)) { - f2fs_disable_compressed_file(inode); - return; - } - } - - if (is_inode_flag_set(inode, FI_COMPRESSED_FILE)) - return; - - for (i = 0; i < ext_cnt; i++) { - if (!is_extension_exist(name, ext[i], false)) - continue; - - /* Do not use inline_data with compression */ - stat_dec_inline_inode(inode); - clear_inode_flag(inode, FI_INLINE_DATA); - set_compress_context(inode); - return; - } -} - static int f2fs_create(struct user_namespace *mnt_userns, struct inode *dir, struct dentry *dentry, umode_t mode, bool excl) { @@ -352,15 +351,13 @@ static int f2fs_create(struct user_namespace *mnt_userns, struct inode *dir, if (err) return err; - inode = f2fs_new_inode(mnt_userns, dir, mode); + inode = f2fs_new_inode(mnt_userns, dir, mode, dentry->d_name.name); if (IS_ERR(inode)) return PTR_ERR(inode); if (!test_opt(sbi, DISABLE_EXT_IDENTIFY)) set_file_temperature(sbi, inode, dentry->d_name.name); - set_compress_inode(sbi, inode, dentry->d_name.name); - inode->i_op = &f2fs_file_inode_operations; inode->i_fop = &f2fs_file_operations; inode->i_mapping->a_ops = &f2fs_dblock_aops; @@ -689,7 +686,7 @@ static int f2fs_symlink(struct user_namespace *mnt_userns, struct inode *dir, if (err) return err; - inode = f2fs_new_inode(mnt_userns, dir, S_IFLNK | S_IRWXUGO); + inode = f2fs_new_inode(mnt_userns, dir, S_IFLNK | S_IRWXUGO, NULL); if (IS_ERR(inode)) return PTR_ERR(inode); @@ -760,7 +757,7 @@ static int f2fs_mkdir(struct user_namespace *mnt_userns, struct inode *dir, if (err) return err; - inode = f2fs_new_inode(mnt_userns, dir, S_IFDIR | mode); + inode = f2fs_new_inode(mnt_userns, dir, S_IFDIR | mode, NULL); if (IS_ERR(inode)) return PTR_ERR(inode); @@ -817,7 +814,7 @@ static int f2fs_mknod(struct user_namespace *mnt_userns, struct inode *dir, if (err) return err; - inode = f2fs_new_inode(mnt_userns, dir, mode); + inode = f2fs_new_inode(mnt_userns, dir, mode, NULL); if (IS_ERR(inode)) return PTR_ERR(inode); @@ -856,7 +853,7 @@ static int __f2fs_tmpfile(struct user_namespace *mnt_userns, struct inode *dir, if (err) return err; - inode = f2fs_new_inode(mnt_userns, dir, mode); + inode = f2fs_new_inode(mnt_userns, dir, mode, NULL); if (IS_ERR(inode)) return PTR_ERR(inode);
On 2022/11/24 5:29, Jaegeuk Kim wrote: >>> + if (S_ISDIR(inode->i_mode)) >>> + goto inherit_comp; >> >> Documentation/filesystems/f2fs.rst >> >> - Priority in between FS_COMPR_FL, FS_NOCOMP_FS, extensions: >> >> * compress_extension=so; nocompress_extension=zip; chattr +c dir; touch >> dir/foo.so; touch dir/bar.zip; touch dir/baz.txt; then foo.so and baz.txt >> should be compresse, bar.zip should be non-compressed. chattr +c dir/bar.zip >> can enable compress on bar.zip. >> >> It looks nocompress_extension has higher priority than flag inheriting? > > I think so. Hi Sheng, Jaegeuk, Yup, I guess I misunderstand the code. :) Thanks,
On 2022/11/24 5:46, Jaegeuk Kim wrote: > If compress_extension is set, and a newly created file matches the > extension, the file could be marked as compression file. However, > if inline_data is also enabled, there is no chance to check its > extension since f2fs_should_compress() always returns false. > > This patch moves set_compress_inode(), which do extension check, in > f2fs_should_compress() to check extensions before setting inline > data flag. > > Fixes: 7165841d578e ("f2fs: fix to check inline_data during compressed inode conversion") > Signed-off-by: Sheng Yong <shengyong@oppo.com> > Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org> Reviewed-by: Chao Yu <chao@kernel.org> Thanks,
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 6a8cbf5bb1871..a3420fbb29214 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -4355,6 +4355,7 @@ static inline int set_compress_context(struct inode *inode) F2FS_I(inode)->i_compress_flag |= F2FS_OPTION(sbi).compress_level << COMPRESS_LEVEL_OFFSET; + F2FS_I(inode)->i_flags &= ~F2FS_NOCOMP_FL; F2FS_I(inode)->i_flags |= F2FS_COMPR_FL; set_inode_flag(inode, FI_COMPRESSED_FILE); stat_inc_compr_inode(inode); diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index e104409c3a0e5..36ec5cf7cf859 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c @@ -22,8 +22,170 @@ #include "acl.h" #include <trace/events/f2fs.h> +static inline int is_extension_exist(const unsigned char *s, const char *sub, + bool tmp_ext) +{ + size_t slen = strlen(s); + size_t sublen = strlen(sub); + int i; + + if (sublen == 1 && *sub == '*') + return 1; + + /* + * filename format of multimedia file should be defined as: + * "filename + '.' + extension + (optional: '.' + temp extension)". + */ + if (slen < sublen + 2) + return 0; + + if (!tmp_ext) { + /* file has no temp extension */ + if (s[slen - sublen - 1] != '.') + return 0; + return !strncasecmp(s + slen - sublen, sub, sublen); + } + + for (i = 1; i < slen - sublen; i++) { + if (s[i] != '.') + continue; + if (!strncasecmp(s + i + 1, sub, sublen)) + return 1; + } + + return 0; +} + +int f2fs_update_extension_list(struct f2fs_sb_info *sbi, const char *name, + bool hot, bool set) +{ + __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; + int cold_count = le32_to_cpu(sbi->raw_super->extension_count); + int hot_count = sbi->raw_super->hot_ext_count; + int total_count = cold_count + hot_count; + int start, count; + int i; + + if (set) { + if (total_count == F2FS_MAX_EXTENSION) + return -EINVAL; + } else { + if (!hot && !cold_count) + return -EINVAL; + if (hot && !hot_count) + return -EINVAL; + } + + if (hot) { + start = cold_count; + count = total_count; + } else { + start = 0; + count = cold_count; + } + + for (i = start; i < count; i++) { + if (strcmp(name, extlist[i])) + continue; + + if (set) + return -EINVAL; + + memcpy(extlist[i], extlist[i + 1], + F2FS_EXTENSION_LEN * (total_count - i - 1)); + memset(extlist[total_count - 1], 0, F2FS_EXTENSION_LEN); + if (hot) + sbi->raw_super->hot_ext_count = hot_count - 1; + else + sbi->raw_super->extension_count = + cpu_to_le32(cold_count - 1); + return 0; + } + + if (!set) + return -EINVAL; + + if (hot) { + memcpy(extlist[count], name, strlen(name)); + sbi->raw_super->hot_ext_count = hot_count + 1; + } else { + char buf[F2FS_MAX_EXTENSION][F2FS_EXTENSION_LEN]; + + memcpy(buf, &extlist[cold_count], + F2FS_EXTENSION_LEN * hot_count); + memset(extlist[cold_count], 0, F2FS_EXTENSION_LEN); + memcpy(extlist[cold_count], name, strlen(name)); + memcpy(&extlist[cold_count + 1], buf, + F2FS_EXTENSION_LEN * hot_count); + sbi->raw_super->extension_count = cpu_to_le32(cold_count + 1); + } + return 0; +} + +static void set_compress_new_inode(struct f2fs_sb_info *sbi, struct inode *dir, + struct inode *inode, const unsigned char *name) +{ + struct f2fs_inode_info *fi = F2FS_I(inode); + __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; + unsigned char (*noext)[F2FS_EXTENSION_LEN] = + F2FS_OPTION(sbi).noextensions; + unsigned char (*ext)[F2FS_EXTENSION_LEN] = F2FS_OPTION(sbi).extensions; + unsigned char ext_cnt = F2FS_OPTION(sbi).compress_ext_cnt; + unsigned char noext_cnt = F2FS_OPTION(sbi).nocompress_ext_cnt; + bool may_compress = false; + int i, cold_count, hot_count; + + if (!f2fs_sb_has_compression(sbi) || !name) + return; + if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode)) + return; + + /* Inherit the compression flag in directory */ + if (fi->i_flags & FS_COMPR_FL) + may_compress = true; + + /* Start to check extension list for regular file */ + if ((!ext_cnt && !noext_cnt) || S_ISDIR(inode->i_mode)) + goto set_compress; + + /* Don't compress hot files. */ + f2fs_down_read(&sbi->sb_lock); + cold_count = le32_to_cpu(sbi->raw_super->extension_count); + hot_count = sbi->raw_super->hot_ext_count; + for (i = cold_count; i < cold_count + hot_count; i++) + if (is_extension_exist(name, extlist[i], false)) { + may_compress = false; + f2fs_up_read(&sbi->sb_lock); + goto set_compress; + } + f2fs_up_read(&sbi->sb_lock); + + /* Don't compress unallowed extension. */ + for (i = 0; i < noext_cnt; i++) { + if (is_extension_exist(name, noext[i], false)) { + may_compress = false; + goto set_compress; + } + } + + /* Compress wanting extension. */ + for (i = 0; i < ext_cnt; i++) { + if (is_extension_exist(name, ext[i], false)) { + may_compress = true; + goto set_compress; + } + } + +set_compress: + if (may_compress) + set_compress_context(inode); + else if (fi->i_flags & F2FS_COMPR_FL) + fi->i_flags &= ~F2FS_COMPR_FL; +} + static struct inode *f2fs_new_inode(struct user_namespace *mnt_userns, - struct inode *dir, umode_t mode) + struct inode *dir, umode_t mode, + const char *name) { struct f2fs_sb_info *sbi = F2FS_I_SB(dir); nid_t ino; @@ -114,12 +276,8 @@ static struct inode *f2fs_new_inode(struct user_namespace *mnt_userns, if (F2FS_I(inode)->i_flags & F2FS_PROJINHERIT_FL) set_inode_flag(inode, FI_PROJ_INHERIT); - if (f2fs_sb_has_compression(sbi)) { - /* Inherit the compression flag in directory */ - if ((F2FS_I(dir)->i_flags & F2FS_COMPR_FL) && - f2fs_may_compress(inode)) - set_compress_context(inode); - } + /* Check compression first. */ + set_compress_new_inode(sbi, dir, inode, name); /* Should enable inline_data after compression set */ if (test_opt(sbi, INLINE_DATA) && f2fs_may_inline_data(inode)) @@ -153,40 +311,6 @@ static struct inode *f2fs_new_inode(struct user_namespace *mnt_userns, return ERR_PTR(err); } -static inline int is_extension_exist(const unsigned char *s, const char *sub, - bool tmp_ext) -{ - size_t slen = strlen(s); - size_t sublen = strlen(sub); - int i; - - if (sublen == 1 && *sub == '*') - return 1; - - /* - * filename format of multimedia file should be defined as: - * "filename + '.' + extension + (optional: '.' + temp extension)". - */ - if (slen < sublen + 2) - return 0; - - if (!tmp_ext) { - /* file has no temp extension */ - if (s[slen - sublen - 1] != '.') - return 0; - return !strncasecmp(s + slen - sublen, sub, sublen); - } - - for (i = 1; i < slen - sublen; i++) { - if (s[i] != '.') - continue; - if (!strncasecmp(s + i + 1, sub, sublen)) - return 1; - } - - return 0; -} - /* * Set file's temperature for hot/cold data separation */ @@ -217,124 +341,6 @@ static inline void set_file_temperature(struct f2fs_sb_info *sbi, struct inode * file_set_hot(inode); } -int f2fs_update_extension_list(struct f2fs_sb_info *sbi, const char *name, - bool hot, bool set) -{ - __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; - int cold_count = le32_to_cpu(sbi->raw_super->extension_count); - int hot_count = sbi->raw_super->hot_ext_count; - int total_count = cold_count + hot_count; - int start, count; - int i; - - if (set) { - if (total_count == F2FS_MAX_EXTENSION) - return -EINVAL; - } else { - if (!hot && !cold_count) - return -EINVAL; - if (hot && !hot_count) - return -EINVAL; - } - - if (hot) { - start = cold_count; - count = total_count; - } else { - start = 0; - count = cold_count; - } - - for (i = start; i < count; i++) { - if (strcmp(name, extlist[i])) - continue; - - if (set) - return -EINVAL; - - memcpy(extlist[i], extlist[i + 1], - F2FS_EXTENSION_LEN * (total_count - i - 1)); - memset(extlist[total_count - 1], 0, F2FS_EXTENSION_LEN); - if (hot) - sbi->raw_super->hot_ext_count = hot_count - 1; - else - sbi->raw_super->extension_count = - cpu_to_le32(cold_count - 1); - return 0; - } - - if (!set) - return -EINVAL; - - if (hot) { - memcpy(extlist[count], name, strlen(name)); - sbi->raw_super->hot_ext_count = hot_count + 1; - } else { - char buf[F2FS_MAX_EXTENSION][F2FS_EXTENSION_LEN]; - - memcpy(buf, &extlist[cold_count], - F2FS_EXTENSION_LEN * hot_count); - memset(extlist[cold_count], 0, F2FS_EXTENSION_LEN); - memcpy(extlist[cold_count], name, strlen(name)); - memcpy(&extlist[cold_count + 1], buf, - F2FS_EXTENSION_LEN * hot_count); - sbi->raw_super->extension_count = cpu_to_le32(cold_count + 1); - } - return 0; -} - -static void set_compress_inode(struct f2fs_sb_info *sbi, struct inode *inode, - const unsigned char *name) -{ - __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; - unsigned char (*noext)[F2FS_EXTENSION_LEN] = F2FS_OPTION(sbi).noextensions; - unsigned char (*ext)[F2FS_EXTENSION_LEN] = F2FS_OPTION(sbi).extensions; - unsigned char ext_cnt = F2FS_OPTION(sbi).compress_ext_cnt; - unsigned char noext_cnt = F2FS_OPTION(sbi).nocompress_ext_cnt; - int i, cold_count, hot_count; - - if (!f2fs_sb_has_compression(sbi) || - F2FS_I(inode)->i_flags & F2FS_NOCOMP_FL || - !f2fs_may_compress(inode) || - (!ext_cnt && !noext_cnt)) - return; - - f2fs_down_read(&sbi->sb_lock); - - cold_count = le32_to_cpu(sbi->raw_super->extension_count); - hot_count = sbi->raw_super->hot_ext_count; - - for (i = cold_count; i < cold_count + hot_count; i++) { - if (is_extension_exist(name, extlist[i], false)) { - f2fs_up_read(&sbi->sb_lock); - return; - } - } - - f2fs_up_read(&sbi->sb_lock); - - for (i = 0; i < noext_cnt; i++) { - if (is_extension_exist(name, noext[i], false)) { - f2fs_disable_compressed_file(inode); - return; - } - } - - if (is_inode_flag_set(inode, FI_COMPRESSED_FILE)) - return; - - for (i = 0; i < ext_cnt; i++) { - if (!is_extension_exist(name, ext[i], false)) - continue; - - /* Do not use inline_data with compression */ - stat_dec_inline_inode(inode); - clear_inode_flag(inode, FI_INLINE_DATA); - set_compress_context(inode); - return; - } -} - static int f2fs_create(struct user_namespace *mnt_userns, struct inode *dir, struct dentry *dentry, umode_t mode, bool excl) { @@ -352,15 +358,13 @@ static int f2fs_create(struct user_namespace *mnt_userns, struct inode *dir, if (err) return err; - inode = f2fs_new_inode(mnt_userns, dir, mode); + inode = f2fs_new_inode(mnt_userns, dir, mode, dentry->d_name.name); if (IS_ERR(inode)) return PTR_ERR(inode); if (!test_opt(sbi, DISABLE_EXT_IDENTIFY)) set_file_temperature(sbi, inode, dentry->d_name.name); - set_compress_inode(sbi, inode, dentry->d_name.name); - inode->i_op = &f2fs_file_inode_operations; inode->i_fop = &f2fs_file_operations; inode->i_mapping->a_ops = &f2fs_dblock_aops; @@ -689,7 +693,7 @@ static int f2fs_symlink(struct user_namespace *mnt_userns, struct inode *dir, if (err) return err; - inode = f2fs_new_inode(mnt_userns, dir, S_IFLNK | S_IRWXUGO); + inode = f2fs_new_inode(mnt_userns, dir, S_IFLNK | S_IRWXUGO, NULL); if (IS_ERR(inode)) return PTR_ERR(inode); @@ -760,7 +764,7 @@ static int f2fs_mkdir(struct user_namespace *mnt_userns, struct inode *dir, if (err) return err; - inode = f2fs_new_inode(mnt_userns, dir, S_IFDIR | mode); + inode = f2fs_new_inode(mnt_userns, dir, S_IFDIR | mode, dentry->d_name.name); if (IS_ERR(inode)) return PTR_ERR(inode); @@ -817,7 +821,7 @@ static int f2fs_mknod(struct user_namespace *mnt_userns, struct inode *dir, if (err) return err; - inode = f2fs_new_inode(mnt_userns, dir, mode); + inode = f2fs_new_inode(mnt_userns, dir, mode, NULL); if (IS_ERR(inode)) return PTR_ERR(inode); @@ -856,7 +860,7 @@ static int __f2fs_tmpfile(struct user_namespace *mnt_userns, struct inode *dir, if (err) return err; - inode = f2fs_new_inode(mnt_userns, dir, mode); + inode = f2fs_new_inode(mnt_userns, dir, mode, NULL); if (IS_ERR(inode)) return PTR_ERR(inode);