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

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 1433ecda was 1433ecda, checked in by Jiri Svoboda <jiri@…>, 7 years ago

Fix cstyle: make ccheck-fix and commit only files where all the changes are good.

  • 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
[1433ecda]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 }
[1433ecda]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) {
[1433ecda]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.