Changeset beb9336 in mainline for uspace/srv/fs/ext4fs/ext4fs_ops.c


Ignore:
Timestamp:
2012-08-24T14:07:52Z (12 years ago)
Author:
Frantisek Princ <frantisek.princ@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
041ab64
Parents:
bd29f9c9 (diff), db81577 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge with mainline

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/fs/ext4fs/ext4fs_ops.c

    rbd29f9c9 rbeb9336  
    2929/** @addtogroup fs
    3030 * @{
    31  */
    32 
     31 */
    3332/**
    34  * @file        ext4fs_ops.c
    35  * @brief       VFS operations for EXT4 filesystem.
     33 * @file  ext4fs_ops.c
     34 * @brief VFS operations for ext4 filesystem.
    3635 */
    3736
     
    4241#include <macros.h>
    4342#include <malloc.h>
    44 #include <string.h>
    4543#include <adt/hash_table.h>
    4644#include <ipc/loc.h>
     
    4846#include "../../vfs/vfs.h"
    4947
    50 #define EXT4FS_NODE(node)       ((node) ? (ext4fs_node_t *) (node)->data : NULL)
    51 
    52 #define OPEN_NODES_KEYS 2
    53 #define OPEN_NODES_DEV_HANDLE_KEY 0
    54 #define OPEN_NODES_INODE_KEY 1
    55 #define OPEN_NODES_BUCKETS 256
     48#define EXT4FS_NODE(node) \
     49        ((node) ? (ext4fs_node_t *) (node)->data : NULL)
     50
     51#define OPEN_NODES_KEYS  2
     52
     53#define OPEN_NODES_DEV_HANDLE_KEY  0
     54#define OPEN_NODES_INODE_KEY       1
     55
     56#define OPEN_NODES_BUCKETS  256
    5657
    5758/**
     
    8788static int ext4fs_node_put_core(ext4fs_node_t *);
    8889
    89 /* Forward declarations of EXT4 libfs operations. */
     90/* Forward declarations of ext4 libfs operations. */
    9091
    9192static int ext4fs_root_get(fs_node_t **, service_id_t);
     
    122123/** Compare given item with values in hash table.
    123124 *
    124  * @return      bool result of compare operation
    125125 */
    126126static int open_nodes_compare(unsigned long key[], hash_count_t keys,
    127127    link_t *item)
    128128{
    129         ext4fs_node_t *enode = hash_table_get_instance(item, ext4fs_node_t, link);
    130129        assert(keys > 0);
     130       
     131        ext4fs_node_t *enode =
     132            hash_table_get_instance(item, ext4fs_node_t, link);
     133       
    131134        if (enode->instance->service_id !=
    132             ((service_id_t) key[OPEN_NODES_DEV_HANDLE_KEY])) {
     135            ((service_id_t) key[OPEN_NODES_DEV_HANDLE_KEY]))
    133136                return false;
    134         }
    135         if (keys == 1) {
     137       
     138        if (keys == 1)
    136139                return true;
    137         }
     140       
    138141        assert(keys == 2);
     142       
    139143        return (enode->inode_ref->index == key[OPEN_NODES_INODE_KEY]);
    140144}
     
    154158};
    155159
    156 
    157160/** Basic initialization of the driver.
    158161 *
    159  * There is only needed to create hash table for storing open nodes.
    160  *
    161  * @return      error code
     162 * This is only needed to create the hash table
     163 * for storing open nodes.
     164 *
     165 * @return Error code
     166 *
    162167 */
    163168int ext4fs_global_init(void)
    164169{
    165170        if (!hash_table_create(&open_nodes, OPEN_NODES_BUCKETS,
    166             OPEN_NODES_KEYS, &open_nodes_ops)) {
     171            OPEN_NODES_KEYS, &open_nodes_ops))
    167172                return ENOMEM;
    168         }
     173       
    169174        return EOK;
    170175}
     
    172177/* Finalization of the driver.
    173178 *
    174  * There is only needed to destroy hash table.
    175  *
    176  * @return      error code
     179 * This is only needed to destroy the hash table.
     180 *
     181 * @return Error code
    177182 */
    178183int ext4fs_global_fini(void)
     
    182187}
    183188
    184 
    185189/*
    186  * EXT4 libfs operations.
     190 * Ext4 libfs operations.
    187191 */
    188192
    189193/** Get instance from internal table by service_id.
    190194 *
    191  * @param service_id    device identifier
    192  * @param inst          output instance if successful operation
    193  * @return              error code
     195 * @param service_id Device identifier
     196 * @param inst       Output instance if successful operation
     197 *
     198 * @return Error code
     199 *
    194200 */
    195201int ext4fs_instance_get(service_id_t service_id, ext4fs_instance_t **inst)
    196202{
    197203        fibril_mutex_lock(&instance_list_mutex);
    198 
     204       
    199205        if (list_empty(&instance_list)) {
    200206                fibril_mutex_unlock(&instance_list_mutex);
    201207                return EINVAL;
    202208        }
    203 
    204         ext4fs_instance_t *tmp;
     209       
    205210        list_foreach(instance_list, link) {
    206                 tmp = list_get_instance(link, ext4fs_instance_t, link);
    207 
     211                ext4fs_instance_t *tmp =
     212                    list_get_instance(link, ext4fs_instance_t, link);
     213               
    208214                if (tmp->service_id == service_id) {
    209215                        *inst = tmp;
     
    212218                }
    213219        }
    214 
     220       
    215221        fibril_mutex_unlock(&instance_list_mutex);
    216222        return EINVAL;
    217223}
    218224
    219 
    220225/** Get root node of filesystem specified by service_id.
    221226 *
    222  * @param rfn           output pointer to loaded node
    223  * @param service_id    device to load root node from
    224  * @return              error code
     227 * @param rfn        Output pointer to loaded node
     228 * @param service_id Device to load root node from
     229 *
     230 * @return Error code
     231 *
    225232 */
    226233int ext4fs_root_get(fs_node_t **rfn, service_id_t service_id)
     
    233240 * If match is found, load and return matching node.
    234241 *
    235  * @param rfn           output pointer to node if operation successful
    236  * @param pfn           parent directory node
    237  * @param component     name to check directory for
    238  * @return              error code
     242 * @param rfn       Output pointer to node if operation successful
     243 * @param pfn       Parent directory node
     244 * @param component Name to check directory for
     245 *
     246 * @return Error code
     247 *
    239248 */
    240249int ext4fs_match(fs_node_t **rfn, fs_node_t *pfn, const char *component)
    241250{
    242         int rc;
    243 
    244251        ext4fs_node_t *eparent = EXT4FS_NODE(pfn);
    245252        ext4_filesystem_t *fs = eparent->instance->filesystem;
    246 
     253       
    247254        if (!ext4_inode_is_type(fs->superblock, eparent->inode_ref->inode,
    248             EXT4_INODE_MODE_DIRECTORY)) {
     255            EXT4_INODE_MODE_DIRECTORY))
    249256                return ENOTDIR;
    250         }
    251 
     257       
    252258        /* Try to find entry */
    253259        ext4_directory_search_result_t result;
    254         rc = ext4_directory_find_entry(&result, eparent->inode_ref, component);
     260        int rc = ext4_directory_find_entry(&result, eparent->inode_ref,
     261            component);
    255262        if (rc != EOK) {
    256263                if (rc == ENOENT) {
     
    258265                        return EOK;
    259266                }
    260                 return rc;
    261         }
    262 
     267               
     268                return rc;
     269        }
     270       
    263271        /* Load node from search result */
    264272        uint32_t inode = ext4_directory_entry_ll_get_inode(result.dentry);
    265273        rc = ext4fs_node_get_core(rfn, eparent->instance, inode);
    266         if (rc != EOK) {
    267                 return rc;
    268         }
    269 
     274        if (rc != EOK)
     275                return rc;
     276       
    270277        /* Destroy search result structure */
    271         rc = ext4_directory_destroy_result(&result);
    272         if (rc != EOK) {
    273                 return rc;
    274         }
    275 
    276         return EOK;
     278        return ext4_directory_destroy_result(&result);
    277279}
    278280
     
    281283 * It's wrapper for node_put_core operation
    282284 *
    283  * @param rfn           output pointer to loaded node if operation successful
    284  * @param service_id    device identifier
    285  * @param index         node index (here i-node number)
    286  * @return              error code
     285 * @param rfn        Output pointer to loaded node if operation successful
     286 * @param service_id Device identifier
     287 * @param index      Node index (here i-node number)
     288 *
     289 * @return Error code
     290 *
    287291 */
    288292int ext4fs_node_get(fs_node_t **rfn, service_id_t service_id, fs_index_t index)
    289293{
    290         int rc;
    291 
    292294        ext4fs_instance_t *inst;
    293         rc = ext4fs_instance_get(service_id, &inst);
    294         if (rc != EOK) {
    295                 return rc;
    296         }
    297 
     295        int rc = ext4fs_instance_get(service_id, &inst);
     296        if (rc != EOK)
     297                return rc;
     298       
    298299        return ext4fs_node_get_core(rfn, inst, index);
    299300}
     
    301302/** Main function for getting node from the filesystem.
    302303 *
    303  * @param rfn           output point to loaded node if operation successful
    304  * @param inst          instance of filesystem
    305  * @param index         index of node (i-node number)
    306  * @return              error code
     304 * @param rfn   Output point to loaded node if operation successful
     305 * @param inst  Instance of filesystem
     306 * @param index Index of node (i-node number)
     307 *
     308 * @return Error code
     309 *
    307310 */
    308311int ext4fs_node_get_core(fs_node_t **rfn, ext4fs_instance_t *inst,
    309                 fs_index_t index)
    310 {
    311         int rc;
    312 
     312    fs_index_t index)
     313{
    313314        fibril_mutex_lock(&open_nodes_lock);
    314 
     315       
    315316        /* Check if the node is not already open */
    316317        unsigned long key[] = {
    317318                [OPEN_NODES_DEV_HANDLE_KEY] = inst->service_id,
    318                 [OPEN_NODES_INODE_KEY] = index,
     319                [OPEN_NODES_INODE_KEY] = index
    319320        };
    320 
     321       
    321322        link_t *already_open = hash_table_find(&open_nodes, key);
    322323        ext4fs_node_t *enode = NULL;
     
    325326                *rfn = enode->fs_node;
    326327                enode->references++;
    327 
     328               
    328329                fibril_mutex_unlock(&open_nodes_lock);
    329330                return EOK;
    330331        }
    331 
     332       
    332333        /* Prepare new enode */
    333334        enode = malloc(sizeof(ext4fs_node_t));
     
    336337                return ENOMEM;
    337338        }
    338 
     339       
    339340        /* Prepare new fs_node and initialize */
    340341        fs_node_t *fs_node = malloc(sizeof(fs_node_t));
     
    344345                return ENOMEM;
    345346        }
     347       
    346348        fs_node_initialize(fs_node);
    347 
     349       
    348350        /* Load i-node from filesystem */
    349351        ext4_inode_ref_t *inode_ref;
    350         rc = ext4_filesystem_get_inode_ref(inst->filesystem, index, &inode_ref);
     352        int rc = ext4_filesystem_get_inode_ref(inst->filesystem, index,
     353            &inode_ref);
    351354        if (rc != EOK) {
    352355                free(enode);
     
    355358                return rc;
    356359        }
    357 
     360       
    358361        /* Initialize enode */
    359362        enode->inode_ref = inode_ref;
     
    362365        enode->fs_node = fs_node;
    363366        link_initialize(&enode->link);
    364 
     367       
    365368        fs_node->data = enode;
    366369        *rfn = fs_node;
    367 
     370       
    368371        hash_table_insert(&open_nodes, key, &enode->link);
    369372        inst->open_nodes_count++;
    370 
     373       
    371374        fibril_mutex_unlock(&open_nodes_lock);
    372 
     375       
    373376        return EOK;
    374377}
     
    376379/** Put previously loaded node.
    377380 *
    378  * @param enode         node to put back
    379  * @return              error code
     381 * @param enode Node to put back
     382 *
     383 * @return Error code
     384 *
    380385 */
    381386int ext4fs_node_put_core(ext4fs_node_t *enode)
    382387{
    383         int rc;
    384388        unsigned long key[] = {
    385389                [OPEN_NODES_DEV_HANDLE_KEY] = enode->instance->service_id,
    386                 [OPEN_NODES_INODE_KEY] = enode->inode_ref->index,
     390                [OPEN_NODES_INODE_KEY] = enode->inode_ref->index
    387391        };
    388 
     392       
    389393        hash_table_remove(&open_nodes, key, OPEN_NODES_KEYS);
    390394        assert(enode->instance->open_nodes_count > 0);
    391395        enode->instance->open_nodes_count--;
    392 
     396       
    393397        /* Put inode back in filesystem */
    394         rc = ext4_filesystem_put_inode_ref(enode->inode_ref);
    395         if (rc != EOK) {
    396                 return rc;
    397         }
    398 
     398        int rc = ext4_filesystem_put_inode_ref(enode->inode_ref);
     399        if (rc != EOK)
     400                return rc;
     401       
    399402        /* Destroy data structure */
    400403        free(enode->fs_node);
    401404        free(enode);
    402 
     405       
    403406        return EOK;
    404407}
    405408
    406 
    407409/** Open node.
    408410 *
    409411 * This operation is stateless in this driver.
    410412 *
    411  * @param fn    node to open
    412  * @return      error code (EOK)
     413 * @param fn Node to open
     414 *
     415 * @return EOK
     416 *
    413417 */
    414418int ext4fs_node_open(fs_node_t *fn)
     
    418422}
    419423
    420 
    421424/** Put previously loaded node.
    422425 *
    423  * It's wrapper for node_put_core operation
    424  *
    425  * @param fn    node to put back
    426  * @return      error code
     426 * A wrapper for node_put_core operation
     427 *
     428 * @param fn Node to put back
     429 * @return Error code
     430 *
    427431 */
    428432int ext4fs_node_put(fs_node_t *fn)
    429433{
    430         int rc;
    431 
    432434        fibril_mutex_lock(&open_nodes_lock);
    433 
     435       
    434436        ext4fs_node_t *enode = EXT4FS_NODE(fn);
    435437        assert(enode->references > 0);
    436438        enode->references--;
    437439        if (enode->references == 0) {
    438                 rc = ext4fs_node_put_core(enode);
     440                int rc = ext4fs_node_put_core(enode);
    439441                if (rc != EOK) {
    440442                        fibril_mutex_unlock(&open_nodes_lock);
     
    442444                }
    443445        }
    444 
     446       
    445447        fibril_mutex_unlock(&open_nodes_lock);
    446 
     448       
    447449        return EOK;
    448450}
    449451
    450 
    451452/** Create new node in filesystem.
    452453 *
    453  * @param rfn           output pointer to newly created node if successful
    454  * @param service_id    device identifier, where the filesystem is
    455  * @param flags         flags for specification of new node parameters
    456  * @return              error code
     454 * @param rfn        Output pointer to newly created node if successful
     455 * @param service_id Device identifier, where the filesystem is
     456 * @param flags      Flags for specification of new node parameters
     457 *
     458 * @return Error code
     459 *
    457460 */
    458461int ext4fs_create_node(fs_node_t **rfn, service_id_t service_id, int flags)
    459462{
    460         int rc;
    461 
    462463        /* Allocate enode */
    463464        ext4fs_node_t *enode;
    464465        enode = malloc(sizeof(ext4fs_node_t));
    465         if (enode == NULL) {
     466        if (enode == NULL)
    466467                return ENOMEM;
    467         }
    468 
     468       
    469469        /* Allocate fs_node */
    470470        fs_node_t *fs_node;
     
    474474                return ENOMEM;
    475475        }
    476 
     476       
    477477        /* Load instance */
    478478        ext4fs_instance_t *inst;
    479         rc = ext4fs_instance_get(service_id, &inst);
     479        int rc = ext4fs_instance_get(service_id, &inst);
    480480        if (rc != EOK) {
    481481                free(enode);
     
    483483                return rc;
    484484        }
    485 
     485       
    486486        /* Allocate new i-node in filesystem */
    487487        ext4_inode_ref_t *inode_ref;
     
    492492                return rc;
    493493        }
    494 
     494       
    495495        /* Do some interconnections in references */
    496496        enode->inode_ref = inode_ref;
    497497        enode->instance = inst;
    498498        enode->references = 1;
    499 
     499       
    500500        link_initialize(&enode->link);
    501 
     501       
    502502        unsigned long key[] = {
    503503                [OPEN_NODES_DEV_HANDLE_KEY] = inst->service_id,
    504                 [OPEN_NODES_INODE_KEY] = inode_ref->index,
     504                [OPEN_NODES_INODE_KEY] = inode_ref->index
    505505        };
    506 
     506       
    507507        fibril_mutex_lock(&open_nodes_lock);
    508508        hash_table_insert(&open_nodes, key, &enode->link);
    509509        fibril_mutex_unlock(&open_nodes_lock);
    510510        inst->open_nodes_count++;
    511 
     511       
    512512        enode->inode_ref->dirty = true;
    513 
     513       
    514514        fs_node_initialize(fs_node);
    515515        fs_node->data = enode;
    516516        enode->fs_node = fs_node;
    517517        *rfn = fs_node;
    518 
     518       
    519519        return EOK;
    520520}
    521521
    522 
    523522/** Destroy existing node.
    524523 *
    525  * @param fs    node to destroy
    526  * @return      error code
     524 * @param fs Node to destroy
     525 *
     526 * @return Error code
     527 *
    527528 */
    528529int ext4fs_destroy_node(fs_node_t *fn)
    529530{
    530         int rc;
    531 
    532531        /* If directory, check for children */
    533532        bool has_children;
    534         rc = ext4fs_has_children(&has_children, fn);
     533        int rc = ext4fs_has_children(&has_children, fn);
    535534        if (rc != EOK) {
    536535                ext4fs_node_put(fn);
    537536                return rc;
    538537        }
    539 
     538       
    540539        if (has_children) {
    541540                ext4fs_node_put(fn);
    542541                return EINVAL;
    543542        }
    544 
     543       
    545544        ext4fs_node_t *enode = EXT4FS_NODE(fn);
    546545        ext4_inode_ref_t *inode_ref = enode->inode_ref;
    547 
     546       
    548547        /* Release data blocks */
    549548        rc = ext4_filesystem_truncate_inode(inode_ref, 0);
     
    552551                return rc;
    553552        }
    554 
    555         // TODO set real deletion time when it will be supported, temporary set fake time
    556 //      time_t now = time(NULL);
     553       
     554        /*
     555         * TODO: Sset real deletion time when it will be supported.
     556         * Temporary set fake deletion time.
     557         */
    557558        ext4_inode_set_deletion_time(inode_ref->inode, 0xdeadbeef);
    558559        inode_ref->dirty = true;
    559 
     560       
    560561        /* Free inode */
    561562        rc = ext4_filesystem_free_inode(inode_ref);
     
    564565                return rc;
    565566        }
    566 
     567       
    567568        return ext4fs_node_put(fn);
    568569}
    569570
    570 
    571571/** Link the specfied node to directory.
    572572 *
    573  * @param pfn           parent node to link in
    574  * @param cfn           node to be linked
    575  * @param name          name which will be assigned to directory entry
    576  * @return              error code
     573 * @param pfn  Parent node to link in
     574 * @param cfn  Node to be linked
     575 * @param name Name which will be assigned to directory entry
     576 *
     577 * @return Error code
     578 *
    577579 */
    578580int ext4fs_link(fs_node_t *pfn, fs_node_t *cfn, const char *name)
    579581{
    580         int rc;
    581 
    582582        /* Check maximum name length */
    583         if (strlen(name) > EXT4_DIRECTORY_FILENAME_LEN) {
     583        if (str_size(name) > EXT4_DIRECTORY_FILENAME_LEN)
    584584                return ENAMETOOLONG;
    585         }
     585       
    586586        ext4fs_node_t *parent = EXT4FS_NODE(pfn);
    587587        ext4fs_node_t *child = EXT4FS_NODE(cfn);
    588588        ext4_filesystem_t *fs = parent->instance->filesystem;
    589 
     589       
    590590        /* Add entry to parent directory */
    591         rc = ext4_directory_add_entry(parent->inode_ref, name, child->inode_ref);
    592         if (rc != EOK) {
    593                 return rc;
    594         }
    595 
     591        int rc = ext4_directory_add_entry(parent->inode_ref, name,
     592            child->inode_ref);
     593        if (rc != EOK)
     594                return rc;
     595       
    596596        /* Fill new dir -> add '.' and '..' entries */
    597         if (ext4_inode_is_type(fs->superblock, child->inode_ref->inode, EXT4_INODE_MODE_DIRECTORY)) {
    598 
    599                 rc = ext4_directory_add_entry(child->inode_ref, ".", child->inode_ref);
     597        if (ext4_inode_is_type(fs->superblock, child->inode_ref->inode,
     598            EXT4_INODE_MODE_DIRECTORY)) {
     599                rc = ext4_directory_add_entry(child->inode_ref, ".",
     600                    child->inode_ref);
    600601                if (rc != EOK) {
    601602                        ext4_directory_remove_entry(parent->inode_ref, name);
    602603                        return rc;
    603604                }
    604 
    605                 rc = ext4_directory_add_entry(child->inode_ref, "..", parent->inode_ref);
     605               
     606                rc = ext4_directory_add_entry(child->inode_ref, "..",
     607                    parent->inode_ref);
    606608                if (rc != EOK) {
    607609                        ext4_directory_remove_entry(parent->inode_ref, name);
     
    609611                        return rc;
    610612                }
    611 
     613               
    612614                /* Initialize directory index if supported */
    613                 if (ext4_superblock_has_feature_compatible(
    614                                 fs->superblock, EXT4_FEATURE_COMPAT_DIR_INDEX)) {
    615 
     615                if (ext4_superblock_has_feature_compatible(fs->superblock,
     616                    EXT4_FEATURE_COMPAT_DIR_INDEX)) {
    616617                        rc = ext4_directory_dx_init(child->inode_ref);
    617                         if (rc != EOK) {
     618                        if (rc != EOK)
    618619                                return rc;
    619                         }
    620 
    621                         ext4_inode_set_flag(child->inode_ref->inode, EXT4_INODE_FLAG_INDEX);
     620                       
     621                        ext4_inode_set_flag(child->inode_ref->inode,
     622                            EXT4_INODE_FLAG_INDEX);
    622623                        child->inode_ref->dirty = true;
    623624                }
    624 
    625                 uint16_t parent_links = ext4_inode_get_links_count(parent->inode_ref->inode);
     625       
     626                uint16_t parent_links =
     627                    ext4_inode_get_links_count(parent->inode_ref->inode);
    626628                parent_links++;
    627629                ext4_inode_set_links_count(parent->inode_ref->inode, parent_links);
    628 
     630               
    629631                parent->inode_ref->dirty = true;
    630 
    631         }
    632 
    633         uint16_t child_links = ext4_inode_get_links_count(child->inode_ref->inode);
     632        }
     633       
     634        uint16_t child_links =
     635            ext4_inode_get_links_count(child->inode_ref->inode);
    634636        child_links++;
    635637        ext4_inode_set_links_count(child->inode_ref->inode, child_links);
    636 
     638       
    637639        child->inode_ref->dirty = true;
    638 
     640       
    639641        return EOK;
    640642}
    641643
    642 
    643644/** Unlink node from specified directory.
    644645 *
    645  * @param pfn           parent node to delete node from
    646  * @param cfn           child node to be unlinked from directory
    647  * @param name          name of entry that will be removed
    648  * @return              error code
     646 * @param pfn  Parent node to delete node from
     647 * @param cfn  Child node to be unlinked from directory
     648 * @param name Name of entry that will be removed
     649 *
     650 * @return Error code
     651 *
    649652 */
    650653int ext4fs_unlink(fs_node_t *pfn, fs_node_t *cfn, const char *name)
    651654{
    652         int rc;
    653 
    654655        bool has_children;
    655         rc = ext4fs_has_children(&has_children, cfn);
    656         if (rc != EOK) {
    657                 return rc;
    658         }
    659 
     656        int rc = ext4fs_has_children(&has_children, cfn);
     657        if (rc != EOK)
     658                return rc;
     659       
    660660        /* Cannot unlink non-empty node */
    661         if (has_children) {
     661        if (has_children)
    662662                return ENOTEMPTY;
    663         }
    664 
     663       
    665664        /* Remove entry from parent directory */
    666665        ext4_inode_ref_t *parent = EXT4FS_NODE(pfn)->inode_ref;
    667666        rc = ext4_directory_remove_entry(parent, name);
    668         if (rc != EOK) {
    669                 return rc;
    670         }
    671 
     667        if (rc != EOK)
     668                return rc;
     669       
    672670        /* Decrement links count */
    673         ext4_inode_ref_t * child_inode_ref = EXT4FS_NODE(cfn)->inode_ref;
    674 
    675         uint32_t lnk_count = ext4_inode_get_links_count(child_inode_ref->inode);
     671        ext4_inode_ref_t *child_inode_ref = EXT4FS_NODE(cfn)->inode_ref;
     672       
     673        uint32_t lnk_count =
     674            ext4_inode_get_links_count(child_inode_ref->inode);
    676675        lnk_count--;
    677 
     676       
    678677        /* If directory - handle links from parent */
    679         if (lnk_count <= 1 && ext4fs_is_directory(cfn)) {
    680 
     678        if ((lnk_count <= 1) && (ext4fs_is_directory(cfn))) {
    681679                assert(lnk_count == 1);
     680               
    682681                lnk_count--;
    683 
     682               
    684683                ext4_inode_ref_t *parent_inode_ref = EXT4FS_NODE(pfn)->inode_ref;
    685 
     684               
    686685                uint32_t parent_lnk_count = ext4_inode_get_links_count(
    687                                 parent_inode_ref->inode);
    688 
     686                    parent_inode_ref->inode);
     687               
    689688                parent_lnk_count--;
    690689                ext4_inode_set_links_count(parent_inode_ref->inode, parent_lnk_count);
    691 
     690               
    692691                parent->dirty = true;
    693692        }
    694693
    695         // TODO set timestamps for parent (when we have wall-clock time)
    696 //      time_t now = time(NULL);
    697 //      ext4_inode_set_change_inode_time(parent->inode, (uint32_t)now);
    698 //      ext4_inode_set_modification_time(parent->inode, (uint32_t)now);
    699 //      parent->dirty = true;
    700 
    701         // TODO set timestamp for inode
    702 //      ext4_inode_set_change_inode_time(child_inode_ref->inode, (uint32_t)now);
     694        /*
     695         * TODO: Update timestamps of the parent
     696         * (when we have wall-clock time).
     697         *
     698         * ext4_inode_set_change_inode_time(parent->inode, (uint32_t) now);
     699         * ext4_inode_set_modification_time(parent->inode, (uint32_t) now);
     700         * parent->dirty = true;
     701         */
     702       
     703        /*
     704         * TODO: Update timestamp for inode.
     705         *
     706         * ext4_inode_set_change_inode_time(child_inode_ref->inode,
     707         *     (uint32_t) now);
     708         */
     709       
    703710        ext4_inode_set_links_count(child_inode_ref->inode, lnk_count);
    704711        child_inode_ref->dirty = true;
    705 
     712       
    706713        return EOK;
    707714}
    708715
    709 
    710716/** Check if specified node has children.
    711  * 
     717 *
    712718 * For files is response allways false and check is executed only for directories.
    713719 *
    714  * @param has_children          output value for response
    715  * @param fn                    node to check
    716  * @return                      error code
     720 * @param has_children Output value for response
     721 * @param fn           Node to check
     722 *
     723 * @return Error code
     724 *
    717725 */
    718726int ext4fs_has_children(bool *has_children, fs_node_t *fn)
    719727{
    720         int rc;
    721 
    722728        ext4fs_node_t *enode = EXT4FS_NODE(fn);
    723729        ext4_filesystem_t *fs = enode->instance->filesystem;
    724 
     730       
    725731        /* Check if node is directory */
    726732        if (!ext4_inode_is_type(fs->superblock, enode->inode_ref->inode,
     
    729735                return EOK;
    730736        }
    731 
     737       
    732738        ext4_directory_iterator_t it;
    733         rc = ext4_directory_iterator_init(&it, enode->inode_ref, 0);
    734         if (rc != EOK) {
    735                 return rc;
    736         }
    737 
     739        int rc = ext4_directory_iterator_init(&it, enode->inode_ref, 0);
     740        if (rc != EOK)
     741                return rc;
     742       
    738743        /* Find a non-empty directory entry */
    739744        bool found = false;
    740745        while (it.current != NULL) {
    741746                if (it.current->inode != 0) {
    742                         uint16_t name_size = ext4_directory_entry_ll_get_name_length(fs->superblock,
    743                                 it.current);
     747                        uint16_t name_size =
     748                            ext4_directory_entry_ll_get_name_length(fs->superblock,
     749                            it.current);
    744750                        if (!ext4fs_is_dots(it.current->name, name_size)) {
    745751                                found = true;
     
    747753                        }
    748754                }
    749 
     755               
    750756                rc = ext4_directory_iterator_next(&it);
    751757                if (rc != EOK) {
     
    754760                }
    755761        }
    756 
     762       
    757763        rc = ext4_directory_iterator_fini(&it);
    758         if (rc != EOK) {
    759                 return rc;
    760         }
    761 
     764        if (rc != EOK)
     765                return rc;
     766       
    762767        *has_children = found;
    763 
     768       
    764769        return EOK;
    765770}
    766771
    767 
    768772/** Unpack index number from node.
    769  *     
    770  * @param fn    node to load index from
    771  * @return      index number of i-node
     773 *
     774 * @param fn Node to load index from
     775 *
     776 * @return Index number of i-node
     777 *
    772778 */
    773779fs_index_t ext4fs_index_get(fs_node_t *fn)
     
    777783}
    778784
    779 
    780785/** Get real size of file / directory.
    781786 *
    782  * @param fn    node to get size of
    783  * @return      real size of node
     787 * @param fn Node to get size of
     788 *
     789 * @return Real size of node
     790 *
    784791 */
    785792aoff64_t ext4fs_size_get(fs_node_t *fn)
     
    790797}
    791798
    792 
    793799/** Get number of links to specified node.
    794800 *
    795  * @param fn    node to get links to
    796  * @return      number of links
     801 * @param fn Node to get links to
     802 *
     803 * @return Number of links
     804 *
    797805 */
    798806unsigned ext4fs_lnkcnt_get(fs_node_t *fn)
     
    800808        ext4fs_node_t *enode = EXT4FS_NODE(fn);
    801809        uint32_t lnkcnt = ext4_inode_get_links_count(enode->inode_ref->inode);
    802 
     810       
    803811        if (ext4fs_is_directory(fn)) {
    804                 if (lnkcnt > 1) {
     812                if (lnkcnt > 1)
    805813                        return 1;
    806                 } else {
     814                else
    807815                        return 0;
    808                 }
    809         }
    810 
     816        }
     817       
    811818        /* For regular files return real links count */
    812819        return lnkcnt;
    813820}
    814821
    815 
    816822/** Check if node is directory.
    817823 *
    818  * @param fn    node to check
    819  * @return      result of check
     824 * @param fn Node to check
     825 *
     826 * @return Result of check
     827 *
    820828 */
    821829bool ext4fs_is_directory(fs_node_t *fn)
     
    823831        ext4fs_node_t *enode = EXT4FS_NODE(fn);
    824832        ext4_superblock_t *sb = enode->instance->filesystem->superblock;
    825         return ext4_inode_is_type(
    826                         sb, enode->inode_ref->inode, EXT4_INODE_MODE_DIRECTORY);
    827 }
    828 
     833       
     834        return ext4_inode_is_type(sb, enode->inode_ref->inode,
     835            EXT4_INODE_MODE_DIRECTORY);
     836}
    829837
    830838/** Check if node is regular file.
    831839 *
    832  * @param fn    node to check
    833  * @return      result of check
     840 * @param fn Node to check
     841 *
     842 * @return Result of check
     843 *
    834844 */
    835845bool ext4fs_is_file(fs_node_t *fn)
     
    837847        ext4fs_node_t *enode = EXT4FS_NODE(fn);
    838848        ext4_superblock_t *sb = enode->instance->filesystem->superblock;
    839         return ext4_inode_is_type(
    840                         sb, enode->inode_ref->inode, EXT4_INODE_MODE_FILE);
     849       
     850        return ext4_inode_is_type(sb, enode->inode_ref->inode,
     851            EXT4_INODE_MODE_FILE);
    841852}
    842853
    843854/** Extract device identifier from node.
    844855 *
    845  * @param node  node to extract id from
    846  * @return      id of device, where is the filesystem
     856 * @param node Node to extract id from
     857 *
     858 * @return id of device, where is the filesystem
     859 *
    847860 */
    848861service_id_t ext4fs_service_get(fs_node_t *fn)
     
    874887};
    875888
    876 
    877889/*
    878890 * VFS operations.
    879891 */
    880892
    881 /** Mount operation. 
     893/** Mount operation.
    882894 *
    883895 * Try to mount specified filesystem from device.
    884  *
    885  * @param service_id    identifier of device
    886  * @param opts          mount options
    887  * @param index         output value - index of root node
    888  * @param size          output value - size of root node
    889  * @param lnkcnt        output value - link count of root node
    890  * @return              error code
     896 *
     897 * @param service_id Identifier of device
     898 * @param opts       Mount options
     899 * @param index      Output value - index of root node
     900 * @param size       Output value - size of root node
     901 * @param lnkcnt     Output value - link count of root node
     902 *
     903 * @return Error code
     904 *
    891905 */
    892906static int ext4fs_mounted(service_id_t service_id, const char *opts,
    893    fs_index_t *index, aoff64_t *size, unsigned *lnkcnt)
    894 {
    895         int rc;
    896 
     907    fs_index_t *index, aoff64_t *size, unsigned *lnkcnt)
     908{
    897909        /* Allocate libext4 filesystem structure */
    898         ext4_filesystem_t *fs;
    899         fs = (ext4_filesystem_t *) malloc(sizeof(ext4_filesystem_t));
    900         if (fs == NULL) {
     910        ext4_filesystem_t *fs = (ext4_filesystem_t *)
     911            malloc(sizeof(ext4_filesystem_t));
     912        if (fs == NULL)
    901913                return ENOMEM;
    902         }
    903 
     914       
    904915        /* Allocate instance structure */
    905         ext4fs_instance_t *inst;
    906         inst = (ext4fs_instance_t *) malloc(sizeof(ext4fs_instance_t));
     916        ext4fs_instance_t *inst = (ext4fs_instance_t *)
     917            malloc(sizeof(ext4fs_instance_t));
    907918        if (inst == NULL) {
    908919                free(fs);
    909920                return ENOMEM;
    910921        }
    911 
     922       
    912923        enum cache_mode cmode;
    913         if (str_cmp(opts, "wtcache") == 0) {
     924        if (str_cmp(opts, "wtcache") == 0)
    914925                cmode = CACHE_MODE_WT;
    915         } else {
     926        else
    916927                cmode = CACHE_MODE_WB;
    917         }
    918 
     928       
    919929        /* Initialize the filesystem */
    920         rc = ext4_filesystem_init(fs, service_id, cmode);
     930        int rc = ext4_filesystem_init(fs, service_id, cmode);
    921931        if (rc != EOK) {
    922932                free(fs);
     
    924934                return rc;
    925935        }
    926 
     936       
    927937        /* Do some sanity checking */
    928938        rc = ext4_filesystem_check_sanity(fs);
     
    933943                return rc;
    934944        }
    935 
     945       
    936946        /* Check flags */
    937947        bool read_only;
     
    943953                return rc;
    944954        }
    945 
     955       
    946956        /* Initialize instance */
    947957        link_initialize(&inst->link);
     
    949959        inst->filesystem = fs;
    950960        inst->open_nodes_count = 0;
    951 
     961       
    952962        /* Read root node */
    953963        fs_node_t *root_node;
     
    959969                return rc;
    960970        }
    961 
     971       
    962972        /* Add instance to the list */
    963973        fibril_mutex_lock(&instance_list_mutex);
    964974        list_append(&inst->link, &instance_list);
    965975        fibril_mutex_unlock(&instance_list_mutex);
    966 
     976       
    967977        ext4fs_node_t *enode = EXT4FS_NODE(root_node);
    968 
     978       
    969979        *index = EXT4_INODE_ROOT_INDEX;
    970980        *size = ext4_inode_get_size(fs->superblock, enode->inode_ref->inode);
    971981        *lnkcnt = 1;
    972 
     982       
    973983        ext4fs_node_put(root_node);
    974 
     984       
    975985        return EOK;
    976986}
     
    980990 * Correctly release the filesystem.
    981991 *
    982  * @param service_id    device to be unmounted
    983  * @return              error code
     992 * @param service_id Device to be unmounted
     993 *
     994 * @return Error code
     995 *
    984996 */
    985997static int ext4fs_unmounted(service_id_t service_id)
    986998{
    987         int rc;
    988 
    989999        ext4fs_instance_t *inst;
    990         rc = ext4fs_instance_get(service_id, &inst);
    991         if (rc != EOK) {
    992                 return rc;
    993         }
    994 
     1000        int rc = ext4fs_instance_get(service_id, &inst);
     1001        if (rc != EOK)
     1002                return rc;
     1003       
    9951004        fibril_mutex_lock(&open_nodes_lock);
    996 
     1005       
    9971006        if (inst->open_nodes_count != 0) {
    9981007                fibril_mutex_unlock(&open_nodes_lock);
    9991008                return EBUSY;
    10001009        }
    1001 
     1010       
    10021011        /* Remove the instance from the list */
    10031012        fibril_mutex_lock(&instance_list_mutex);
    10041013        list_remove(&inst->link);
    10051014        fibril_mutex_unlock(&instance_list_mutex);
    1006 
     1015       
    10071016        fibril_mutex_unlock(&open_nodes_lock);
    1008 
     1017       
    10091018        return ext4_filesystem_fini(inst->filesystem);
    10101019}
    10111020
    1012 
    10131021/** Read bytes from node.
    10141022 *
    1015  * @param service_id    device to read data from
    1016  * @param index         number of node to read from
    1017  * @param pos           position where the read should be started
    1018  * @param rbytes        output value, where the real size was returned
    1019  * @return              error code
    1020  */
    1021 static int ext4fs_read(service_id_t service_id, fs_index_t index,
    1022                 aoff64_t pos, size_t *rbytes)
    1023 {
    1024         int rc;
    1025 
     1023 * @param service_id Device to read data from
     1024 * @param index      Number of node to read from
     1025 * @param pos        Position where the read should be started
     1026 * @param rbytes     Output value, where the real size was returned
     1027 *
     1028 * @return Error code
     1029 *
     1030 */
     1031static int ext4fs_read(service_id_t service_id, fs_index_t index, aoff64_t pos,
     1032    size_t *rbytes)
     1033{
    10261034        /*
    10271035         * Receive the read request.
     
    10331041                return EINVAL;
    10341042        }
    1035 
     1043       
    10361044        ext4fs_instance_t *inst;
    1037         rc = ext4fs_instance_get(service_id, &inst);
     1045        int rc = ext4fs_instance_get(service_id, &inst);
    10381046        if (rc != EOK) {
    10391047                async_answer_0(callid, rc);
    10401048                return rc;
    10411049        }
    1042 
     1050       
    10431051        /* Load i-node */
    10441052        ext4_inode_ref_t *inode_ref;
     
    10481056                return rc;
    10491057        }
    1050 
     1058       
    10511059        /* Read from i-node by type */
    10521060        if (ext4_inode_is_type(inst->filesystem->superblock, inode_ref->inode,
    1053                         EXT4_INODE_MODE_FILE)) {
     1061            EXT4_INODE_MODE_FILE)) {
    10541062                rc = ext4fs_read_file(callid, pos, size, inst, inode_ref,
    1055                                 rbytes);
     1063                    rbytes);
    10561064        } else if (ext4_inode_is_type(inst->filesystem->superblock,
    1057                         inode_ref->inode, EXT4_INODE_MODE_DIRECTORY)) {
     1065            inode_ref->inode, EXT4_INODE_MODE_DIRECTORY)) {
    10581066                rc = ext4fs_read_directory(callid, pos, size, inst, inode_ref,
    1059                                 rbytes);
     1067                    rbytes);
    10601068        } else {
    10611069                /* Other inode types not supported */
     
    10631071                rc = ENOTSUP;
    10641072        }
    1065 
     1073       
    10661074        ext4_filesystem_put_inode_ref(inode_ref);
    1067 
     1075       
    10681076        return rc;
    10691077}
     
    10711079/** Check if filename is dot or dotdot (reserved names).
    10721080 *
    1073  * @param name          name to check
    1074  * @param name_size     length of string name
    1075  * @return              result of the check
     1081 * @param name      Name to check
     1082 * @param name_size Length of string name
     1083 *
     1084 * @return Result of the check
     1085 *
    10761086 */
    10771087bool ext4fs_is_dots(const uint8_t *name, size_t name_size)
    10781088{
    1079         if (name_size == 1 && name[0] == '.') {
     1089        if ((name_size == 1) && (name[0] == '.'))
    10801090                return true;
    1081         }
    1082 
    1083         if (name_size == 2 && name[0] == '.' && name[1] == '.') {
     1091       
     1092        if ((name_size == 2) && (name[0] == '.') && (name[1] == '.'))
    10841093                return true;
    1085         }
    1086 
     1094       
    10871095        return false;
    10881096}
     
    10901098/** Read data from directory.
    10911099 *
    1092  * @param callid        IPC id of call (for communication)
    1093  * @param pos           position to start reading from
    1094  * @param size          how many bytes to read
    1095  * @param inst          filesystem instance
    1096  * @param inode_ref     node to read data from
    1097  * @param rbytes        output value to return real number of bytes was read
    1098  * @return              error code
     1100 * @param callid    IPC id of call (for communication)
     1101 * @param pos       Position to start reading from
     1102 * @param size      How many bytes to read
     1103 * @param inst      Filesystem instance
     1104 * @param inode_ref Node to read data from
     1105 * @param rbytes    Output value to return real number of bytes was read
     1106 *
     1107 * @return Error code
     1108 *
    10991109 */
    11001110int ext4fs_read_directory(ipc_callid_t callid, aoff64_t pos, size_t size,
    11011111    ext4fs_instance_t *inst, ext4_inode_ref_t *inode_ref, size_t *rbytes)
    11021112{
    1103         int rc;
    1104 
    11051113        ext4_directory_iterator_t it;
    1106         rc = ext4_directory_iterator_init(&it, inode_ref, pos);
     1114        int rc = ext4_directory_iterator_init(&it, inode_ref, pos);
    11071115        if (rc != EOK) {
    11081116                async_answer_0(callid, rc);
    11091117                return rc;
    11101118        }
    1111 
    1112         /* Find next interesting directory entry.
     1119       
     1120        /*
     1121         * Find next interesting directory entry.
    11131122         * We want to skip . and .. entries
    11141123         * as these are not used in HelenOS
     
    11161125        bool found = false;
    11171126        while (it.current != NULL) {
    1118 
    1119                 if (it.current->inode == 0) {
     1127                if (it.current->inode == 0)
    11201128                        goto skip;
    1121                 }
    1122 
     1129               
    11231130                uint16_t name_size = ext4_directory_entry_ll_get_name_length(
    11241131                    inst->filesystem->superblock, it.current);
    1125 
    1126                 /* skip . and .. */
    1127                 if (ext4fs_is_dots(it.current->name, name_size)) {
     1132               
     1133                /* Skip . and .. */
     1134                if (ext4fs_is_dots(it.current->name, name_size))
    11281135                        goto skip;
    1129                 }
    1130 
    1131                 /* The on-disk entry does not contain \0 at the end
     1136               
     1137                /*
     1138                 * The on-disk entry does not contain \0 at the end
    11321139                 * end of entry name, so we copy it to new buffer
    11331140                 * and add the \0 at the end
    11341141                 */
    1135                 uint8_t *buf = malloc(name_size+1);
     1142                uint8_t *buf = malloc(name_size + 1);
    11361143                if (buf == NULL) {
    11371144                        ext4_directory_iterator_fini(&it);
     
    11391146                        return ENOMEM;
    11401147                }
     1148               
    11411149                memcpy(buf, &it.current->name, name_size);
    11421150                *(buf + name_size) = 0;
    11431151                found = true;
     1152               
    11441153                (void) async_data_read_finalize(callid, buf, name_size + 1);
    11451154                free(buf);
    11461155                break;
    1147 
     1156               
    11481157skip:
    11491158                rc = ext4_directory_iterator_next(&it);
     
    11541163                }
    11551164        }
    1156 
     1165       
    11571166        uint64_t next;
    11581167        if (found) {
    11591168                rc = ext4_directory_iterator_next(&it);
    1160                 if (rc != EOK) {
     1169                if (rc != EOK)
    11611170                        return rc;
    1162                 }
     1171               
    11631172                next = it.current_offset;
    11641173        }
    1165 
     1174       
    11661175        rc = ext4_directory_iterator_fini(&it);
    1167         if (rc != EOK) {
    1168                 return rc;
    1169         }
    1170 
     1176        if (rc != EOK)
     1177                return rc;
     1178       
    11711179        /* Prepare return values */
    11721180        if (found) {
     
    11791187}
    11801188
    1181 
    11821189/** Read data from file.
    11831190 *
    1184  * @param callid        IPC id of call (for communication)
    1185  * @param pos           position to start reading from
    1186  * @param size          how many bytes to read
    1187  * @param inst          filesystem instance
    1188  * @param inode_ref     node to read data from
    1189  * @param rbytes        output value to return real number of bytes was read
    1190  * @return              error code
     1191 * @param callid    IPC id of call (for communication)
     1192 * @param pos       Position to start reading from
     1193 * @param size      How many bytes to read
     1194 * @param inst      Filesystem instance
     1195 * @param inode_ref Node to read data from
     1196 * @param rbytes    Output value to return real number of bytes was read
     1197 *
     1198 * @return Error code
     1199 *
    11911200 */
    11921201int ext4fs_read_file(ipc_callid_t callid, aoff64_t pos, size_t size,
    11931202    ext4fs_instance_t *inst, ext4_inode_ref_t *inode_ref, size_t *rbytes)
    11941203{
    1195         int rc;
    1196 
    11971204        ext4_superblock_t *sb = inst->filesystem->superblock;
    11981205        uint64_t file_size = ext4_inode_get_size(sb, inode_ref->inode);
    1199 
     1206       
    12001207        if (pos >= file_size) {
    12011208                /* Read 0 bytes successfully */
     
    12041211                return EOK;
    12051212        }
    1206 
     1213       
    12071214        /* For now, we only read data from one block at a time */
    12081215        uint32_t block_size = ext4_superblock_get_block_size(sb);
     
    12101217        uint32_t offset_in_block = pos % block_size;
    12111218        uint32_t bytes = min(block_size - offset_in_block, size);
    1212 
     1219       
    12131220        /* Handle end of file */
    1214         if (pos + bytes > file_size) {
     1221        if (pos + bytes > file_size)
    12151222                bytes = file_size - pos;
    1216         }
    1217 
     1223       
    12181224        /* Get the real block number */
    12191225        uint32_t fs_block;
    1220         rc = ext4_filesystem_get_inode_data_block_index(inode_ref, file_block, &fs_block);
     1226        int rc = ext4_filesystem_get_inode_data_block_index(inode_ref,
     1227            file_block, &fs_block);
    12211228        if (rc != EOK) {
    12221229                async_answer_0(callid, rc);
    12231230                return rc;
    12241231        }
    1225 
    1226         /* Check for sparse file
     1232       
     1233        /*
     1234         * Check for sparse file.
    12271235         * If ext4_filesystem_get_inode_data_block_index returned
    12281236         * fs_block == 0, it means that the given block is not allocated for the
     
    12361244                        return ENOMEM;
    12371245                }
    1238 
     1246               
    12391247                memset(buffer, 0, bytes);
    1240 
     1248               
    12411249                async_data_read_finalize(callid, buffer, bytes);
    12421250                *rbytes = bytes;
    1243 
     1251               
    12441252                free(buffer);
    1245 
    12461253                return EOK;
    12471254        }
    1248 
     1255       
    12491256        /* Usual case - we need to read a block from device */
    12501257        block_t *block;
     
    12541261                return rc;
    12551262        }
    1256 
     1263       
    12571264        assert(offset_in_block + bytes <= block_size);
    12581265        async_data_read_finalize(callid, block->data + offset_in_block, bytes);
    1259 
     1266       
    12601267        rc = block_put(block);
    1261         if (rc != EOK) {
    1262                 return rc;
    1263         }
    1264 
     1268        if (rc != EOK)
     1269                return rc;
     1270       
    12651271        *rbytes = bytes;
    12661272        return EOK;
    12671273}
    12681274
    1269 
    12701275/** Write bytes to file
    12711276 *
    1272  * @param service_id    device identifier
    1273  * @param index         i-node number of file
    1274  * @param pos           position in file to start reading from
    1275  * @param wbytes        output value - real number of written bytes
    1276  * @param nsize         output value - new size of i-node
    1277  * @return              error code
    1278  */
    1279 static int ext4fs_write(service_id_t service_id, fs_index_t index,
    1280                 aoff64_t pos, size_t *wbytes, aoff64_t *nsize)
    1281 {
    1282         int rc;
    1283 
     1277 * @param service_id Device identifier
     1278 * @param index      I-node number of file
     1279 * @param pos        Position in file to start reading from
     1280 * @param wbytes     Output value - real number of written bytes
     1281 * @param nsize      Output value - new size of i-node
     1282 *
     1283 * @return Error code
     1284 *
     1285 */
     1286static int ext4fs_write(service_id_t service_id, fs_index_t index, aoff64_t pos,
     1287    size_t *wbytes, aoff64_t *nsize)
     1288{
    12841289        fs_node_t *fn;
    1285         rc = ext4fs_node_get(&fn, service_id, index);
    1286         if (rc != EOK) {
    1287                 return rc;
    1288         }
    1289 
     1290        int rc = ext4fs_node_get(&fn, service_id, index);
     1291        if (rc != EOK)
     1292                return rc;
     1293       
    12901294        ipc_callid_t callid;
    12911295        size_t len;
    12921296        if (!async_data_write_receive(&callid, &len)) {
    1293                 rc = EINVAL;
     1297                ext4fs_node_put(fn);
     1298                async_answer_0(callid, EINVAL);
     1299                return EINVAL;
     1300        }
     1301       
     1302        ext4fs_node_t *enode = EXT4FS_NODE(fn);
     1303        ext4_filesystem_t *fs = enode->instance->filesystem;
     1304       
     1305        uint32_t block_size = ext4_superblock_get_block_size(fs->superblock);
     1306       
     1307        /* Prevent writing to more than one block */
     1308        uint32_t bytes = min(len, block_size - (pos % block_size));
     1309       
     1310        int flags = BLOCK_FLAGS_NONE;
     1311        if (bytes == block_size)
     1312                flags = BLOCK_FLAGS_NOREAD;
     1313       
     1314        uint32_t iblock =  pos / block_size;
     1315        uint32_t fblock;
     1316       
     1317        /* Load inode */
     1318        ext4_inode_ref_t *inode_ref = enode->inode_ref;
     1319        rc = ext4_filesystem_get_inode_data_block_index(inode_ref, iblock,
     1320            &fblock);
     1321        if (rc != EOK) {
    12941322                ext4fs_node_put(fn);
    12951323                async_answer_0(callid, rc);
    12961324                return rc;
    12971325        }
    1298 
    1299 
    1300         ext4fs_node_t *enode = EXT4FS_NODE(fn);
    1301         ext4_filesystem_t *fs = enode->instance->filesystem;
    1302 
    1303         uint32_t block_size = ext4_superblock_get_block_size(fs->superblock);
    1304 
    1305         /* Prevent writing to more than one block */
    1306         uint32_t bytes = min(len, block_size - (pos % block_size));
    1307 
    1308         int flags = BLOCK_FLAGS_NONE;
    1309         if (bytes == block_size) {
    1310                 flags = BLOCK_FLAGS_NOREAD;
    1311         }
    1312 
    1313         uint32_t iblock =  pos / block_size;
    1314         uint32_t fblock;
    1315 
    1316         /* Load inode */
    1317         ext4_inode_ref_t *inode_ref = enode->inode_ref;
    1318         rc = ext4_filesystem_get_inode_data_block_index(inode_ref, iblock, &fblock);
    1319         if (rc != EOK) {
    1320                 ext4fs_node_put(fn);
    1321                 async_answer_0(callid, rc);
    1322                 return rc;
    1323         }
    1324 
     1326       
    13251327        /* Check for sparse file */
    13261328        if (fblock == 0) {
    1327 
    1328                 if (ext4_superblock_has_feature_incompatible(
    1329                                 fs->superblock, EXT4_FEATURE_INCOMPAT_EXTENTS) &&
    1330                                 (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) {
    1331 
    1332                         uint32_t last_iblock = ext4_inode_get_size(fs->superblock, inode_ref->inode) / block_size;
     1329                if ((ext4_superblock_has_feature_incompatible(fs->superblock,
     1330                    EXT4_FEATURE_INCOMPAT_EXTENTS)) &&
     1331                    (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) {
     1332                        uint32_t last_iblock =
     1333                            ext4_inode_get_size(fs->superblock, inode_ref->inode) /
     1334                            block_size;
     1335                       
    13331336                        while (last_iblock < iblock) {
    1334                                 rc = ext4_extent_append_block(inode_ref, &last_iblock, &fblock, true);
     1337                                rc = ext4_extent_append_block(inode_ref, &last_iblock,
     1338                                    &fblock, true);
    13351339                                if (rc != EOK) {
    13361340                                        ext4fs_node_put(fn);
     
    13391343                                }
    13401344                        }
    1341 
    1342                         rc = ext4_extent_append_block(inode_ref, &last_iblock, &fblock, false);
     1345                       
     1346                        rc = ext4_extent_append_block(inode_ref, &last_iblock,
     1347                            &fblock, false);
    13431348                        if (rc != EOK) {
    13441349                                ext4fs_node_put(fn);
     
    13461351                                return rc;
    13471352                        }
    1348 
    13491353                } else {
    1350                         rc =  ext4_balloc_alloc_block(inode_ref, &fblock);
     1354                        rc = ext4_balloc_alloc_block(inode_ref, &fblock);
    13511355                        if (rc != EOK) {
    13521356                                ext4fs_node_put(fn);
     
    13541358                                return rc;
    13551359                        }
    1356 
    1357                         rc = ext4_filesystem_set_inode_data_block_index(inode_ref, iblock, fblock);
     1360                       
     1361                        rc = ext4_filesystem_set_inode_data_block_index(inode_ref,
     1362                            iblock, fblock);
    13581363                        if (rc != EOK) {
    13591364                                ext4_balloc_free_block(inode_ref, fblock);
     
    13631368                        }
    13641369                }
    1365 
     1370               
    13661371                flags = BLOCK_FLAGS_NOREAD;
    13671372                inode_ref->dirty = true;
    13681373        }
    1369 
     1374       
    13701375        /* Load target block */
    13711376        block_t *write_block;
     
    13761381                return rc;
    13771382        }
    1378 
    1379         if (flags == BLOCK_FLAGS_NOREAD) {
     1383       
     1384        if (flags == BLOCK_FLAGS_NOREAD)
    13801385                memset(write_block->data, 0, block_size);
    1381         }
    1382 
    1383         rc = async_data_write_finalize(callid, write_block->data + (pos % block_size), bytes);
     1386       
     1387        rc = async_data_write_finalize(callid, write_block->data +
     1388            (pos % block_size), bytes);
    13841389        if (rc != EOK) {
    13851390                ext4fs_node_put(fn);
    13861391                return rc;
    13871392        }
    1388 
     1393       
    13891394        write_block->dirty = true;
    1390 
     1395       
    13911396        rc = block_put(write_block);
    13921397        if (rc != EOK) {
     
    13941399                return rc;
    13951400        }
    1396 
     1401       
    13971402        /* Do some counting */
    1398         uint32_t old_inode_size = ext4_inode_get_size(fs->superblock, inode_ref->inode);
     1403        uint32_t old_inode_size = ext4_inode_get_size(fs->superblock,
     1404            inode_ref->inode);
    13991405        if (pos + bytes > old_inode_size) {
    14001406                ext4_inode_set_size(inode_ref->inode, pos + bytes);
    14011407                inode_ref->dirty = true;
    14021408        }
    1403 
     1409       
    14041410        *nsize = ext4_inode_get_size(fs->superblock, inode_ref->inode);
    14051411        *wbytes = bytes;
    1406 
     1412       
    14071413        return ext4fs_node_put(fn);
    14081414}
    14091415
    1410 
    14111416/** Truncate file.
    14121417 *
    14131418 * Only the direction to shorter file is supported.
    14141419 *
    1415  * @param service_id    device identifier
    1416  * @param index         index if node to truncated
    1417  * @param new_size      new size of file
    1418  * @return              error code
     1420 * @param service_id Device identifier
     1421 * @param index      Index if node to truncated
     1422 * @param new_size   New size of file
     1423 *
     1424 * @return Error code
     1425 *
    14191426 */
    14201427static int ext4fs_truncate(service_id_t service_id, fs_index_t index,
    1421                 aoff64_t new_size)
    1422 {
    1423         int rc;
    1424 
     1428    aoff64_t new_size)
     1429{
    14251430        fs_node_t *fn;
    1426         rc = ext4fs_node_get(&fn, service_id, index);
    1427         if (rc != EOK) {
    1428                 return rc;
    1429         }
    1430 
     1431        int rc = ext4fs_node_get(&fn, service_id, index);
     1432        if (rc != EOK)
     1433                return rc;
     1434       
    14311435        ext4fs_node_t *enode = EXT4FS_NODE(fn);
    14321436        ext4_inode_ref_t *inode_ref = enode->inode_ref;
    1433 
     1437       
    14341438        rc = ext4_filesystem_truncate_inode(inode_ref, new_size);
    14351439        ext4fs_node_put(fn);
    1436 
     1440       
    14371441        return rc;
    14381442}
    14391443
    1440 
    14411444/** Close file.
    14421445 *
    1443  * @param service_id    device identifier
    1444  * @param index         i-node number
    1445  * @return              error code
     1446 * @param service_id Device identifier
     1447 * @param index      I-node number
     1448 *
     1449 * @return Error code
     1450 *
    14461451 */
    14471452static int ext4fs_close(service_id_t service_id, fs_index_t index)
     
    14501455}
    14511456
    1452 
    14531457/** Destroy node specified by index.
    14541458 *
    1455  * @param service_id    device identifier
    1456  * @param index         number of i-node to destroy
    1457  * @return              error code
     1459 * @param service_id Device identifier
     1460 * @param index      I-node to destroy
     1461 *
     1462 * @return Error code
     1463 *
    14581464 */
    14591465static int ext4fs_destroy(service_id_t service_id, fs_index_t index)
    14601466{
    1461         int rc;
    1462 
    14631467        fs_node_t *fn;
    1464         rc = ext4fs_node_get(&fn, service_id, index);
    1465         if (rc != EOK) {
    1466                 return rc;
    1467         }
    1468 
     1468        int rc = ext4fs_node_get(&fn, service_id, index);
     1469        if (rc != EOK)
     1470                return rc;
     1471       
    14691472        /* Destroy the inode */
    14701473        return ext4fs_destroy_node(fn);
    14711474}
    14721475
    1473 /** Enforce inode synchronization (write) to device.
    1474  *
    1475  * @param service_id    device identifier
    1476  * @param index         i-node number.
     1476/** Enforce inode synchronization (write) to device.
     1477 *
     1478 * @param service_id Device identifier
     1479 * @param index      I-node number.
     1480 *
    14771481 */
    14781482static int ext4fs_sync(service_id_t service_id, fs_index_t index)
    14791483{
    1480         int rc;
    1481 
    14821484        fs_node_t *fn;
    1483         rc = ext4fs_node_get(&fn, service_id, index);
    1484         if (rc != EOK) {
    1485                 return rc;
    1486         }
    1487 
     1485        int rc = ext4fs_node_get(&fn, service_id, index);
     1486        if (rc != EOK)
     1487                return rc;
     1488       
    14881489        ext4fs_node_t *enode = EXT4FS_NODE(fn);
    14891490        enode->inode_ref->dirty = true;
    1490 
     1491       
    14911492        return ext4fs_node_put(fn);
    14921493}
     
    15031504        .close = ext4fs_close,
    15041505        .destroy = ext4fs_destroy,
    1505         .sync = ext4fs_sync,
     1506        .sync = ext4fs_sync
    15061507};
    15071508
Note: See TracChangeset for help on using the changeset viewer.