Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset c6aca755 in mainline


Ignore:
Timestamp:
2011-06-20T18:50:11Z (11 years ago)
Author:
Oleg Romanenko <romanenko.oleg@…>
Branches:
lfn, master
Children:
b85c19a
Parents:
e65e406
Message:

Rewrite fat_directory_xxx api. Add functions for iterating and accessing
directory entries.

Location:
uspace/srv/fs/fat
Files:
3 edited

Legend:

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

    re65e406 rc6aca755  
    222222        if (d->attr == FAT_ATTR_LFN) {
    223223                /* long name entry */
    224                 if (d->attr & FAT_LFN_ERASED)
     224                if (FAT_LFN_ORDER(d) & FAT_LFN_ERASED)
    225225                        return FAT_DENTRY_FREE;
    226226                else
  • uspace/srv/fs/fat/fat_directory.c

    re65e406 rc6aca755  
    4040#include <errno.h>
    4141#include <byteorder.h>
     42#include <mem.h>
     43
     44int fat_directory_block_load(fat_directory_t *);
     45
    4246
    4347int fat_directory_open(fat_node_t *nodep, fat_directory_t *di)
    4448{
     49        di->b = NULL;
    4550        di->nodep = nodep;     
    4651        if (di->nodep->type != FAT_DIRECTORY)
     
    4954        di->bs = block_bb_get(di->nodep->idx->devmap_handle);
    5055        di->blocks = di->nodep->size / BPS(di->bs);
    51         di->b = NULL;
    5256        di->pos = 0;
    5357        di->bnum = 0;
     
    7478}
    7579
    76 int fat_directory_scan(fat_directory_t *di, fat_dentry_t **d)
     80int fat_directory_block_load(fat_directory_t *di)
    7781{
    7882        uint32_t i;
    7983        int rc;
    80        
     84
    8185        i = (di->pos * sizeof(fat_dentry_t)) / BPS(di->bs);
    8286        if (i < di->blocks) {
     
    9397                        di->bnum = i;
    9498                }
     99                return EOK;
     100        }
     101        return ENOENT;
     102}
     103
     104int fat_directory_next(fat_directory_t *di)
     105{
     106        int rc;
     107
     108        di->pos += 1;
     109        rc = fat_directory_block_load(di);
     110        if (rc!=EOK)
     111                di->pos -= 1;
     112       
     113        return rc;
     114}
     115
     116int fat_directory_prev(fat_directory_t *di)
     117{
     118        int rc=EOK;
     119       
     120        if (di->pos > 0) {
     121                di->pos -= 1;
     122                rc=fat_directory_block_load(di);
     123        }
     124        else
     125                return ENOENT;
     126       
     127        if (rc!=EOK)
     128                di->pos += 1;
     129       
     130        return rc;
     131}
     132
     133int fat_directory_seek(fat_directory_t *di, aoff64_t pos)
     134{
     135        aoff64_t _pos = di->pos;
     136        int rc;
     137        di->pos = pos;
     138        rc = fat_directory_block_load(di);
     139        if (rc!=EOK)
     140                di->pos = _pos;
     141       
     142        return rc;
     143}
     144
     145int fat_directory_get(fat_directory_t *di, fat_dentry_t **d)
     146{
     147        int rc;
     148       
     149        rc = fat_directory_block_load(di);
     150        if (rc == EOK) {
    95151                aoff64_t o = di->pos % (BPS(di->bs) / sizeof(fat_dentry_t));
    96152                *d = ((fat_dentry_t *)di->b->data) + o;
    97                 di->pos+=1;
    98                 return EOK;
    99         }
    100         return ENOENT;
     153        }
     154       
     155        return rc;
    101156}
    102157
     
    105160        fat_dentry_t *d = NULL;
    106161
    107         while (fat_directory_scan(di, &d) == EOK && d) {
    108                 switch (fat_classify_dentry(d)) {
    109                 case FAT_DENTRY_LAST:
    110                         di->long_entry_count = 0;
    111                         di->long_entry = false;
    112                         return ENOENT;
    113                 case FAT_DENTRY_LFN:
    114                         if (di->long_entry) {
    115                                 /* We found long entry */
    116                                 di->long_entry_count--;
    117                                 if ((FAT_LFN_ORDER(d) == di->long_entry_count) &&
    118                                         (di->checksum == FAT_LFN_CHKSUM(d))) {
    119                                         /* Right order! */
    120                                         di->lfn_offset = fat_lfn_copy_entry(d, di->lfn_utf16,
    121                                             di->lfn_offset);
     162        do {
     163                if (fat_directory_get(di, &d) == EOK) {
     164                        switch (fat_classify_dentry(d)) {
     165                        case FAT_DENTRY_LAST:
     166                                di->long_entry_count = 0;
     167                                di->long_entry = false;
     168                                return ENOENT;
     169                        case FAT_DENTRY_LFN:
     170                                if (di->long_entry) {
     171                                        /* We found long entry */
     172                                        di->long_entry_count--;
     173                                        if ((FAT_LFN_ORDER(d) == di->long_entry_count) &&
     174                                                (di->checksum == FAT_LFN_CHKSUM(d))) {
     175                                                /* Right order! */
     176                                                di->lfn_offset = fat_lfn_copy_entry(d, di->lfn_utf16,
     177                                                        di->lfn_offset);
     178                                        } else {
     179                                                /* Something wrong with order. Skip this long entries set */
     180                                                di->long_entry_count = 0;
     181                                                di->long_entry = false;
     182                                        }
    122183                                } else {
    123                                         /* Something wrong with order. Skip this long entries set */
    124                                         di->long_entry_count = 0;
    125                                         di->long_entry = false;
    126                                 }
    127                         } else {
    128                                 if (FAT_IS_LFN(d)) {
    129                                         /* We found Last long entry! */
    130                                         if (FAT_LFN_COUNT(d) <= FAT_LFN_MAX_COUNT) {
    131                                                 di->long_entry = true;
    132                                                 di->long_entry_count = FAT_LFN_COUNT(d);
    133                                                 di->lfn_size = (FAT_LFN_ENTRY_SIZE *
    134                                                         (FAT_LFN_COUNT(d) - 1)) + fat_lfn_size(d);
    135                                                 di->lfn_offset = di->lfn_size;
    136                                                 di->lfn_offset = fat_lfn_copy_entry(d, di->lfn_utf16,
    137                                                     di->lfn_offset);
    138                                                 di->checksum = FAT_LFN_CHKSUM(d);
     184                                        if (FAT_IS_LFN(d)) {
     185                                                /* We found Last long entry! */
     186                                                if (FAT_LFN_COUNT(d) <= FAT_LFN_MAX_COUNT) {
     187                                                        di->long_entry = true;
     188                                                        di->long_entry_count = FAT_LFN_COUNT(d);
     189                                                        di->lfn_size = (FAT_LFN_ENTRY_SIZE *
     190                                                                (FAT_LFN_COUNT(d) - 1)) + fat_lfn_size(d);
     191                                                        di->lfn_offset = di->lfn_size;
     192                                                        di->lfn_offset = fat_lfn_copy_entry(d, di->lfn_utf16,
     193                                                                di->lfn_offset);
     194                                                        di->checksum = FAT_LFN_CHKSUM(d);
     195                                                }
    139196                                        }
    140197                                }
     198                                break;
     199                        case FAT_DENTRY_VALID:
     200                                if (di->long_entry &&
     201                                        (di->checksum == fat_dentry_chksum(d->name))) {
     202                                        int rc;
     203                                        rc = fat_lfn_convert_name(di->lfn_utf16, di->lfn_size,
     204                                                (uint8_t*)name, FAT_LFN_NAME_SIZE);
     205                                        if (rc!=EOK)
     206                                                fat_dentry_name_get(d, name);
     207                                }
     208                                else
     209                                        fat_dentry_name_get(d, name);
     210                               
     211                                *de = d;
     212                                di->long_entry_count = 0;
     213                                di->long_entry = false;
     214                                return EOK;
     215                        default:
     216                        case FAT_DENTRY_SKIP:
     217                        case FAT_DENTRY_FREE:
     218                                di->long_entry_count = 0;
     219                                di->long_entry = false;
     220                                break;
    141221                        }
     222                }
     223        } while (fat_directory_next(di) == EOK);
     224       
     225        return ENOENT;
     226}
     227
     228int fat_directory_erase(fat_directory_t *di)
     229{
     230        int rc;
     231        fat_dentry_t *d;
     232        bool flag = false;
     233
     234        rc = fat_directory_get(di, &d);
     235        if (rc != EOK)
     236                return rc;
     237        di->checksum = fat_dentry_chksum(d->name);
     238
     239        d->name[0] = FAT_DENTRY_ERASED;
     240        di->b->dirty = true;
     241       
     242        while (!flag && fat_directory_prev(di) == EOK) {
     243                if (fat_directory_get(di, &d) == EOK &&
     244                        fat_classify_dentry(d) == FAT_DENTRY_LFN &&                     
     245                        di->checksum == FAT_LFN_CHKSUM(d)) {
     246                                if (FAT_IS_LFN(d))
     247                                        flag = true;
     248                                memset(d, 0, sizeof(fat_dentry_t));
     249                                d->name[0] = FAT_DENTRY_ERASED;
     250                                di->b->dirty = true;
     251                }
     252                else
    142253                        break;
    143                 case FAT_DENTRY_VALID:
    144                         if (di->long_entry &&
    145                                 (di->checksum == fat_dentry_chksum(d->name))) {
    146                                 int rc;
    147                                 rc = fat_lfn_convert_name(di->lfn_utf16, di->lfn_size,
    148                                         (uint8_t*)name, FAT_LFN_NAME_SIZE);
    149                                 if (rc!=EOK)
    150                                         fat_dentry_name_get(d, name);
    151                         }
    152                         else
    153                                 fat_dentry_name_get(d, name);
    154                        
    155                         *de = d;
    156                         di->long_entry_count = 0;
    157                         di->long_entry = false;
    158                         return EOK;
    159                 default:
    160                 case FAT_DENTRY_SKIP:
    161                 case FAT_DENTRY_FREE:
    162                         di->long_entry_count = 0;
    163                         di->long_entry = false;
    164                         break;
    165                 }
    166         }
    167         return ENOENT;
     254        }
     255
     256        return EOK;
    168257}
    169258
  • uspace/srv/fs/fat/fat_directory.h

    re65e406 rc6aca755  
    5959extern int fat_directory_open(fat_node_t *, fat_directory_t *);
    6060extern int fat_directory_close(fat_directory_t *);
    61 extern int fat_directory_scan(fat_directory_t *, fat_dentry_t **);
     61
     62extern int fat_directory_next(fat_directory_t *);
     63extern int fat_directory_prev(fat_directory_t *);
     64extern int fat_directory_seek(fat_directory_t *, aoff64_t pos);
     65extern int fat_directory_get(fat_directory_t *, fat_dentry_t **);
     66extern int fat_directory_dirty(fat_directory_t *);
     67
    6268extern int fat_directory_read(fat_directory_t *, char *, fat_dentry_t **);
     69extern int fat_directory_erase(fat_directory_t *);
    6370
    6471
Note: See TracChangeset for help on using the changeset viewer.