Changeset 5d95f02 in mainline
- 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
- Location:
- uspace/srv/fs/fat
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/fat/fat.h
r0dbe5ac r5d95f02 47 47 #endif 48 48 49 #define min(a, b) 49 #define min(a, b) ((a) < (b) ? (a) : (b)) 50 50 51 51 /* … … 56 56 #define RSCNT(bs) uint16_t_le2host((bs)->rscnt) 57 57 #define FATCNT(bs) (bs)->fatcnt 58 #define SF(bs) (uint16_t_le2host((bs)->sec_per_fat) !=0 ? \ 58 59 #define SF(bs) (uint16_t_le2host((bs)->sec_per_fat) ? \ 59 60 uint16_t_le2host((bs)->sec_per_fat) : \ 60 61 uint32_t_le2host(bs->fat32.sectors_per_fat)) 62 61 63 #define RDE(bs) uint16_t_le2host((bs)->root_ent_max) 62 #define TS(bs) (uint16_t_le2host((bs)->totsec16) != 0 ? \ 63 uint16_t_le2host((bs)->totsec16) : \ 64 uint32_t_le2host(bs->totsec32)) 65 66 #define BS_BLOCK 0 67 #define BS_SIZE 512 64 65 #define TS(bs) (uint16_t_le2host((bs)->totsec16) ? \ 66 uint16_t_le2host((bs)->totsec16) : \ 67 uint32_t_le2host(bs->totsec32)) 68 69 #define BS_BLOCK 0 70 #define BS_SIZE 512 68 71 69 72 typedef struct fat_bs { -
uspace/srv/fs/fat/fat_dentry.c
r0dbe5ac r5d95f02 221 221 uint8_t fat_dentry_chksum(uint8_t *name) 222 222 { 223 uint8_t i, sum=0; 224 for (i=0; i<(FAT_NAME_LEN+FAT_EXT_LEN); i++) { 223 uint8_t i, sum = 0; 224 225 for (i = 0; i < (FAT_NAME_LEN + FAT_EXT_LEN); i++) 225 226 sum = ((sum & 1) ? 0x80 : 0) + (sum >> 1) + name[i]; 226 } 227 227 228 return sum; 228 229 } … … 269 270 { 270 271 int i; 271 for (i =FAT_LFN_PART3_SIZE-1; i>=0 && *offset>0; i--) {272 for (i = FAT_LFN_PART3_SIZE - 1; i >= 0 && *offset > 0; i--) { 272 273 if (d->lfn.part3[i] == 0 || d->lfn.part3[i] == FAT_LFN_PAD) 273 274 continue; … … 275 276 dst[(*offset)] = uint16_t_le2host(d->lfn.part3[i]); 276 277 } 277 for (i =FAT_LFN_PART2_SIZE-1; i>=0 && *offset>0; i--) {278 for (i = FAT_LFN_PART2_SIZE - 1; i >= 0 && *offset > 0; i--) { 278 279 if (d->lfn.part2[i] == 0 || d->lfn.part2[i] == FAT_LFN_PAD) 279 280 continue; … … 281 282 dst[(*offset)] = uint16_t_le2host(d->lfn.part2[i]); 282 283 } 283 for (i =FAT_LFN_PART1_SIZE-1; i>=0 && *offset>0; i--) {284 for (i = FAT_LFN_PART1_SIZE - 1; i >= 0 && *offset > 0; i--) { 284 285 if (d->lfn.part1[i] == 0 || d->lfn.part1[i] == FAT_LFN_PAD) 285 286 continue; … … 290 291 } 291 292 292 size_t fat_lfn_set_entry(const uint16_t *src, size_t *offset, size_t size, fat_dentry_t *d) 293 size_t fat_lfn_set_entry(const uint16_t *src, size_t *offset, size_t size, 294 fat_dentry_t *d) 293 295 { 294 296 size_t idx; 295 for (idx =0; idx < FAT_LFN_PART1_SIZE; idx++) {297 for (idx = 0; idx < FAT_LFN_PART1_SIZE; idx++) { 296 298 if (*offset < size) { 297 299 d->lfn.part1[idx] = host2uint16_t_le(src[*offset]); 298 300 (*offset)++; 299 } 300 else 301 } else 301 302 d->lfn.part1[idx] = FAT_LFN_PAD; 302 303 } 303 for (idx =0; idx < FAT_LFN_PART2_SIZE; idx++) {304 for (idx = 0; idx < FAT_LFN_PART2_SIZE; idx++) { 304 305 if (*offset < size) { 305 306 d->lfn.part2[idx] = host2uint16_t_le(src[*offset]); 306 307 (*offset)++; 307 } 308 else 308 } else 309 309 d->lfn.part2[idx] = FAT_LFN_PAD; 310 310 } 311 for (idx =0; idx < FAT_LFN_PART3_SIZE; idx++) {311 for (idx = 0; idx < FAT_LFN_PART3_SIZE; idx++) { 312 312 if (*offset < size) { 313 313 d->lfn.part3[idx] = host2uint16_t_le(src[*offset]); 314 314 (*offset)++; 315 } 316 else 315 } else 317 316 d->lfn.part3[idx] = FAT_LFN_PAD; 318 317 } … … 339 338 else 340 339 *dst = pad; 341 } 342 else 340 } else 343 341 break; 344 342 -
uspace/srv/fs/fat/fat_dentry.h
r0dbe5ac r5d95f02 71 71 #define FAT_LFN_ERASED 0x80 72 72 73 #define FAT_LFN_ORDER(d) ( d->lfn.order)73 #define FAT_LFN_ORDER(d) ((d)->lfn.order) 74 74 #define FAT_IS_LFN(d) \ 75 ((FAT_LFN_ORDER( d) & FAT_LFN_LAST) == FAT_LFN_LAST)75 ((FAT_LFN_ORDER((d)) & FAT_LFN_LAST) == FAT_LFN_LAST) 76 76 #define FAT_LFN_COUNT(d) \ 77 (FAT_LFN_ORDER( d) ^ FAT_LFN_LAST)78 #define FAT_LFN_PART1(d) ( d->lfn.part1)79 #define FAT_LFN_PART2(d) ( d->lfn.part2)80 #define FAT_LFN_PART3(d) ( d->lfn.part3)81 #define FAT_LFN_ATTR(d) ( d->lfn.attr)82 #define FAT_LFN_CHKSUM(d) ( d->lfn.check_sum)77 (FAT_LFN_ORDER((d)) ^ FAT_LFN_LAST) 78 #define FAT_LFN_PART1(d) ((d)->lfn.part1) 79 #define FAT_LFN_PART2(d) ((d)->lfn.part2) 80 #define FAT_LFN_PART3(d) ((d)->lfn.part3) 81 #define FAT_LFN_ATTR(d) ((d)->lfn.attr) 82 #define FAT_LFN_CHKSUM(d) ((d)->lfn.check_sum) 83 83 84 84 #define FAT_LFN_NAME_SIZE 260 … … 98 98 } fat_dentry_clsf_t; 99 99 100 typedef struct { 101 union { 102 struct { 103 uint8_t name[8]; 104 uint8_t ext[3]; 105 uint8_t attr; 106 uint8_t lcase; 107 uint8_t ctime_fine; 108 uint16_t ctime; 109 uint16_t cdate; 110 uint16_t adate; 111 union { 112 uint16_t eaidx; /* FAT12/FAT16 */ 113 uint16_t firstc_hi; /* FAT32 */ 114 } __attribute__ ((packed)); 115 uint16_t mtime; 116 uint16_t mdate; 117 union { 118 uint16_t firstc; /* FAT12/FAT16 */ 119 uint16_t firstc_lo; /* FAT32 */ 120 } __attribute__ ((packed)); 121 uint32_t size; 100 typedef union { 101 struct { 102 uint8_t name[8]; 103 uint8_t ext[3]; 104 uint8_t attr; 105 uint8_t lcase; 106 uint8_t ctime_fine; 107 uint16_t ctime; 108 uint16_t cdate; 109 uint16_t adate; 110 union { 111 uint16_t eaidx; /* FAT12/FAT16 */ 112 uint16_t firstc_hi; /* FAT32 */ 122 113 } __attribute__ ((packed)); 123 struct { 124 uint8_t order; 125 uint16_t part1[FAT_LFN_PART1_SIZE]; 126 uint8_t attr; 127 uint8_t type; 128 uint8_t check_sum; 129 uint16_t part2[FAT_LFN_PART2_SIZE]; 130 uint16_t firstc_lo; /* MUST be 0 */ 131 uint16_t part3[FAT_LFN_PART3_SIZE]; 132 } __attribute__ ((packed)) lfn; 133 }; 114 uint16_t mtime; 115 uint16_t mdate; 116 union { 117 uint16_t firstc; /* FAT12/FAT16 */ 118 uint16_t firstc_lo; /* FAT32 */ 119 } __attribute__ ((packed)); 120 uint32_t size; 121 } __attribute__ ((packed)); 122 struct { 123 uint8_t order; 124 uint16_t part1[FAT_LFN_PART1_SIZE]; 125 uint8_t attr; 126 uint8_t type; 127 uint8_t check_sum; 128 uint16_t part2[FAT_LFN_PART2_SIZE]; 129 uint16_t firstc_lo; /* MUST be 0 */ 130 uint16_t part3[FAT_LFN_PART3_SIZE]; 131 } __attribute__ ((packed)) lfn; 134 132 } __attribute__ ((packed)) fat_dentry_t; 135 133 … … 144 142 extern size_t fat_lfn_size(const fat_dentry_t *); 145 143 extern size_t fat_lfn_get_entry(const fat_dentry_t *, uint16_t *, size_t *); 146 extern size_t fat_lfn_set_entry(const uint16_t *, size_t *, size_t, fat_dentry_t *); 144 extern size_t fat_lfn_set_entry(const uint16_t *, size_t *, size_t, 145 fat_dentry_t *); 147 146 148 extern void str_to_ascii(char * dst, const char *src, size_t count, uint8_t pad);149 extern size_t utf16_length(const uint16_t * wstr);147 extern void str_to_ascii(char *, const char *, size_t, uint8_t); 148 extern size_t utf16_length(const uint16_t *); 150 149 151 extern bool fat_valid_name(const char *name); 152 extern bool fat_valid_short_name(const char *name); 153 150 extern bool fat_valid_name(const char *); 151 extern bool fat_valid_short_name(const char *); 154 152 155 153 #endif -
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 } -
uspace/srv/fs/fat/fat_directory.h
r0dbe5ac r5d95f02 63 63 extern int fat_directory_write(fat_directory_t *, const char *, fat_dentry_t *); 64 64 extern int fat_directory_erase(fat_directory_t *); 65 extern int fat_directory_lookup_name(fat_directory_t *, const char *, fat_dentry_t **); 65 extern int fat_directory_lookup_name(fat_directory_t *, const char *, 66 fat_dentry_t **); 66 67 extern bool fat_directory_is_sfn_exist(fat_directory_t *, fat_dentry_t *); 67 68 68 extern int fat_directory_lookup_free(fat_directory_t * di, size_t count);69 extern int fat_directory_write_dentry(fat_directory_t * di, fat_dentry_t *de);70 extern int fat_directory_create_sfn(fat_directory_t * di, fat_dentry_t *de, const char *lname);71 extern int fat_directory_expand(fat_directory_t *di);72 69 extern int fat_directory_lookup_free(fat_directory_t *, size_t); 70 extern int fat_directory_write_dentry(fat_directory_t *, fat_dentry_t *); 71 extern int fat_directory_create_sfn(fat_directory_t *, fat_dentry_t *, 72 const char *); 73 extern int fat_directory_expand(fat_directory_t *); 73 74 74 75 #endif -
uspace/srv/fs/fat/fat_fat.c
r0dbe5ac r5d95f02 51 51 #include <mem.h> 52 52 53 /*54 * Convenience macros for computing some frequently used values from the55 * primitive boot sector members.56 */57 #define CLBN2PBN(bs, cl, bn) \58 (SSA((bs)) + ((cl) - FAT_CLST_FIRST) * SPC((bs)) + (bn) % SPC((bs)))59 60 53 #define IS_ODD(number) (number & 0x1) 61 54 … … 244 237 * @return EOK on success or a negative error code. 245 238 */ 246 int fat_fill_gap(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t mcl, aoff64_t pos) 239 int 240 fat_fill_gap(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t mcl, aoff64_t pos) 247 241 { 248 242 block_t *b; … … 286 280 } 287 281 288 /** Get cluster from the first FAT. FAT12 version282 /** Get cluster from the first FAT. 289 283 * 290 284 * @param bs Buffer holding the boot sector for the file system. … … 304 298 int rc; 305 299 306 offset = (clst + clst /2);300 offset = (clst + clst / 2); 307 301 if (offset / BPS(bs) >= SF(bs)) 308 302 return ERANGE; … … 313 307 return rc; 314 308 315 byte1 = ((uint8_t *) b->data)[offset % BPS(bs)];309 byte1 = ((uint8_t *) b->data)[offset % BPS(bs)]; 316 310 /* This cluster access spans a sector boundary. Check only for FAT12 */ 317 311 if ((offset % BPS(bs)) + 1 == BPS(bs)) { 318 /* Is itlast sector of FAT? */312 /* Is this the last sector of FAT? */ 319 313 if (offset / BPS(bs) < SF(bs)) { 320 /* No . Readingnext sector */314 /* No, read the next sector */ 321 315 rc = block_get(&b1, service_id, 1 + RSCNT(bs) + 322 SF(bs)*fatno + offset / BPS(bs), BLOCK_FLAGS_NONE); 316 SF(bs) * fatno + offset / BPS(bs), 317 BLOCK_FLAGS_NONE); 323 318 if (rc != EOK) { 324 319 block_put(b); … … 336 331 return rc; 337 332 } 338 } 339 else { 340 /* Yes. It is last sector of FAT */ 333 } else { 334 /* Yes. This is the last sector of FAT */ 341 335 block_put(b); 342 336 return ERANGE; 343 337 } 344 } 345 else 346 byte2 = ((uint8_t*) b->data)[(offset % BPS(bs))+1]; 338 } else 339 byte2 = ((uint8_t *) b->data)[(offset % BPS(bs)) + 1]; 347 340 348 341 *value = uint16_t_le2host(byte1 | (byte2 << 8)); … … 353 346 354 347 rc = block_put(b); 348 355 349 return rc; 356 350 } 357 351 358 /** Get cluster from the first FAT. FAT16 version352 /** Get cluster from the first FAT. 359 353 * 360 354 * @param bs Buffer holding the boot sector for the file system. … … 387 381 } 388 382 389 /** Get cluster from the first FAT. FAT32 version383 /** Get cluster from the first FAT. 390 384 * 391 385 * @param bs Buffer holding the boot sector for the file system. … … 411 405 return rc; 412 406 413 *value = uint32_t_le2host(*(uint32_t *)(b->data + offset % BPS(bs))) & FAT32_MASK; 407 *value = uint32_t_le2host(*(uint32_t *)(b->data + offset % BPS(bs))) & 408 FAT32_MASK; 414 409 415 410 rc = block_put(b); … … 436 431 assert(fatno < FATCNT(bs)); 437 432 438 if (FAT_IS_FAT12(bs)) {433 if (FAT_IS_FAT12(bs)) 439 434 rc = fat_get_cluster_fat12(bs, service_id, fatno, clst, value); 440 } 441 else { 442 if (FAT_IS_FAT32(bs)) 443 rc = fat_get_cluster_fat32(bs, service_id, fatno, clst, value); 444 else 445 rc = fat_get_cluster_fat16(bs, service_id, fatno, clst, value); 446 } 435 else if (FAT_IS_FAT16(bs)) 436 rc = fat_get_cluster_fat16(bs, service_id, fatno, clst, value); 437 else 438 rc = fat_get_cluster_fat32(bs, service_id, fatno, clst, value); 447 439 448 440 return rc; 449 441 } 450 442 451 /** Set cluster in one instance of FAT. FAT12 version.443 /** Set cluster in one instance of FAT. 452 444 * 453 445 * @param bs Buffer holding the boot sector for the file system. … … 463 455 fat_cluster_t clst, fat_cluster_t value) 464 456 { 465 block_t *b, *b1 =NULL;457 block_t *b, *b1 = NULL; 466 458 aoff64_t offset; 467 459 uint16_t byte1, byte2; 468 460 int rc; 469 461 470 offset = (clst + clst /2);462 offset = (clst + clst / 2); 471 463 if (offset / BPS(bs) >= SF(bs)) 472 464 return ERANGE; … … 479 471 byte1 = ((uint8_t*) b->data)[offset % BPS(bs)]; 480 472 bool border = false; 481 /* This cluster access spans a sector boundary. Check only for FAT12*/482 if ((offset % BPS(bs)) +1 == BPS(bs)) {483 /* Is it last sector of FAT? */473 /* This cluster access spans a sector boundary. */ 474 if ((offset % BPS(bs)) + 1 == BPS(bs)) { 475 /* Is it the last sector of FAT? */ 484 476 if (offset / BPS(bs) < SF(bs)) { 485 /* No . Readingnext sector */477 /* No, read the next sector */ 486 478 rc = block_get(&b1, service_id, 1 + RSCNT(bs) + 487 SF(bs)*fatno + offset / BPS(bs), BLOCK_FLAGS_NONE); 479 SF(bs) * fatno + offset / BPS(bs), 480 BLOCK_FLAGS_NONE); 488 481 if (rc != EOK) { 489 482 block_put(b); … … 494 487 * first byte of next sector 495 488 */ 496 byte2 = ((uint8_t *) b1->data)[0];489 byte2 = ((uint8_t *) b1->data)[0]; 497 490 border = true; 498 } 499 else { 500 /* Yes. It is last sector of fat */ 491 } else { 492 /* Yes. This is the last sector of FAT */ 501 493 block_put(b); 502 494 return ERANGE; … … 504 496 } 505 497 else 506 byte2 = ((uint8_t*) b->data)[(offset % BPS(bs)) +1];498 byte2 = ((uint8_t*) b->data)[(offset % BPS(bs)) + 1]; 507 499 508 500 if (IS_ODD(clst)) { … … 519 511 byte2 = byte2 | (value >> 8); 520 512 521 ((uint8_t *) b->data)[(offset % BPS(bs))] = byte1;513 ((uint8_t *) b->data)[(offset % BPS(bs))] = byte1; 522 514 if (border) { 523 ((uint8_t *) b1->data)[0] = byte2;515 ((uint8_t *) b1->data)[0] = byte2; 524 516 525 517 b1->dirty = true; … … 530 522 } 531 523 } else 532 ((uint8_t *) b->data)[(offset % BPS(bs))+1] = byte2;524 ((uint8_t *) b->data)[(offset % BPS(bs)) + 1] = byte2; 533 525 534 526 b->dirty = true; /* need to sync block */ 535 527 rc = block_put(b); 528 536 529 return rc; 537 530 } 538 531 539 /** Set cluster in one instance of FAT. FAT16 version.532 /** Set cluster in one instance of FAT. 540 533 * 541 534 * @param bs Buffer holding the boot sector for the file system. … … 566 559 b->dirty = true; /* need to sync block */ 567 560 rc = block_put(b); 561 568 562 return rc; 569 563 } 570 564 571 /** Set cluster in one instance of FAT. FAT32 version.565 /** Set cluster in one instance of FAT. 572 566 * 573 567 * @param bs Buffer holding the boot sector for the file system. … … 602 596 b->dirty = true; /* need to sync block */ 603 597 rc = block_put(b); 598 604 599 return rc; 605 600 } … … 625 620 if (FAT_IS_FAT12(bs)) 626 621 rc = fat_set_cluster_fat12(bs, service_id, fatno, clst, value); 627 else if (FAT_IS_FAT32(bs)) 622 else if (FAT_IS_FAT16(bs)) 623 rc = fat_set_cluster_fat16(bs, service_id, fatno, clst, value); 624 else 628 625 rc = fat_set_cluster_fat32(bs, service_id, fatno, clst, value); 629 else630 rc = fat_set_cluster_fat16(bs, service_id, fatno, clst, value);631 626 632 627 return rc; … … 695 690 */ 696 691 fibril_mutex_lock(&fat_alloc_lock); 697 for (clst=FAT_CLST_FIRST; clst < CC(bs)+2 && found < nclsts; clst++) { 692 for (clst = FAT_CLST_FIRST; clst < CC(bs) + 2 && found < nclsts; 693 clst++) { 698 694 rc = fat_get_cluster(bs, service_id, FAT1, clst, &value); 699 695 if (rc != EOK) 700 break;696 break; 701 697 702 698 if (value == FAT_CLST_RES0) { 703 /*704 * The cluster is free. Put it into our stack705 * of found clusters and mark it as non-free.706 */707 lifo[found] = clst;708 rc = fat_set_cluster(bs, service_id, FAT1, clst,709 (found == 0) ? clst_last1 : lifo[found - 1]);710 if (rc != EOK)711 break;712 713 found++;699 /* 700 * The cluster is free. Put it into our stack 701 * of found clusters and mark it as non-free. 702 */ 703 lifo[found] = clst; 704 rc = fat_set_cluster(bs, service_id, FAT1, clst, 705 (found == 0) ? clst_last1 : lifo[found - 1]); 706 if (rc != EOK) 707 break; 708 709 found++; 714 710 } 715 711 } … … 727 723 728 724 /* If something wrong - free the clusters */ 729 if (found > 0) { 730 while (found--) { 731 rc = fat_set_cluster(bs, service_id, FAT1, lifo[found], 725 while (found--) { 726 (void) fat_set_cluster(bs, service_id, FAT1, lifo[found], 732 727 FAT_CLST_RES0); 733 }734 728 } 735 729 736 730 free(lifo); 737 731 fibril_mutex_unlock(&fat_alloc_lock); 732 738 733 return ENOSPC; 739 734 } … … 757 752 while (firstc < FAT_CLST_LAST1(bs)) { 758 753 assert(firstc >= FAT_CLST_FIRST && firstc < clst_bad); 754 759 755 rc = fat_get_cluster(bs, service_id, FAT1, firstc, &nextc); 760 756 if (rc != EOK) 761 757 return rc; 758 762 759 for (fatno = FAT1; fatno < FATCNT(bs); fatno++) { 763 760 rc = fat_set_cluster(bs, service_id, fatno, firstc, … … 766 763 return rc; 767 764 } 768 769 765 firstc = nextc; 770 766 } … … 782 778 * @return EOK on success or a negative error code. 783 779 */ 784 int 785 fat_append_clusters(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t mcl, 780 int fat_append_clusters(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t mcl, 786 781 fat_cluster_t lcl) 787 782 { … … 942 937 * sanitized to support file systems with this property. 943 938 */ 944 if (!FAT_IS_FAT32(bs) && (RDE(bs) * sizeof(fat_dentry_t)) % BPS(bs) != 0) 939 if (!FAT_IS_FAT32(bs) && 940 (RDE(bs) * sizeof(fat_dentry_t)) % BPS(bs) != 0) 945 941 return ENOTSUP; 946 942 … … 955 951 return EIO; 956 952 957 /* Check that first byte of FAT contains the media descriptor. */ 953 /* 954 * Check that first byte of FAT contains the media descriptor. 955 */ 958 956 if ((e0 & 0xff) != bs->mdesc) 959 957 return ENOTSUP; … … 964 962 */ 965 963 if (!FAT_IS_FAT12(bs) && 966 964 ((e0 >> 8) != (FAT_MASK(bs) >> 8) || e1 != FAT_MASK(bs))) 967 965 return ENOTSUP; 968 966 } -
uspace/srv/fs/fat/fat_fat.h
r0dbe5ac r5d95f02 76 76 #define CC(bs) (DS(bs) / SPC(bs)) 77 77 78 #define CLBN2PBN(bs, cl, bn) \ 79 (SSA((bs)) + ((cl) - FAT_CLST_FIRST) * SPC((bs)) + (bn) % SPC((bs))) 80 78 81 #define FAT_IS_FAT12(bs) (CC(bs) < FAT12_CLST_MAX) 79 82 #define FAT_IS_FAT16(bs) \
Note:
See TracChangeset
for help on using the changeset viewer.