Changeset ee257b2 in mainline


Ignore:
Timestamp:
2011-07-27T21:37:13Z (13 years ago)
Author:
Maurizio Lombardi <m.lombardi85@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
9530d94
Parents:
4bf0052a
Message:

Add a open_nodes hashtable (code imported from the ext2fs implementation)
Fix the number of hard links in the parent inode when linking/unlinking a child directory.

Location:
uspace/srv/fs/minixfs
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/fs/minixfs/mfs.c

    r4bf0052a ree257b2  
    157157        }
    158158
     159        rc = mfs_global_init();
     160        if (rc != EOK) {
     161                printf(NAME ": Failed global initialization\n");
     162                goto err;
     163        }
     164
    159165        rc = fs_register(vfs_sess, &mfs_reg, &mfs_vfs_info, mfs_connection);
    160166        if (rc != EOK)
  • uspace/srv/fs/minixfs/mfs.h

    r4bf0052a ree257b2  
    146146        devmap_handle_t handle;
    147147        struct mfs_sb_info *sbi;
     148        unsigned open_nodes_cnt;
    148149};
    149150
     
    152153        struct mfs_ino_info *ino_i;
    153154        struct mfs_instance *instance;
     155        unsigned refcnt;
     156        fs_node_t *fsnode;
     157        link_t link;
    154158};
    155159
     
    186190mfs_sync(ipc_callid_t rid, ipc_call_t *request);
    187191
     192extern int
     193mfs_global_init(void);
     194
    188195/*mfs_inode.c*/
    189196extern int
  • uspace/srv/fs/minixfs/mfs_ops.c

    r4bf0052a ree257b2  
    3434#include <fibril_synch.h>
    3535#include <align.h>
     36#include <adt/hash_table.h>
    3637#include "mfs.h"
     38
     39#define OPEN_NODES_KEYS 2
     40#define OPEN_NODES_DEV_HANDLE_KEY 0
     41#define OPEN_NODES_INODE_KEY 1
     42#define OPEN_NODES_BUCKETS 256
    3743
    3844static bool check_magic_number(uint16_t magic, bool *native,
     
    5763static int mfs_unlink(fs_node_t *, fs_node_t *, const char *name);
    5864static int mfs_destroy_node(fs_node_t *fn);
     65static hash_index_t open_nodes_hash(unsigned long key[]);
     66static int open_nodes_compare(unsigned long key[], hash_count_t keys,
     67                link_t *item);
     68static void open_nodes_remove_cb(link_t *link);
    5969
    6070static int mfs_node_get(fs_node_t **rfn, devmap_handle_t devmap_handle,
     
    6474static LIST_INITIALIZE(inst_list);
    6575static FIBRIL_MUTEX_INITIALIZE(inst_list_mutex);
     76static hash_table_t open_nodes;
     77static FIBRIL_MUTEX_INITIALIZE(open_nodes_lock);
    6678
    6779libfs_ops_t mfs_libfs_ops = {
     
    8597};
    8698
     99/* Hash table interface for open nodes hash table */
     100static hash_index_t open_nodes_hash(unsigned long key[])
     101{
     102        /* TODO: This is very simple and probably can be improved */
     103        return key[OPEN_NODES_INODE_KEY] % OPEN_NODES_BUCKETS;
     104}
     105
     106static int open_nodes_compare(unsigned long key[], hash_count_t keys,
     107                link_t *item)
     108{
     109        struct mfs_node *mnode = hash_table_get_instance(item, struct mfs_node, link);
     110        assert(keys > 0);
     111        if (mnode->instance->handle !=
     112            ((devmap_handle_t) key[OPEN_NODES_DEV_HANDLE_KEY])) {
     113                return false;
     114        }
     115        if (keys == 1) {
     116                return true;
     117        }
     118        assert(keys == 2);
     119        return (mnode->ino_i->index == key[OPEN_NODES_INODE_KEY]);
     120}
     121
     122static void open_nodes_remove_cb(link_t *link)
     123{
     124        /* We don't use remove callback for this hash table */
     125}
     126
     127static hash_table_operations_t open_nodes_ops = {
     128        .hash = open_nodes_hash,
     129        .compare = open_nodes_compare,
     130        .remove_callback = open_nodes_remove_cb,
     131};
     132
     133int mfs_global_init(void)
     134{
     135        if (!hash_table_create(&open_nodes, OPEN_NODES_BUCKETS,
     136                        OPEN_NODES_KEYS, &open_nodes_ops)) {
     137                return ENOMEM;
     138        }
     139        return EOK;
     140}
     141
    87142void mfs_mounted(ipc_callid_t rid, ipc_call_t *request)
    88143{
     
    138193                return;
    139194        }
     195
     196        instance->open_nodes_cnt = 0;
    140197
    141198        sb = malloc(MFS_SUPERBLOCK_SIZE);
     
    265322        }
    266323
     324        if (inst->open_nodes_cnt != 0) {
     325                async_answer_0(rid, EBUSY);
     326                return;
     327        }
     328
    267329        (void) block_cache_fini(devmap);
    268330        block_fini(devmap);
     
    292354        fs_node_t *fsnode;
    293355        uint32_t inum;
     356
     357        mfsdebug("%s()\n", __FUNCTION__);
    294358
    295359        r = mfs_instance_get(handle, &inst);
     
    342406        mnode->ino_i = ino_i;
    343407        mnode->instance = inst;
    344 
    345         r = put_inode(mnode);
    346         on_error(r, goto out_err_2);
     408        mnode->refcnt = 1;
     409
     410        link_initialize(&mnode->link);
     411
     412        unsigned long key[] = {
     413                [OPEN_NODES_DEV_HANDLE_KEY] = inst->handle,
     414                [OPEN_NODES_INODE_KEY] = inum,
     415        };
     416
     417        fibril_mutex_lock(&open_nodes_lock);
     418        hash_table_insert(&open_nodes, key, &mnode->link);
     419        fibril_mutex_unlock(&open_nodes_lock);
     420        inst->open_nodes_cnt++;
     421
     422        mnode->ino_i->dirty = true;
    347423
    348424        fs_node_initialize(fsnode);
    349425        fsnode->data = mnode;
     426        mnode->fsnode = fsnode;
    350427        *rfn = fsnode;
    351428
     
    366443        struct mfs_dentry_info d_info;
    367444        int r;
     445
     446        mfsdebug("%s()\n", __FUNCTION__);
    368447
    369448        if (!S_ISDIR(ino_i->i_mode))
     
    420499        struct mfs_instance *instance;
    421500
     501        mfsdebug("%s()\n", __FUNCTION__);
     502
    422503        rc = mfs_instance_get(devmap_handle, &instance);
    423504        on_error(rc, return rc);
     
    428509static int mfs_node_put(fs_node_t *fsnode)
    429510{
     511        int rc = EOK;
    430512        struct mfs_node *mnode = fsnode->data;
    431513
    432         put_inode(mnode);
    433         free(mnode->ino_i);
    434         free(mnode);
    435         free(fsnode);
    436 
    437         return EOK;
     514        mfsdebug("%s()\n", __FUNCTION__);
     515
     516        fibril_mutex_lock(&open_nodes_lock);
     517
     518        assert(mnode->refcnt > 0);
     519        mnode->refcnt--;
     520        if (mnode->refcnt == 0) {
     521                unsigned long key[] = {
     522                        [OPEN_NODES_DEV_HANDLE_KEY] = mnode->instance->handle,
     523                        [OPEN_NODES_INODE_KEY] = mnode->ino_i->index
     524                };
     525                hash_table_remove(&open_nodes, key, OPEN_NODES_KEYS);
     526                assert(mnode->instance->open_nodes_cnt > 0);
     527                mnode->instance->open_nodes_cnt--;
     528                rc = put_inode(mnode);
     529                free(mnode->ino_i);
     530                free(mnode);
     531                free(fsnode);
     532        }
     533
     534        fibril_mutex_unlock(&open_nodes_lock);
     535        return rc;
    438536}
    439537
     
    459557        struct mfs_node *mnode = fsnode->data;
    460558
     559        mfsdebug("%s()\n", __FUNCTION__);
     560
    461561        assert(mnode);
    462562        assert(mnode->ino_i);
    463563
    464         return mnode->ino_i->i_nlinks;;
     564        return mnode->ino_i->i_nlinks;
    465565}
    466566
     
    471571        struct mfs_node *mnode = NULL;
    472572        int rc;
     573
     574        mfsdebug("%s()\n", __FUNCTION__);
     575
     576        fibril_mutex_lock(&open_nodes_lock);
     577
     578        /* Check if the node is not already open */
     579        unsigned long key[] = {
     580                [OPEN_NODES_DEV_HANDLE_KEY] = inst->handle,
     581                [OPEN_NODES_INODE_KEY] = index,
     582        };
     583        link_t *already_open = hash_table_find(&open_nodes, key);
     584
     585        if (already_open) {
     586                mnode = hash_table_get_instance(already_open, struct mfs_node, link);
     587                *rfn = mnode->fsnode;
     588                mnode->refcnt++;
     589
     590                fibril_mutex_unlock(&open_nodes_lock);
     591                return EOK;
     592        }
    473593
    474594        node = malloc(sizeof(fs_node_t));
     
    493613        ino_i->index = index;
    494614        mnode->ino_i = ino_i;
     615        mnode->refcnt = 1;
     616        link_initialize(&mnode->link);
    495617
    496618        mnode->instance = inst;
    497619        node->data = mnode;
     620        mnode->fsnode = node;
    498621        *rfn = node;
     622
     623        hash_table_insert(&open_nodes, key, &mnode->link);
     624        inst->open_nodes_cnt++;
     625
     626        fibril_mutex_unlock(&open_nodes_lock);
    499627
    500628        return EOK;
     
    505633        if (mnode)
    506634                free(mnode);
     635        fibril_mutex_unlock(&open_nodes_lock);
    507636        return rc;
    508637}
     
    542671        struct mfs_sb_info *sbi = parent->instance->sbi;
    543672
     673        mfsdebug("%s()\n", __FUNCTION__);
     674
    544675        if (str_size(name) > sbi->max_name_len)
    545676                return ENAMETOOLONG;
     
    551682                r = insert_dentry(child, ".", child->ino_i->index);
    552683                on_error(r, goto exit_error);
     684                child->ino_i->i_nlinks++;
     685                child->ino_i->dirty = true;
    553686                r = insert_dentry(child, "..", parent->ino_i->index);
     687                on_error(r, goto exit_error);
     688                parent->ino_i->i_nlinks++;
     689                parent->ino_i->dirty = true;
    554690        }
    555691
     
    566702        int r;
    567703
     704        mfsdebug("%s()\n", __FUNCTION__);
     705
    568706        if (!parent)
    569707                return EBUSY;
     
    583721        --chino->i_nlinks;
    584722
     723        if (chino->i_nlinks == 0 && S_ISDIR(chino->i_mode)) {
     724                parent->ino_i->i_nlinks--;
     725                parent->ino_i->dirty = true;
     726        }
     727
    585728        chino->dirty = true;
    586729
    587         return EOK;
     730        return r;
    588731}
    589732
Note: See TracChangeset for help on using the changeset viewer.