Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/ext4/src/filesystem.c

    r395df52 rfcb0d76  
    3232 */
    3333/**
    34  * @file  filesystem.c
     34 * @file  libext4_filesystem.c
    3535 * @brief More complex filesystem operations.
    3636 */
     
    4242#include <crypto.h>
    4343#include <ipc/vfs.h>
    44 #include <libfs.h>
    4544#include <stdlib.h>
    4645#include "ext4/balloc.h"
     
    5150#include "ext4/ialloc.h"
    5251#include "ext4/inode.h"
    53 #include "ext4/ops.h"
    5452#include "ext4/superblock.h"
    5553
    56 static int ext4_filesystem_check_features(ext4_filesystem_t *, bool *);
    57 
    58 /** Initialize filesystem for opening.
    59  *
    60  * But do not mark mounted just yet.
     54/** Initialize filesystem and read all needed data.
    6155 *
    6256 * @param fs         Filesystem instance to be initialized
    63  * @param service_id Block device to open
    64  * @param cmode      Cache mode
    65  *
    66  * @return Error code
    67  *
    68  */
    69 static int ext4_filesystem_init(ext4_filesystem_t *fs, service_id_t service_id,
     57 * @param service_id Identifier if device with the filesystem
     58 *
     59 * @return Error code
     60 *
     61 */
     62int ext4_filesystem_init(ext4_filesystem_t *fs, service_id_t service_id,
    7063    enum cache_mode cmode)
    7164{
     
    120113                goto err_2;
    121114        }
    122 
     115       
    123116        rc = ext4_superblock_check_sanity(fs->superblock);
    124117        if (rc != EOK)
    125118                goto err_2;
    126119
    127         /* Check flags */
    128         bool read_only;
    129         rc = ext4_filesystem_check_features(fs, &read_only);
     120        /* Mark system as mounted */
     121        ext4_superblock_set_state(fs->superblock, EXT4_SUPERBLOCK_STATE_ERROR_FS);
     122        rc = ext4_superblock_write_direct(fs->device, fs->superblock);
    130123        if (rc != EOK)
    131124                goto err_2;
    132125
     126        uint16_t mnt_count = ext4_superblock_get_mount_count(fs->superblock);
     127        ext4_superblock_set_mount_count(fs->superblock, mnt_count + 1);
     128
    133129        return EOK;
     130
    134131err_2:
    135132        block_cache_fini(fs->device);
     
    142139}
    143140
    144 /** Finalize filesystem.
    145  *
    146  * @param fs Filesystem to be finalized
    147  *
    148  */
    149 static void ext4_filesystem_fini(ext4_filesystem_t *fs)
    150 {
     141/** Destroy filesystem instance (used by unmount operation).
     142 *
     143 * @param fs Filesystem to be destroyed
     144 *
     145 * @return Error code
     146 *
     147 */
     148int ext4_filesystem_fini(ext4_filesystem_t *fs)
     149{
     150        /* Write the superblock to the device */
     151        ext4_superblock_set_state(fs->superblock, EXT4_SUPERBLOCK_STATE_VALID_FS);
     152        int rc = ext4_superblock_write_direct(fs->device, fs->superblock);
     153       
    151154        /* Release memory space for superblock */
    152155        free(fs->superblock);
     
    155158        block_cache_fini(fs->device);
    156159        block_fini(fs->device);
    157 }
    158 
    159 /** Probe filesystem.
    160  *
    161  * @param service_id Block device to probe
    162  *
    163  * @return EOK or negative error code.
    164  *
    165  */
    166 int ext4_filesystem_probe(service_id_t service_id)
    167 {
    168         ext4_filesystem_t *fs = NULL;
    169         int rc;
    170 
    171         fs = calloc(1, sizeof(ext4_filesystem_t));
    172         if (fs == NULL)
    173                 return ENOMEM;
    174 
    175         /* Initialize the file system for opening */
    176         rc = ext4_filesystem_init(fs, service_id, CACHE_MODE_WT);
    177         if (rc != EOK) {
    178                 free(fs);
    179                 return rc;
    180         }
    181 
    182         ext4_filesystem_fini(fs);
    183         return EOK;
    184 }
    185 
    186 /** Open filesystem and read all needed data.
    187  *
    188  * @param fs         Filesystem to be initialized
    189  * @param inst       Instance
    190  * @param service_id Identifier if device with the filesystem
    191  * @param cmode      Cache mode
    192  * @param size       Output value - size of root node
    193  *
    194  * @return Error code
    195  *
    196  */
    197 int ext4_filesystem_open(ext4_instance_t *inst, service_id_t service_id,
    198     enum cache_mode cmode, aoff64_t *size, ext4_filesystem_t **rfs)
    199 {
    200         ext4_filesystem_t *fs = NULL;
    201         fs_node_t *root_node = NULL;
    202         int rc;
    203 
    204         fs = calloc(1, sizeof(ext4_filesystem_t));
    205         if (fs == NULL) {
    206                 rc = ENOMEM;
    207                 goto error;
    208         }
    209 
    210         inst->filesystem = fs;
    211 
    212         /* Initialize the file system for opening */
    213         rc = ext4_filesystem_init(fs, service_id, cmode);
    214         if (rc != EOK)
    215                 goto error;
    216 
    217         /* Read root node */
    218         rc = ext4_node_get_core(&root_node, inst, EXT4_INODE_ROOT_INDEX);
    219         if (rc != EOK)
    220                 goto error;
    221 
    222         /* Mark system as mounted */
    223         ext4_superblock_set_state(fs->superblock, EXT4_SUPERBLOCK_STATE_ERROR_FS);
    224         rc = ext4_superblock_write_direct(fs->device, fs->superblock);
    225         if (rc != EOK)
    226                 goto error;
    227 
    228         uint16_t mnt_count = ext4_superblock_get_mount_count(fs->superblock);
    229         ext4_superblock_set_mount_count(fs->superblock, mnt_count + 1);
    230 
    231         ext4_node_t *enode = EXT4_NODE(root_node);
    232 
    233         *size = ext4_inode_get_size(fs->superblock, enode->inode_ref->inode);
    234 
    235         ext4_node_put(root_node);
    236         *rfs = fs;
    237         return EOK;
    238 error:
    239         if (root_node != NULL)
    240                 ext4_node_put(root_node);
    241 
    242         if (fs != NULL) {
    243                 ext4_filesystem_fini(fs);
    244                 free(fs);
    245         }
    246 
     160       
    247161        return rc;
    248 }
    249 
    250 /** Close filesystem.
    251  *
    252  * @param fs Filesystem to be destroyed
    253  *
    254  * @return EOK or negative error code. On error the state of the file
    255  *         system is unchanged.
    256  *
    257  */
    258 int ext4_filesystem_close(ext4_filesystem_t *fs)
    259 {
    260         /* Write the superblock to the device */
    261         ext4_superblock_set_state(fs->superblock, EXT4_SUPERBLOCK_STATE_VALID_FS);
    262         int rc = ext4_superblock_write_direct(fs->device, fs->superblock);
    263         if (rc != EOK)
    264                 return rc;
    265 
    266         ext4_filesystem_fini(fs);
    267         return EOK;
    268162}
    269163
     
    275169 *
    276170 * @param fs        Filesystem to be checked
    277  * @param read_only Place to write flag saying whether filesystem
    278  *                  should be mounted only for reading
    279  *
    280  * @return Error code
    281  *
    282  */
    283 static int ext4_filesystem_check_features(ext4_filesystem_t *fs,
    284     bool *read_only)
     171 * @param read_only Flag if filesystem should be mounted only for reading
     172 *
     173 * @return Error code
     174 *
     175 */
     176int ext4_filesystem_check_features(ext4_filesystem_t *fs, bool *read_only)
    285177{
    286178        /* Feature flags are present only in higher revisions */
Note: See TracChangeset for help on using the changeset viewer.