Changeset bf9dc4e2 in mainline for uspace/srv/vfs/vfs_ops.c


Ignore:
Timestamp:
2013-07-28T19:32:36Z (11 years ago)
Author:
Jiri Zarevucky <zarevucky.jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
778d26d
Parents:
d60ce4a
Message:

Relativize and simplify lookup().

File:
1 edited

Legend:

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

    rd60ce4a rbf9dc4e2  
    6868FIBRIL_RWLOCK_INITIALIZE(namespace_rwlock);
    6969
    70 vfs_pair_t rootfs = {
    71         .fs_handle = 0,
    72         .service_id = 0
    73 };
     70vfs_node_t *root = NULL;
    7471
    7572static int vfs_mount_internal(ipc_callid_t rid, service_id_t service_id,
     
    9087        /* Resolve the path to the mountpoint. */
    9188        fibril_rwlock_write_lock(&namespace_rwlock);
    92         if (rootfs.fs_handle) {
    93                 /* We already have the root FS. */
    94                 if (str_cmp(mp, "/") == 0) {
    95                         /* Trying to mount root FS over root FS */
    96                         fibril_rwlock_write_unlock(&namespace_rwlock);
    97                         async_answer_0(rid, EBUSY);
    98                         return EBUSY;
    99                 }
    100                
    101                 rc = vfs_lookup_internal(mp, L_MP, &mp_res, NULL);
    102                 if (rc != EOK) {
    103                         /* The lookup failed for some reason. */
    104                         fibril_rwlock_write_unlock(&namespace_rwlock);
    105                         async_answer_0(rid, rc);
    106                         return rc;
    107                 }
    108                
    109                 mp_node = vfs_node_get(&mp_res);
    110                 if (!mp_node) {
    111                         fibril_rwlock_write_unlock(&namespace_rwlock);
    112                         async_answer_0(rid, ENOMEM);
    113                         return ENOMEM;
    114                 }
    115                
    116                 /*
    117                  * Now we hold a reference to mp_node.
    118                  * It will be dropped upon the corresponding VFS_IN_UNMOUNT.
    119                  * This prevents the mount point from being deleted.
    120                  */
    121         } else {
     89        if (root == NULL) {
    12290                /* We still don't have the root file system mounted. */
    123                 if (str_cmp(mp, "/") == 0) {
    124                         /*
    125                          * For this simple, but important case,
    126                          * we are almost done.
    127                          */
    128                        
    129                         /* Tell the mountee that it is being mounted. */
    130                         exch = vfs_exchange_grab(fs_handle);
    131                         msg = async_send_1(exch, VFS_OUT_MOUNTED,
    132                             (sysarg_t) service_id, &answer);
    133                         /* Send the mount options */
    134                         rc = async_data_write_start(exch, (void *)opts,
    135                             str_size(opts));
    136                         vfs_exchange_release(exch);
    137                        
    138                         if (rc != EOK) {
    139                                 async_forget(msg);
    140                                 fibril_rwlock_write_unlock(&namespace_rwlock);
    141                                 async_answer_0(rid, rc);
    142                                 return rc;
    143                         }
    144                         async_wait_for(msg, &rc);
    145                        
    146                         if (rc != EOK) {
    147                                 fibril_rwlock_write_unlock(&namespace_rwlock);
    148                                 async_answer_0(rid, rc);
    149                                 return rc;
    150                         }
    151 
    152                         rindex = (fs_index_t) IPC_GET_ARG1(answer);
    153                         rsize = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG2(answer),
    154                             IPC_GET_ARG3(answer));
    155                         rlnkcnt = (unsigned) IPC_GET_ARG4(answer);
    156                        
    157                         mr_res.triplet.fs_handle = fs_handle;
    158                         mr_res.triplet.service_id = service_id;
    159                         mr_res.triplet.index = rindex;
    160                         mr_res.size = rsize;
    161                         mr_res.lnkcnt = rlnkcnt;
    162                         mr_res.type = VFS_NODE_DIRECTORY;
    163                        
    164                         rootfs.fs_handle = fs_handle;
    165                         rootfs.service_id = service_id;
    166                        
    167                         /* Add reference to the mounted root. */
    168                         mr_node = vfs_node_get(&mr_res);
    169                         assert(mr_node);
    170                        
    171                         fibril_rwlock_write_unlock(&namespace_rwlock);
    172                         async_answer_0(rid, rc);
    173                         return rc;
    174                 } else {
     91                if (str_cmp(mp, "/") != 0) {
    17592                        /*
    17693                         * We can't resolve this without the root filesystem
     
    18198                        return ENOENT;
    18299                }
    183         }
     100               
     101                /*
     102                 * For this simple, but important case,
     103                 * we are almost done.
     104                 */
     105                       
     106                /* Tell the mountee that it is being mounted. */
     107                exch = vfs_exchange_grab(fs_handle);
     108                msg = async_send_1(exch, VFS_OUT_MOUNTED,
     109                    (sysarg_t) service_id, &answer);
     110                /* Send the mount options */
     111                rc = async_data_write_start(exch, (void *)opts,
     112                    str_size(opts));
     113                vfs_exchange_release(exch);
     114                       
     115                if (rc != EOK) {
     116                        async_forget(msg);
     117                        fibril_rwlock_write_unlock(&namespace_rwlock);
     118                        async_answer_0(rid, rc);
     119                        return rc;
     120                }
     121                async_wait_for(msg, &rc);
     122                       
     123                if (rc != EOK) {
     124                        fibril_rwlock_write_unlock(&namespace_rwlock);
     125                        async_answer_0(rid, rc);
     126                        return rc;
     127                }
     128
     129                rindex = (fs_index_t) IPC_GET_ARG1(answer);
     130                rsize = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG2(answer),
     131                    IPC_GET_ARG3(answer));
     132                rlnkcnt = (unsigned) IPC_GET_ARG4(answer);
     133               
     134                mr_res.triplet.fs_handle = fs_handle;
     135                mr_res.triplet.service_id = service_id;
     136                mr_res.triplet.index = rindex;
     137                mr_res.size = rsize;
     138                mr_res.lnkcnt = rlnkcnt;
     139                mr_res.type = VFS_NODE_DIRECTORY;
     140                       
     141                /* Add reference to the mounted root. */
     142                root = vfs_node_get(&mr_res);
     143                assert(root);
     144                       
     145                fibril_rwlock_write_unlock(&namespace_rwlock);
     146                async_answer_0(rid, rc);
     147                return rc;
     148        }
     149       
     150        /* We already have the root FS. */
     151        if (str_cmp(mp, "/") == 0) {
     152                /* Trying to mount root FS over root FS */
     153                fibril_rwlock_write_unlock(&namespace_rwlock);
     154                async_answer_0(rid, EBUSY);
     155                return EBUSY;
     156        }
     157       
     158        rc = vfs_lookup_internal((vfs_triplet_t *) root, mp, L_DIRECTORY, &mp_res);
     159        if (rc != EOK) {
     160                /* The lookup failed. */
     161                fibril_rwlock_write_unlock(&namespace_rwlock);
     162                async_answer_0(rid, rc);
     163                return rc;
     164        }
     165       
     166        mp_node = vfs_node_get(&mp_res);
     167        if (!mp_node) {
     168                fibril_rwlock_write_unlock(&namespace_rwlock);
     169                async_answer_0(rid, ENOMEM);
     170                return ENOMEM;
     171        }
     172       
     173        /*
     174         * Now we hold a reference to mp_node.
     175         * It will be dropped upon the corresponding VFS_IN_UNMOUNT.
     176         * This prevents the mount point from being deleted.
     177         */
    184178       
    185179        /*
     
    435429         * Lookup the mounted root and instantiate it.
    436430         */
    437         rc = vfs_lookup_internal(mp, L_ROOT, &mr_res, NULL);
     431        rc = vfs_lookup_internal((vfs_triplet_t *) root, mp, 0, &mr_res);
    438432        if (rc != EOK) {
    439433                fibril_rwlock_write_unlock(&namespace_rwlock);
     
    488482                }
    489483               
    490                 rootfs.fs_handle = 0;
    491                 rootfs.service_id = 0;
     484                root = NULL;
    492485        } else {
    493486               
     
    499492                 */
    500493               
    501                 rc = vfs_lookup_internal(mp, L_MP, &mp_res, NULL);
     494                rc = vfs_lookup_internal((vfs_triplet_t *) root, mp, L_MP, &mp_res);
    502495                if (rc != EOK) {
    503496                        fibril_rwlock_write_unlock(&namespace_rwlock);
     
    624617        /* Lookup the file structure corresponding to the file descriptor. */
    625618        vfs_file_t *parent = NULL;
    626         vfs_pair_t *parent_node = NULL;
     619        vfs_node_t *parent_node = root;
    627620        // TODO: Client-side root.
    628621        if (parentfd != -1) {
     
    633626                        return;
    634627                }
    635                 parent_node = (vfs_pair_t *)parent->node;
     628                parent_node = parent->node;
    636629        }
    637630       
     
    639632       
    640633        vfs_lookup_res_t lr;
    641         rc = vfs_lookup_internal(path, walk_lookup_flags(flags), &lr, parent_node);
     634        rc = vfs_lookup_internal((vfs_triplet_t *) parent_node, path, walk_lookup_flags(flags), &lr);
    642635        free(path);
    643636
     
    10691062        vfs_file_t *parent = NULL;
    10701063        vfs_file_t *expect = NULL;
    1071         vfs_pair_t *parent_node = NULL;
     1064        vfs_node_t *parent_node = root;
    10721065       
    10731066        int parentfd = IPC_GET_ARG1(*request);
     
    10911084                        goto exit;
    10921085                }
    1093                 parent_node = (vfs_pair_t *)parent->node;
     1086                parent_node = parent->node;
    10941087        }
    10951088       
     
    11021095               
    11031096                vfs_lookup_res_t lr;
    1104                 rc = vfs_lookup_internal(path, lflag, &lr, parent_node);
     1097                rc = vfs_lookup_internal((vfs_triplet_t *) parent_node, path, lflag, &lr);
    11051098                if (rc != EOK) {
    11061099                        goto exit;
     
    11171110       
    11181111        vfs_lookup_res_t lr;
    1119         rc = vfs_lookup_internal(path, lflag | L_UNLINK, &lr, parent_node);
     1112        rc = vfs_lookup_internal((vfs_triplet_t *) parent_node, path, lflag | L_UNLINK, &lr);
    11201113        if (rc != EOK) {
    11211114                goto exit;
     
    12011194       
    12021195        /* Lookup the node belonging to the old file name. */
    1203         rc = vfs_lookup_internal(oldc, L_NONE, &old_lr, NULL);
     1196        rc = vfs_lookup_internal((vfs_triplet_t *) root, oldc, L_NONE, &old_lr);
    12041197        if (rc != EOK) {
    12051198                fibril_rwlock_write_unlock(&namespace_rwlock);
     
    12371230       
    12381231        /* Lookup parent of the new file name. */
    1239         rc = vfs_lookup_internal(parentc, L_NONE, &new_par_lr, NULL);
     1232        rc = vfs_lookup_internal((vfs_triplet_t *) root, parentc, L_NONE, &new_par_lr);
    12401233        free(parentc);  /* not needed anymore */
    12411234        if (rc != EOK) {
     
    12611254        /* Destroy the old link for the new name. */
    12621255        vfs_node_t *new_node = NULL;
    1263         rc = vfs_lookup_internal(newc, L_UNLINK, &new_lr, NULL);
     1256        rc = vfs_lookup_internal((vfs_triplet_t *) root, newc, L_UNLINK, &new_lr);
    12641257       
    12651258        switch (rc) {
     
    12911284       
    12921285        /* Create the new link for the new name. */
    1293         rc = vfs_lookup_internal(newc, L_LINK, NULL, NULL, old_node->index);
     1286        rc = vfs_link_internal((vfs_triplet_t *) root, newc, (vfs_triplet_t *) old_node);
    12941287        if (rc != EOK) {
    12951288                fibril_rwlock_write_unlock(&namespace_rwlock);
     
    13081301       
    13091302        /* Destroy the link for the old name. */
    1310         rc = vfs_lookup_internal(oldc, L_UNLINK, NULL, NULL);
     1303        rc = vfs_lookup_internal((vfs_triplet_t *) root, oldc, L_UNLINK, NULL);
    13111304        if (rc != EOK) {
    13121305                fibril_rwlock_write_unlock(&namespace_rwlock);
Note: See TracChangeset for help on using the changeset viewer.