source: mainline/uspace/srv/fs/exfat/exfat_bitmap.c@ a35b458

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since a35b458 was a35b458, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 7 years ago

style: Remove trailing whitespace on _all_ lines, including empty ones, for particular file types.

Command used: tools/srepl '\s\+$' '' -- *.c *.h *.py *.sh *.s *.S *.ag

Currently, whitespace on empty lines is very inconsistent.
There are two basic choices: Either remove the whitespace, or keep empty lines
indented to the level of surrounding code. The former is AFAICT more common,
and also much easier to do automatically.

Alternatively, we could write script for automatic indentation, and use that
instead. However, if such a script exists, it's possible to use the indented
style locally, by having the editor apply relevant conversions on load/save,
without affecting remote repository. IMO, it makes more sense to adopt
the simpler rule.

  • Property mode set to 100644
File size: 6.5 KB
RevLine 
[5d5863c]1/*
2 * Copyright (c) 2011 Oleg Romanenko
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup fs
30 * @{
31 */
32
33/**
34 * @file exfat_bitmap.c
35 * @brief Functions that manipulate the Bitmap Table.
36 */
37
38#include "exfat_bitmap.h"
39#include "../../vfs/vfs.h"
40#include <libfs.h>
[f73b291]41#include <block.h>
[5d5863c]42#include <errno.h>
43#include <byteorder.h>
44#include <align.h>
45#include <assert.h>
46#include <fibril_synch.h>
47#include <mem.h>
48
49
[1b20da0]50errno_t exfat_bitmap_is_free(exfat_bs_t *bs, service_id_t service_id,
[5d5863c]51 exfat_cluster_t clst)
52{
[25c60f4]53 fs_node_t *fn;
[ff0c270]54 block_t *b = NULL;
[25c60f4]55 exfat_node_t *bitmapp;
56 uint8_t *bitmap;
[b7fd2a0]57 errno_t rc;
[25c60f4]58 bool alloc;
59
60 clst -= EXFAT_CLST_FIRST;
[a35b458]61
[375ab5e]62 rc = exfat_bitmap_get(&fn, service_id);
[25c60f4]63 if (rc != EOK)
64 return rc;
65 bitmapp = EXFAT_NODE(fn);
[a35b458]66
[25c60f4]67 aoff64_t offset = clst / 8;
68 rc = exfat_block_get(&b, bs, bitmapp, offset / BPS(bs), BLOCK_FLAGS_NONE);
69 if (rc != EOK) {
70 (void) exfat_node_put(fn);
71 return rc;
72 }
73 bitmap = (uint8_t *)b->data;
74 alloc = bitmap[offset % BPS(bs)] & (1 << (clst % 8));
75
76 rc = block_put(b);
77 if (rc != EOK) {
78 (void) exfat_node_put(fn);
79 return rc;
80 }
81 rc = exfat_node_put(fn);
82 if (rc != EOK)
83 return rc;
84
85 if (alloc)
86 return ENOENT;
87
[5d5863c]88 return EOK;
89}
90
[1b20da0]91errno_t exfat_bitmap_set_cluster(exfat_bs_t *bs, service_id_t service_id,
[25c60f4]92 exfat_cluster_t clst)
[5d5863c]93{
94 fs_node_t *fn;
[ff0c270]95 block_t *b = NULL;
[5d5863c]96 exfat_node_t *bitmapp;
97 uint8_t *bitmap;
[b7fd2a0]98 errno_t rc;
[5d5863c]99
[25c60f4]100 clst -= EXFAT_CLST_FIRST;
[a35b458]101
[375ab5e]102 rc = exfat_bitmap_get(&fn, service_id);
[5d5863c]103 if (rc != EOK)
104 return rc;
105 bitmapp = EXFAT_NODE(fn);
[a35b458]106
[25c60f4]107 aoff64_t offset = clst / 8;
[5d5863c]108 rc = exfat_block_get(&b, bs, bitmapp, offset / BPS(bs), BLOCK_FLAGS_NONE);
109 if (rc != EOK) {
110 (void) exfat_node_put(fn);
111 return rc;
112 }
113 bitmap = (uint8_t *)b->data;
[25c60f4]114 bitmap[offset % BPS(bs)] |= (1 << (clst % 8));
[5d5863c]115
116 b->dirty = true;
117 rc = block_put(b);
118 if (rc != EOK) {
119 (void) exfat_node_put(fn);
120 return rc;
121 }
[a35b458]122
[5d5863c]123 return exfat_node_put(fn);
124}
125
[1b20da0]126errno_t exfat_bitmap_clear_cluster(exfat_bs_t *bs, service_id_t service_id,
[25c60f4]127 exfat_cluster_t clst)
[5d5863c]128{
[25c60f4]129 fs_node_t *fn;
[ff0c270]130 block_t *b = NULL;
[25c60f4]131 exfat_node_t *bitmapp;
132 uint8_t *bitmap;
[b7fd2a0]133 errno_t rc;
[25c60f4]134
135 clst -= EXFAT_CLST_FIRST;
[a35b458]136
[375ab5e]137 rc = exfat_bitmap_get(&fn, service_id);
[25c60f4]138 if (rc != EOK)
139 return rc;
140 bitmapp = EXFAT_NODE(fn);
[a35b458]141
[25c60f4]142 aoff64_t offset = clst / 8;
[ff0c270]143 rc = exfat_block_get(&b, bs, bitmapp, offset / BPS(bs),
144 BLOCK_FLAGS_NONE);
[25c60f4]145 if (rc != EOK) {
146 (void) exfat_node_put(fn);
147 return rc;
148 }
149 bitmap = (uint8_t *)b->data;
150 bitmap[offset % BPS(bs)] &= ~(1 << (clst % 8));
151
152 b->dirty = true;
153 rc = block_put(b);
154 if (rc != EOK) {
155 (void) exfat_node_put(fn);
156 return rc;
157 }
[a35b458]158
[25c60f4]159 return exfat_node_put(fn);
[5d5863c]160}
161
[1b20da0]162errno_t exfat_bitmap_set_clusters(exfat_bs_t *bs, service_id_t service_id,
[5d5863c]163 exfat_cluster_t firstc, exfat_cluster_t count)
164{
[b7fd2a0]165 errno_t rc;
[5d5863c]166 exfat_cluster_t clst;
167 clst = firstc;
168
[ff0c270]169 while (clst < firstc + count ) {
[e738d56]170 rc = exfat_bitmap_set_cluster(bs, service_id, clst);
[5d5863c]171 if (rc != EOK) {
[ff0c270]172 if (clst - firstc > 0)
[e738d56]173 (void) exfat_bitmap_clear_clusters(bs, service_id,
[ff0c270]174 firstc, clst - firstc);
[5d5863c]175 return rc;
176 }
177 clst++;
178 }
179 return EOK;
180}
181
[1b20da0]182errno_t exfat_bitmap_clear_clusters(exfat_bs_t *bs, service_id_t service_id,
[5d5863c]183 exfat_cluster_t firstc, exfat_cluster_t count)
184{
[b7fd2a0]185 errno_t rc;
[5d5863c]186 exfat_cluster_t clst;
187 clst = firstc;
188
[ff0c270]189 while (clst < firstc + count) {
[e738d56]190 rc = exfat_bitmap_clear_cluster(bs, service_id, clst);
[5d5863c]191 if (rc != EOK)
192 return rc;
193 clst++;
194 }
195 return EOK;
196}
197
[1b20da0]198errno_t exfat_bitmap_alloc_clusters(exfat_bs_t *bs, service_id_t service_id,
[5d5863c]199 exfat_cluster_t *firstc, exfat_cluster_t count)
200{
201 exfat_cluster_t startc, endc;
202 startc = EXFAT_CLST_FIRST;
203
[ff0c270]204 while (startc < DATA_CNT(bs) + 2) {
[e0d98b2]205 endc = startc;
[e738d56]206 while (exfat_bitmap_is_free(bs, service_id, endc) == EOK) {
[ff0c270]207 if ((endc - startc) + 1 == count) {
[e0d98b2]208 *firstc = startc;
[e738d56]209 return exfat_bitmap_set_clusters(bs, service_id, startc, count);
[ff0c270]210 } else
[e0d98b2]211 endc++;
212 }
213 startc = endc+1;
[5d5863c]214 }
215 return ENOSPC;
216}
217
218
[1b20da0]219errno_t exfat_bitmap_append_clusters(exfat_bs_t *bs, exfat_node_t *nodep,
[5d5863c]220 exfat_cluster_t count)
221{
222 if (nodep->firstc == 0) {
[1b20da0]223 return exfat_bitmap_alloc_clusters(bs, nodep->idx->service_id,
[5d5863c]224 &nodep->firstc, count);
225 } else {
226 exfat_cluster_t lastc, clst;
227 lastc = nodep->firstc + ROUND_UP(nodep->size, BPC(bs)) / BPC(bs) - 1;
228
[ff0c270]229 clst = lastc + 1;
[e738d56]230 while (exfat_bitmap_is_free(bs, nodep->idx->service_id, clst) == EOK) {
[ff0c270]231 if (clst - lastc == count){
[1b20da0]232 return exfat_bitmap_set_clusters(bs, nodep->idx->service_id,
[ff0c270]233 lastc + 1, count);
234 } else
[5d5863c]235 clst++;
236 }
237 return ENOSPC;
238 }
239}
240
241
[1b20da0]242errno_t exfat_bitmap_free_clusters(exfat_bs_t *bs, exfat_node_t *nodep,
[5d5863c]243 exfat_cluster_t count)
244{
245 exfat_cluster_t lastc;
246 lastc = nodep->firstc + ROUND_UP(nodep->size, BPC(bs)) / BPC(bs) - 1;
247 lastc -= count;
248
[e738d56]249 return exfat_bitmap_clear_clusters(bs, nodep->idx->service_id, lastc + 1, count);
[5d5863c]250}
251
252
[b7fd2a0]253errno_t exfat_bitmap_replicate_clusters(exfat_bs_t *bs, exfat_node_t *nodep)
[5d5863c]254{
[b7fd2a0]255 errno_t rc;
[5d5863c]256 exfat_cluster_t lastc, clst;
[375ab5e]257 service_id_t service_id = nodep->idx->service_id;
[5d5863c]258 lastc = nodep->firstc + ROUND_UP(nodep->size, BPC(bs)) / BPC(bs) - 1;
259
260 for (clst = nodep->firstc; clst < lastc; clst++) {
[ff0c270]261 rc = exfat_set_cluster(bs, service_id, clst, clst + 1);
[5d5863c]262 if (rc != EOK)
263 return rc;
264 }
265
[375ab5e]266 return exfat_set_cluster(bs, service_id, lastc, EXFAT_CLST_EOF);
[5d5863c]267}
268
269
270
271/**
272 * @}
273 */
Note: See TracBrowser for help on using the repository browser.