Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/fs/mfs/mfs_balloc.c

    r9d58539 r1eaa3cf  
    4444mfs_alloc_bit(struct mfs_instance *inst, uint32_t *idx, bmap_id_t bid);
    4545
     46static int
     47mfs_count_free_bits(struct mfs_instance *inst, bmap_id_t bid, uint32_t *free);
     48
     49
    4650/**Allocate a new inode.
    4751 *
     
    8488{
    8589        int r = mfs_alloc_bit(inst, zone, BMAP_ZONE);
     90        if (r != EOK)
     91                return r;
     92
     93        /* Update the cached number of free zones */
     94        struct mfs_sb_info *sbi = inst->sbi;
     95        if (sbi->nfree_zones_valid)
     96                sbi->nfree_zones--;
    8697
    8798        *zone += inst->sbi->firstdatazone - 1;
     
    99110mfs_free_zone(struct mfs_instance *inst, uint32_t zone)
    100111{
     112        int r;
     113
    101114        zone -= inst->sbi->firstdatazone - 1;
    102115
    103         return mfs_free_bit(inst, zone, BMAP_ZONE);
     116        r = mfs_free_bit(inst, zone, BMAP_ZONE);
     117        if (r != EOK)
     118                return r;
     119
     120        /* Update the cached number of free zones */
     121        struct mfs_sb_info *sbi = inst->sbi;
     122        if (sbi->nfree_zones_valid)
     123                sbi->nfree_zones++;
     124
     125        return r;
     126}
     127
     128/** Count the number of free zones
     129 *
     130 * @param inst          Pointer to the instance structure.
     131 * @param zones         Pointer to the memory location where the result
     132 *                      will be stored.
     133 *
     134 * @return              EOK on success or a negative error code.
     135 */
     136int
     137mfs_count_free_zones(struct mfs_instance *inst, uint32_t *zones)
     138{
     139        return mfs_count_free_bits(inst, BMAP_ZONE, zones);
     140}
     141
     142/** Count the number of free inodes
     143 *
     144 * @param inst          Pointer to the instance structure.
     145 * @param zones         Pointer to the memory location where the result
     146 *                      will be stored.
     147 *
     148 * @return              EOK on success or a negative error code.
     149 */
     150
     151int
     152mfs_count_free_inodes(struct mfs_instance *inst, uint32_t *inodes)
     153{
     154        return mfs_count_free_bits(inst, BMAP_INODE, inodes);
     155}
     156
     157/** Count the number of free bits in a bitmap
     158 *
     159 * @param inst          Pointer to the instance structure.
     160 * @param bid           Type of the bitmap (inode or zone).
     161 * @param free          Pointer to the memory location where the result
     162 *                      will be stores.
     163 *
     164 * @return              EOK on success or a negative error code.
     165 */
     166static int
     167mfs_count_free_bits(struct mfs_instance *inst, bmap_id_t bid, uint32_t *free)
     168{
     169        int r;
     170        unsigned start_block;
     171        unsigned long nblocks;
     172        unsigned long nbits;
     173        unsigned long block;
     174        unsigned long free_bits = 0;
     175        bitchunk_t chunk;
     176        size_t const bitchunk_bits = sizeof(bitchunk_t) * 8;
     177        block_t *b;
     178        struct mfs_sb_info *sbi = inst->sbi;
     179
     180        start_block = MFS_BMAP_START_BLOCK(sbi, bid);
     181        nblocks = MFS_BMAP_SIZE_BLOCKS(sbi, bid);
     182        nbits = MFS_BMAP_SIZE_BITS(sbi, bid);
     183
     184        for (block = 0; block < nblocks; ++block) {
     185                r = block_get(&b, inst->service_id, block + start_block,
     186                    BLOCK_FLAGS_NONE);
     187                if (r != EOK)
     188                        return r;
     189
     190                size_t i;
     191                bitchunk_t *data = (bitchunk_t *) b->data;
     192
     193                /* Read the bitmap block, chunk per chunk,
     194                 * counting the zero bits.
     195                 */
     196                for (i = 0; i < sbi->block_size / sizeof(bitchunk_t); ++i) {
     197                        chunk = conv32(sbi->native, data[i]);
     198
     199                        size_t bit;
     200                        for (bit = 0; bit < bitchunk_bits && nbits > 0;
     201                            ++bit, --nbits) {
     202                                if (!(chunk & (1 << bit)))
     203                                        free_bits++;
     204                        }
     205
     206                        if (nbits == 0)
     207                                break;
     208                }
     209
     210                r = block_put(b);
     211                if (r != EOK)
     212                        return r;
     213        }
     214
     215        *free = free_bits;
     216        assert(nbits == 0);
     217
     218        return EOK;
    104219}
    105220
     
    124239        sbi = inst->sbi;
    125240
     241        start_block = MFS_BMAP_START_BLOCK(sbi, bid);
     242
    126243        if (bid == BMAP_ZONE) {
    127244                search = &sbi->zsearch;
    128                 start_block = 2 + sbi->ibmap_blocks;
    129245                if (idx > sbi->nzones) {
    130                         printf(NAME ": Error! Trying to free beyond the" \
     246                        printf(NAME ": Error! Trying to free beyond the "
    131247                            "bitmap max size\n");
    132248                        return -1;
     
    135251                /* bid == BMAP_INODE */
    136252                search = &sbi->isearch;
    137                 start_block = 2;
    138253                if (idx > sbi->ninodes) {
    139                         printf(NAME ": Error! Trying to free beyond the" \
     254                        printf(NAME ": Error! Trying to free beyond the "
    140255                            "bitmap max size\n");
    141256                        return -1;
     
    192307        sbi = inst->sbi;
    193308
     309        start_block = MFS_BMAP_START_BLOCK(sbi, bid);
     310        limit = MFS_BMAP_SIZE_BITS(sbi, bid);
     311        nblocks = MFS_BMAP_SIZE_BLOCKS(sbi, bid);
     312
    194313        if (bid == BMAP_ZONE) {
    195314                search = &sbi->zsearch;
    196                 start_block = 2 + sbi->ibmap_blocks;
    197                 nblocks = sbi->zbmap_blocks;
    198                 limit = sbi->nzones - sbi->firstdatazone - 1;
    199315        } else {
    200316                /* bid == BMAP_INODE */
    201317                search = &sbi->isearch;
    202                 start_block = 2;
    203                 nblocks = sbi->ibmap_blocks;
    204                 limit = sbi->ninodes;
    205318        }
    206319        bits_per_block = sbi->block_size * 8;
Note: See TracChangeset for help on using the changeset viewer.