Ignore:
File:
1 edited

Legend:

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

    rfcb0d76 r395df52  
    3232 */
    3333/**
    34  * @file  libext4_filesystem.c
     34 * @file  filesystem.c
    3535 * @brief More complex filesystem operations.
    3636 */
     
    4242#include <crypto.h>
    4343#include <ipc/vfs.h>
     44#include <libfs.h>
    4445#include <stdlib.h>
    4546#include "ext4/balloc.h"
     
    5051#include "ext4/ialloc.h"
    5152#include "ext4/inode.h"
     53#include "ext4/ops.h"
    5254#include "ext4/superblock.h"
    5355
    54 /** Initialize filesystem and read all needed data.
     56static int ext4_filesystem_check_features(ext4_filesystem_t *, bool *);
     57
     58/** Initialize filesystem for opening.
     59 *
     60 * But do not mark mounted just yet.
    5561 *
    5662 * @param fs         Filesystem instance to be initialized
    57  * @param service_id Identifier if device with the filesystem
     63 * @param service_id Block device to open
     64 * @param cmode      Cache mode
    5865 *
    5966 * @return Error code
    6067 *
    6168 */
    62 int ext4_filesystem_init(ext4_filesystem_t *fs, service_id_t service_id,
     69static int ext4_filesystem_init(ext4_filesystem_t *fs, service_id_t service_id,
    6370    enum cache_mode cmode)
    6471{
     
    113120                goto err_2;
    114121        }
    115        
     122
    116123        rc = ext4_superblock_check_sanity(fs->superblock);
    117124        if (rc != EOK)
    118125                goto err_2;
    119126
    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);
     127        /* Check flags */
     128        bool read_only;
     129        rc = ext4_filesystem_check_features(fs, &read_only);
    123130        if (rc != EOK)
    124131                goto err_2;
    125132
    126         uint16_t mnt_count = ext4_superblock_get_mount_count(fs->superblock);
    127         ext4_superblock_set_mount_count(fs->superblock, mnt_count + 1);
    128 
    129133        return EOK;
    130 
    131134err_2:
    132135        block_cache_fini(fs->device);
     
    139142}
    140143
    141 /** Destroy filesystem instance (used by unmount operation).
     144/** Finalize filesystem.
     145 *
     146 * @param fs Filesystem to be finalized
     147 *
     148 */
     149static void ext4_filesystem_fini(ext4_filesystem_t *fs)
     150{
     151        /* Release memory space for superblock */
     152        free(fs->superblock);
     153
     154        /* Finish work with block library */
     155        block_cache_fini(fs->device);
     156        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 */
     166int 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 */
     197int 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;
     238error:
     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
     247        return rc;
     248}
     249
     250/** Close filesystem.
    142251 *
    143252 * @param fs Filesystem to be destroyed
    144253 *
    145  * @return Error code
    146  *
    147  */
    148 int ext4_filesystem_fini(ext4_filesystem_t *fs)
     254 * @return EOK or negative error code. On error the state of the file
     255 *         system is unchanged.
     256 *
     257 */
     258int ext4_filesystem_close(ext4_filesystem_t *fs)
    149259{
    150260        /* Write the superblock to the device */
    151261        ext4_superblock_set_state(fs->superblock, EXT4_SUPERBLOCK_STATE_VALID_FS);
    152262        int rc = ext4_superblock_write_direct(fs->device, fs->superblock);
    153        
    154         /* Release memory space for superblock */
    155         free(fs->superblock);
    156 
    157         /* Finish work with block library */
    158         block_cache_fini(fs->device);
    159         block_fini(fs->device);
    160        
    161         return rc;
     263        if (rc != EOK)
     264                return rc;
     265
     266        ext4_filesystem_fini(fs);
     267        return EOK;
    162268}
    163269
     
    169275 *
    170276 * @param fs        Filesystem to be checked
    171  * @param read_only Flag if filesystem should be mounted only for reading
     277 * @param read_only Place to write flag saying whether filesystem
     278 *                  should be mounted only for reading
    172279 *
    173280 * @return Error code
    174281 *
    175282 */
    176 int ext4_filesystem_check_features(ext4_filesystem_t *fs, bool *read_only)
     283static int ext4_filesystem_check_features(ext4_filesystem_t *fs,
     284    bool *read_only)
    177285{
    178286        /* Feature flags are present only in higher revisions */
Note: See TracChangeset for help on using the changeset viewer.