Changeset ed6cf34b in mainline
- Timestamp:
- 2010-07-26T15:00:10Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 7a23d60
- Parents:
- 746f623
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/fat/fat_fat.c
r746f623 red6cf34b 49 49 #include <mem.h> 50 50 51 /* 52 * Convenience macros for accessing some frequently used boot sector members. 53 */ 54 #define BPS(bs) uint16_t_le2host((bs)->bps) 55 #define SPC(bs) (bs)->spc 56 #define RSCNT(bs) uint16_t_le2host((bs)->rscnt) 57 #define FATCNT(bs) (bs)->fatcnt 58 #define SF(bs) uint16_t_le2host((bs)->sec_per_fat) 59 #define RDE(bs) uint16_t_le2host((bs)->root_ent_max) 60 #define TS(bs) (uint16_t_le2host((bs)->totsec16) != 0 ? \ 61 uint16_t_le2host((bs)->totsec16) : \ 62 uint32_t_le2host(bs->totsec32)) 63 64 /* 65 * Convenience macros for computing some frequently used values from the 66 * primitive boot sector members. 67 */ 68 #define RDS(bs) ((sizeof(fat_dentry_t) * RDE((bs))) / BPS((bs))) + \ 69 (((sizeof(fat_dentry_t) * RDE((bs))) % BPS((bs))) != 0) 70 #define SSA(bs) (RSCNT((bs)) + FATCNT((bs)) * SF((bs)) + RDS(bs)) 71 72 #define CLBN2PBN(bs, cl, bn) \ 73 (SSA((bs)) + ((cl) - FAT_CLST_FIRST) * SPC((bs)) + (bn) % SPC((bs))) 74 75 51 76 /** 52 77 * The fat_alloc_lock mutex protects all copies of the File Allocation Table … … 74 99 { 75 100 block_t *b; 76 unsigned bps;77 unsigned rscnt; /* block address of the first FAT */78 101 uint16_t clusters = 0; 79 102 fat_cluster_t clst = firstc; 80 103 int rc; 81 82 bps = uint16_t_le2host(bs->bps);83 rscnt = uint16_t_le2host(bs->rscnt);84 104 85 105 if (firstc == FAT_CLST_RES0) { … … 99 119 if (lastc) 100 120 *lastc = clst; /* remember the last cluster number */ 101 fsec = (clst * sizeof(fat_cluster_t)) / bps;102 fidx = clst % ( bps/ sizeof(fat_cluster_t));121 fsec = (clst * sizeof(fat_cluster_t)) / BPS(bs); 122 fidx = clst % (BPS(bs) / sizeof(fat_cluster_t)); 103 123 /* read FAT1 */ 104 rc = block_get(&b, dev_handle, rscnt + fsec, BLOCK_FLAGS_NONE); 124 rc = block_get(&b, dev_handle, RSCNT(bs) + fsec, 125 BLOCK_FLAGS_NONE); 105 126 if (rc != EOK) 106 127 return rc; … … 138 159 return ELIMIT; 139 160 140 if (((((nodep->size - 1) / bs->bps) / bs->spc) == bn / bs->spc) && 141 (nodep->lastc_cached_valid) && (nodep->firstc != FAT_CLST_ROOT)) { 161 if (nodep->firstc == FAT_CLST_ROOT) 162 goto fall_through; 163 164 if (((((nodep->size - 1) / BPS(bs)) / SPC(bs)) == bn / SPC(bs)) && 165 nodep->lastc_cached_valid) { 142 166 /* 143 167 * This is a request to read a block within the last cluster 144 168 * when fortunately we have the last cluster number cached. 145 169 */ 146 fat_cluster_t lastc = nodep->lastc_cached_value;147 unsigned bps;148 unsigned rscnt; /* block address of the first FAT */149 unsigned rde;150 unsigned rds; /* root directory size */151 unsigned sf;152 unsigned ssa; /* size of the system area */153 154 bps = uint16_t_le2host(bs->bps);155 rscnt = uint16_t_le2host(bs->rscnt);156 rde = uint16_t_le2host(bs->root_ent_max);157 sf = uint16_t_le2host(bs->sec_per_fat);158 159 rds = (sizeof(fat_dentry_t) * rde) / bps;160 rds += ((sizeof(fat_dentry_t) * rde) % bps != 0);161 ssa = rscnt + bs->fatcnt * sf + rds;162 163 170 return block_get(block, nodep->idx->dev_handle, 164 ssa + (lastc - FAT_CLST_FIRST) * bs->spc + bn % bs->spc,165 flags);166 } else { 167 return _fat_block_get(block, bs, nodep->idx->dev_handle, 168 nodep->firstc, bn, flags);169 }171 CLBN2PBN(bs, nodep->lastc_cached_value, bn), flags); 172 } 173 174 fall_through: 175 return _fat_block_get(block, bs, nodep->idx->dev_handle, nodep->firstc, 176 bn, flags); 170 177 } 171 178 … … 186 193 fat_cluster_t firstc, aoff64_t bn, int flags) 187 194 { 188 unsigned bps;189 unsigned rscnt; /* block address of the first FAT */190 unsigned rde;191 unsigned rds; /* root directory size */192 unsigned sf;193 unsigned ssa; /* size of the system area */194 195 uint16_t clusters; 195 196 unsigned max_clusters; … … 203 204 return ELIMIT; 204 205 205 bps = uint16_t_le2host(bs->bps);206 rscnt = uint16_t_le2host(bs->rscnt);207 rde = uint16_t_le2host(bs->root_ent_max);208 sf = uint16_t_le2host(bs->sec_per_fat);209 210 rds = (sizeof(fat_dentry_t) * rde) / bps;211 rds += ((sizeof(fat_dentry_t) * rde) % bps != 0);212 ssa = rscnt + bs->fatcnt * sf + rds;213 214 206 if (firstc == FAT_CLST_ROOT) { 215 207 /* root directory special case */ 216 assert(bn < rds);217 rc = block_get(block, dev_handle, rscnt + bs->fatcnt * sf + bn,218 flags);208 assert(bn < RDS(bs)); 209 rc = block_get(block, dev_handle, 210 RSCNT(bs) + FATCNT(bs) * SF(bs) + bn, flags); 219 211 return rc; 220 212 } 221 213 222 max_clusters = bn / bs->spc;214 max_clusters = bn / SPC(bs); 223 215 rc = fat_cluster_walk(bs, dev_handle, firstc, &lastc, &clusters, 224 216 max_clusters); … … 227 219 assert(clusters == max_clusters); 228 220 229 rc = block_get(block, dev_handle, 230 ssa + (lastc - FAT_CLST_FIRST) * bs->spc + bn % bs->spc, flags); 221 rc = block_get(block, dev_handle, CLBN2PBN(bs, lastc, bn), flags); 231 222 232 223 return rc; … … 247 238 int fat_fill_gap(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t mcl, aoff64_t pos) 248 239 { 249 uint16_t bps;250 unsigned spc;251 240 block_t *b; 252 241 aoff64_t o, boundary; 253 242 int rc; 254 243 255 bps = uint16_t_le2host(bs->bps); 256 spc = bs->spc; 257 258 boundary = ROUND_UP(nodep->size, bps * spc); 244 boundary = ROUND_UP(nodep->size, BPS(bs) * SPC(bs)); 259 245 260 246 /* zero out already allocated space */ 261 247 for (o = nodep->size; o < pos && o < boundary; 262 o = ALIGN_DOWN(o + bps, bps)) {263 int flags = (o % bps== 0) ?248 o = ALIGN_DOWN(o + BPS(bs), BPS(bs))) { 249 int flags = (o % BPS(bs) == 0) ? 264 250 BLOCK_FLAGS_NOREAD : BLOCK_FLAGS_NONE; 265 rc = fat_block_get(&b, bs, nodep, o / bps, flags);266 if (rc != EOK) 267 return rc; 268 memset(b->data + o % bps, 0, bps - o % bps);251 rc = fat_block_get(&b, bs, nodep, o / BPS(bs), flags); 252 if (rc != EOK) 253 return rc; 254 memset(b->data + o % BPS(bs), 0, BPS(bs) - o % BPS(bs)); 269 255 b->dirty = true; /* need to sync node */ 270 256 rc = block_put(b); … … 277 263 278 264 /* zero out the initial part of the new cluster chain */ 279 for (o = boundary; o < pos; o += bps) {265 for (o = boundary; o < pos; o += BPS(bs)) { 280 266 rc = _fat_block_get(&b, bs, nodep->idx->dev_handle, mcl, 281 (o - boundary) / bps, BLOCK_FLAGS_NOREAD);282 if (rc != EOK) 283 return rc; 284 memset(b->data, 0, min( bps, pos - o));267 (o - boundary) / BPS(bs), BLOCK_FLAGS_NOREAD); 268 if (rc != EOK) 269 return rc; 270 memset(b->data, 0, min(BPS(bs), pos - o)); 285 271 b->dirty = true; /* need to sync node */ 286 272 rc = block_put(b); … … 306 292 { 307 293 block_t *b; 308 uint16_t bps;309 uint16_t rscnt;310 uint16_t sf;311 294 fat_cluster_t *cp; 312 295 int rc; 313 296 314 bps = uint16_t_le2host(bs->bps); 315 rscnt = uint16_t_le2host(bs->rscnt); 316 sf = uint16_t_le2host(bs->sec_per_fat); 317 318 rc = block_get(&b, dev_handle, rscnt + sf * fatno + 319 (clst * sizeof(fat_cluster_t)) / bps, BLOCK_FLAGS_NONE); 297 rc = block_get(&b, dev_handle, RSCNT(bs) + SF(bs) * fatno + 298 (clst * sizeof(fat_cluster_t)) / BPS(bs), BLOCK_FLAGS_NONE); 320 299 if (rc != EOK) 321 300 return rc; 322 cp = (fat_cluster_t *)b->data + clst % (bps / sizeof(fat_cluster_t)); 301 cp = (fat_cluster_t *)b->data + 302 clst % (BPS(bs) / sizeof(fat_cluster_t)); 323 303 *value = uint16_t_le2host(*cp); 324 304 rc = block_put(b); … … 342 322 { 343 323 block_t *b; 344 uint16_t bps;345 uint16_t rscnt;346 uint16_t sf;347 324 fat_cluster_t *cp; 348 325 int rc; 349 326 350 bps = uint16_t_le2host(bs->bps); 351 rscnt = uint16_t_le2host(bs->rscnt); 352 sf = uint16_t_le2host(bs->sec_per_fat); 353 354 assert(fatno < bs->fatcnt); 355 rc = block_get(&b, dev_handle, rscnt + sf * fatno + 356 (clst * sizeof(fat_cluster_t)) / bps, BLOCK_FLAGS_NONE); 327 assert(fatno < FATCNT(bs)); 328 rc = block_get(&b, dev_handle, RSCNT(bs) + SF(bs) * fatno + 329 (clst * sizeof(fat_cluster_t)) / BPS(bs), BLOCK_FLAGS_NONE); 357 330 if (rc != EOK) 358 331 return rc; 359 cp = (fat_cluster_t *)b->data + clst % (bps / sizeof(fat_cluster_t)); 332 cp = (fat_cluster_t *)b->data + 333 clst % (BPS(bs) / sizeof(fat_cluster_t)); 360 334 *cp = host2uint16_t_le(value); 361 335 b->dirty = true; /* need to sync block */ … … 413 387 fat_cluster_t *mcl, fat_cluster_t *lcl) 414 388 { 415 uint16_t bps;416 uint16_t rscnt;417 uint16_t sf;418 uint32_t ts;419 unsigned rde;420 unsigned rds;421 unsigned ssa;422 389 block_t *blk; 423 390 fat_cluster_t *lifo; /* stack for storing free cluster numbers */ … … 429 396 if (!lifo) 430 397 return ENOMEM; 431 432 bps = uint16_t_le2host(bs->bps);433 rscnt = uint16_t_le2host(bs->rscnt);434 sf = uint16_t_le2host(bs->sec_per_fat);435 rde = uint16_t_le2host(bs->root_ent_max);436 ts = (uint32_t) uint16_t_le2host(bs->totsec16);437 if (ts == 0)438 ts = uint32_t_le2host(bs->totsec32);439 440 rds = (sizeof(fat_dentry_t) * rde) / bps;441 rds += ((sizeof(fat_dentry_t) * rde) % bps != 0);442 ssa = rscnt + bs->fatcnt * sf + rds;443 398 444 399 /* … … 446 401 */ 447 402 fibril_mutex_lock(&fat_alloc_lock); 448 for (b = 0, cl = 0; b < sf; b++) { 449 rc = block_get(&blk, dev_handle, rscnt + b, BLOCK_FLAGS_NONE); 403 for (b = 0, cl = 0; b < SF(bs); b++) { 404 rc = block_get(&blk, dev_handle, RSCNT(bs) + b, 405 BLOCK_FLAGS_NONE); 450 406 if (rc != EOK) 451 407 goto error; 452 for (c = 0; c < bps/ sizeof(fat_cluster_t); c++, cl++) {408 for (c = 0; c < BPS(bs) / sizeof(fat_cluster_t); c++, cl++) { 453 409 /* 454 410 * Check if the cluster is physically there. This check … … 457 413 * from the size of the file allocation table. 458 414 */ 459 if ((cl >= 2) && ((cl - 2) * bs->spc + ssa >= ts)) { 415 if ((cl >= 2) && 416 ((cl - 2) * SPC(bs) + SSA(bs) >= TS(bs))) { 460 417 rc = block_put(blk); 461 418 if (rc != EOK) … … 660 617 int i; 661 618 block_t *b; 662 unsigned bps; 663 int rc; 664 665 bps = uint16_t_le2host(bs->bps); 666 667 for (i = 0; i < bs->spc; i++) { 619 int rc; 620 621 for (i = 0; i < SPC(bs); i++) { 668 622 rc = _fat_block_get(&b, bs, dev_handle, c, i, 669 623 BLOCK_FLAGS_NOREAD); 670 624 if (rc != EOK) 671 625 return rc; 672 memset(b->data, 0, bps);626 memset(b->data, 0, BPS(bs)); 673 627 b->dirty = true; 674 628 rc = block_put(b);
Note:
See TracChangeset
for help on using the changeset viewer.