Changeset 5d95f02 in mainline for uspace/srv/fs/fat/fat_directory.c
- Timestamp:
- 2011-08-26T23:04:07Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 4bf6895
- Parents:
- 0dbe5ac
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/fat/fat_directory.c
r0dbe5ac r5d95f02 46 46 #include <stdio.h> 47 47 48 int fat_directory_block_load(fat_directory_t *);49 50 51 48 int fat_directory_open(fat_node_t *nodep, fat_directory_t *di) 52 49 { … … 57 54 58 55 di->bs = block_bb_get(di->nodep->idx->service_id); 59 di->blocks = ROUND_UP(nodep->size, BPS(di->bs)) /BPS(di->bs);56 di->blocks = ROUND_UP(nodep->size, BPS(di->bs)) / BPS(di->bs); 60 57 di->pos = 0; 61 58 di->bnum = 0; 62 59 di->last = false; 60 63 61 return EOK; 64 62 } … … 66 64 int fat_directory_close(fat_directory_t *di) 67 65 { 68 int rc =EOK;66 int rc = EOK; 69 67 70 68 if (di->b) … … 74 72 } 75 73 76 int fat_directory_block_load(fat_directory_t *di)74 static int fat_directory_block_load(fat_directory_t *di) 77 75 { 78 76 uint32_t i; … … 86 84 } 87 85 if (!di->b) { 88 rc = fat_block_get(&di->b, di->bs, di->nodep, i, BLOCK_FLAGS_NONE); 86 rc = fat_block_get(&di->b, di->bs, di->nodep, i, 87 BLOCK_FLAGS_NONE); 89 88 if (rc != EOK) { 90 89 di->b = NULL; … … 95 94 return EOK; 96 95 } 96 97 97 return ENOENT; 98 98 } … … 104 104 di->pos += 1; 105 105 rc = fat_directory_block_load(di); 106 if (rc !=EOK)106 if (rc != EOK) 107 107 di->pos -= 1; 108 108 … … 112 112 int fat_directory_prev(fat_directory_t *di) 113 113 { 114 int rc =EOK;114 int rc = EOK; 115 115 116 116 if (di->pos > 0) { 117 117 di->pos -= 1; 118 rc=fat_directory_block_load(di); 119 } 120 else 118 rc = fat_directory_block_load(di); 119 } else 121 120 return ENOENT; 122 121 123 if (rc !=EOK)122 if (rc != EOK) 124 123 di->pos += 1; 125 124 … … 134 133 di->pos = pos; 135 134 rc = fat_directory_block_load(di); 136 if (rc !=EOK)135 if (rc != EOK) 137 136 di->pos = _pos; 138 137 … … 161 160 int long_entry_count = 0; 162 161 uint8_t checksum = 0; 162 int rc; 163 163 164 164 do { 165 if (fat_directory_get(di, &d) == EOK) { 166 switch (fat_classify_dentry(d)) { 167 case FAT_DENTRY_LAST: 168 long_entry_count = 0; 169 long_entry = false; 170 return ENOENT; 171 case FAT_DENTRY_LFN: 172 if (long_entry) { 173 /* We found long entry */ 174 long_entry_count--; 175 if ((FAT_LFN_ORDER(d) == long_entry_count) && 176 (checksum == FAT_LFN_CHKSUM(d))) { 177 /* Right order! */ 178 fat_lfn_get_entry(d, wname, &lfn_offset); 179 } else { 180 /* Something wrong with order. Skip this long entries set */ 181 long_entry_count = 0; 182 long_entry = false; 183 } 165 rc = fat_directory_get(di, &d); 166 if (rc != EOK) 167 return rc; 168 169 switch (fat_classify_dentry(d)) { 170 case FAT_DENTRY_LAST: 171 long_entry_count = 0; 172 long_entry = false; 173 return ENOENT; 174 case FAT_DENTRY_LFN: 175 if (long_entry) { 176 /* We found long entry */ 177 long_entry_count--; 178 if ((FAT_LFN_ORDER(d) == long_entry_count) && 179 (checksum == FAT_LFN_CHKSUM(d))) { 180 /* Right order! */ 181 fat_lfn_get_entry(d, wname, 182 &lfn_offset); 184 183 } else { 185 if (FAT_IS_LFN(d)) { 186 /* We found Last long entry! */ 187 if (FAT_LFN_COUNT(d) <= FAT_LFN_MAX_COUNT) { 188 long_entry = true; 189 long_entry_count = FAT_LFN_COUNT(d); 190 lfn_size = (FAT_LFN_ENTRY_SIZE * 191 (FAT_LFN_COUNT(d) - 1)) + fat_lfn_size(d); 192 lfn_offset = lfn_size; 193 fat_lfn_get_entry(d, wname, &lfn_offset); 194 checksum = FAT_LFN_CHKSUM(d); 195 } 196 } 184 /* 185 * Something wrong with order. 186 * Skip this long entries set. 187 */ 188 long_entry_count = 0; 189 long_entry = false; 197 190 } 198 break; 199 case FAT_DENTRY_VALID: 200 if (long_entry && 201 (checksum == fat_dentry_chksum(d->name))) { 202 wname[lfn_size] = '\0'; 203 if (utf16_to_str(name, FAT_LFN_NAME_SIZE, wname) != EOK) 204 fat_dentry_name_get(d, name); 191 } else if (FAT_IS_LFN(d)) { 192 /* We found Last long entry! */ 193 if (FAT_LFN_COUNT(d) <= FAT_LFN_MAX_COUNT) { 194 long_entry = true; 195 long_entry_count = FAT_LFN_COUNT(d); 196 lfn_size = (FAT_LFN_ENTRY_SIZE * 197 (FAT_LFN_COUNT(d) - 1)) + 198 fat_lfn_size(d); 199 lfn_offset = lfn_size; 200 fat_lfn_get_entry(d, wname, 201 &lfn_offset); 202 checksum = FAT_LFN_CHKSUM(d); 205 203 } 206 else 204 } 205 break; 206 case FAT_DENTRY_VALID: 207 if (long_entry && 208 (checksum == fat_dentry_chksum(d->name))) { 209 wname[lfn_size] = '\0'; 210 if (utf16_to_str(name, FAT_LFN_NAME_SIZE, 211 wname) != EOK) 207 212 fat_dentry_name_get(d, name); 213 } else 214 fat_dentry_name_get(d, name); 208 215 209 *de = d; 210 return EOK; 211 default: 212 case FAT_DENTRY_SKIP: 213 case FAT_DENTRY_FREE: 214 long_entry_count = 0; 215 long_entry = false; 216 break; 217 } 216 *de = d; 217 return EOK; 218 default: 219 case FAT_DENTRY_SKIP: 220 case FAT_DENTRY_FREE: 221 long_entry_count = 0; 222 long_entry = false; 223 break; 218 224 } 219 225 } while (fat_directory_next(di) == EOK); … … 239 245 while (!flag && fat_directory_prev(di) == EOK) { 240 246 if (fat_directory_get(di, &d) == EOK && 241 fat_classify_dentry(d) == FAT_DENTRY_LFN && 242 checksum == FAT_LFN_CHKSUM(d)) { 243 if (FAT_IS_LFN(d)) 244 flag = true; 245 memset(d, 0, sizeof(fat_dentry_t)); 246 d->name[0] = FAT_DENTRY_ERASED; 247 di->b->dirty = true; 248 } 249 else 247 fat_classify_dentry(d) == FAT_DENTRY_LFN && 248 checksum == FAT_LFN_CHKSUM(d)) { 249 if (FAT_IS_LFN(d)) 250 flag = true; 251 memset(d, 0, sizeof(fat_dentry_t)); 252 d->name[0] = FAT_DENTRY_ERASED; 253 di->b->dirty = true; 254 } else 250 255 break; 251 256 } … … 257 262 { 258 263 int rc; 259 bool enable_lfn = true; /* We can use this variable to switch off LFN support*/264 bool enable_lfn = true; /* TODO: make this a mount option */ 260 265 261 266 if (fat_valid_short_name(name)) { 262 /* NAME could be directly stored in dentry without creating LFN */ 267 /* 268 * NAME could be directly stored in dentry without creating 269 * LFN. 270 */ 263 271 fat_dentry_name_set(de, name); 264 272 if (fat_directory_is_sfn_exist(di, de)) … … 313 321 if (rc != EOK) 314 322 return rc; 315 fat_lfn_set_entry(wname, &lfn_offset, lfn_size +1, d);323 fat_lfn_set_entry(wname, &lfn_offset, lfn_size + 1, d); 316 324 FAT_LFN_CHKSUM(d) = checksum; 317 325 FAT_LFN_ORDER(d) = ++idx; … … 327 335 } 328 336 329 int fat_directory_create_sfn(fat_directory_t *di, fat_dentry_t *de, const char *lname) 330 { 331 char name[FAT_NAME_LEN+1]; 332 char ext[FAT_EXT_LEN+1]; 333 char number[FAT_NAME_LEN+1]; 337 int fat_directory_create_sfn(fat_directory_t *di, fat_dentry_t *de, 338 const char *lname) 339 { 340 char name[FAT_NAME_LEN + 1]; 341 char ext[FAT_EXT_LEN + 1]; 342 char number[FAT_NAME_LEN + 1]; 334 343 memset(name, FAT_PAD, FAT_NAME_LEN); 335 344 memset(ext, FAT_PAD, FAT_EXT_LEN); … … 349 358 350 359 unsigned idx; 351 for (idx =1; idx <= FAT_MAX_SFN; idx++) {360 for (idx = 1; idx <= FAT_MAX_SFN; idx++) { 352 361 snprintf(number, sizeof(number), "%u", idx); 353 362 354 363 /* Fill de->name with FAT_PAD */ 355 memset(de->name, FAT_PAD, FAT_NAME_LEN +FAT_EXT_LEN);364 memset(de->name, FAT_PAD, FAT_NAME_LEN + FAT_EXT_LEN); 356 365 /* Copy ext */ 357 366 memcpy(de->ext, ext, str_size(ext)); … … 361 370 /* Copy number */ 362 371 size_t offset; 363 if (str_size(name)+str_size(number) +1 >FAT_NAME_LEN)364 offset = FAT_NAME_LEN - str_size(number) -1;372 if (str_size(name)+str_size(number) + 1 > FAT_NAME_LEN) 373 offset = FAT_NAME_LEN - str_size(number) - 1; 365 374 else 366 375 offset = str_size(name); 367 376 de->name[offset] = '~'; 368 377 offset++; 369 memcpy(de->name +offset, number, str_size(number));378 memcpy(de->name + offset, number, str_size(number)); 370 379 371 380 if (!fat_directory_is_sfn_exist(di, de)) 372 381 return EOK; 373 382 } 383 374 384 return ERANGE; 375 385 } … … 381 391 382 392 rc = fat_directory_get(di, &d); 383 if (rc !=EOK)393 if (rc != EOK) 384 394 return rc; 385 395 memcpy(d, de, sizeof(fat_dentry_t)); 386 396 di->b->dirty = true; 397 387 398 return EOK; 388 399 } … … 397 408 return ENOSPC; 398 409 } 399 rc = fat_alloc_clusters(di->bs, di->nodep->idx->service_id, 1, &mcl, &lcl); 410 rc = fat_alloc_clusters(di->bs, di->nodep->idx->service_id, 1, &mcl, 411 &lcl); 400 412 if (rc != EOK) 401 413 return rc; 402 414 rc = fat_zero_cluster(di->bs, di->nodep->idx->service_id, mcl); 403 415 if (rc != EOK) { 404 (void) fat_free_clusters(di->bs, di->nodep->idx->service_id, mcl); 416 (void) fat_free_clusters(di->bs, di->nodep->idx->service_id, 417 mcl); 405 418 return rc; 406 419 } 407 420 rc = fat_append_clusters(di->bs, di->nodep, mcl, lcl); 408 421 if (rc != EOK) { 409 (void) fat_free_clusters(di->bs, di->nodep->idx->service_id, mcl); 422 (void) fat_free_clusters(di->bs, di->nodep->idx->service_id, 423 mcl); 410 424 return rc; 411 425 } … … 422 436 size_t found; 423 437 aoff64_t pos; 438 int rc; 424 439 425 440 do { 426 441 found = 0; 427 pos =0;442 pos = 0; 428 443 fat_directory_seek(di, 0); 429 444 do { 430 if (fat_directory_get(di, &d) == EOK) { 431 switch (fat_classify_dentry(d)) { 432 case FAT_DENTRY_LAST: 433 case FAT_DENTRY_FREE: 434 if (found==0) pos = di->pos; 435 found++; 436 if (found == count) { 437 fat_directory_seek(di, pos); 438 return EOK; 439 } 440 break; 441 case FAT_DENTRY_VALID: 442 case FAT_DENTRY_LFN: 443 case FAT_DENTRY_SKIP: 444 default: 445 found = 0; 446 break; 445 rc = fat_directory_get(di, &d); 446 if (rc != EOK) 447 return rc; 448 449 switch (fat_classify_dentry(d)) { 450 case FAT_DENTRY_LAST: 451 case FAT_DENTRY_FREE: 452 if (found == 0) 453 pos = di->pos; 454 found++; 455 if (found == count) { 456 fat_directory_seek(di, pos); 457 return EOK; 447 458 } 459 break; 460 case FAT_DENTRY_VALID: 461 case FAT_DENTRY_LFN: 462 case FAT_DENTRY_SKIP: 463 default: 464 found = 0; 465 break; 448 466 } 449 467 } while (fat_directory_next(di) == EOK); 450 468 } while (fat_directory_expand(di) == EOK); 469 451 470 return ENOSPC; 452 471 } 453 472 454 int fat_directory_lookup_name(fat_directory_t *di, const char *name, fat_dentry_t **de) 473 int fat_directory_lookup_name(fat_directory_t *di, const char *name, 474 fat_dentry_t **de) 455 475 { 456 476 char entry[FAT_LFN_NAME_SIZE]; 477 457 478 fat_directory_seek(di, 0); 458 479 while (fat_directory_read(di, entry, de) == EOK) { … … 464 485 } 465 486 } 487 466 488 return ENOENT; 467 489 } … … 470 492 { 471 493 fat_dentry_t *d; 494 int rc; 495 472 496 fat_directory_seek(di, 0); 473 497 do { 474 if (fat_directory_get(di, &d) == EOK) { 475 switch (fat_classify_dentry(d)) { 476 case FAT_DENTRY_LAST: 477 return false; 478 case FAT_DENTRY_VALID: 479 if (bcmp(de->name, d->name, FAT_NAME_LEN+FAT_EXT_LEN)==0) 480 return true; 481 break; 482 default: 483 case FAT_DENTRY_LFN: 484 case FAT_DENTRY_SKIP: 485 case FAT_DENTRY_FREE: 486 break; 487 } 498 rc = fat_directory_get(di, &d); 499 if (rc != EOK) 500 return false; 501 502 switch (fat_classify_dentry(d)) { 503 case FAT_DENTRY_LAST: 504 return false; 505 case FAT_DENTRY_VALID: 506 if (bcmp(de->name, d->name, 507 FAT_NAME_LEN + FAT_EXT_LEN)==0) 508 return true; 509 break; 510 default: 511 case FAT_DENTRY_LFN: 512 case FAT_DENTRY_SKIP: 513 case FAT_DENTRY_FREE: 514 break; 488 515 } 489 516 } while (fat_directory_next(di) == EOK); 517 490 518 return false; 491 519 }
Note:
See TracChangeset
for help on using the changeset viewer.