Changeset bf9dc4e2 in mainline for uspace/srv/vfs/vfs_ops.c
- Timestamp:
- 2013-07-28T19:32:36Z (11 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 778d26d
- Parents:
- d60ce4a
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/vfs/vfs_ops.c
rd60ce4a rbf9dc4e2 68 68 FIBRIL_RWLOCK_INITIALIZE(namespace_rwlock); 69 69 70 vfs_pair_t rootfs = { 71 .fs_handle = 0, 72 .service_id = 0 73 }; 70 vfs_node_t *root = NULL; 74 71 75 72 static int vfs_mount_internal(ipc_callid_t rid, service_id_t service_id, … … 90 87 /* Resolve the path to the mountpoint. */ 91 88 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) { 122 90 /* 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) { 175 92 /* 176 93 * We can't resolve this without the root filesystem … … 181 98 return ENOENT; 182 99 } 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 */ 184 178 185 179 /* … … 435 429 * Lookup the mounted root and instantiate it. 436 430 */ 437 rc = vfs_lookup_internal( mp, L_ROOT, &mr_res, NULL);431 rc = vfs_lookup_internal((vfs_triplet_t *) root, mp, 0, &mr_res); 438 432 if (rc != EOK) { 439 433 fibril_rwlock_write_unlock(&namespace_rwlock); … … 488 482 } 489 483 490 rootfs.fs_handle = 0; 491 rootfs.service_id = 0; 484 root = NULL; 492 485 } else { 493 486 … … 499 492 */ 500 493 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); 502 495 if (rc != EOK) { 503 496 fibril_rwlock_write_unlock(&namespace_rwlock); … … 624 617 /* Lookup the file structure corresponding to the file descriptor. */ 625 618 vfs_file_t *parent = NULL; 626 vfs_ pair_t *parent_node = NULL;619 vfs_node_t *parent_node = root; 627 620 // TODO: Client-side root. 628 621 if (parentfd != -1) { … … 633 626 return; 634 627 } 635 parent_node = (vfs_pair_t *)parent->node;628 parent_node = parent->node; 636 629 } 637 630 … … 639 632 640 633 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); 642 635 free(path); 643 636 … … 1069 1062 vfs_file_t *parent = NULL; 1070 1063 vfs_file_t *expect = NULL; 1071 vfs_ pair_t *parent_node = NULL;1064 vfs_node_t *parent_node = root; 1072 1065 1073 1066 int parentfd = IPC_GET_ARG1(*request); … … 1091 1084 goto exit; 1092 1085 } 1093 parent_node = (vfs_pair_t *)parent->node;1086 parent_node = parent->node; 1094 1087 } 1095 1088 … … 1102 1095 1103 1096 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); 1105 1098 if (rc != EOK) { 1106 1099 goto exit; … … 1117 1110 1118 1111 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); 1120 1113 if (rc != EOK) { 1121 1114 goto exit; … … 1201 1194 1202 1195 /* 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); 1204 1197 if (rc != EOK) { 1205 1198 fibril_rwlock_write_unlock(&namespace_rwlock); … … 1237 1230 1238 1231 /* 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); 1240 1233 free(parentc); /* not needed anymore */ 1241 1234 if (rc != EOK) { … … 1261 1254 /* Destroy the old link for the new name. */ 1262 1255 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); 1264 1257 1265 1258 switch (rc) { … … 1291 1284 1292 1285 /* Create the new link for the new name. */ 1293 rc = vfs_l ookup_internal(newc, L_LINK, NULL, NULL, old_node->index);1286 rc = vfs_link_internal((vfs_triplet_t *) root, newc, (vfs_triplet_t *) old_node); 1294 1287 if (rc != EOK) { 1295 1288 fibril_rwlock_write_unlock(&namespace_rwlock); … … 1308 1301 1309 1302 /* 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); 1311 1304 if (rc != EOK) { 1312 1305 fibril_rwlock_write_unlock(&namespace_rwlock);
Note:
See TracChangeset
for help on using the changeset viewer.