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
Line 
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>
41#include <block.h>
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
50errno_t exfat_bitmap_is_free(exfat_bs_t *bs, service_id_t service_id,
51 exfat_cluster_t clst)
52{
53 fs_node_t *fn;
54 block_t *b = NULL;
55 exfat_node_t *bitmapp;
56 uint8_t *bitmap;
57 errno_t rc;
58 bool alloc;
59
60 clst -= EXFAT_CLST_FIRST;
61
62 rc = exfat_bitmap_get(&fn, service_id);
63 if (rc != EOK)
64 return rc;
65 bitmapp = EXFAT_NODE(fn);
66
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
88 return EOK;
89}
90
91errno_t exfat_bitmap_set_cluster(exfat_bs_t *bs, service_id_t service_id,
92 exfat_cluster_t clst)
93{
94 fs_node_t *fn;
95 block_t *b = NULL;
96 exfat_node_t *bitmapp;
97 uint8_t *bitmap;
98 errno_t rc;
99
100 clst -= EXFAT_CLST_FIRST;
101
102 rc = exfat_bitmap_get(&fn, service_id);
103 if (rc != EOK)
104 return rc;
105 bitmapp = EXFAT_NODE(fn);
106
107 aoff64_t offset = clst / 8;
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;
114 bitmap[offset % BPS(bs)] |= (1 << (clst % 8));
115
116 b->dirty = true;
117 rc = block_put(b);
118 if (rc != EOK) {
119 (void) exfat_node_put(fn);
120 return rc;
121 }
122
123 return exfat_node_put(fn);
124}
125
126errno_t exfat_bitmap_clear_cluster(exfat_bs_t *bs, service_id_t service_id,
127 exfat_cluster_t clst)
128{
129 fs_node_t *fn;
130 block_t *b = NULL;
131 exfat_node_t *bitmapp;
132 uint8_t *bitmap;
133 errno_t rc;
134
135 clst -= EXFAT_CLST_FIRST;
136
137 rc = exfat_bitmap_get(&fn, service_id);
138 if (rc != EOK)
139 return rc;
140 bitmapp = EXFAT_NODE(fn);
141
142 aoff64_t offset = clst / 8;
143 rc = exfat_block_get(&b, bs, bitmapp, offset / BPS(bs),
144 BLOCK_FLAGS_NONE);
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 }
158
159 return exfat_node_put(fn);
160}
161
162errno_t exfat_bitmap_set_clusters(exfat_bs_t *bs, service_id_t service_id,
163 exfat_cluster_t firstc, exfat_cluster_t count)
164{
165 errno_t rc;
166 exfat_cluster_t clst;
167 clst = firstc;
168
169 while (clst < firstc + count ) {
170 rc = exfat_bitmap_set_cluster(bs, service_id, clst);
171 if (rc != EOK) {
172 if (clst - firstc > 0)
173 (void) exfat_bitmap_clear_clusters(bs, service_id,
174 firstc, clst - firstc);
175 return rc;
176 }
177 clst++;
178 }
179 return EOK;
180}
181
182errno_t exfat_bitmap_clear_clusters(exfat_bs_t *bs, service_id_t service_id,
183 exfat_cluster_t firstc, exfat_cluster_t count)
184{
185 errno_t rc;
186 exfat_cluster_t clst;
187 clst = firstc;
188
189 while (clst < firstc + count) {
190 rc = exfat_bitmap_clear_cluster(bs, service_id, clst);
191 if (rc != EOK)
192 return rc;
193 clst++;
194 }
195 return EOK;
196}
197
198errno_t exfat_bitmap_alloc_clusters(exfat_bs_t *bs, service_id_t service_id,
199 exfat_cluster_t *firstc, exfat_cluster_t count)
200{
201 exfat_cluster_t startc, endc;
202 startc = EXFAT_CLST_FIRST;
203
204 while (startc < DATA_CNT(bs) + 2) {
205 endc = startc;
206 while (exfat_bitmap_is_free(bs, service_id, endc) == EOK) {
207 if ((endc - startc) + 1 == count) {
208 *firstc = startc;
209 return exfat_bitmap_set_clusters(bs, service_id, startc, count);
210 } else
211 endc++;
212 }
213 startc = endc+1;
214 }
215 return ENOSPC;
216}
217
218
219errno_t exfat_bitmap_append_clusters(exfat_bs_t *bs, exfat_node_t *nodep,
220 exfat_cluster_t count)
221{
222 if (nodep->firstc == 0) {
223 return exfat_bitmap_alloc_clusters(bs, nodep->idx->service_id,
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
229 clst = lastc + 1;
230 while (exfat_bitmap_is_free(bs, nodep->idx->service_id, clst) == EOK) {
231 if (clst - lastc == count){
232 return exfat_bitmap_set_clusters(bs, nodep->idx->service_id,
233 lastc + 1, count);
234 } else
235 clst++;
236 }
237 return ENOSPC;
238 }
239}
240
241
242errno_t exfat_bitmap_free_clusters(exfat_bs_t *bs, exfat_node_t *nodep,
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
249 return exfat_bitmap_clear_clusters(bs, nodep->idx->service_id, lastc + 1, count);
250}
251
252
253errno_t exfat_bitmap_replicate_clusters(exfat_bs_t *bs, exfat_node_t *nodep)
254{
255 errno_t rc;
256 exfat_cluster_t lastc, clst;
257 service_id_t service_id = nodep->idx->service_id;
258 lastc = nodep->firstc + ROUND_UP(nodep->size, BPC(bs)) / BPC(bs) - 1;
259
260 for (clst = nodep->firstc; clst < lastc; clst++) {
261 rc = exfat_set_cluster(bs, service_id, clst, clst + 1);
262 if (rc != EOK)
263 return rc;
264 }
265
266 return exfat_set_cluster(bs, service_id, lastc, EXFAT_CLST_EOF);
267}
268
269
270
271/**
272 * @}
273 */
Note: See TracBrowser for help on using the repository browser.