Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/vfs/vfs_node.c

    r5bcd5b7 r4e00f87  
    4545#include <async.h>
    4646#include <errno.h>
    47 #include <macros.h>
    4847
    4948/** Mutex protecting the VFS node hash table. */
     
    107106void vfs_node_delref(vfs_node_t *node)
    108107{
    109         bool free_node = false;
    110        
    111         fibril_mutex_lock(&nodes_mutex);
    112        
    113         node->refcnt--;
    114         if (node->refcnt == 0) {
     108        bool free_vfs_node = false;
     109        bool free_fs_node = false;
     110       
     111        fibril_mutex_lock(&nodes_mutex);
     112       
     113        if (node->refcnt-- == 1) {
    115114               
    116115                /*
     
    120119               
    121120                hash_table_remove_item(&nodes, &node->nh_link);
    122                 free_node = true;
     121                free_vfs_node = true;
     122               
     123                if (!node->lnkcnt)
     124                        free_fs_node = true;
    123125        }
    124126       
    125127        fibril_mutex_unlock(&nodes_mutex);
    126128       
    127         if (free_node) {
     129        if (free_fs_node) {
     130               
    128131                /*
    129                  * DESTROY will free up the file's resources if there are no more hard links.
     132                 * The node is not visible in the file system namespace.
     133                 * Free up its resources.
    130134                 */
    131135               
    132136                async_exch_t *exch = vfs_exchange_grab(node->fs_handle);
    133                 async_msg_2(exch, VFS_OUT_DESTROY,
    134                         (sysarg_t) node->service_id, (sysarg_t)node->index);
     137                sysarg_t rc = async_req_2_0(exch, VFS_OUT_DESTROY,
     138                    (sysarg_t) node->service_id, (sysarg_t)node->index);
     139               
     140                assert(rc == EOK);
    135141                vfs_exchange_release(exch);
    136 
     142        }
     143       
     144        if (free_vfs_node)
    137145                free(node);
    138         }
    139146}
    140147
     
    183190                node->index = result->triplet.index;
    184191                node->size = result->size;
     192                node->lnkcnt = result->lnkcnt;
    185193                node->type = result->type;
    186194                fibril_rwlock_initialize(&node->contents_rwlock);
     
    188196        } else {
    189197                node = hash_table_get_inst(tmp, vfs_node_t, nh_link);
     198                if (node->type == VFS_NODE_UNKNOWN &&
     199                    result->type != VFS_NODE_UNKNOWN) {
     200                        /* Upgrade the node type. */
     201                        node->type = result->type;
     202                }
    190203        }
    191204
     205        assert(node->size == result->size || node->type != VFS_NODE_FILE);
     206        assert(node->lnkcnt == result->lnkcnt);
     207        assert(node->type == result->type || result->type == VFS_NODE_UNKNOWN);
     208
    192209        _vfs_node_addref(node);
    193         fibril_mutex_unlock(&nodes_mutex);
    194 
    195         return node;
    196 }
    197 
    198 vfs_node_t *vfs_node_peek(vfs_lookup_res_t *result)
    199 {
    200         vfs_node_t *node = NULL;
    201 
    202         fibril_mutex_lock(&nodes_mutex);
    203         ht_link_t *tmp = hash_table_find(&nodes, &result->triplet);
    204         if (tmp) {
    205                 node = hash_table_get_inst(tmp, vfs_node_t, nh_link);
    206         }
    207210        fibril_mutex_unlock(&nodes_mutex);
    208211
     
    315318}
    316319
    317 int64_t vfs_node_get_size(vfs_node_t *node)
    318 {
    319         if (node->size == -1) {
    320                 sysarg_t sz1 = 0;
    321                 sysarg_t sz2 = 0;
    322                
    323                 async_exch_t *exch = vfs_exchange_grab(node->fs_handle);
    324                 (void) async_req_2_2(exch, VFS_OUT_GET_SIZE,
    325                         node->service_id, node->index, &sz1, &sz2);
    326                 vfs_exchange_release(exch);
    327                
    328                 node->size = MERGE_LOUP32(sz1, sz2);
    329         }
    330         return node->size;
    331 }
    332 
    333 bool vfs_node_has_children(vfs_node_t *node)
    334 {
    335         async_exch_t *exch = vfs_exchange_grab(node->fs_handle);
    336         int rc = async_req_2_0(exch, VFS_OUT_IS_EMPTY, node->service_id, node->index);
    337         vfs_exchange_release(exch);
    338         return rc == ENOTEMPTY;
    339 }
    340 
    341320/**
    342321 * @}
Note: See TracChangeset for help on using the changeset viewer.