From patchwork Fri Jan 13 19:12:39 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve Kenton X-Patchwork-Id: 9516309 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id BB15B60761 for ; Fri, 13 Jan 2017 19:48:49 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A9976205A8 for ; Fri, 13 Jan 2017 19:48:49 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9DFC828778; Fri, 13 Jan 2017 19:48:49 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 16DCC205A8 for ; Fri, 13 Jan 2017 19:48:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751166AbdAMTsq (ORCPT ); Fri, 13 Jan 2017 14:48:46 -0500 Received: from mail-co1nam03on0124.outbound.protection.outlook.com ([104.47.40.124]:15931 "EHLO NAM03-CO1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1750945AbdAMTso (ORCPT ); Fri, 13 Jan 2017 14:48:44 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sooners.onmicrosoft.com; s=selector1-ou-edu; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=wARllLQ9X0vdhmX5/q9uv471M6fyk16DOtxGzujjqUg=; b=JUn/tVi4ObrC5QJ/qRAAF2e5fLXG82GDasvkPyiY7oa6QHtyQdVIFneHH8EYXEHhhJLjaJ6/TD/SjP17jgZQUwJzKYodn/k9ZZmin9uN0II/teCwcW8nIOd9+2l2s3kMxC5n0chDiX+6/I7IBtCqr0Kyge99EXXAfcOiNKbZMl4= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=skenton@ou.edu; Received: from localhost.localdomain (68.97.3.132) by BN6PR03MB2690.namprd03.prod.outlook.com (10.173.144.9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.845.12; Fri, 13 Jan 2017 19:12:51 +0000 From: Steve Kenton To: CC: , Steve Kenton Subject: [PATCH V2 1/1] fs/udf RFC sanitize types, use consistent naming and add kernel doc comments Date: Fri, 13 Jan 2017 13:12:39 -0600 Message-ID: <20170113191239.23101-1-skenton@ou.edu> X-Mailer: git-send-email 2.9.2.277.g2949358 MIME-Version: 1.0 X-Originating-IP: [68.97.3.132] X-ClientProxiedBy: MWHPR04CA0035.namprd04.prod.outlook.com (10.172.163.21) To BN6PR03MB2690.namprd03.prod.outlook.com (10.173.144.9) X-MS-Office365-Filtering-Correlation-Id: 60465929-972d-4d89-ac69-08d43be82c31 X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(22001); SRVR:BN6PR03MB2690; X-Microsoft-Exchange-Diagnostics: 1; BN6PR03MB2690; 3:33Zod1P2q6Zt+pKySslyXdXnMiuGwe5AlhglaHJsGivICoOxNX4sYuYzhQMaKq4bkX8JwH8vLc0bkkuUhtRGPZ4+rKqnltvztWr0Svt0W1/cmMwm6oVoJThWHemrsWLYBUOHylAjMxySBZSmEUT/eZbnmOakWRjKDtcfzXEbHU+P7yChdj1PhZmTFSL9NJV/TVMBDXoxJAFREZsmJXwXEvEyBojBamlsp11qZc2QGNTG4/s6wEgKoXP04ZLjciqGZfnidKMMlTeFYGCD2QzeYg== X-Microsoft-Exchange-Diagnostics: 1; BN6PR03MB2690; 25:5Y4cGzXZWoGFD8o51rCW2q2qMVyg9k0GDfHGZkA51KbY9HhseqhfQXlBLDQLdhjS5KioAulOxWz2mMgbpa1T/pil38oZbFXSWm0x6YGo2MvNlUNADh7Qg0m504jQ9stWV0TEOC57DIcxsY0N22i8863Eys3jEATsS//V1qX9j5yH/tmIKgxUelh5fXMEUBzdk+cGU2/t2ljOjf6rCUwMU0YBvMVWadq51HVz4ybTw17F35YASqAT8+MR/J8vi9FIGr2SOQPUSqmhPmwPuPE5W+aWzl5dewd8hPyySeFzXQYdx+xmYMEB4dXu8cgiLaJXGKTQZVtL0nkmjROgPHTEqoMfLn63Z1JcRXkF41gHTaCAyJXxbZloTfrRm0/cWoxKHO+3T29dbX1kSKEGIVVmoGQmk9mSYjdpzLnEHi7umULVXQ7N4DC8DCgq8J0KInB3RoWmxEnVtxEnMFmBFyFR96eMmhd7mzR5l8wU9iqxrpQ9oy+/5ZERortrdnK+ZAYgNf630ee4C/7J4vdDhpA4op+qp3xmVOFhizZExLODYnHKeg5VLeZ6Eh9EkjQ4SySocO2QlcqPRRirz/w7aKzqTZj2QiReaN+RGjsxrHsMb0GtFqr0gqPukvbfJTjQQ/rJr0lZuHLortetURqyyvmOv4vZQn4n01nLN5NdrOKsRusDqFzObsDxduakc9vm/H8s+9dhM6bgJcCBmJEzkKw+QYueMDyF03vQ3vf/uDgfgbutpAOXg3GKMQ3K2u+s/DwKjuDpDCNZWGPQckhuthOdwNvly8L0vZHPPSV7TzG2GKY= X-Microsoft-Exchange-Diagnostics: 1; BN6PR03MB2690; 31:qjbLkn9Jb7qM0orvpCNkic9KRvXq5xLOc7rY6EcXAACPKrt2LSdRxsKg4g0d7HBQ3Csqttu+gIQPRQAwUfABdMyoG2A9KEKkbpDrBfV9D+bwOfFIU7YlUxd3LxQRVDcesRzR6Gv0WwQcLHw7djp252kwMGGqQpP2xdnntzc6M0LPHgR9qYxkK5+gNi3fAiK/T5PsDd9pX3gNDulh+OK4MO3FDKBGc4HzWvJNKA2Rt14M25A6w/0KBZ9IsgRMBPKOUebPXDbIPNYjoivcCrIU0w==; 20:PGNk6CE3cMHU8Zsim+pMQH9ydIC/CYpAySRrdP4SHpXjRdH+4S9RWxIzdPWITzR4MaPo7Ccq6qqMS0Z3yggJwNVzpoZ7st6VLGORC6ibPXGbY8/HBIhZKpecLcvgnoI62+04PUWavQDQv0OIcShhHCtPgecSS1YTPAIZlrAP9ig2ZOg11aD9abyHbQD2xIAeX4Ab/9kVzTn+DJEN5N2p3XlsIxO0Ca77tlZTW0nDzW0u5UWHyJ7PzLc23UIqcQcMLzDYwp5bco6vQbZFfBELV8RTTkoX2UjFVDSPLj1luxw+vbBtqTbmtBfzx4nxqY7pklW/gev5uObzTFR4JP8/RbXWRCn73Ya0RsEEvUhFaJY4WOR04E4aVXKntcDDb4gybjWQZFlb6AeurUkGW62GVHkmUa4Qohn4jNgET13vZYhNfXuRQwJfHurReTEWnBmEt0lp8C2d1sfcVCxVPiOWwEAaFpEs5uWy7s6CpobBMKochzmHSKPQgU+O67o1HjSv X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(179259710895377); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040375)(601004)(2401047)(5005006)(8121501046)(3002001)(10201501046)(6041248)(20161123562025)(20161123555025)(20161123564025)(20161123560025)(6072148)(6047074); SRVR:BN6PR03MB2690; BCL:0; PCL:0; RULEID:; SRVR:BN6PR03MB2690; X-Microsoft-Exchange-Diagnostics: 1; BN6PR03MB2690; 4:o02oBSrtNaps8zxgQpAkule0jRXgAqi7htJmLBWALisGkqgG8NHq3F5Mb3b1FnfHUDyIWmuNV7hz9LAdYjg+QsFJdj17+jqbk4LZIW4hO4S/lbBvhQQe8jB9mwFpAvuJyUHmajw8lhCP3KU06kYsdeT9+hnSHxmGyrN7PCouBBd+6cphxI4gKo2Te2SoKIDLXaf0N2RXck88/ASmKRE0/2zZ2fDqcwSX/YiQfRqNMNyuTj3WxZEOGAxF4vnnBHxU7tBjHib93Z4u7Q5PFk5lWt76Yr3NTWLZpqwmP/mJSKi+GBmt3bI4+RfpOXmc+j5ZWlMTYq9ve9Oc4zI013A24PSmN6w7G7EOGrF0ewhLZGWgVv4rlHzbhcGq7UsjbxphM6+t8S6Oa3Vn7SE9smT8tW0HI5NUbBBOTLaQNCiaoiRzTRNV3XDDzNkqSY2p35tduqqggviL2/Tf3iw70tBSOUYGiCfLFjK4fFQSPBEzWYjcVwdA8KWOVdZdBCS4K7zhFp4P4Wts77dK2g/CEgtFflg0G1061AWuMbvv4c4u/+KPA/6GIj/myGbLUEaIAWm1S8Ort05UKHfT3vkjWeEkIH2Akp4FSDlSXmbOacNhi2osdYs0F/CkD2Lkw7reWvsxENKsv8WmgBx3ofJu1TmRZw== X-Forefront-PRVS: 018632C080 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10019020)(4630300001)(6009001)(6069001)(7916002)(39410400002)(39840400002)(39450400003)(199003)(189002)(97736004)(68736007)(50986999)(33646002)(38730400001)(101416001)(54906002)(66066001)(2906002)(5003940100001)(6486002)(27001)(23001)(16001)(26001)(15001)(13001)(14001)(24001)(12001)(22001)(25001)(4326007)(1076002)(3846002)(6116002)(6506006)(47776003)(6512007)(25786008)(42186005)(105586002)(48376002)(81166006)(81156014)(2351001)(50466002)(8676002)(106356001)(75432002)(86362001)(36756003)(6916009)(5660300001)(92566002)(305945005)(189998001)(110136003)(7736002)(88552002)(50226002)(6666003)(575784001); DIR:OUT; SFP:1102; SCL:1; SRVR:BN6PR03MB2690; H:localhost.localdomain; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; Received-SPF: None (protection.outlook.com: ou.edu does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; BN6PR03MB2690; 23:qx2D6xTzXa4xV2U1k5tfxF5Rsg4Bp7pKtBYi6BA4H?= =?us-ascii?Q?ZGOLzrHonAXViPuhsjZ9cj0gcVjj/8+Ikcysm4ZLPLaPgL5EsbRegD2lWR6N?= =?us-ascii?Q?QdnyEtrSNrdo21RdHyxovcH4YNwFu7C6HS2FqKYt9iFGpsHR00xkZtivG06V?= =?us-ascii?Q?/tawyes1mkpid+fVrtyvSHiaqZwsrTNAIXj5sGmWEfGx8fKXK/YqIJuoHNo3?= =?us-ascii?Q?APccjhPyX+nT7ZaiwbaI772xTZeZUbSPT4qPYOE35jAw14DoZd8gUQzftGu8?= =?us-ascii?Q?fzuwNbyJDJc0hkABkZoW5hAEWK0MuZY8Imo8MR19P10rfpdKPvXHxRJq4k6W?= =?us-ascii?Q?KgXrBVRQD39ZeNBYz1ED6WLgCd4pFGfD2Miajqy6W2IU6fNcc/UmAGSLlNBK?= =?us-ascii?Q?HMc0PtG8ujN6uVrNFaQgGMbqwBBLharZVgR+fUNYknqE4ivmZTq6aqHYPwqH?= =?us-ascii?Q?rqqMcgW+eHXuUD4TgA+q+uyI//Q//VjhCGmos3UvVuusHQrGsZRDgexZcKCW?= =?us-ascii?Q?K3Rx7sZ8y8SoP9SRBtV7xeXWEms0iswcsi1i6I011prWO5TC6l7tr4lZGHaJ?= =?us-ascii?Q?zR7CK05vDHlq88SpQ+MEUD5x8LvSsmvqCL9JyT9hK80wOYMKb1KePDdWZw9B?= =?us-ascii?Q?/v5z0VsSQBAXXKNAUf5Co/Zi66FLesZ0UoTdCX1hL62tdZ+C+cO/J2OYGF+S?= =?us-ascii?Q?6SIBY8NrzJyE12aj8dFhjdLJhbmCNUYlsDvpgWeNrgkYjWf1s8VMu1xr4O8Y?= =?us-ascii?Q?kfOUaw2WkwZiK/OOMy3PmKIO/2mS4p7KWn2iVCgwGcbKZQgGn0jiCeF2nHw0?= =?us-ascii?Q?aYlvgGq1P61fIiFmRL+XdUo8HFKmDlu3r7hwkWm9/c2VEtwX6tKWHGx9BkKD?= =?us-ascii?Q?LKcb1sWdlCb8EZiD3L8HGe2ek2CoTTLs036nJflasLdMWc91BHn/GBoP5+Q0?= =?us-ascii?Q?Vnric+G3DUneksnelodexWNW1qAl00jCoDkXYLAWJKFZId8Wbs+ZaPQ5WcOe?= =?us-ascii?Q?Av4Um2vyoM9D+vj5ybiA/OEbsnwk0RsRZm2UuJLop7LyIBGGPLpXnNY4w1kg?= =?us-ascii?Q?JraYMZcxjKNtgHhlIGZLy/y1uvUb146U1K/zQ0JFy/af9KJFGgZ+ekdNhPcg?= =?us-ascii?Q?r8A6zmftp7rzrpOLs+w43G+irMGd3biCk9+wNijL8q88SaZaR7Zm10HQbnnA?= =?us-ascii?Q?wzJfUWCGn2C80gzeu38G9WCma+Sbj/8LgiyZ2cxzFyYtnQ2SJas24HaCg6mD?= =?us-ascii?Q?mSUG1CVvr/nRcjidCEHSmFx0iNY4u4KhAALFxbMtLGAPf51uJO/YFAaE958C?= =?us-ascii?Q?YirdcJxAEziPcKRjwwhqqUZOVI9aatM3ENv/PjRxUy/5rlejPqW0L4USXTAQ?= =?us-ascii?Q?V8+kJIl/BVW2UzpYOj58XVSZJA=3D?= X-Microsoft-Exchange-Diagnostics: 1; BN6PR03MB2690; 6:0hAbkg6ywUtH89dDNlZ7/tDrUGpFn4lkXEXQFFP6GPN/esk+7sQJ3iIx7GeQjc7ImOvhUaAdOoZrt4bNjDgZ6jQrd/vv2S7w0fD0ws++KypA1OBo7zEsT6GKq9Ngqc2fHWoIdVdhwCjlEK2GQErNoP9QRcOxgaAQGQf5jEn0kc1++KHW30b19B1Op2tH/P66tevcpX8wO5mKY0TJBZQEEf0oGvzJrnPdB3Ny3xAma2xmNrOHkxBzMiga28vC19B/hKrViXMnrBGryGr1PMrAWoqMM3PN+pKhTULbrtzDeR2vm7hgX/VcTTzXIRPBzpZPxMzOLxI/5uw++BsosFxnQeHO7RPHpr+kLW1pL3RC1/hwTKsufH6Mh9RNa9+dbMNYqR42JjgCg9N4PJM4goa/Fr5U6pqc/ZZbUmFra8YT1K4=; 5:EGFDRlXb4B3tDWf/ePRJlSRTvcdp9mhAmEjkh4hDJurtdALqKUtGufPAT7wlGyvwUMNbAV/FZ9f6L+9jzVkMDkTmgMzEltL5nCtBN8VbvW0GqoRw5SHE8t5HwLZfw0QqoDVDYkMknF0w8VIp8S49qTMPO8fTpcOflEPZG4w9fTk=; 24:CWlXbcAgJIEpWi/ehWpblY260OcNYzTbEVRXbAZBoj2IzWjjbYzmNhP+lucGOkRsC4FaUaH9M9WkUl4TLwMYi11G+/8d6RUNMjuNq1GGEtU= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; BN6PR03MB2690; 7:bLUIApxaCm44aCWZe6V8OPyMHB9wnS79oANzPKJhAHmq4tx1QB7qMGSvN1aw/DhamyRIkPhHQ9HW+auVM+H8LJTNXiEnaty4C2yzJ+OeABl9i9cw4SOmGzHYHXTUN49VYIAIVsFU6arf0vLXIBHGLsZENBRracCOy1WVZCWNPJZ2rBB03tBcPdKrQ4UV9adaWp/Lw8oUUfNhH/TUxoB41HzfQK2b2P29ybcsQR+w6+hDkInxRdUyoWQxrClI1SAOhWCDw3npUk7EQhc14pM4nnf77p3SP691SVvWDE4ks3TWUWwQJbkTHO/oT6RKNkNrELtOMYPo91HCCHKUnAu5Zp/XU7YAH9nxMApYRSkqKoI6lkjoc3jBNQ9ikNbSsOKIhGz0BhrjA/fXmQjdjAOAwtR6O5TORcqWJqXa1nXChp47XHQTUvvX3o/aXMI1RNG4/QphEvwW7+suoUwBlsMZuQ==; 20:JDc6n659ujvV2IHXTTBnU8IZ1KhLEvNEvWmhA+QQbRWPbEOpC5x1RGrUxEak0NJG05On/epaTKcbfrePi005ZXcWJDE/QMCQJ7w6gBt/NWbxI+ym3wNCtk3O936ONE9hXxeSzMvVIyBaRjuqiEGxH15mBFOtVFrahvv5s37zI7U= X-OriginatorOrg: ou.edu X-MS-Exchange-CrossTenant-OriginalArrivalTime: 13 Jan 2017 19:12:51.8840 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN6PR03MB2690 Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Signed-off-by: Steve Kenton --- V2: fix sector_t variable print format fs/udf/balloc.c | 332 ++++++++++++++++++++++++++++++++++++++----------------- fs/udf/udfdecl.h | 10 +- 2 files changed, 238 insertions(+), 104 deletions(-) diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c index e0fd65f..a6720dd 100644 --- a/fs/udf/balloc.c +++ b/fs/udf/balloc.c @@ -4,6 +4,17 @@ * PURPOSE * Block allocation handling routines for the OSTA-UDF(tm) filesystem. * + * Note, ECMA-167 block numbers are unsigned 32-bit values and UDF extents + * cannot exceed an unsigned 30-bit byte length so both were traditionally + * unsigned 32-bit types despite the use of block_count << bits_per_block + * to compute extent_length, which might otherwise risk overflow. But, + * UDF filesystems can consist of up to 64K partitions on multiple volumes + * and files can have multiple extents resulting in terrabyte+ lengths. + * So, use the VFS preferred 64-bit sector_t and loff_t types for block + * numbers and file offsets respectively and int for UDF partition number + * and extent type as well as extent byte lengths and extent block counts. + * All together this makes the UDF code feel similar to other filesystems. + * * COPYRIGHT * This file is distributed under the terms of the GNU General Public * License (GPL). Copies of the GPL can be obtained from: @@ -31,8 +42,12 @@ #define udf_test_bit test_bit_le #define udf_find_next_one_bit find_next_bit_le +/* + * Read the bitmap from the media - udf_tread() wraps fixed/variable media + * to deal with certain peculiar antique optical cartridge devices. Still needed ??? + */ static int read_block_bitmap(struct super_block *sb, - struct udf_bitmap *bitmap, unsigned int block, + struct udf_bitmap *bitmap, sector_t block, unsigned long bitmap_nr) { struct buffer_head *bh = NULL; @@ -89,7 +104,16 @@ static inline int load_block_bitmap(struct super_block *sb, return slot; } -static void udf_add_free_space(struct super_block *sb, u16 partition, u32 cnt) +/** + * udf_update_free_space() - Adjust the partition free space available total + * @sb: Super block of UDF filesystem mount + * @partition: UDF partition to use + * @count: Number of blocks to add/subtract + * + * All the blocks are in the same extent which limits the maximum block count + * This is just the on-media book keeping for allocate/free performed elsewhere + */ +static void udf_update_free_space(struct super_block *sb, int partition, int count) { struct udf_sb_info *sbi = UDF_SB(sb); struct logicalVolIntegrityDesc *lvid; @@ -98,20 +122,34 @@ static void udf_add_free_space(struct super_block *sb, u16 partition, u32 cnt) return; lvid = (struct logicalVolIntegrityDesc *)sbi->s_lvid_bh->b_data; - le32_add_cpu(&lvid->freeSpaceTable[partition], cnt); + le32_add_cpu(&lvid->freeSpaceTable[partition], count); udf_updated_lvid(sb); } +/* + * Unallocated/freespace bitmap implementation routines + */ + +/** + * udf_bitmap_free_blocks() - Free extent blocks + * @sb: Super block of UDF filesystem mount + * @bitmap: Space bitmap + * @eloc: Extent location/length descriptor + * @offset: Block offset from the start of the extent + * @count: Number of blocks to free + * + * All the blocks are in the same extent which limits the maximum block count + */ static void udf_bitmap_free_blocks(struct super_block *sb, struct udf_bitmap *bitmap, - struct kernel_lb_addr *bloc, - uint32_t offset, - uint32_t count) + struct kernel_lb_addr *eloc, + sector_t offset, + int count) { struct udf_sb_info *sbi = UDF_SB(sb); struct buffer_head *bh = NULL; struct udf_part_map *partmap; - unsigned long block; + sector_t block; unsigned long block_group; unsigned long bit; unsigned long i; @@ -119,17 +157,17 @@ static void udf_bitmap_free_blocks(struct super_block *sb, unsigned long overflow; mutex_lock(&sbi->s_alloc_mutex); - partmap = &sbi->s_partmaps[bloc->partitionReferenceNum]; - if (bloc->logicalBlockNum + count < count || - (bloc->logicalBlockNum + count) > partmap->s_partition_len) { + partmap = &sbi->s_partmaps[eloc->partitionReferenceNum]; + if (eloc->logicalBlockNum + count < count || + (eloc->logicalBlockNum + count) > partmap->s_partition_len) { udf_debug("%d < %d || %d + %d > %d\n", - bloc->logicalBlockNum, 0, - bloc->logicalBlockNum, count, + eloc->logicalBlockNum, 0, + eloc->logicalBlockNum, count, partmap->s_partition_len); goto error_return; } - block = bloc->logicalBlockNum + offset + + block = eloc->logicalBlockNum + offset + (sizeof(struct spaceBitmapDesc) << 3); do { @@ -156,7 +194,7 @@ static void udf_bitmap_free_blocks(struct super_block *sb, ((char *)bh->b_data)[(bit + i) >> 3]); } } - udf_add_free_space(sb, sbi->s_partition, count); + udf_update_free_space(sb, sbi->s_partition, count); mark_buffer_dirty(bh); if (overflow) { block += count; @@ -168,25 +206,38 @@ static void udf_bitmap_free_blocks(struct super_block *sb, mutex_unlock(&sbi->s_alloc_mutex); } +/** + * udf_bitmap_prealloc_blocks() - Allocate partition blocks + * @sb: Super block of UDF filesystem mount + * @bitmap: Space bitmap + * @partition: UDF partition to use + * @first_block: Start of a free, or for write once media unrecorded, extent + * @count: Maximum number of blocks to try and allocate + * + * All the blocks are in the same extent which limits the maximum block count + * + * Return: Number of blocks allocated on success or 0 on failure + */ static int udf_bitmap_prealloc_blocks(struct super_block *sb, struct udf_bitmap *bitmap, - uint16_t partition, uint32_t first_block, - uint32_t block_count) + int partition, sector_t first_block, + int count) { struct udf_sb_info *sbi = UDF_SB(sb); int alloc_count = 0; - int bit, block, block_group, group_start; + sector_t block; + int bit, block_group, group_start; int nr_groups, bitmap_nr; struct buffer_head *bh; - __u32 part_len; + sector_t part_len; mutex_lock(&sbi->s_alloc_mutex); part_len = sbi->s_partmaps[partition].s_partition_len; if (first_block >= part_len) goto out; - if (first_block + block_count > part_len) - block_count = part_len - first_block; + if (first_block + count > part_len) + count = part_len - first_block; do { nr_groups = udf_compute_nr_groups(sb, partition); @@ -201,33 +252,43 @@ static int udf_bitmap_prealloc_blocks(struct super_block *sb, bit = block % (sb->s_blocksize << 3); - while (bit < (sb->s_blocksize << 3) && block_count > 0) { + while (bit < (sb->s_blocksize << 3) && count > 0) { if (!udf_clear_bit(bit, bh->b_data)) goto out; - block_count--; + count--; alloc_count++; bit++; block++; } mark_buffer_dirty(bh); - } while (block_count > 0); + } while (count > 0); out: - udf_add_free_space(sb, partition, -alloc_count); + udf_update_free_space(sb, partition, -alloc_count); mutex_unlock(&sbi->s_alloc_mutex); return alloc_count; } -static int udf_bitmap_new_block(struct super_block *sb, - struct udf_bitmap *bitmap, uint16_t partition, - uint32_t goal, int *err) +/** + * udf_bitmap_new_block() - Allocate a partition block close to goal + * @sb: Super block of UDF filesystem mount + * @bitmap: Space bitmap + * @partition: UDF partition to use + * @goal: The block on the partition to which proximity is desired + * @err: If not successful this is the error that caused the failure + * + * Return: Partition block number on success or 0 and set *err on failure + */ +static sector_t udf_bitmap_new_block(struct super_block *sb, + struct udf_bitmap *bitmap, int partition, + sector_t goal, int *err) { struct udf_sb_info *sbi = UDF_SB(sb); - int newbit, bit = 0, block, block_group, group_start; + int newbit, bit = 0, block_group, group_start; int end_goal, nr_groups, bitmap_nr, i; struct buffer_head *bh = NULL; char *ptr; - int newblock = 0; + sector_t block, newblock = 0; *err = -ENOSPC; mutex_lock(&sbi->s_alloc_mutex); @@ -332,7 +393,7 @@ static int udf_bitmap_new_block(struct super_block *sb, mark_buffer_dirty(bh); - udf_add_free_space(sb, partition, -1); + udf_update_free_space(sb, partition, -1); mutex_unlock(&sbi->s_alloc_mutex); *err = 0; return newblock; @@ -343,37 +404,51 @@ static int udf_bitmap_new_block(struct super_block *sb, return 0; } +/* + * Unallocated/freespace table implementation routines + */ + +/** + * udf_table_free_blocks() - Free extent blocks + * @sb: Super block of UDF filesystem mount + * @bitmap: Space table + * @eloc: Extent location/length descriptor + * @offset: Block offset from the start of the extent + * @count: Number of blocks to free + * + * All the blocks are in the same extent which limits the maximum block count + */ static void udf_table_free_blocks(struct super_block *sb, struct inode *table, - struct kernel_lb_addr *bloc, - uint32_t offset, - uint32_t count) + struct kernel_lb_addr *eloc, + sector_t offset, + int count) { struct udf_sb_info *sbi = UDF_SB(sb); struct udf_part_map *partmap; - uint32_t start, end; - uint32_t elen; - struct kernel_lb_addr eloc; + sector_t start, end; + int elen; + struct kernel_lb_addr bloc; struct extent_position oepos, epos; - int8_t etype; + int etype; struct udf_inode_info *iinfo; mutex_lock(&sbi->s_alloc_mutex); - partmap = &sbi->s_partmaps[bloc->partitionReferenceNum]; - if (bloc->logicalBlockNum + count < count || - (bloc->logicalBlockNum + count) > partmap->s_partition_len) { + partmap = &sbi->s_partmaps[eloc->partitionReferenceNum]; + if (eloc->logicalBlockNum + count < count || + (eloc->logicalBlockNum + count) > partmap->s_partition_len) { udf_debug("%d < %d || %d + %d > %d\n", - bloc->logicalBlockNum, 0, - bloc->logicalBlockNum, count, + eloc->logicalBlockNum, 0, + eloc->logicalBlockNum, count, partmap->s_partition_len); goto error_return; } iinfo = UDF_I(table); - udf_add_free_space(sb, sbi->s_partition, count); + udf_update_free_space(sb, sbi->s_partition, count); - start = bloc->logicalBlockNum + offset; - end = bloc->logicalBlockNum + offset + count - 1; + start = eloc->logicalBlockNum + offset; + end = eloc->logicalBlockNum + offset + count - 1; epos.offset = oepos.offset = sizeof(struct unallocSpaceEntry); elen = 0; @@ -381,12 +456,12 @@ static void udf_table_free_blocks(struct super_block *sb, epos.bh = oepos.bh = NULL; while (count && - (etype = udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1) { - if (((eloc.logicalBlockNum + + (etype = udf_next_aext(table, &epos, &bloc, &elen, 1)) != -1) { + if (((bloc.logicalBlockNum + (elen >> sb->s_blocksize_bits)) == start)) { if ((0x3FFFFFFF - elen) < (count << sb->s_blocksize_bits)) { - uint32_t tmp = ((0x3FFFFFFF - elen) >> + int tmp = ((0x3FFFFFFF - elen) >> sb->s_blocksize_bits); count -= tmp; start += tmp; @@ -399,26 +474,26 @@ static void udf_table_free_blocks(struct super_block *sb, start += count; count = 0; } - udf_write_aext(table, &oepos, &eloc, elen, 1); - } else if (eloc.logicalBlockNum == (end + 1)) { + udf_write_aext(table, &oepos, &bloc, elen, 1); + } else if (bloc.logicalBlockNum == (end + 1)) { if ((0x3FFFFFFF - elen) < (count << sb->s_blocksize_bits)) { - uint32_t tmp = ((0x3FFFFFFF - elen) >> + int tmp = ((0x3FFFFFFF - elen) >> sb->s_blocksize_bits); count -= tmp; end -= tmp; - eloc.logicalBlockNum -= tmp; + bloc.logicalBlockNum -= tmp; elen = (etype << 30) | (0x40000000 - sb->s_blocksize); } else { - eloc.logicalBlockNum = start; + bloc.logicalBlockNum = start; elen = (etype << 30) | (elen + (count << sb->s_blocksize_bits)); end -= count; count = 0; } - udf_write_aext(table, &oepos, &eloc, elen, 1); + udf_write_aext(table, &oepos, &bloc, elen, 1); } if (epos.bh != oepos.bh) { @@ -448,7 +523,7 @@ static void udf_table_free_blocks(struct super_block *sb, int adsize; - eloc.logicalBlockNum = start; + bloc.logicalBlockNum = start; elen = EXT_RECORDED_ALLOCATED | (count << sb->s_blocksize_bits); @@ -464,16 +539,16 @@ static void udf_table_free_blocks(struct super_block *sb, if (epos.offset + (2 * adsize) > sb->s_blocksize) { /* Steal a block from the extent being free'd */ - udf_setup_indirect_aext(table, eloc.logicalBlockNum, + udf_setup_indirect_aext(table, bloc.logicalBlockNum, &epos); - eloc.logicalBlockNum++; + bloc.logicalBlockNum++; elen -= sb->s_blocksize; } /* It's possible that stealing the block emptied the extent */ if (elen) - __udf_add_aext(table, &epos, &eloc, elen, 1); + __udf_add_aext(table, &epos, &bloc, elen, 1); } brelse(epos.bh); @@ -484,16 +559,28 @@ static void udf_table_free_blocks(struct super_block *sb, return; } +/** + * udf_table_prealloc_blocks() - Allocate partition blocks + * @sb: Super block of UDF filesystem mount + * @bitmap: Space table + * @partition: UDF partition to use + * @first_block: Start of a free, or for write once media unrecorded, extent + * @count: Maximum number of blocks to try and allocate + * + * All the blocks are in the same extent which limits the maximum block count + * + * Return: Number of blocks allocated on success or 0 on failure + */ static int udf_table_prealloc_blocks(struct super_block *sb, - struct inode *table, uint16_t partition, - uint32_t first_block, uint32_t block_count) + struct inode *table, int partition, + sector_t first_block, int count) { struct udf_sb_info *sbi = UDF_SB(sb); int alloc_count = 0; - uint32_t elen, adsize; + int elen, adsize; struct kernel_lb_addr eloc; struct extent_position epos; - int8_t etype = -1; + int etype = -1; struct udf_inode_info *iinfo; if (first_block >= sbi->s_partmaps[partition].s_partition_len) @@ -515,7 +602,7 @@ static int udf_table_prealloc_blocks(struct super_block *sb, while (first_block != eloc.logicalBlockNum && (etype = udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1) { - udf_debug("eloc=%d, elen=%d, first_block=%d\n", + udf_debug("eloc=%d, elen=%d, first_block=%llu\n", eloc.logicalBlockNum, elen, first_block); ; /* empty loop body */ } @@ -524,8 +611,8 @@ static int udf_table_prealloc_blocks(struct super_block *sb, epos.offset -= adsize; alloc_count = (elen >> sb->s_blocksize_bits); - if (alloc_count > block_count) { - alloc_count = block_count; + if (alloc_count > count) { + alloc_count = count; eloc.logicalBlockNum += alloc_count; elen -= (alloc_count << sb->s_blocksize_bits); udf_write_aext(table, &epos, &eloc, @@ -540,22 +627,32 @@ static int udf_table_prealloc_blocks(struct super_block *sb, brelse(epos.bh); if (alloc_count) - udf_add_free_space(sb, partition, -alloc_count); + udf_update_free_space(sb, partition, -alloc_count); mutex_unlock(&sbi->s_alloc_mutex); return alloc_count; } -static int udf_table_new_block(struct super_block *sb, - struct inode *table, uint16_t partition, - uint32_t goal, int *err) +/** + * udf_table_new_block() - Allocate a partition block close to goal + * @sb: Super block of UDF filesystem mount + * @bitmap: Space table + * @partition: UDF partition to use + * @goal: The block on the partition to which proximity is desired + * @err: If not successful this is the error that caused the failure + * + * Return: Partition block number on success or 0 and set *err on failure + */ +static sector_t udf_table_new_block(struct super_block *sb, + struct inode *table, int partition, + sector_t goal, int *err) { struct udf_sb_info *sbi = UDF_SB(sb); - uint32_t spread = 0xFFFFFFFF, nspread = 0xFFFFFFFF; - uint32_t newblock = 0, adsize; - uint32_t elen, goal_elen = 0; + unsigned int spread = 0xFFFFFFFF, nspread = 0xFFFFFFFF; + sector_t newblock = 0; + int elen, adsize, goal_elen = 0; struct kernel_lb_addr eloc, uninitialized_var(goal_eloc); struct extent_position epos, goal_epos; - int8_t etype; + int etype; struct udf_inode_info *iinfo = UDF_I(table); *err = -ENOSPC; @@ -572,8 +669,8 @@ static int udf_table_new_block(struct super_block *sb, goal = 0; /* We search for the closest matching block to goal. If we find - a exact hit, we stop. Otherwise we keep going till we run out - of extents. We store the buffer_head, bloc, and extoffset + an exact hit, we stop. Otherwise we keep going till we run out + of extents. We store the buffer_head, eloc, and offset of the current closest match and use that when we are done. */ epos.offset = sizeof(struct unallocSpaceEntry); @@ -630,44 +727,68 @@ static int udf_table_new_block(struct super_block *sb, udf_delete_aext(table, goal_epos, goal_eloc, goal_elen); brelse(goal_epos.bh); - udf_add_free_space(sb, partition, -1); + udf_update_free_space(sb, partition, -1); mutex_unlock(&sbi->s_alloc_mutex); *err = 0; return newblock; } +/** + * udf_free_blocks() - Free extent blocks + * @sb: Super block of UDF filesystem mount + * @inode: If not NULL decrease the byte count allocated to the inode + * @eloc: Extent location/length descriptor + * @offset: Block offset from the start of the extent + * @count: Number of blocks to free + * + * All the blocks are in the same extent which limits the maximum block count + * Use the media appropriate bitmap/table routine for the sb and partition + */ void udf_free_blocks(struct super_block *sb, struct inode *inode, - struct kernel_lb_addr *bloc, uint32_t offset, - uint32_t count) + struct kernel_lb_addr *eloc, sector_t offset, + int count) { - uint16_t partition = bloc->partitionReferenceNum; + int partition = eloc->partitionReferenceNum; struct udf_part_map *map = &UDF_SB(sb)->s_partmaps[partition]; if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) { udf_bitmap_free_blocks(sb, map->s_uspace.s_bitmap, - bloc, offset, count); + eloc, offset, count); } else if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE) { udf_table_free_blocks(sb, map->s_uspace.s_table, - bloc, offset, count); + eloc, offset, count); } else if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP) { udf_bitmap_free_blocks(sb, map->s_fspace.s_bitmap, - bloc, offset, count); + eloc, offset, count); } else if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE) { udf_table_free_blocks(sb, map->s_fspace.s_table, - bloc, offset, count); + eloc, offset, count); } if (inode) { inode_sub_bytes(inode, - ((sector_t)count) << sb->s_blocksize_bits); + ((loff_t)count) << sb->s_blocksize_bits); } } +/** + * udf_prealloc_blocks() - Allocate partition blocks and reserve them + * @sb: Super block of UDF filesystem mount + * @inode: If not NULL increase the byte count allocated to the inode + * @partition: UDF partition to use + * @first_block: Start of a free, or for write once media unrecorded, extent + * @count: Maximum number of blocks to try and allocate + * + * All the blocks are in the same extent which limits the maximum block count + * Use the media appropriate bitmap/table routine for the sb and partition + * + * Return: Number of blocks allocated on success or 0 on failure + */ inline int udf_prealloc_blocks(struct super_block *sb, struct inode *inode, - uint16_t partition, uint32_t first_block, - uint32_t block_count) + int partition, sector_t first_block, + int count) { struct udf_part_map *map = &UDF_SB(sb)->s_partmaps[partition]; int allocated; @@ -676,22 +797,22 @@ inline int udf_prealloc_blocks(struct super_block *sb, allocated = udf_bitmap_prealloc_blocks(sb, map->s_uspace.s_bitmap, partition, first_block, - block_count); + count); else if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE) allocated = udf_table_prealloc_blocks(sb, map->s_uspace.s_table, partition, first_block, - block_count); + count); else if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP) allocated = udf_bitmap_prealloc_blocks(sb, map->s_fspace.s_bitmap, partition, first_block, - block_count); + count); else if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE) allocated = udf_table_prealloc_blocks(sb, map->s_fspace.s_table, partition, first_block, - block_count); + count); else return 0; @@ -700,34 +821,47 @@ inline int udf_prealloc_blocks(struct super_block *sb, return allocated; } -inline int udf_new_block(struct super_block *sb, +/** + * udf_new_block() - Allocate a partition block close to goal + * @sb: Super block of UDF filesystem mount + * @inode: If not NULL increase the byte count allocated to the inode + * @partition: UDF partition to use + * @goal: The block on the partition to which proximity is desired + * @err: If not successful this is the error that caused the failure + * + * Use the media appropriate bitmap/table routine for the sb and partition + * Reduce latency for things like directory expansion - Maybe "near" instead of "new"? + * + * Return: Partition block number on success or 0 and set *err on failure + */ +inline sector_t udf_new_block(struct super_block *sb, struct inode *inode, - uint16_t partition, uint32_t goal, int *err) + int partition, sector_t goal, int *err) { struct udf_part_map *map = &UDF_SB(sb)->s_partmaps[partition]; - int block; + sector_t newblock; if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) - block = udf_bitmap_new_block(sb, + newblock = udf_bitmap_new_block(sb, map->s_uspace.s_bitmap, partition, goal, err); else if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE) - block = udf_table_new_block(sb, + newblock = udf_table_new_block(sb, map->s_uspace.s_table, partition, goal, err); else if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP) - block = udf_bitmap_new_block(sb, + newblock = udf_bitmap_new_block(sb, map->s_fspace.s_bitmap, partition, goal, err); else if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE) - block = udf_table_new_block(sb, + newblock = udf_table_new_block(sb, map->s_fspace.s_table, partition, goal, err); else { *err = -EIO; return 0; } - if (inode && block) + if (inode && newblock) inode_add_bytes(inode, sb->s_blocksize); - return block; + return newblock; } diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h index 263829e..321fecc 100644 --- a/fs/udf/udfdecl.h +++ b/fs/udf/udfdecl.h @@ -225,11 +225,11 @@ extern void udf_truncate_extents(struct inode *); /* balloc.c */ extern void udf_free_blocks(struct super_block *, struct inode *, - struct kernel_lb_addr *, uint32_t, uint32_t); -extern int udf_prealloc_blocks(struct super_block *, struct inode *, uint16_t, - uint32_t, uint32_t); -extern int udf_new_block(struct super_block *, struct inode *, uint16_t, - uint32_t, int *); + struct kernel_lb_addr *, sector_t, int); +extern int udf_prealloc_blocks(struct super_block *, struct inode *, int, + sector_t, int); +extern sector_t udf_new_block(struct super_block *, struct inode *, int, + sector_t, int *); /* directory.c */ extern struct fileIdentDesc *udf_fileident_read(struct inode *, loff_t *,