Ignore:
File:
1 edited

Legend:

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

    r4cac2d69 rf29a3a2  
    266266       
    267267        /* We want the client to send us the mount point. */
    268         char *mp;
    269         int rc = async_data_write_accept((void **) &mp, true, 0, MAX_PATH_LEN,
    270             0, NULL);
    271         if (rc != EOK) {
    272                 ipc_answer_0(rid, rc);
    273                 return;
    274         }
     268        ipc_callid_t callid;
     269        size_t size;
     270        if (!async_data_write_receive(&callid, &size)) {
     271                ipc_answer_0(callid, EINVAL);
     272                ipc_answer_0(rid, EINVAL);
     273                return;
     274        }
     275       
     276        /* Check whether size is reasonable wrt. the mount point. */
     277        if ((size < 1) || (size > MAX_PATH_LEN)) {
     278                ipc_answer_0(callid, EINVAL);
     279                ipc_answer_0(rid, EINVAL);
     280                return;
     281        }
     282       
     283        /* Allocate buffer for the mount point data being received. */
     284        char *mp = malloc(size + 1);
     285        if (!mp) {
     286                ipc_answer_0(callid, ENOMEM);
     287                ipc_answer_0(rid, ENOMEM);
     288                return;
     289        }
     290       
     291        /* Deliver the mount point. */
     292        ipcarg_t retval = async_data_write_finalize(callid, mp, size);
     293        if (retval != EOK) {
     294                ipc_answer_0(rid, retval);
     295                free(mp);
     296                return;
     297        }
     298        mp[size] = '\0';
    275299       
    276300        /* Now we expect to receive the mount options. */
    277         char *opts;
    278         rc = async_data_write_accept((void **) &opts, true, 0, MAX_MNTOPTS_LEN,
    279             0, NULL);
    280         if (rc != EOK) {
     301        if (!async_data_write_receive(&callid, &size)) {
     302                ipc_answer_0(callid, EINVAL);
     303                ipc_answer_0(rid, EINVAL);
    281304                free(mp);
    282                 ipc_answer_0(rid, rc);
    283                 return;
    284         }
     305                return;
     306        }
     307
     308        /* Check the offered options size. */
     309        if (size > MAX_MNTOPTS_LEN) {
     310                ipc_answer_0(callid, EINVAL);
     311                ipc_answer_0(rid, EINVAL);
     312                free(mp);
     313                return;
     314        }
     315
     316        /* Allocate buffer for the mount options. */
     317        char *opts = (char *) malloc(size + 1);
     318        if (!opts) {
     319                ipc_answer_0(callid, ENOMEM);
     320                ipc_answer_0(rid, ENOMEM);
     321                free(mp);
     322                return;
     323        }
     324
     325        /* Deliver the mount options. */
     326        retval = async_data_write_finalize(callid, opts, size);
     327        if (retval != EOK) {
     328                ipc_answer_0(rid, retval);
     329                free(mp);
     330                free(opts);
     331                return;
     332        }
     333        opts[size] = '\0';
    285334       
    286335        /*
     
    288337         * system.
    289338         */
    290         char *fs_name;
    291         rc = async_data_write_accept((void **) &fs_name, true, 0, FS_NAME_MAXLEN,
    292             0, NULL);
    293         if (rc != EOK) {
     339        if (!async_data_write_receive(&callid, &size)) {
     340                ipc_answer_0(callid, EINVAL);
     341                ipc_answer_0(rid, EINVAL);
    294342                free(mp);
    295343                free(opts);
    296                 ipc_answer_0(rid, rc);
    297                 return;
    298         }
    299        
     344                return;
     345        }
     346       
     347        /*
     348         * Don't receive more than is necessary for storing a full file system
     349         * name.
     350         */
     351        if ((size < 1) || (size > FS_NAME_MAXLEN)) {
     352                ipc_answer_0(callid, EINVAL);
     353                ipc_answer_0(rid, EINVAL);
     354                free(mp);
     355                free(opts);
     356                return;
     357        }
     358       
     359        /*
     360         * Allocate buffer for file system name.
     361         */
     362        char *fs_name = (char *) malloc(size + 1);
     363        if (fs_name == NULL) {
     364                ipc_answer_0(callid, ENOMEM);
     365                ipc_answer_0(rid, ENOMEM);
     366                free(mp);
     367                free(opts);
     368                return;
     369        }
     370       
     371        /* Deliver the file system name. */
     372        retval = async_data_write_finalize(callid, fs_name, size);
     373        if (retval != EOK) {
     374                ipc_answer_0(rid, retval);
     375                free(mp);
     376                free(opts);
     377                free(fs_name);
     378                return;
     379        }
     380        fs_name[size] = '\0';
     381
    300382        /*
    301383         * Wait for IPC_M_PING so that we can return an error if we don't know
     
    303385         */
    304386        ipc_call_t data;
    305         ipc_callid_t callid = async_get_call(&data);
     387        callid = async_get_call(&data);
    306388        if (IPC_GET_METHOD(data) != IPC_M_PING) {
    307389                ipc_answer_0(callid, ENOTSUP);
     
    360442         * Receive the mount point path.
    361443         */
    362         rc = async_data_write_accept((void **) &mp, true, 0, MAX_PATH_LEN,
    363             0, NULL);
     444        rc = async_data_string_receive(&mp, MAX_PATH_LEN);
    364445        if (rc != EOK)
    365446                ipc_answer_0(rid, rc);
     
    525606                lflag |= L_EXCLUSIVE;
    526607       
    527         char *path;
    528         int rc = async_data_write_accept((void **) &path, true, 0, 0, 0, NULL);
    529         if (rc != EOK) {
    530                 ipc_answer_0(rid, rc);
    531                 return;
    532         }
     608        ipc_callid_t callid;
     609        if (!async_data_write_receive(&callid, &len)) {
     610                ipc_answer_0(callid, EINVAL);
     611                ipc_answer_0(rid, EINVAL);
     612                return;
     613        }
     614       
     615        char *path = malloc(len + 1);
     616        if (!path) {
     617                ipc_answer_0(callid, ENOMEM);
     618                ipc_answer_0(rid, ENOMEM);
     619                return;
     620        }
     621       
     622        int rc;
     623        if ((rc = async_data_write_finalize(callid, path, len))) {
     624                ipc_answer_0(rid, rc);
     625                free(path);
     626                return;
     627        }
     628        path[len] = '\0';
    533629       
    534630        /*
     
    798894       
    799895        /*
     896         * Now we need to receive a call with client's
     897         * IPC_M_DATA_READ/IPC_M_DATA_WRITE request.
     898         */
     899        ipc_callid_t callid;
     900        int res;
     901        if (read)
     902                res = async_data_read_receive(&callid, NULL);
     903        else
     904                res = async_data_write_receive(&callid, NULL);
     905        if (!res) {
     906                ipc_answer_0(callid, EINVAL);
     907                ipc_answer_0(rid, EINVAL);
     908                return;
     909        }
     910       
     911        /*
    800912         * Lock the open file structure so that no other thread can manipulate
    801913         * the same open file at a time.
     
    821933        }
    822934       
    823         int fs_phone = vfs_grab_phone(file->node->fs_handle);
    824        
    825         /*
    826          * Make a VFS_READ/VFS_WRITE request at the destination FS server
    827          * and forward the IPC_M_DATA_READ/IPC_M_DATA_WRITE request to the
     935        int fs_phone = vfs_grab_phone(file->node->fs_handle);   
     936       
     937        /* Make a VFS_READ/VFS_WRITE request at the destination FS server. */
     938        aid_t msg;
     939        ipc_call_t answer;
     940        if (!read && file->append)
     941                file->pos = file->node->size;
     942        msg = async_send_3(fs_phone, read ? VFS_OUT_READ : VFS_OUT_WRITE,
     943            file->node->dev_handle, file->node->index, file->pos, &answer);
     944       
     945        /*
     946         * Forward the IPC_M_DATA_READ/IPC_M_DATA_WRITE request to the
    828947         * destination FS server. The call will be routed as if sent by
    829948         * ourselves. Note that call arguments are immutable in this case so we
    830949         * don't have to bother.
    831950         */
     951        ipc_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
     952
     953        /* Wait for reply from the FS server. */
    832954        ipcarg_t rc;
    833         ipc_call_t answer;
    834         if (read) {
    835                 if (file->append)
    836                         file->pos = file->node->size;
    837                
    838                 rc = async_data_read_forward_3_1(fs_phone, VFS_OUT_READ,
    839                     file->node->dev_handle, file->node->index, file->pos,
    840                     &answer);
    841         } else {
    842                 rc = async_data_write_forward_3_1(fs_phone, VFS_OUT_WRITE,
    843                     file->node->dev_handle, file->node->index, file->pos,
    844                     &answer);
    845         }
     955        async_wait_for(msg, &rc);
    846956       
    847957        vfs_release_phone(fs_phone);
    848958       
    849959        size_t bytes = IPC_GET_ARG1(answer);
    850        
     960
    851961        if (file->node->type == VFS_NODE_DIRECTORY)
    852962                fibril_rwlock_read_unlock(&namespace_rwlock);
     
    10101120void vfs_stat(ipc_callid_t rid, ipc_call_t *request)
    10111121{
    1012         char *path;
    1013         int rc = async_data_write_accept((void **) &path, true, 0, 0, 0, NULL);
    1014         if (rc != EOK) {
    1015                 ipc_answer_0(rid, rc);
    1016                 return;
    1017         }
    1018        
     1122        size_t len;
    10191123        ipc_callid_t callid;
     1124
     1125        if (!async_data_write_receive(&callid, &len)) {
     1126                ipc_answer_0(callid, EINVAL);
     1127                ipc_answer_0(rid, EINVAL);
     1128                return;
     1129        }
     1130        char *path = malloc(len + 1);
     1131        if (!path) {
     1132                ipc_answer_0(callid, ENOMEM);
     1133                ipc_answer_0(rid, ENOMEM);
     1134                return;
     1135        }
     1136        int rc;
     1137        if ((rc = async_data_write_finalize(callid, path, len))) {
     1138                ipc_answer_0(rid, rc);
     1139                free(path);
     1140                return;
     1141        }
     1142        path[len] = '\0';
     1143
    10201144        if (!async_data_read_receive(&callid, NULL)) {
    10211145                free(path);
     
    10631187{
    10641188        int mode = IPC_GET_ARG1(*request);
    1065        
    1066         char *path;
    1067         int rc = async_data_write_accept((void **) &path, true, 0, 0, 0, NULL);
    1068         if (rc != EOK) {
    1069                 ipc_answer_0(rid, rc);
    1070                 return;
    1071         }
    1072        
     1189
     1190        size_t len;
     1191        ipc_callid_t callid;
     1192
     1193        if (!async_data_write_receive(&callid, &len)) {
     1194                ipc_answer_0(callid, EINVAL);
     1195                ipc_answer_0(rid, EINVAL);
     1196                return;
     1197        }
     1198        char *path = malloc(len + 1);
     1199        if (!path) {
     1200                ipc_answer_0(callid, ENOMEM);
     1201                ipc_answer_0(rid, ENOMEM);
     1202                return;
     1203        }
     1204        int rc;
     1205        if ((rc = async_data_write_finalize(callid, path, len))) {
     1206                ipc_answer_0(rid, rc);
     1207                free(path);
     1208                return;
     1209        }
     1210        path[len] = '\0';
     1211
    10731212        /* Ignore mode for now. */
    10741213        (void) mode;
     
    10851224{
    10861225        int lflag = IPC_GET_ARG1(*request);
    1087        
    1088         char *path;
    1089         int rc = async_data_write_accept((void **) &path, true, 0, 0, 0, NULL);
    1090         if (rc != EOK) {
    1091                 ipc_answer_0(rid, rc);
    1092                 return;
    1093         }
     1226
     1227        size_t len;
     1228        ipc_callid_t callid;
     1229
     1230        if (!async_data_write_receive(&callid, &len)) {
     1231                ipc_answer_0(callid, EINVAL);
     1232                ipc_answer_0(rid, EINVAL);
     1233                return;
     1234        }
     1235        char *path = malloc(len + 1);
     1236        if (!path) {
     1237                ipc_answer_0(callid, ENOMEM);
     1238                ipc_answer_0(rid, ENOMEM);
     1239                return;
     1240        }
     1241        int rc;
     1242        if ((rc = async_data_write_finalize(callid, path, len))) {
     1243                ipc_answer_0(rid, rc);
     1244                free(path);
     1245                return;
     1246        }
     1247        path[len] = '\0';
    10941248       
    10951249        fibril_rwlock_write_lock(&namespace_rwlock);
     
    11201274void vfs_rename(ipc_callid_t rid, ipc_call_t *request)
    11211275{
     1276        size_t olen, nlen;
     1277        ipc_callid_t callid;
     1278        int rc;
     1279
    11221280        /* Retrieve the old path. */
    1123         char *old;
    1124         int rc = async_data_write_accept((void **) &old, true, 0, 0, 0, NULL);
    1125         if (rc != EOK) {
    1126                 ipc_answer_0(rid, rc);
    1127                 return;
    1128         }
     1281        if (!async_data_write_receive(&callid, &olen)) {
     1282                ipc_answer_0(callid, EINVAL);
     1283                ipc_answer_0(rid, EINVAL);
     1284                return;
     1285        }
     1286        char *old = malloc(olen + 1);
     1287        if (!old) {
     1288                ipc_answer_0(callid, ENOMEM);
     1289                ipc_answer_0(rid, ENOMEM);
     1290                return;
     1291        }
     1292        if ((rc = async_data_write_finalize(callid, old, olen))) {
     1293                ipc_answer_0(rid, rc);
     1294                free(old);
     1295                return;
     1296        }
     1297        old[olen] = '\0';
    11291298       
    11301299        /* Retrieve the new path. */
    1131         char *new;
    1132         rc = async_data_write_accept((void **) &new, true, 0, 0, 0, NULL);
    1133         if (rc != EOK) {
     1300        if (!async_data_write_receive(&callid, &nlen)) {
     1301                ipc_answer_0(callid, EINVAL);
     1302                ipc_answer_0(rid, EINVAL);
    11341303                free(old);
    1135                 ipc_answer_0(rid, rc);
    1136                 return;
    1137         }
    1138        
    1139         size_t olen;
    1140         size_t nlen;
     1304                return;
     1305        }
     1306        char *new = malloc(nlen + 1);
     1307        if (!new) {
     1308                ipc_answer_0(callid, ENOMEM);
     1309                ipc_answer_0(rid, ENOMEM);
     1310                free(old);
     1311                return;
     1312        }
     1313        if ((rc = async_data_write_finalize(callid, new, nlen))) {
     1314                ipc_answer_0(rid, rc);
     1315                free(old);
     1316                free(new);
     1317                return;
     1318        }
     1319        new[nlen] = '\0';
     1320
    11411321        char *oldc = canonify(old, &olen);
    11421322        char *newc = canonify(new, &nlen);
    1143        
    1144         if ((!oldc) || (!newc)) {
     1323        if (!oldc || !newc) {
    11451324                ipc_answer_0(rid, EINVAL);
    11461325                free(old);
     
    11481327                return;
    11491328        }
    1150        
    11511329        oldc[olen] = '\0';
    11521330        newc[nlen] = '\0';
    1153        
    11541331        if ((!str_lcmp(newc, oldc, str_length(oldc))) &&
    11551332            ((newc[str_length(oldc)] == '/') ||
     
    11721349        vfs_lookup_res_t new_par_lr;
    11731350        fibril_rwlock_write_lock(&namespace_rwlock);
    1174        
    11751351        /* Lookup the node belonging to the old file name. */
    11761352        rc = vfs_lookup_internal(oldc, L_NONE, &old_lr, NULL);
     
    11821358                return;
    11831359        }
    1184        
    11851360        vfs_node_t *old_node = vfs_node_get(&old_lr);
    11861361        if (!old_node) {
     
    11911366                return;
    11921367        }
    1193        
    11941368        /* Determine the path to the parent of the node with the new name. */
    11951369        char *parentc = str_dup(newc);
     
    12011375                return;
    12021376        }
    1203        
    12041377        char *lastsl = str_rchr(parentc + 1, '/');
    12051378        if (lastsl)
     
    12071380        else
    12081381                parentc[1] = '\0';
    1209        
    12101382        /* Lookup parent of the new file name. */
    12111383        rc = vfs_lookup_internal(parentc, L_NONE, &new_par_lr, NULL);
     
    12181390                return;
    12191391        }
    1220        
    12211392        /* Check whether linking to the same file system instance. */
    12221393        if ((old_node->fs_handle != new_par_lr.triplet.fs_handle) ||
     
    12281399                return;
    12291400        }
    1230        
    12311401        /* Destroy the old link for the new name. */
    12321402        vfs_node_t *new_node = NULL;
    12331403        rc = vfs_lookup_internal(newc, L_UNLINK, &new_lr, NULL);
    1234        
    12351404        switch (rc) {
    12361405        case ENOENT:
     
    12571426                return;
    12581427        }
    1259        
    12601428        /* Create the new link for the new name. */
    12611429        rc = vfs_lookup_internal(newc, L_LINK, NULL, NULL, old_node->index);
     
    12691437                return;
    12701438        }
    1271        
    12721439        fibril_mutex_lock(&nodes_mutex);
    12731440        old_node->lnkcnt++;
    12741441        fibril_mutex_unlock(&nodes_mutex);
    1275        
    12761442        /* Destroy the link for the old name. */
    12771443        rc = vfs_lookup_internal(oldc, L_UNLINK, NULL, NULL);
     
    12861452                return;
    12871453        }
    1288        
    12891454        fibril_mutex_lock(&nodes_mutex);
    12901455        old_node->lnkcnt--;
     
    12921457        fibril_rwlock_write_unlock(&namespace_rwlock);
    12931458        vfs_node_put(old_node);
    1294        
    12951459        if (new_node)
    12961460                vfs_node_put(new_node);
    1297        
    12981461        free(old);
    12991462        free(new);
Note: See TracChangeset for help on using the changeset viewer.