Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/fs/ext2fs/ext2fs_ops.c

    r82a3b31f refcebe1  
    11/*
    2  * Copyright (c) 2008 Jakub Jermar
    32 * Copyright (c) 2011 Martin Sucha
    43 * All rights reserved.
     
    8786 */
    8887static int ext2fs_instance_get(devmap_handle_t, ext2fs_instance_t **);
    89 static void ext2fs_read_directory(ipc_callid_t, ipc_callid_t, aoff64_t,
    90         size_t, ext2fs_instance_t *, ext2_inode_ref_t *);
    91 static void ext2fs_read_file(ipc_callid_t, ipc_callid_t, aoff64_t,
    92         size_t, ext2fs_instance_t *, ext2_inode_ref_t *);
     88static int ext2fs_read_directory(ipc_callid_t, aoff64_t, size_t,
     89    ext2fs_instance_t *, ext2_inode_ref_t *, size_t *);
     90static int ext2fs_read_file(ipc_callid_t, aoff64_t, size_t, ext2fs_instance_t *,
     91    ext2_inode_ref_t *, size_t *);
    9392static bool ext2fs_is_dots(const uint8_t *, size_t);
    9493static int ext2fs_node_get_core(fs_node_t **, ext2fs_instance_t *, fs_index_t);
     
    111110static aoff64_t ext2fs_size_get(fs_node_t *);
    112111static unsigned ext2fs_lnkcnt_get(fs_node_t *);
    113 static char ext2fs_plb_get_char(unsigned);
    114112static bool ext2fs_is_directory(fs_node_t *);
    115113static bool ext2fs_is_file(fs_node_t *node);
     
    187185{
    188186        EXT2FS_DBG("(%" PRIun ", -)", devmap_handle);
    189         link_t *link;
    190187        ext2fs_instance_t *tmp;
    191188       
     
    198195        }
    199196
    200         for (link = instance_list.next; link != &instance_list; link = link->next) {
     197        list_foreach(instance_list, link) {
    201198                tmp = list_get_instance(link, ext2fs_instance_t, link);
    202199               
     
    241238        }
    242239       
    243         rc = ext2_directory_iterator_init(&it, fs, eparent->inode_ref);
     240        rc = ext2_directory_iterator_init(&it, fs, eparent->inode_ref, 0);
    244241        if (rc != EOK) {
    245242                return rc;
     
    479476        }
    480477       
    481         rc = ext2_directory_iterator_init(&it, fs, enode->inode_ref);
     478        rc = ext2_directory_iterator_init(&it, fs, enode->inode_ref, 0);
    482479        if (rc != EOK) {
    483480                EXT2FS_DBG("error %u", rc);
     
    539536        EXT2FS_DBG("%u", count);
    540537        return count;
    541 }
    542 
    543 char ext2fs_plb_get_char(unsigned pos)
    544 {
    545         return ext2fs_reg.plb_ro[pos % PLB_SIZE];
    546538}
    547539
     
    587579        .size_get = ext2fs_size_get,
    588580        .lnkcnt_get = ext2fs_lnkcnt_get,
    589         .plb_get_char = ext2fs_plb_get_char,
    590581        .is_directory = ext2fs_is_directory,
    591582        .is_file = ext2fs_is_file,
     
    597588 */
    598589
    599 void ext2fs_mounted(ipc_callid_t rid, ipc_call_t *request)
    600 {
    601         EXT2FS_DBG("");
    602         int rc;
    603         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
     590static int ext2fs_mounted(devmap_handle_t devmap_handle, const char *opts,
     591   fs_index_t *index, aoff64_t *size, unsigned *lnkcnt)
     592{
     593        EXT2FS_DBG("");
     594        int rc;
    604595        ext2_filesystem_t *fs;
    605596        ext2fs_instance_t *inst;
    606597        bool read_only;
    607598       
    608         /* Accept the mount options */
    609         char *opts;
    610         rc = async_data_write_accept((void **) &opts, true, 0, 0, 0, NULL);
    611        
    612         if (rc != EOK) {
    613                 async_answer_0(rid, rc);
    614                 return;
    615         }
    616 
    617         free(opts);
    618        
    619599        /* Allocate libext2 filesystem structure */
    620600        fs = (ext2_filesystem_t *) malloc(sizeof(ext2_filesystem_t));
    621         if (fs == NULL) {
    622                 async_answer_0(rid, ENOMEM);
    623                 return;
    624         }
     601        if (fs == NULL)
     602                return ENOMEM;
    625603       
    626604        /* Allocate instance structure */
     
    628606        if (inst == NULL) {
    629607                free(fs);
    630                 async_answer_0(rid, ENOMEM);
    631                 return;
     608                return ENOMEM;
    632609        }
    633610       
     
    637614                free(fs);
    638615                free(inst);
    639                 async_answer_0(rid, rc);
    640                 return;
     616                return rc;
    641617        }
    642618       
     
    647623                free(fs);
    648624                free(inst);
    649                 async_answer_0(rid, rc);
    650                 return;
     625                return rc;
    651626        }
    652627       
     
    657632                free(fs);
    658633                free(inst);
    659                 async_answer_0(rid, rc);
    660                 return;
     634                return rc;
    661635        }
    662636       
     
    674648                free(fs);
    675649                free(inst);
    676                 async_answer_0(rid, rc);
    677                 return;
     650                return rc;
    678651        }
    679652        ext2fs_node_t *enode = EXT2FS_NODE(root_node);
     
    684657        fibril_mutex_unlock(&instance_list_mutex);
    685658       
    686         async_answer_3(rid, EOK,
    687             EXT2_INODE_ROOT_INDEX,
    688             0,
    689             ext2_inode_get_usage_count(enode->inode_ref->inode));
     659        *index = EXT2_INODE_ROOT_INDEX;
     660        *size = 0;
     661        *lnkcnt = ext2_inode_get_usage_count(enode->inode_ref->inode);
    690662       
    691663        ext2fs_node_put(root_node);
    692 }
    693 
    694 void ext2fs_mount(ipc_callid_t rid, ipc_call_t *request)
    695 {
    696         EXT2FS_DBG("");
    697         libfs_mount(&ext2fs_libfs_ops, ext2fs_reg.fs_handle, rid, request);
    698 }
    699 
    700 void ext2fs_unmounted(ipc_callid_t rid, ipc_call_t *request)
    701 {
    702         EXT2FS_DBG("");
    703         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
     664
     665        return EOK;
     666}
     667
     668static int ext2fs_unmounted(devmap_handle_t devmap_handle)
     669{
     670        EXT2FS_DBG("");
    704671        ext2fs_instance_t *inst;
    705672        int rc;
     
    707674        rc = ext2fs_instance_get(devmap_handle, &inst);
    708675       
    709         if (rc != EOK) {
    710                 async_answer_0(rid, rc);
    711                 return;
    712         }
     676        if (rc != EOK)
     677                return rc;
    713678       
    714679        fibril_mutex_lock(&open_nodes_lock);
     
    717682        if (inst->open_nodes_count != 0) {
    718683                fibril_mutex_unlock(&open_nodes_lock);
    719                 async_answer_0(rid, EBUSY);
    720                 return;
     684                return EBUSY;
    721685        }
    722686       
     
    730694        ext2_filesystem_fini(inst->filesystem);
    731695       
    732         async_answer_0(rid, EOK);
    733 }
    734 
    735 void ext2fs_unmount(ipc_callid_t rid, ipc_call_t *request)
    736 {
    737         EXT2FS_DBG("");
    738         libfs_unmount(&ext2fs_libfs_ops, rid, request);
    739 }
    740 
    741 void ext2fs_lookup(ipc_callid_t rid, ipc_call_t *request)
    742 {
    743         EXT2FS_DBG("");
    744         libfs_lookup(&ext2fs_libfs_ops, ext2fs_reg.fs_handle, rid, request);
    745 }
    746 
    747 void ext2fs_read(ipc_callid_t rid, ipc_call_t *request)
    748 {
    749         EXT2FS_DBG("");
    750         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    751         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    752         aoff64_t pos =
    753             (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
     696        return EOK;
     697}
     698
     699static int
     700ext2fs_read(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos,
     701    size_t *rbytes)
     702{
     703        EXT2FS_DBG("");
    754704       
    755705        ext2fs_instance_t *inst;
     
    764714        if (!async_data_read_receive(&callid, &size)) {
    765715                async_answer_0(callid, EINVAL);
    766                 async_answer_0(rid, EINVAL);
    767                 return;
     716                return EINVAL;
    768717        }
    769718       
     
    771720        if (rc != EOK) {
    772721                async_answer_0(callid, rc);
    773                 async_answer_0(rid, rc);
    774                 return;
     722                return rc;
    775723        }
    776724       
     
    778726        if (rc != EOK) {
    779727                async_answer_0(callid, rc);
    780                 async_answer_0(rid, rc);
    781                 return;
     728                return rc;
    782729        }
    783730       
    784731        if (ext2_inode_is_type(inst->filesystem->superblock, inode_ref->inode,
    785                     EXT2_INODE_MODE_FILE)) {
    786                 ext2fs_read_file(rid, callid, pos, size, inst, inode_ref);
    787         }
    788         else if (ext2_inode_is_type(inst->filesystem->superblock, inode_ref->inode,
    789                     EXT2_INODE_MODE_DIRECTORY)) {
    790                 ext2fs_read_directory(rid, callid, pos, size, inst, inode_ref);
    791         }
    792         else {
     732            EXT2_INODE_MODE_FILE)) {
     733                rc = ext2fs_read_file(callid, pos, size, inst, inode_ref,
     734                    rbytes);
     735        } else if (ext2_inode_is_type(inst->filesystem->superblock,
     736            inode_ref->inode, EXT2_INODE_MODE_DIRECTORY)) {
     737                rc = ext2fs_read_directory(callid, pos, size, inst, inode_ref,
     738                    rbytes);
     739        } else {
    793740                /* Other inode types not supported */
    794741                async_answer_0(callid, ENOTSUP);
    795                 async_answer_0(rid, ENOTSUP);
     742                rc = ENOTSUP;
    796743        }
    797744       
    798745        ext2_filesystem_put_inode_ref(inode_ref);
    799746       
     747        return rc;
    800748}
    801749
     
    815763}
    816764
    817 void ext2fs_read_directory(ipc_callid_t rid, ipc_callid_t callid, aoff64_t pos,
    818         size_t size, ext2fs_instance_t *inst, ext2_inode_ref_t *inode_ref)
     765int ext2fs_read_directory(ipc_callid_t callid, aoff64_t pos, size_t size,
     766    ext2fs_instance_t *inst, ext2_inode_ref_t *inode_ref, size_t *rbytes)
    819767{
    820768        ext2_directory_iterator_t it;
    821         aoff64_t cur;
     769        aoff64_t next;
    822770        uint8_t *buf;
    823771        size_t name_size;
     
    825773        bool found = false;
    826774       
    827         rc = ext2_directory_iterator_init(&it, inst->filesystem, inode_ref);
     775        rc = ext2_directory_iterator_init(&it, inst->filesystem, inode_ref, pos);
    828776        if (rc != EOK) {
    829777                async_answer_0(callid, rc);
    830                 async_answer_0(rid, rc);
    831                 return;
    832         }
    833        
    834         /* Find the index we want to read
    835          * Note that we need to iterate and count as
    836          * the underlying structure is a linked list
    837          * Moreover, we want to skip . and .. entries
     778                return rc;
     779        }
     780       
     781        /* Find next interesting directory entry.
     782         * We want to skip . and .. entries
    838783         * as these are not used in HelenOS
    839784         */
    840         cur = 0;
    841785        while (it.current != NULL) {
    842786                if (it.current->inode == 0) {
     
    845789               
    846790                name_size = ext2_directory_entry_ll_get_name_length(
    847                         inst->filesystem->superblock, it.current);
     791                    inst->filesystem->superblock, it.current);
    848792               
    849793                /* skip . and .. */
     
    852796                }
    853797               
    854                 /* Is this the dir entry we want to read? */
    855                 if (cur == pos) {
    856                         /* The on-disk entry does not contain \0 at the end
    857                          * end of entry name, so we copy it to new buffer
    858                          * and add the \0 at the end
    859                          */
    860                         buf = malloc(name_size+1);
    861                         if (buf == NULL) {
    862                                 ext2_directory_iterator_fini(&it);
    863                                 async_answer_0(callid, ENOMEM);
    864                                 async_answer_0(rid, ENOMEM);
    865                                 return;
    866                         }
    867                         memcpy(buf, &it.current->name, name_size);
    868                         *(buf+name_size) = 0;
    869                         found = true;
    870                         (void) async_data_read_finalize(callid, buf, name_size+1);
    871                         free(buf);
    872                         break;
    873                 }
    874                 cur++;
     798                /* The on-disk entry does not contain \0 at the end
     799                 * end of entry name, so we copy it to new buffer
     800                 * and add the \0 at the end
     801                 */
     802                buf = malloc(name_size+1);
     803                if (buf == NULL) {
     804                        ext2_directory_iterator_fini(&it);
     805                        async_answer_0(callid, ENOMEM);
     806                        return ENOMEM;
     807                }
     808                memcpy(buf, &it.current->name, name_size);
     809                *(buf + name_size) = 0;
     810                found = true;
     811                (void) async_data_read_finalize(callid, buf, name_size + 1);
     812                free(buf);
     813                break;
    875814               
    876815skip:
     
    879818                        ext2_directory_iterator_fini(&it);
    880819                        async_answer_0(callid, rc);
    881                         async_answer_0(rid, rc);
    882                         return;
    883                 }
     820                        return rc;
     821                }
     822        }
     823       
     824        if (found) {
     825                rc = ext2_directory_iterator_next(&it);
     826                if (rc != EOK)
     827                        return rc;
     828                next = it.current_offset;
    884829        }
    885830       
    886831        rc = ext2_directory_iterator_fini(&it);
    887         if (rc != EOK) {
    888                 async_answer_0(rid, rc);
    889                 return;
    890         }
     832        if (rc != EOK)
     833                return rc;
    891834       
    892835        if (found) {
    893                 async_answer_1(rid, EOK, 1);
    894         }
    895         else {
     836                *rbytes = next - pos;
     837                return EOK;
     838        } else {
    896839                async_answer_0(callid, ENOENT);
    897                 async_answer_0(rid, ENOENT);
    898         }
    899 }
    900 
    901 void ext2fs_read_file(ipc_callid_t rid, ipc_callid_t callid, aoff64_t pos,
    902         size_t size, ext2fs_instance_t *inst, ext2_inode_ref_t *inode_ref)
     840                return ENOENT;
     841        }
     842}
     843
     844int ext2fs_read_file(ipc_callid_t callid, aoff64_t pos, size_t size,
     845    ext2fs_instance_t *inst, ext2_inode_ref_t *inode_ref, size_t *rbytes)
    903846{
    904847        int rc;
     
    918861                /* Read 0 bytes successfully */
    919862                async_data_read_finalize(callid, NULL, 0);
    920                 async_answer_1(rid, EOK, 0);
    921                 return;
     863                *rbytes = 0;
     864                return EOK;
    922865        }
    923866       
     
    938881        if (rc != EOK) {
    939882                async_answer_0(callid, rc);
    940                 async_answer_0(rid, rc);
    941                 return;
     883                return rc;
    942884        }
    943885       
     
    951893                if (buffer == NULL) {
    952894                        async_answer_0(callid, ENOMEM);
    953                         async_answer_0(rid, ENOMEM);
    954                         return;
     895                        return ENOMEM;
    955896                }
    956897               
     
    958899               
    959900                async_data_read_finalize(callid, buffer, bytes);
    960                 async_answer_1(rid, EOK, bytes);
     901                *rbytes = bytes;
    961902               
    962903                free(buffer);
    963904               
    964                 return;
     905                return EOK;
    965906        }
    966907       
     
    969910        if (rc != EOK) {
    970911                async_answer_0(callid, rc);
    971                 async_answer_0(rid, rc);
    972                 return;
     912                return rc;
    973913        }
    974914       
     
    977917       
    978918        rc = block_put(block);
    979         if (rc != EOK) {
    980                 async_answer_0(rid, rc);
    981                 return;
    982         }
    983                
    984         async_answer_1(rid, EOK, bytes);
    985 }
    986 
    987 void ext2fs_write(ipc_callid_t rid, ipc_call_t *request)
    988 {
    989         EXT2FS_DBG("");
    990 //      devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    991 //      fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    992 //      aoff64_t pos =
    993 //          (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
    994        
    995         // TODO
    996         async_answer_0(rid, ENOTSUP);
    997 }
    998 
    999 void ext2fs_truncate(ipc_callid_t rid, ipc_call_t *request)
    1000 {
    1001         EXT2FS_DBG("");
    1002 //      devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    1003 //      fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    1004 //      aoff64_t size =
    1005 //          (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
    1006        
    1007         // TODO
    1008         async_answer_0(rid, ENOTSUP);
    1009 }
    1010 
    1011 void ext2fs_close(ipc_callid_t rid, ipc_call_t *request)
    1012 {
    1013         EXT2FS_DBG("");
    1014         async_answer_0(rid, EOK);
    1015 }
    1016 
    1017 void ext2fs_destroy(ipc_callid_t rid, ipc_call_t *request)
    1018 {
    1019         EXT2FS_DBG("");
    1020 //      devmap_handle_t devmap_handle = (devmap_handle_t)IPC_GET_ARG1(*request);
    1021 //      fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request);
    1022        
    1023         // TODO
    1024         async_answer_0(rid, ENOTSUP);
    1025 }
    1026 
    1027 void ext2fs_open_node(ipc_callid_t rid, ipc_call_t *request)
    1028 {
    1029         EXT2FS_DBG("");
    1030         libfs_open_node(&ext2fs_libfs_ops, ext2fs_reg.fs_handle, rid, request);
    1031 }
    1032 
    1033 void ext2fs_stat(ipc_callid_t rid, ipc_call_t *request)
    1034 {
    1035         EXT2FS_DBG("");
    1036         libfs_stat(&ext2fs_libfs_ops, ext2fs_reg.fs_handle, rid, request);
    1037 }
    1038 
    1039 void ext2fs_sync(ipc_callid_t rid, ipc_call_t *request)
    1040 {
    1041         EXT2FS_DBG("");
    1042 //      devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    1043 //      fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    1044        
    1045         // TODO
    1046         async_answer_0(rid, ENOTSUP);
    1047 }
     919        if (rc != EOK)
     920                return rc;
     921       
     922        *rbytes = bytes;
     923        return EOK;
     924}
     925
     926static int
     927ext2fs_write(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos,
     928    size_t *wbytes, aoff64_t *nsize)
     929{
     930        EXT2FS_DBG("");
     931        return ENOTSUP;
     932}
     933
     934static int
     935ext2fs_truncate(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t size)
     936{
     937        EXT2FS_DBG("");
     938        return ENOTSUP;
     939}
     940
     941static int ext2fs_close(devmap_handle_t devmap_handle, fs_index_t index)
     942{
     943        EXT2FS_DBG("");
     944        return EOK;
     945}
     946
     947static int ext2fs_destroy(devmap_handle_t devmap_handle, fs_index_t index)
     948{
     949        EXT2FS_DBG("");
     950        return ENOTSUP;
     951}
     952
     953static int ext2fs_sync(devmap_handle_t devmap_handle, fs_index_t index)
     954{
     955        EXT2FS_DBG("");
     956        return ENOTSUP;
     957}
     958
     959vfs_out_ops_t ext2fs_ops = {
     960        .mounted = ext2fs_mounted,
     961        .unmounted = ext2fs_unmounted,
     962        .read = ext2fs_read,
     963        .write = ext2fs_write,
     964        .truncate = ext2fs_truncate,
     965        .close = ext2fs_close,
     966        .destroy = ext2fs_destroy,
     967        .sync = ext2fs_sync,
     968};
    1048969
    1049970/**
    1050971 * @}
    1051972 */
     973
Note: See TracChangeset for help on using the changeset viewer.