Changeset 0fdd6bb in mainline
- Timestamp:
- 2008-11-23T16:22:40Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- a5da446
- Parents:
- d2093d6
- Location:
- uspace
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/libc/include/errno.h
rd2093d6 r0fdd6bb 48 48 #define EXDEV (-264) 49 49 #define EIO (-265) 50 #define EMLINK (-266) 50 51 51 52 #endif -
uspace/srv/fs/fat/fat.h
rd2093d6 r0fdd6bb 210 210 extern fat_idx_t *fat_idx_get_by_index(dev_handle_t, fs_index_t); 211 211 extern void fat_idx_destroy(fat_idx_t *); 212 extern void fat_idx_hashin(fat_idx_t *); 212 213 213 214 extern int fat_idx_init(void); -
uspace/srv/fs/fat/fat_dentry.c
rd2093d6 r0fdd6bb 37 37 38 38 #include "fat_dentry.h" 39 #include <ctype.h> 39 40 40 41 #define FAT_PAD ' ' … … 45 46 #define FAT_DENTRY_ERASED 0xe5 46 47 47 void dentry_name_canonify(fat_dentry_t *d, char *buf) 48 static bool is_d_char(const char ch) 49 { 50 if (isalnum(ch) || ch == '_') 51 return true; 52 else 53 return false; 54 } 55 56 bool fat_dentry_name_verify(const char *name) 57 { 58 unsigned i, dot; 59 bool dot_found = false; 60 61 62 for (i = 0; name[i]; i++) { 63 if (name[i] == '.') { 64 if (dot_found) { 65 return false; 66 } else { 67 dot_found = true; 68 dot = i; 69 } 70 } else { 71 if (!is_d_char(name[i])) 72 return false; 73 } 74 } 75 76 if (dot_found) { 77 if (dot > FAT_NAME_LEN) 78 return false; 79 if (i - dot > FAT_EXT_LEN + 1) 80 return false; 81 } else { 82 if (i > FAT_NAME_LEN) 83 return false; 84 } 85 86 return true; 87 } 88 89 void fat_dentry_name_get(const fat_dentry_t *d, char *buf) 48 90 { 49 91 int i; … … 72 114 } 73 115 74 fat_dentry_clsf_t fat_classify_dentry(fat_dentry_t *d) 116 void fat_dentry_name_set(fat_dentry_t *d, const char *name) 117 { 118 int i; 119 const char fake_ext[] = " "; 120 121 122 for (i = 0; i < FAT_NAME_LEN; i++) { 123 switch ((uint8_t) *name) { 124 case 0xe5: 125 d->name[i] = FAT_DENTRY_E5_ESC; 126 name++; 127 break; 128 case '\0': 129 case '.': 130 d->name[i] = FAT_PAD; 131 break; 132 default: 133 d->name[i] = toupper(*name++); 134 break; 135 } 136 } 137 if (*name++ != '.') 138 name = fake_ext; 139 for (i = 0; i < FAT_EXT_LEN; i++) { 140 switch ((uint8_t) *name) { 141 case 0xe5: 142 d->ext[i] = FAT_DENTRY_E5_ESC; 143 name++; 144 break; 145 case '\0': 146 d->ext[i] = FAT_PAD; 147 break; 148 default: 149 d->ext[i] = toupper(*name++); 150 break; 151 } 152 } 153 } 154 155 fat_dentry_clsf_t fat_classify_dentry(const fat_dentry_t *d) 75 156 { 76 157 if (d->attr & FAT_ATTR_VOLLABEL) { … … 80 161 if (d->name[0] == FAT_DENTRY_ERASED) { 81 162 /* not-currently-used entry */ 82 return FAT_DENTRY_ SKIP;163 return FAT_DENTRY_FREE; 83 164 } 84 165 if (d->name[0] == FAT_DENTRY_UNUSED) { -
uspace/srv/fs/fat/fat_dentry.h
rd2093d6 r0fdd6bb 35 35 36 36 #include <stdint.h> 37 #include <bool.h> 37 38 38 39 #define FAT_NAME_LEN 8 … … 46 47 FAT_DENTRY_SKIP, 47 48 FAT_DENTRY_LAST, 49 FAT_DENTRY_FREE, 48 50 FAT_DENTRY_VALID 49 51 } fat_dentry_clsf_t; … … 71 73 } __attribute__ ((packed)) fat_dentry_t; 72 74 73 extern void dentry_name_canonify(fat_dentry_t *, char *); 74 extern fat_dentry_clsf_t fat_classify_dentry(fat_dentry_t *); 75 extern bool fat_dentry_name_verify(const char *); 76 extern void fat_dentry_name_get(const fat_dentry_t *, char *); 77 extern void fat_dentry_name_set(fat_dentry_t *, const char *); 78 extern fat_dentry_clsf_t fat_classify_dentry(const fat_dentry_t *); 75 79 76 80 #endif -
uspace/srv/fs/fat/fat_idx.c
rd2093d6 r0fdd6bb 424 424 } 425 425 426 void fat_idx_hashin(fat_idx_t *idx) 427 { 428 unsigned long pkey[] = { 429 [UPH_DH_KEY] = idx->dev_handle, 430 [UPH_PFC_KEY] = idx->pfc, 431 [UPH_PDI_KEY] = idx->pdi, 432 }; 433 434 futex_down(&used_futex); 435 hash_table_insert(&up_hash, pkey, &idx->uph_link); 436 futex_up(&used_futex); 437 } 438 426 439 fat_idx_t * 427 440 fat_idx_get_by_index(dev_handle_t dev_handle, fs_index_t index) -
uspace/srv/fs/fat/fat_ops.c
rd2093d6 r0fdd6bb 344 344 int fat_link(void *prnt, void *chld, const char *name) 345 345 { 346 return ENOTSUP; /* not supported at the moment */ 346 fat_node_t *parentp = (fat_node_t *)prnt; 347 fat_node_t *childp = (fat_node_t *)chld; 348 fat_dentry_t *d; 349 fat_bs_t *bs; 350 block_t *b; 351 int i, j; 352 uint16_t bps; 353 unsigned dps; 354 unsigned blocks; 355 356 futex_down(&childp->lock); 357 if (childp->lnkcnt == 1) { 358 /* 359 * On FAT, we don't support multiple hard links. 360 */ 361 futex_up(&childp->lock); 362 return EMLINK; 363 } 364 assert(childp->lnkcnt == 0); 365 futex_up(&childp->lock); 366 367 if (!fat_dentry_name_verify(name)) { 368 /* 369 * Attempt to create unsupported name. 370 */ 371 return ENOTSUP; 372 } 373 374 /* 375 * Get us an unused parent node's dentry or grow the parent and allocate 376 * a new one. 377 */ 378 379 futex_down(&parentp->idx->lock); 380 bs = block_bb_get(parentp->idx->dev_handle); 381 bps = uint16_t_le2host(bs->bps); 382 dps = bps / sizeof(fat_dentry_t); 383 384 blocks = parentp->size / bps; 385 386 for (i = 0; i < blocks; i++) { 387 b = fat_block_get(bs, parentp, i, BLOCK_FLAGS_NONE); 388 for (j = 0; j < dps; j++) { 389 d = ((fat_dentry_t *)b->data) + j; 390 switch (fat_classify_dentry(d)) { 391 case FAT_DENTRY_SKIP: 392 case FAT_DENTRY_VALID: 393 /* skipping used and meta entries */ 394 continue; 395 case FAT_DENTRY_FREE: 396 case FAT_DENTRY_LAST: 397 /* found an empty slot */ 398 goto hit; 399 } 400 } 401 block_put(b); 402 } 403 404 /* 405 * We need to grow the parent in order to create a new unused dentry. 406 */ 407 futex_up(&parentp->idx->lock); 408 return ENOTSUP; /* XXX */ 409 410 hit: 411 /* 412 * At this point we only establish the link between the parent and the 413 * child. The dentry, except of the name and the extension, will remain 414 * uninitialized until the the corresponding node is synced. Thus the 415 * valid dentry data is kept in the child node structure. 416 */ 417 memset(d, 0, sizeof(fat_dentry_t)); 418 fat_dentry_name_set(d, name); 419 b->dirty = true; /* need to sync block */ 420 block_put(b); 421 futex_up(&parentp->idx->lock); 422 423 futex_down(&childp->idx->lock); 424 childp->idx->pfc = parentp->firstc; 425 childp->idx->pdi = i * dps + j; 426 futex_up(&childp->idx->lock); 427 428 futex_down(&childp->lock); 429 childp->lnkcnt = 1; 430 childp->dirty = true; /* need to sync node */ 431 futex_up(&childp->lock); 432 433 /* 434 * Hash in the index structure into the position hash. 435 */ 436 fat_idx_hashin(childp->idx); 437 438 return EOK; 347 439 } 348 440 … … 375 467 switch (fat_classify_dentry(d)) { 376 468 case FAT_DENTRY_SKIP: 469 case FAT_DENTRY_FREE: 377 470 continue; 378 471 case FAT_DENTRY_LAST: … … 382 475 default: 383 476 case FAT_DENTRY_VALID: 384 dentry_name_canonify(d, name);477 fat_dentry_name_get(d, name); 385 478 break; 386 479 } … … 465 558 switch (fat_classify_dentry(d)) { 466 559 case FAT_DENTRY_SKIP: 560 case FAT_DENTRY_FREE: 467 561 continue; 468 562 case FAT_DENTRY_LAST: … … 699 793 switch (fat_classify_dentry(d)) { 700 794 case FAT_DENTRY_SKIP: 795 case FAT_DENTRY_FREE: 701 796 continue; 702 797 case FAT_DENTRY_LAST: … … 705 800 default: 706 801 case FAT_DENTRY_VALID: 707 dentry_name_canonify(d, name);802 fat_dentry_name_get(d, name); 708 803 block_put(b); 709 804 goto hit;
Note:
See TracChangeset
for help on using the changeset viewer.