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


Ignore:
Timestamp:
2012-04-12T12:16:32Z (12 years ago)
Author:
Frantisek Princ <fp860328@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
831507b
Parents:
7eb033ce
Message:

comments

File:
1 edited

Legend:

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

    r7eb033ce r1fff583  
    5555#define OPEN_NODES_BUCKETS 256
    5656
     57/**
     58 * Type for holding an instance of mounted partition.
     59 */
    5760typedef struct ext4fs_instance {
    5861        link_t link;
     
    6265} ext4fs_instance_t;
    6366
     67/**
     68 * Type for wrapping common fs_node and add some useful pointers.
     69 */
    6470typedef struct ext4fs_node {
    6571        ext4fs_instance_t *instance;
     
    7076} ext4fs_node_t;
    7177
    72 /*
    73  * Forward declarations of auxiliary functions
    74  */
     78// Forward declarations of auxiliary functions
    7579
    7680static int ext4fs_read_directory(ipc_callid_t, aoff64_t, size_t,
     
    8387static int ext4fs_node_put_core(ext4fs_node_t *);
    8488
    85 /*
    86  * Forward declarations of EXT4 libfs operations.
    87  */
     89// Forward declarations of EXT4 libfs operations.
     90
    8891static int ext4fs_root_get(fs_node_t **, service_id_t);
    8992static int ext4fs_match(fs_node_t **, fs_node_t *, const char *);
     
    103106static service_id_t ext4fs_service_get(fs_node_t *node);
    104107
    105 /*
    106  * Static variables
    107  */
     108// Static variables
     109
    108110static LIST_INITIALIZE(instance_list);
    109111static FIBRIL_MUTEX_INITIALIZE(instance_list_mutex);
     
    118120}
    119121
     122/** Compare given item with values in hash table.
     123 *
     124 * @return      bool result of compare operation
     125 */
    120126static int open_nodes_compare(unsigned long key[], hash_count_t keys,
    121127    link_t *item)
     
    134140}
    135141
     142/** Empty callback to correct hash table initialization.
     143 *
     144 */
    136145static void open_nodes_remove_cb(link_t *link)
    137146{
     
    146155
    147156
     157/** Basic initialization of the driver.
     158 *
     159 * There is only needed to create hash table for storing open nodes.
     160 *
     161 * @return      error code
     162 */
    148163int ext4fs_global_init(void)
    149164{
     
    155170}
    156171
    157 
     172/* Finalization of the driver.
     173 *
     174 * There is only needed to destroy hash table.
     175 *
     176 * @return      error code
     177 */
    158178int ext4fs_global_fini(void)
    159179{
     
    167187 */
    168188
     189/** Get instance from internal table by service_id.
     190 *
     191 * @param service_id    device identifier
     192 * @param inst          output instance if successful operation
     193 * @return              error code
     194 */
    169195int ext4fs_instance_get(service_id_t service_id, ext4fs_instance_t **inst)
    170196{
     
    192218
    193219
     220/** Get root node of filesystem specified by service_id.
     221 *
     222 * @param rfn           output pointer to loaded node
     223 * @param service_id    device to load root node from
     224 * @return              error code
     225 */
    194226int ext4fs_root_get(fs_node_t **rfn, service_id_t service_id)
    195227{
     
    197229}
    198230
    199 
     231/** Check if specified name (component) matches with any directory entry.
     232 *
     233 * If match is found, load and return matching node.
     234 *
     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
     239 */
    200240int ext4fs_match(fs_node_t **rfn, fs_node_t *pfn, const char *component)
    201241{
     
    235275}
    236276
    237 
     277/** Get node specified by index
     278 *
     279 * It's wrapper for node_put_core operation
     280 *
     281 * @param rfn           output pointer to loaded node if operation successful
     282 * @param service_id    device identifier
     283 * @param index         node index (here i-node number)
     284 * @return              error code
     285 */
    238286int ext4fs_node_get(fs_node_t **rfn, service_id_t service_id, fs_index_t index)
    239287{
     
    249297}
    250298
    251 
     299/** Main function for getting node from the filesystem.
     300 *
     301 * @param rfn           output point to loaded node if operation successful
     302 * @param inst          instance of filesystem
     303 * @param index         index of node (i-node number)
     304 * @return              error code
     305 */
    252306int ext4fs_node_get_core(fs_node_t **rfn, ext4fs_instance_t *inst,
    253307                fs_index_t index)
     
    274328        }
    275329
     330        // Prepare new enode
    276331        enode = malloc(sizeof(ext4fs_node_t));
    277332        if (enode == NULL) {
     
    288343        fs_node_initialize(fs_node);
    289344
     345        // Load inode from filesystem
    290346        ext4_inode_ref_t *inode_ref;
    291347        rc = ext4_filesystem_get_inode_ref(inst->filesystem, index, &inode_ref);
     
    297353        }
    298354
     355        // Initialize enode
    299356        enode->inode_ref = inode_ref;
    300357        enode->instance = inst;
     
    314371}
    315372
    316 
     373/** Put previously loaded node.
     374 *
     375 * @param enode         node to put back
     376 * @return              error code
     377 */
    317378int ext4fs_node_put_core(ext4fs_node_t *enode)
    318379{
     
    327388        enode->instance->open_nodes_count--;
    328389
     390        // Put inode back in filesystem
    329391        rc = ext4_filesystem_put_inode_ref(enode->inode_ref);
    330392        if (rc != EOK) {
     
    332394        }
    333395
     396        // Destroy data structure
    334397        free(enode->fs_node);
    335398        free(enode);
     
    339402
    340403
     404/** Open node.
     405 *
     406 * This operation is stateless in this driver.
     407 *
     408 * @param fn    node to open
     409 * @return      error code (EOK)
     410 */
    341411int ext4fs_node_open(fs_node_t *fn)
    342412{
     
    345415}
    346416
     417
     418/** Put previously loaded node.
     419 *
     420 * It's wrapper for node_put_core operation
     421 *
     422 * @param fn    node to put back
     423 * @return      error code
     424 */
    347425int ext4fs_node_put(fs_node_t *fn)
    348426{
     
    368446
    369447
     448/** Create new node in filesystem.
     449 *
     450 * @param rfn           output pointer to newly created node if successful
     451 * @param service_id    device identifier, where the filesystem is
     452 * @param flags         flags for specification of new node parameters
     453 * @return              error code
     454 */
    370455int ext4fs_create_node(fs_node_t **rfn, service_id_t service_id, int flags)
    371456{
    372457        int rc;
    373458
     459        // Allocate node structures
    374460        ext4fs_node_t *enode;
    375461        enode = malloc(sizeof(ext4fs_node_t));
     
    385471        }
    386472
     473        // Load instance
    387474        ext4fs_instance_t *inst;
    388475        rc = ext4fs_instance_get(service_id, &inst);
     
    393480        }
    394481
     482        // Allocate new i-node in filesystem
    395483        ext4_inode_ref_t *inode_ref;
    396484        rc = ext4_filesystem_alloc_inode(inst->filesystem, &inode_ref, flags);
     
    401489        }
    402490
     491        // Do some interconnections in references
    403492        enode->inode_ref = inode_ref;
    404493        enode->instance = inst;
     
    428517
    429518
     519/** Destroy existing node.
     520 *
     521 * @param fs    node to destroy
     522 * @return      error code
     523 */
    430524int ext4fs_destroy_node(fs_node_t *fn)
    431525{
    432526        int rc;
    433527
     528        // If directory, check for children
    434529        bool has_children;
    435530        rc = ext4fs_has_children(&has_children, fn);
     
    448543        ext4_inode_ref_t *inode_ref = enode->inode_ref;
    449544
     545        // Release data blocks
    450546        rc = ext4_filesystem_truncate_inode(inode_ref, 0);
    451547        if (rc != EOK) {
     
    454550        }
    455551
     552        // Handle orphans
    456553        uint32_t rev_level = ext4_superblock_get_rev_level(fs->superblock);
    457554        if (rev_level > 0) {
     
    459556        }
    460557
    461         // TODO set real deletion time
     558        // TODO set real deletion time when it will be supported
    462559//      time_t now = time(NULL);
    463560        time_t now = ext4_inode_get_change_inode_time(inode_ref->inode);
     
    465562        inode_ref->dirty = true;
    466563
     564        // Free inode
    467565        rc = ext4_filesystem_free_inode(inode_ref);
    468566        if (rc != EOK) {
     
    476574
    477575
     576/** Link the specfied node to directory.
     577 *
     578 * @param pfn           parent node to link in
     579 * @param cfn           node to be linked
     580 * @param name          name which will be assigned to directory entry
     581 * @return              error code
     582 */
    478583int ext4fs_link(fs_node_t *pfn, fs_node_t *cfn, const char *name)
    479584{
     
    510615                }
    511616
     617                // Initialize directory index if necessary
    512618//              if (ext4_superblock_has_feature_compatible(
    513619//                              fs->superblock, EXT4_FEATURE_COMPAT_DIR_INDEX)) {
     
    540646
    541647
     648/** Unlink node from specified directory.
     649 *
     650 * @param pfn           parent node to delete node from
     651 * @param cfn           child node to be unlinked from directory
     652 * @param name          name of entry that will be removed
     653 * @return              error code
     654 */
    542655int ext4fs_unlink(fs_node_t *pfn, fs_node_t *cfn, const char *name)
    543656{
     
    606719
    607720
     721/** Check if specified node has children.
     722 *
     723 * For files is response allways false and check is executed only for directories.
     724 *
     725 * @param has_children          output value for response
     726 * @param fn                    node to check
     727 * @return                      error code
     728 */
    608729int ext4fs_has_children(bool *has_children, fs_node_t *fn)
    609730{
     
    613734        ext4_filesystem_t *fs = enode->instance->filesystem;
    614735
     736        // Check if node is directory
    615737        if (!ext4_inode_is_type(fs->superblock, enode->inode_ref->inode,
    616738            EXT4_INODE_MODE_DIRECTORY)) {
     
    655777
    656778
     779/** Unpack index number from node.
     780 *     
     781 * @param fn    node to load index from
     782 * @return      index number of i-node
     783 */
    657784fs_index_t ext4fs_index_get(fs_node_t *fn)
    658785{
     
    662789
    663790
     791/** Get real size of file / directory.
     792 *
     793 * @param fn    node to get size of
     794 * @return      real size of node
     795 */
    664796aoff64_t ext4fs_size_get(fs_node_t *fn)
    665797{
     
    670802
    671803
     804/** Get number of links to specified node.
     805 *
     806 * @param fn    node to get links to
     807 * @return      number of links
     808 */
    672809unsigned ext4fs_lnkcnt_get(fs_node_t *fn)
    673810{
     
    688825
    689826
     827/** Check if node is directory.
     828 *
     829 * @param fn    node to check
     830 * @return      result of check
     831 */
    690832bool ext4fs_is_directory(fs_node_t *fn)
    691833{
     
    697839
    698840
     841/** Check if node is regular file.
     842 *
     843 * @param fn    node to check
     844 * @return      result of check
     845 */
    699846bool ext4fs_is_file(fs_node_t *fn)
    700847{
     
    705852}
    706853
    707 
     854/** Extract device identifier from node.
     855 *
     856 * @param node  node to extract id from
     857 * @return      id of device, where is the filesystem
     858 */
    708859service_id_t ext4fs_service_get(fs_node_t *fn)
    709860{
     
    739890 */
    740891
     892/** Mount operation.
     893 *
     894 * Try to mount specified filesystem from device.
     895 *
     896 * @param service_id    identifier of device
     897 * @param opts          mount options
     898 * @param index         TODO
     899 * @param size          TODO
     900 * @param lnkcnt        TODO
     901 * @return              error code
     902 */
    741903static int ext4fs_mounted(service_id_t service_id, const char *opts,
    742904   fs_index_t *index, aoff64_t *size, unsigned *lnkcnt)
     
    816978}
    817979
    818 
     980/** Unmount operation.
     981 *
     982 * Correctly release the filesystem.
     983 *
     984 * @param service_id    device to be unmounted
     985 * @return              error code
     986 */
    819987static int ext4fs_unmounted(service_id_t service_id)
    820988{
     
    8451013
    8461014
     1015/** Read bytes from node.
     1016 *
     1017 * @param service_id    device to read data from
     1018 * @param index         number of node to read from
     1019 * @param pos           position where the read should be started
     1020 * @param rbytes        output value, where the real size was returned
     1021 * @return              error code
     1022 */
    8471023static int ext4fs_read(service_id_t service_id, fs_index_t index,
    8481024                aoff64_t pos, size_t *rbytes)
     
    8671043        }
    8681044
     1045        // Load i-node
    8691046        ext4_inode_ref_t *inode_ref;
    8701047        rc = ext4_filesystem_get_inode_ref(inst->filesystem, index, &inode_ref);
     
    8741051        }
    8751052
     1053        // Read from i-node by type
    8761054        if (ext4_inode_is_type(inst->filesystem->superblock, inode_ref->inode,
    8771055                        EXT4_INODE_MODE_FILE)) {
     
    8931071}
    8941072
     1073/** Check if filename is dot or dotdot (reserved names).
     1074 *
     1075 * @param name          name to check
     1076 * @param name_size     length of string name
     1077 * @return              result of the check
     1078 */
    8951079bool ext4fs_is_dots(const uint8_t *name, size_t name_size)
    8961080{
     
    9061090}
    9071091
     1092/** Read data from directory.
     1093 *
     1094 * @param callid        IPC id of call (for communication)
     1095 * @param pos           position to start reading from
     1096 * @param size          how many bytes to read
     1097 * @param inst          filesystem instance
     1098 * @param inode_ref     node to read data from
     1099 * @param rbytes        output value to return real number of bytes was read
     1100 * @return              error code
     1101 */
    9081102int ext4fs_read_directory(ipc_callid_t callid, aoff64_t pos, size_t size,
    9091103    ext4fs_instance_t *inst, ext4_inode_ref_t *inode_ref, size_t *rbytes)
     
    9771171        }
    9781172
     1173        // Prepare return values
    9791174        if (found) {
    9801175                *rbytes = next - pos;
     
    9861181}
    9871182
     1183
     1184/** Read data from file.
     1185 *
     1186 * @param callid        IPC id of call (for communication)
     1187 * @param pos           position to start reading from
     1188 * @param size          how many bytes to read
     1189 * @param inst          filesystem instance
     1190 * @param inode_ref     node to read data from
     1191 * @param rbytes        output value to return real number of bytes was read
     1192 * @return              error code
     1193 */
    9881194int ext4fs_read_file(ipc_callid_t callid, aoff64_t pos, size_t size,
    9891195    ext4fs_instance_t *inst, ext4_inode_ref_t *inode_ref, size_t *rbytes)
     
    10631269}
    10641270
     1271
     1272/** Write bytes to file
     1273 *
     1274 * @param service_id    device identifier
     1275 * @param index         i-node number of file
     1276 * @param pos           position in file to start reading from
     1277 * @param wbytes        TODO
     1278 * @param nsize         TODO
     1279 * @return              error code
     1280 */
    10651281static int ext4fs_write(service_id_t service_id, fs_index_t index,
    10661282                aoff64_t pos, size_t *wbytes, aoff64_t *nsize)
     
    11001316        uint32_t fblock;
    11011317
     1318        // Load inode
    11021319        ext4_inode_ref_t *inode_ref = enode->inode_ref;
    11031320        rc = ext4_filesystem_get_inode_data_block_index(inode_ref, iblock, &fblock);
     
    11081325        }
    11091326
     1327        // Check for sparse file
    11101328        if (fblock == 0) {
    11111329
     
    11451363        }
    11461364
     1365        // Load target block
    11471366        block_t *write_block;
    11481367        rc = block_get(&write_block, service_id, fblock, flags);
     
    11711390        }
    11721391
     1392        // Do some counting
    11731393        uint32_t old_inode_size = ext4_inode_get_size(fs->superblock, inode_ref->inode);
    11741394        if (pos + bytes > old_inode_size) {
     
    11841404
    11851405
     1406/** Truncate file.
     1407 *
     1408 * Only the direction to shorter file is supported.
     1409 *
     1410 * @param service_id    device identifier
     1411 * @param index         index if node to truncated
     1412 * @param new_size      new size of file
     1413 * @return              error code
     1414 */
    11861415static int ext4fs_truncate(service_id_t service_id, fs_index_t index,
    11871416                aoff64_t new_size)
     
    12051434
    12061435
     1436/** Close file.
     1437 *'
     1438 * @param service_id    device identifier
     1439 * @param index         i-node number
     1440 * @return              error code
     1441 */
    12071442static int ext4fs_close(service_id_t service_id, fs_index_t index)
    12081443{
     
    12111446
    12121447
     1448/** Destroy node specified by index.
     1449 *
     1450 * @param service_id    device identifier
     1451 * @param index         number of i-node to destroy
     1452 * @return              error code
     1453 */
    12131454static int ext4fs_destroy(service_id_t service_id, fs_index_t index)
    12141455{
     
    12251466}
    12261467
    1227 
     1468/** Enforce inode synchronization (write) to device.
     1469 *
     1470 * @param service_id    device identifier
     1471 * @param index         i-node number.
     1472 */
    12281473static int ext4fs_sync(service_id_t service_id, fs_index_t index)
    12291474{
     
    12421487}
    12431488
     1489/** VFS operations
     1490 *
     1491 */
    12441492vfs_out_ops_t ext4fs_ops = {
    12451493        .mounted = ext4fs_mounted,
Note: See TracChangeset for help on using the changeset viewer.