Changeset 0182e5cc in mainline for uspace/srv/fs/fat/fat_fat.c


Ignore:
Timestamp:
2011-05-24T19:56:11Z (13 years ago)
Author:
Oleg Romanenko <romanenko.oleg@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
a1467102
Parents:
88a27f1
Message:
  1. Rewrite and clean fat_get_cluster_fat12
  2. Support MIPS and other arch with only alligned memory access.
  3. Fix incompatibilities with BigEndian.
  4. Tested on IA32 and on MIPS32 EndianBig (GXEmul):

FAT12,16 reading and writing. FAT32 only reading. FAT32 writing - not tested!

  1. Some fixes for FAT32: reading hi and lo part of node cluster number from fat_dentry_t,

but its need more fixes to change size of cluster number from uint16_t to uint32_t etc.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/fs/fat/fat_fat.c

    r88a27f1 r0182e5cc  
    299299{
    300300        block_t *b, *b1;
     301        uint16_t byte1, byte2;
    301302        aoff64_t offset;
    302303        int rc;
    303304
    304305        offset = (clst + clst/2);
    305 
    306306        rc = block_get(&b, devmap_handle, RSCNT(bs) + SF(bs) * fatno +
    307307            offset / BPS(bs), BLOCK_FLAGS_NONE);
    308308        if (rc != EOK)
    309309                return rc;
     310
     311        byte1 = ((uint8_t*) b->data)[offset];
    310312
    311313        /* This cluster access spans a sector boundary. Check only for FAT12 */
     
    324326                        * first byte of next sector
    325327                        */
    326                         *value  = *(uint8_t *)(b->data + BPS(bs) - 1);
    327                         *value |= *(uint8_t *)(b1->data) << 8;
     328                        byte2 = ((uint8_t*) b1->data)[0];
    328329
    329330                        rc = block_put(b1);
     
    340341        }
    341342        else
    342                 *value = *(uint16_t *)(b->data + offset % BPS(bs));
    343 
     343                byte2 = ((uint8_t*) b->data)[offset+1];
     344
     345#ifdef __BE__   
     346        *value = byte2 | (byte1 << 8);
     347#else
     348        *value = byte1 | (byte2 << 8);
     349#endif
     350
     351        *value = uint16_t_le2host(*value);
    344352        if (IS_ODD(clst))
    345                 *value = (*value) >> 4;
     353                *value = *value >> 4;
    346354        else
    347                 *value = (*value) & FAT12_MASK;
    348 
    349         *value = uint16_t_le2host(*value);
     355                *value = *value & FAT12_MASK;
     356
    350357        rc = block_put(b);
    351358
     
    408415                return rc;
    409416
    410         *value = uint32_t_le2host(*(uint32_t *)(b->data + offset % BPS(bs)) & FAT32_MASK);
     417        *value = uint32_t_le2host(*(uint32_t *)(b->data + offset % BPS(bs))) & FAT32_MASK;
    411418
    412419        rc = block_put(b);
     
    433440        assert(fatno < FATCNT(bs));
    434441
    435         if (FAT_IS_FAT12(bs))
     442        if (FAT_IS_FAT12(bs)) {
    436443                rc = fat_get_cluster_fat12(bs, devmap_handle, fatno, clst, value);
    437         else if (FAT_IS_FAT32(bs))
    438                 rc = fat_get_cluster_fat32(bs, devmap_handle, fatno, clst, value);
    439         else
    440                 rc = fat_get_cluster_fat16(bs, devmap_handle, fatno, clst, value);
     444        }
     445        else {
     446                if (FAT_IS_FAT32(bs))
     447                        rc = fat_get_cluster_fat32(bs, devmap_handle, fatno, clst, value);
     448                else
     449                        rc = fat_get_cluster_fat16(bs, devmap_handle, fatno, clst, value);
     450        }
    441451
    442452        return rc;
     
    459469        block_t *b, *b1=NULL;
    460470        aoff64_t offset;
     471        uint16_t byte1, byte2;
    461472        int rc;
    462473
    463474        offset = (clst + clst/2);
    464 
    465475        rc = block_get(&b, devmap_handle, RSCNT(bs) + SF(bs) * fatno +
    466476            offset / BPS(bs), BLOCK_FLAGS_NONE);
     
    468478                return rc;
    469479
    470         value = host2uint32_t_le(value);
    471 
    472         uint16_t temp;
     480        byte1 = ((uint8_t*) b->data)[offset];
    473481        bool border = false;
    474482        /* This cluster access spans a sector boundary. Check only for FAT12 */
     
    487495                        * first byte of next sector
    488496                        */
    489                         temp  = *(uint8_t *)(b->data + BPS(bs) - 1);
    490                         temp |= *(uint8_t *)(b1->data) << 8;
     497                        byte2 = ((uint8_t*) b1->data)[0];
    491498                        border = true;
    492499                }
     
    498505        }
    499506        else
    500                 temp = *(uint16_t *)(b->data + offset % BPS(bs));
     507                byte2 = ((uint8_t*) b->data)[offset+1];
    501508
    502509        if (IS_ODD(clst)) {
    503                 temp &= 0x000f;
    504                 temp |= value << 4;
    505         }
    506         else {
    507                 temp &= 0xf000;
    508                 temp |= value & FAT12_MASK;
    509         }
    510 
     510                byte1 &= 0x0f;
     511                byte2 = 0;
     512                value = (value << 4);
     513        } else {
     514                byte1 = 0;
     515                byte2 &= 0xf0;
     516                value &= FAT12_MASK;
     517        }
     518
     519        byte1 = byte1 | (value & 0xff);
     520        byte2 = byte2 | (value >> 8);
     521
     522        ((uint8_t*) b->data)[offset] = byte1;
    511523        if (border) {
    512                 *(uint8_t *)(b->data + BPS(bs) - 1) = temp & 0xff;
    513                 *(uint8_t *)(b1->data) = temp >> 8;
     524                ((uint8_t*) b1->data)[0] = byte2;
     525
    514526                b1->dirty = true;
    515         } else
    516                 *(uint16_t *)(b->data + offset % BPS(bs)) = temp;
    517 
    518         if (b1 && b1->dirty) {
    519527                rc = block_put(b1);
    520528                if (rc != EOK) {
     
    522530                        return rc;
    523531                }
    524         }
     532        } else
     533                ((uint8_t*) b->data)[offset+1] = byte2;
    525534
    526535        b->dirty = true;        /* need to sync block */
     
    554563                return rc;
    555564
    556         *(uint16_t *)(b->data + offset % BPS(bs)) = host2uint32_t_le(value);
     565        *(uint16_t *)(b->data + offset % BPS(bs)) = host2uint16_t_le(value);
    557566
    558567        b->dirty = true;        /* need to sync block */
Note: See TracChangeset for help on using the changeset viewer.