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

Changeset 3d4fd2c in mainline


Ignore:
Timestamp:
2011-11-22T16:56:09Z (10 years ago)
Author:
Frantisek Princ <frantisek.princ@…>
Branches:
lfn, master
Children:
82d7816
Parents:
bf66ef4
Message:

deleting regular files (directories is not debugged)

Location:
uspace
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/ext4/libext4.h

    rbf66ef4 r3d4fd2c  
    4242#include "libext4_filesystem.h"
    4343#include "libext4_hash.h"
     44#include "libext4_ialloc.h"
    4445#include "libext4_inode.h"
    4546#include "libext4_superblock.h"
  • uspace/lib/ext4/libext4_filesystem.c

    rbf66ef4 r3d4fd2c  
    283283}
    284284
     285int ext4_filesystem_free_inode(ext4_filesystem_t *fs, ext4_inode_ref_t *inode_ref)
     286{
     287        int rc;
     288        // release all indirect blocks
     289
     290        uint32_t fblock;
     291
     292        // 1) Single indirect
     293        fblock = ext4_inode_get_indirect_block(inode_ref->inode, 0);
     294        if (fblock != 0) {
     295                rc = ext4_balloc_free_block(fs, inode_ref, fblock);
     296                if (rc != EOK) {
     297                        // TODO error
     298                }
     299
     300                ext4_inode_set_indirect_block(inode_ref->inode, 0, 0);
     301        }
     302
     303        block_t *block;
     304        uint32_t block_size = ext4_superblock_get_block_size(fs->superblock);
     305        uint32_t count = block_size / sizeof(uint32_t);
     306
     307        // 2) Double indirect
     308        fblock = ext4_inode_get_indirect_block(inode_ref->inode, 1);
     309        if (fblock != 0) {
     310                rc = block_get(&block, fs->device, fblock, BLOCK_FLAGS_NONE);
     311                if (rc != EOK) {
     312                        // TODO error
     313                }
     314
     315                uint32_t ind_block;
     316                for (uint32_t offset = 0; offset < count; ++offset) {
     317                        ind_block = uint32_t_le2host(((uint32_t*)block->data)[offset]);
     318
     319                        if (ind_block != 0) {
     320                                rc = ext4_balloc_free_block(fs, inode_ref, ind_block);
     321                                if (rc != EOK) {
     322                                        // TODO error
     323                                }
     324                        }
     325                }
     326
     327                block_put(block);
     328                rc = ext4_balloc_free_block(fs, inode_ref, fblock);
     329                if (rc != EOK) {
     330                        // TODO error
     331                }
     332
     333                ext4_inode_set_indirect_block(inode_ref->inode, 1, 0);
     334        }
     335
     336
     337        // 3) Tripple indirect
     338        block_t *subblock;
     339        fblock = ext4_inode_get_indirect_block(inode_ref->inode, 2);
     340        if (fblock != 0) {
     341                rc = block_get(&block, fs->device, fblock, BLOCK_FLAGS_NONE);
     342                if (rc != EOK) {
     343                        // TODO error
     344                }
     345
     346                uint32_t ind_block;
     347                for (uint32_t offset = 0; offset < count; ++offset) {
     348                        ind_block = uint32_t_le2host(((uint32_t*)block->data)[offset]);
     349
     350                        if (ind_block != 0) {
     351                                rc = block_get(&subblock, fs->device, ind_block, BLOCK_FLAGS_NONE);
     352                                if (rc != EOK) {
     353                                        // TODO error
     354                                }
     355
     356                                uint32_t ind_subblock;
     357                                for (uint32_t suboffset = 0; suboffset < count; ++suboffset) {
     358                                        ind_subblock = uint32_t_le2host(((uint32_t*)subblock->data)[suboffset]);
     359
     360                                        if (ind_subblock != 0) {
     361                                                rc = ext4_balloc_free_block(fs, inode_ref, ind_subblock);
     362                                                if (rc != EOK) {
     363                                                        // TODO error
     364                                                }
     365                                        }
     366
     367                                }
     368                                block_put(subblock);
     369
     370                        }
     371
     372                        rc = ext4_balloc_free_block(fs, inode_ref, ind_block);
     373                        if (rc != EOK) {
     374                                // TODO error
     375                        }
     376
     377
     378                }
     379
     380                block_put(block);
     381                rc = ext4_balloc_free_block(fs, inode_ref, fblock);
     382                if (rc != EOK) {
     383                        // TODO error
     384                }
     385
     386                ext4_inode_set_indirect_block(inode_ref->inode, 2, 0);
     387        }
     388
     389        // Free inode
     390        rc = ext4_ialloc_free_inode(fs, inode_ref);
     391        if (rc != EOK) {
     392                return rc;
     393        }
     394
     395        return EOK;
     396}
     397
     398int ext4_filesystem_truncate_inode(ext4_filesystem_t *fs,
     399                ext4_inode_ref_t *inode_ref, aoff64_t new_size)
     400{
     401        aoff64_t old_size;
     402        aoff64_t size_diff;
     403
     404        if (! ext4_inode_can_truncate(fs->superblock, inode_ref->inode)) {
     405                // Unable to truncate
     406                return EINVAL;
     407        }
     408
     409        old_size = ext4_inode_get_size(fs->superblock, inode_ref->inode);
     410
     411        if (old_size == new_size) {
     412                // Nothing to do
     413                return EOK;
     414        }
     415
     416        uint32_t block_size;
     417        uint32_t blocks_count, total_blocks;
     418        uint32_t i;
     419
     420        block_size  = ext4_superblock_get_block_size(fs->superblock);
     421
     422        if (old_size < new_size) {
     423                // Currently not supported to expand the file
     424                // TODO
     425                EXT4FS_DBG("trying to expand the file");
     426                return EINVAL;
     427        }
     428
     429        size_diff = old_size - new_size;
     430        blocks_count = size_diff / block_size;
     431        if (size_diff % block_size != 0) {
     432                blocks_count++;
     433        }
     434
     435        total_blocks = old_size / block_size;
     436        if (old_size % block_size != 0) {
     437                total_blocks++;
     438        }
     439
     440        // starting from 1 because of logical blocks are numbered from 0
     441        for (i = 1; i <= blocks_count; ++i) {
     442                // TODO check retval
     443                // TODO decrement inode->blocks_count
     444
     445                ext4_filesystem_release_inode_block(fs, inode_ref, total_blocks - i);
     446        }
     447
     448        ext4_inode_set_size(inode_ref->inode, new_size);
     449
     450        inode_ref->dirty = true;
     451
     452        return EOK;
     453}
     454
    285455int ext4_filesystem_get_inode_data_block_index(ext4_filesystem_t *fs, ext4_inode_t* inode,
    286456    aoff64_t iblock, uint32_t* fblock)
  • uspace/lib/ext4/libext4_filesystem.h

    rbf66ef4 r3d4fd2c  
    6161                ext4_inode_ref_t **);
    6262extern int ext4_filesystem_put_inode_ref(ext4_inode_ref_t *);
     63extern int ext4_filesystem_free_inode(ext4_filesystem_t *, ext4_inode_ref_t *);
     64extern int ext4_filesystem_truncate_inode(ext4_filesystem_t *,
     65                ext4_inode_ref_t *, aoff64_t);
    6366extern int ext4_filesystem_get_inode_data_block_index(ext4_filesystem_t *,
    6467        ext4_inode_t *, aoff64_t iblock, uint32_t *);
  • uspace/lib/ext4/libext4_ialloc.c

    rbf66ef4 r3d4fd2c  
    3636 */
    3737
     38#include <errno.h>
    3839#include "libext4.h"
     40
     41static uint32_t ext4_ialloc_inode2index_in_group(ext4_superblock_t *sb,
     42                uint32_t inode)
     43{
     44        uint32_t inodes_per_group = ext4_superblock_get_inodes_per_group(sb);
     45        return (inode - 1) % inodes_per_group;
     46}
     47
     48static uint32_t ext4_ialloc_get_bgid_of_inode(ext4_superblock_t *sb,
     49                uint32_t inode)
     50{
     51        uint32_t inodes_per_group = ext4_superblock_get_inodes_per_group(sb);
     52        return (inode - 1) / inodes_per_group;
     53
     54}
     55
     56
     57int ext4_ialloc_free_inode(ext4_filesystem_t *fs, ext4_inode_ref_t *inode_ref)
     58{
     59        int rc;
     60        uint32_t block_group = ext4_ialloc_get_bgid_of_inode(
     61                        fs->superblock, inode_ref->index);
     62        uint32_t index_in_group = ext4_ialloc_inode2index_in_group(
     63                        fs->superblock, inode_ref->index);
     64
     65        ext4_block_group_ref_t *bg_ref;
     66        rc = ext4_filesystem_get_block_group_ref(fs, block_group, &bg_ref);
     67        if (rc != EOK) {
     68                EXT4FS_DBG("error in loading bg_ref \%d", rc);
     69                return rc;
     70        }
     71
     72        uint32_t bitmap_block_addr = ext4_block_group_get_inode_bitmap(
     73                        bg_ref->block_group, fs->superblock);
     74        block_t *bitmap_block;
     75        rc = block_get(&bitmap_block, fs->device, bitmap_block_addr, 0);
     76        if (rc != EOK) {
     77                EXT4FS_DBG("error in loading bitmap \%d", rc);
     78                return rc;
     79        }
     80
     81        ext4_bitmap_free_bit(bitmap_block->data, index_in_group);
     82        bitmap_block->dirty = true;
     83
     84        rc = block_put(bitmap_block);
     85        if (rc != EOK) {
     86                // Error in saving bitmap
     87                ext4_filesystem_put_block_group_ref(bg_ref);
     88                EXT4FS_DBG("error in saving bitmap \%d", rc);
     89                return rc;
     90        }
     91
     92        // Update superblock free inodes count
     93        uint32_t sb_free_inodes = ext4_superblock_get_free_inodes_count(fs->superblock);
     94        sb_free_inodes--;
     95        ext4_superblock_set_free_inodes_count(fs->superblock, sb_free_inodes);
     96
     97        // Update block group free inodes count
     98        uint32_t free_inodes = ext4_block_group_get_free_inodes_count(
     99                        bg_ref->block_group, fs->superblock);
     100        free_inodes++;
     101        ext4_block_group_set_free_inodes_count(bg_ref->block_group,
     102                        fs->superblock, free_inodes);
     103        bg_ref->dirty = true;
     104
     105        rc = ext4_filesystem_put_block_group_ref(bg_ref);
     106        if (rc != EOK) {
     107                EXT4FS_DBG("error in saving bg_ref \%d", rc);
     108                // TODO error
     109                return rc;
     110        }
     111
     112        return EOK;
     113}
    39114
    40115
  • uspace/lib/ext4/libext4_ialloc.h

    rbf66ef4 r3d4fd2c  
    3434#define LIBEXT4_LIBEXT4_IALLOC_H_
    3535
     36#include "libext4_filesystem.h"
     37#include "libext4_inode.h"
     38
     39extern int ext4_ialloc_free_inode(ext4_filesystem_t *, ext4_inode_ref_t *);
    3640
    3741#endif
  • uspace/srv/fs/ext4fs/ext4fs_ops.c

    rbf66ef4 r3d4fd2c  
    382382int ext4fs_destroy_node(fs_node_t *fn)
    383383{
     384        int rc;
     385
     386        bool has_children;
     387        rc = ext4fs_has_children(&has_children, fn);
     388        if (rc != EOK) {
     389                ext4fs_node_put(fn);
     390                return rc;
     391        }
     392
     393        if (has_children) {
     394                EXT4FS_DBG("destroying non-empty node");
     395                ext4fs_node_put(fn);
     396                return EINVAL;
     397        }
     398
     399        ext4fs_node_t *enode = EXT4FS_NODE(fn);
     400        ext4_filesystem_t *fs = enode->instance->filesystem;
     401        ext4_inode_ref_t *inode_ref = enode->inode_ref;
     402
     403        EXT4FS_DBG("destroying \%u", inode_ref->index);
     404
     405        rc = ext4_filesystem_truncate_inode(fs, inode_ref, 0);
     406        if (rc != EOK) {
     407                ext4fs_node_put(fn);
     408                return rc;
     409        }
     410
     411        rc = ext4_filesystem_free_inode(fs, inode_ref);
     412        if (rc != EOK) {
     413                ext4fs_node_put(fn);
     414                return rc;
     415        }
     416
     417        ext4fs_node_put(fn);
     418        return EOK;
     419
     420//      EXT4FS_DBG("not supported");
     421//
     422//      // TODO
     423//      return ENOTSUP;
     424}
     425
     426
     427int ext4fs_link(fs_node_t *pfn, fs_node_t *cfn, const char *name)
     428{
    384429        EXT4FS_DBG("not supported");
    385430
     
    389434
    390435
    391 int ext4fs_link(fs_node_t *pfn, fs_node_t *cfn, const char *name)
    392 {
    393         EXT4FS_DBG("not supported");
    394 
    395         // TODO
    396         return ENOTSUP;
    397 }
    398 
    399 
    400436int ext4fs_unlink(fs_node_t *pfn, fs_node_t *cfn, const char *name)
    401437{
     438        EXT4FS_DBG("unlinking \%s", name);
     439
    402440        int rc;
    403441
     
    430468        child_inode_ref->dirty = true;
    431469
     470//      EXT4FS_DBG("links count = \%u", lnk_count);
     471
    432472        // If directory - handle links from parent
    433473        if (lnk_count <= 1 && ext4fs_is_directory(cfn)) {
    434474
    435                 ext4_inode_ref_t *parent_inode_ref = EXT4FS_NODE(pfn)->inode_ref;
    436                 uint32_t parent_lnk_count = ext4_inode_get_links_count(
    437                                 parent_inode_ref->inode);
    438                 parent_lnk_count--;
    439                 ext4_inode_set_links_count(parent_inode_ref->inode, parent_lnk_count);
    440 
    441                 parent_inode_ref->dirty = true;
     475//              EXT4FS_DBG("directory will be removed, lnlk_count = \%u", lnk_count);
     476
     477                if (lnk_count) {
     478                        lnk_count = ext4_inode_get_links_count(child_inode_ref->inode);
     479                        lnk_count--;
     480                        ext4_inode_set_links_count(child_inode_ref->inode, lnk_count);
     481                }
     482
     483//              ext4_inode_ref_t *parent_inode_ref = EXT4FS_NODE(pfn)->inode_ref;
     484//              uint32_t parent_lnk_count = ext4_inode_get_links_count(
     485//                              parent_inode_ref->inode);
     486//
     487//              EXT4FS_DBG("directory will be removed, parent link count = \%u", parent_lnk_count);
     488//
     489//              parent_lnk_count--;
     490//              ext4_inode_set_links_count(parent_inode_ref->inode, parent_lnk_count);
     491//
     492//              parent_inode_ref->dirty = true;
    442493        }
    443494
     
    10211072ext4fs_truncate(service_id_t service_id, fs_index_t index, aoff64_t new_size)
    10221073{
     1074        int rc;
    10231075        fs_node_t *fn;
    1024         ext4fs_node_t *enode;
    1025         ext4_inode_ref_t *inode_ref;
    1026         ext4_filesystem_t* fs;
    1027         aoff64_t old_size;
    1028         aoff64_t size_diff;
    1029         int rc;
     1076//      aoff64_t old_size;
     1077//      aoff64_t size_diff;
    10301078
    10311079        rc = ext4fs_node_get(&fn, service_id, index);
     
    10341082        }
    10351083
    1036         enode = EXT4FS_NODE(fn);
    1037         inode_ref = enode->inode_ref;
    1038         fs = enode->instance->filesystem;
    1039 
    1040 
    1041         if (! ext4_inode_can_truncate(fs->superblock, inode_ref->inode)) {
    1042                 // Unable to truncate
    1043                 ext4fs_node_put(fn);
    1044                 return EINVAL;
    1045         }
    1046 
    1047         old_size = ext4_inode_get_size(fs->superblock, inode_ref->inode);
    1048 
    1049         if (old_size == new_size) {
    1050                 ext4fs_node_put(fn);
    1051                 return EOK;
    1052         } else {
    1053 
    1054                 uint32_t block_size;
    1055                 uint32_t blocks_count, total_blocks;
    1056                 uint32_t i;
    1057 
    1058                 block_size  = ext4_superblock_get_block_size(fs->superblock);
    1059 
    1060                 if (old_size < new_size) {
    1061                         // Currently not supported to expand the file
    1062                         // TODO
    1063                         EXT4FS_DBG("trying to expand the file");
    1064                         return EINVAL;
    1065                 }
    1066 
    1067                 size_diff = old_size - new_size;
    1068                 blocks_count = size_diff / block_size;
    1069                 if (size_diff % block_size != 0) {
    1070                         blocks_count++;
    1071                 }
    1072 
    1073                 total_blocks = old_size / block_size;
    1074                 if (old_size % block_size != 0) {
    1075                         total_blocks++;
    1076                 }
    1077 
    1078                 inode_ref->dirty = true;
    1079 
    1080                 // starting from 1 because of logical blocks are numbered from 0
    1081                 for (i = 1; i <= blocks_count; ++i) {
    1082                         // TODO check retval
    1083                         // TODO decrement inode->blocks_count
    1084 
    1085                         ext4_filesystem_release_inode_block(fs, inode_ref, total_blocks - i);
    1086                 }
    1087 
    1088                 ext4_inode_set_size(inode_ref->inode, new_size);
    1089 
    1090         }
    1091 
     1084        ext4fs_node_t *enode = EXT4FS_NODE(fn);
     1085        ext4_inode_ref_t *inode_ref = enode->inode_ref;
     1086        ext4_filesystem_t *fs = enode->instance->filesystem;
     1087
     1088        rc = ext4_filesystem_truncate_inode(fs, inode_ref, new_size);
    10921089        ext4fs_node_put(fn);
    10931090
    1094         return EOK;
     1091        return rc;
     1092
     1093//      if (! ext4_inode_can_truncate(fs->superblock, inode_ref->inode)) {
     1094//              // Unable to truncate
     1095//              ext4fs_node_put(fn);
     1096//              return EINVAL;
     1097//      }
     1098//
     1099//      old_size = ext4_inode_get_size(fs->superblock, inode_ref->inode);
     1100//
     1101//      if (old_size == new_size) {
     1102//              ext4fs_node_put(fn);
     1103//              return EOK;
     1104//      } else {
     1105//
     1106//              uint32_t block_size;
     1107//              uint32_t blocks_count, total_blocks;
     1108//              uint32_t i;
     1109//
     1110//              block_size  = ext4_superblock_get_block_size(fs->superblock);
     1111//
     1112//              if (old_size < new_size) {
     1113//                      // Currently not supported to expand the file
     1114//                      // TODO
     1115//                      EXT4FS_DBG("trying to expand the file");
     1116//                      ext4fs_node_put(fn);
     1117//                      return EINVAL;
     1118//              }
     1119//
     1120//              size_diff = old_size - new_size;
     1121//              blocks_count = size_diff / block_size;
     1122//              if (size_diff % block_size != 0) {
     1123//                      blocks_count++;
     1124//              }
     1125//
     1126//              total_blocks = old_size / block_size;
     1127//              if (old_size % block_size != 0) {
     1128//                      total_blocks++;
     1129//              }
     1130//
     1131//              // starting from 1 because of logical blocks are numbered from 0
     1132//              for (i = 1; i <= blocks_count; ++i) {
     1133//                      // TODO check retval
     1134//                      // TODO decrement inode->blocks_count
     1135//
     1136//                      ext4_filesystem_release_inode_block(fs, inode_ref, total_blocks - i);
     1137//              }
     1138//
     1139//              ext4_inode_set_size(inode_ref->inode, new_size);
     1140//
     1141//              inode_ref->dirty = true;
     1142//
     1143//      }
     1144//
     1145//      ext4fs_node_put(fn);
     1146//
     1147//      return EOK;
    10951148}
    10961149
Note: See TracChangeset for help on using the changeset viewer.