Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/vfs/vfs.c

    r8d2dd7f2 rcde999a  
    8686 * and consume system resources.
    8787 *
    88  * Functions that return int return a negative error code on error and do not
     88 * Functions that return int return an error code on error and do not
    8989 * set errno. Depending on function, success is signalled by returning either
    9090 * EOK or a non-negative file handle.
     
    104104 *      aoff64_t pos = 42;
    105105 *      char buf[512];
    106  *      ssize_t size = vfs_read(file, &pos, buf, sizeof(buf));
    107  *      if (size < 0) {
     106 *      size_t nread;
     107 *      rc = vfs_read(file, &pos, buf, sizeof(buf), &nread);
     108 *      if (rc != EOK) {
    108109 *              vfs_put(file);
    109  *              return size;
     110 *              return rc;
    110111 *      }
    111112 *
    112  *      // buf is now filled with data from file
     113 *      // buf is now filled with nread bytes from file
    113114 *
    114115 *      vfs_put(file);
     
    127128static int root_fd = -1;
    128129
    129 static int get_parent_and_child(const char *path, char **child)
     130static int get_parent_and_child(const char *path, int *parent, char **child)
    130131{
    131132        size_t size;
     
    135136
    136137        char *slash = str_rchr(apath, L'/');
    137         int parent;
    138138        if (slash == apath) {
    139                 parent = vfs_root();
     139                *parent = vfs_root();
     140                if (*parent < 0) {
     141                        free(apath);
     142                        return EBADF;
     143                }
    140144                *child = apath;
     145                return EOK;
    141146        } else {
    142147                *slash = '\0';
    143                 parent = vfs_lookup(apath, WALK_DIRECTORY);
    144                 if (parent < 0) {
     148                int rc = vfs_lookup(apath, WALK_DIRECTORY, parent);
     149                if (rc != EOK) {
    145150                        free(apath);
    146                         return parent;
     151                        return rc;
    147152                }
    148153                *slash = '/';
     
    150155                free(apath);
    151156                if (!*child) {
    152                         vfs_put(parent);
     157                        vfs_put(*parent);
    153158                        return ENOMEM;
    154159                }
    155         }
    156 
    157         return parent;
     160
     161                return rc;
     162        }
     163
    158164}
    159165
     
    230236 *                      handle will be allocated from high indices
    231237 *
    232  * @return              New file handle on success or a negative error code
    233  */
    234 int vfs_clone(int file_from, int file_to, bool high)
    235 {
     238 * @return              New file handle on success or an error code
     239 */
     240int vfs_clone(int file_from, int file_to, bool high, int *handle)
     241{
     242        assert(handle != NULL);
     243
    236244        async_exch_t *vfs_exch = vfs_exchange_begin();
    237         int rc = async_req_3_0(vfs_exch, VFS_IN_CLONE, (sysarg_t) file_from,
    238             (sysarg_t) file_to, (sysarg_t) high);
     245        sysarg_t ret;
     246        int rc = async_req_3_1(vfs_exch, VFS_IN_CLONE, (sysarg_t) file_from,
     247            (sysarg_t) file_to, (sysarg_t) high, &ret);
    239248        vfs_exchange_end(vfs_exch);
     249
     250        if (rc == EOK) {
     251                *handle = ret;
     252        }
    240253        return rc;
    241254}
     
    246259 * @param size          Size of @a buf
    247260 *
    248  * @return              EOK on success or a non-negative error code
     261 * @return              EOK on success or a non-error code
    249262 */
    250263int vfs_cwd_get(char *buf, size_t size)
     
    267280 * @param path  Path of the new working directory
    268281 *
    269  * @return      EOK on success or a negative error code
     282 * @return      EOK on success or an error code
    270283 */
    271284int vfs_cwd_set(const char *path)
     
    276289                return ENOMEM;
    277290       
    278         int fd = vfs_lookup(abs, WALK_DIRECTORY);
    279         if (fd < 0) {
     291        int fd;
     292        int rc = vfs_lookup(abs, WALK_DIRECTORY, &fd);
     293        if (rc != EOK) {
    280294                free(abs);
    281                 return fd;
     295                return rc;
    282296        }
    283297       
     
    356370 * @param info    Place to store volume identification information
    357371 *
    358  * @return                      EOK on success or a negative error code
     372 * @return                      EOK on success or an error code
    359373 */
    360374int vfs_fsprobe(const char *fs_name, service_id_t serv,
    361375    vfs_fs_probe_info_t *info)
    362376{
    363         sysarg_t rc;
     377        int rc;
    364378       
    365379        ipc_call_t answer;
     
    390404 *        fstypes->fstypes[0..]. To free the list use vfs_fstypes_free().
    391405 *
    392  * @return                      EOK on success or a negative error code
     406 * @return                      EOK on success or an error code
    393407 */
    394408int vfs_fstypes(vfs_fstypes_t *fstypes)
     
    485499 * @param[out] linkedfd If not NULL, will receive a file handle to the linked
    486500 *                      child
    487  * @return              EOK on success or a negative error code
     501 * @return              EOK on success or an error code
    488502 */
    489503int vfs_link(int parent, const char *child, vfs_file_kind_t kind, int *linkedfd)
    490504{
    491505        int flags = (kind == KIND_DIRECTORY) ? WALK_DIRECTORY : WALK_REGULAR;
    492         int file = vfs_walk(parent, child, WALK_MUST_CREATE | flags);
    493 
    494         if (file < 0)
    495                 return file;
     506        int file = -1;
     507        int rc = vfs_walk(parent, child, WALK_MUST_CREATE | flags, &file);
     508        if (rc != EOK)
     509                return rc;
    496510
    497511        if (linkedfd)
     
    515529 * @param[out] linkedfd If not NULL, will receive a file handle to the linked
    516530 *                      child
    517  * @return              EOK on success or a negative error code
     531 * @return              EOK on success or an error code
    518532 */
    519533int vfs_link_path(const char *path, vfs_file_kind_t kind, int *linkedfd)
    520534{
    521535        char *child;
    522         int parent = get_parent_and_child(path, &child);
    523         if (parent < 0)
    524                 return parent;
    525 
    526         int rc = vfs_link(parent, child, kind, linkedfd);
     536        int parent;
     537        int rc = get_parent_and_child(path, &parent, &child);
     538        if (rc != EOK)
     539                return rc;
     540
     541        rc = vfs_link(parent, child, kind, linkedfd);
    527542
    528543        free(child);
    529544        vfs_put(parent);
    530545        return rc;
    531 }       
     546}
    532547
    533548/** Lookup a path relative to the local root
     
    535550 * @param path  Path to be looked up
    536551 * @param flags Walk flags
    537  *
    538  * @return      File handle representing the result on success or a negative
    539  *              error code on error
    540  */
    541 int vfs_lookup(const char *path, int flags)
     552 * @param[out] handle Pointer to variable where handle is to be written.
     553 *
     554 * @return      EOK on success or an error code.
     555 */
     556int vfs_lookup(const char *path, int flags, int *handle)
    542557{
    543558        size_t size;
     
    545560        if (!p)
    546561                return ENOMEM;
     562
    547563        int root = vfs_root();
    548564        if (root < 0) {
     
    550566                return ENOENT;
    551567        }
    552         int rc = vfs_walk(root, p, flags);
     568
     569        // XXX: Workaround for GCC diagnostics.
     570        *handle = -1;
     571
     572        int rc = vfs_walk(root, p, flags, handle);
    553573        vfs_put(root);
    554574        free(p);
     
    563583 * @param flags Walk flags
    564584 * @param mode  Mode in which to open file in
    565  *
    566  * @return      EOK on success or a negative error code
    567  */
    568 int vfs_lookup_open(const char *path, int flags, int mode)
    569 {
    570         int file = vfs_lookup(path, flags);
    571         if (file < 0)
    572                 return file;
    573 
    574         int rc = vfs_open(file, mode);
     585 * @param[out] handle Pointer to variable where handle is to be written.
     586 *
     587 * @return      EOK on success or an error code
     588 */
     589int vfs_lookup_open(const char *path, int flags, int mode, int *handle)
     590{
     591        int file;
     592        int rc = vfs_lookup(path, flags, &file);
     593        if (rc != EOK)
     594                return rc;
     595
     596        rc = vfs_open(file, mode);
    575597        if (rc != EOK) {
    576598                vfs_put(file);
    577599                return rc;
    578600        }
    579        
    580         return file;
     601
     602        *handle = file;
     603        return EOK;
    581604}
    582605
     
    591614 * @param[out] mountedfd        File handle of the mounted root if not NULL
    592615 *
    593  * @return                      EOK on success or a negative error code
     616 * @return                      EOK on success or an error code
    594617 */
    595618int vfs_mount(int mp, const char *fs_name, service_id_t serv, const char *opts,
    596619    unsigned int flags, unsigned int instance, int *mountedfd)
    597620{
    598         sysarg_t rc, rc1;
     621        int rc, rc1;
    599622       
    600623        if (!mountedfd)
     
    635658 * @param[in] instance          Instance number of the file system server
    636659 *
    637  * @return                      EOK on success or a negative error code
     660 * @return                      EOK on success or an error code
    638661 */
    639662int vfs_mount_path(const char *mp, const char *fs_name, const char *fqsn,
     
    706729                }
    707730               
    708                 int mpfd = vfs_walk(root_fd, mpa, WALK_DIRECTORY);
    709                 if (mpfd >= 0) {
     731                int mpfd;
     732                rc = vfs_walk(root_fd, mpa, WALK_DIRECTORY, &mpfd);
     733                if (rc == EOK) {
    710734                        rc = vfs_mount(mpfd, fs_name, service_id, opts, flags,
    711735                            instance, NULL);
    712736                        vfs_put(mpfd);
    713                 } else {
    714                         rc = mpfd;
    715737                }
    716738        }
     
    730752 * @param mode  Mode in which to open file in
    731753 *
    732  * @return      EOK on success or a negative error code
     754 * @return      EOK on success or an error code
    733755 */
    734756int vfs_open(int file, int mode)
     
    747769 * @param exch          Exchange to the acceptor
    748770 *
    749  * @return              EOK on success or a negative error code
     771 * @return              EOK on success or an error code
    750772 */
    751773int vfs_pass_handle(async_exch_t *vfs_exch, int file, async_exch_t *exch)
     
    759781 * @param file  File handle to put
    760782 *
    761  * @return      EOK on success or a negative error code
     783 * @return      EOK on success or an error code
    762784 */
    763785int vfs_put(int file)
     
    774796 * @param high   If true, the received file handle will be allocated from high
    775797 *               indices
    776  *
    777  * @return       EOK on success or a negative error code
    778  */
    779 int vfs_receive_handle(bool high)
     798 * @param[out] handle  Received handle.
     799 *
     800 * @return       EOK on success or an error code
     801 */
     802int vfs_receive_handle(bool high, int *handle)
    780803{
    781804        ipc_callid_t callid;
     
    790813
    791814        sysarg_t ret;
    792         sysarg_t rc = async_req_1_1(vfs_exch, VFS_IN_WAIT_HANDLE, high, &ret);
     815        int rc = async_req_1_1(vfs_exch, VFS_IN_WAIT_HANDLE, high, &ret);
    793816
    794817        async_exchange_end(vfs_exch);
    795818
    796         if (rc != EOK)
    797                 return rc;
    798         return ret;
     819        if (rc == EOK) {
     820                *handle = (int) ret;
     821        }
     822
     823        return rc;
    799824}
    800825
     
    808833 * @param buf           Buffer, @a nbytes bytes long
    809834 * @param nbytes        Number of bytes to read
    810  *
    811  * @return              On success, non-negative number of bytes read
    812  * @return              On failure, a negative error code
    813  */
    814 ssize_t vfs_read(int file, aoff64_t *pos, void *buf, size_t nbyte)
     835 * @param nread         Place to store number of bytes actually read
     836 *
     837 * @return              On success, EOK and @a *nread is filled with number
     838 *                      of bytes actually read.
     839 * @return              On failure, an error code
     840 */
     841int vfs_read(int file, aoff64_t *pos, void *buf, size_t nbyte, size_t *nread)
    815842{
    816843        ssize_t cnt = 0;
    817         size_t nread = 0;
     844        size_t nr = 0;
    818845        uint8_t *bp = (uint8_t *) buf;
    819846        int rc;
     
    821848        do {
    822849                bp += cnt;
    823                 nread += cnt;
     850                nr += cnt;
    824851                *pos += cnt;
    825                 rc = vfs_read_short(file, *pos, bp, nbyte - nread, &cnt);
    826         } while (rc == EOK && cnt > 0 && (nbyte - nread - cnt) > 0);
    827        
    828         if (rc != EOK)
    829                 return rc;
    830        
     852                rc = vfs_read_short(file, *pos, bp, nbyte - nr, &cnt);
     853        } while (rc == EOK && cnt > 0 && (nbyte - nr - cnt) > 0);
     854       
     855        if (rc != EOK) {
     856                *nread = nr;
     857                return rc;
     858        }
     859       
     860        nr += cnt;
    831861        *pos += cnt;
    832         return nread + cnt;
     862        *nread = nr;
     863        return EOK;
    833864}
    834865
     
    846877 * @param[out] nread    Actual number of bytes read (0 or more)
    847878 *
    848  * @return              EOK on success or a negative error code
     879 * @return              EOK on success or an error code
    849880 */
    850881int vfs_read_short(int file, aoff64_t pos, void *buf, size_t nbyte,
    851882    ssize_t *nread)
    852883{
    853         sysarg_t rc;
     884        int rc;
    854885        ipc_call_t answer;
    855886        aid_t req;
     
    888919 * @param new   New path
    889920 *
    890  * @return      EOK on success or a negative error code
     921 * @return      EOK on success or an error code
    891922 */
    892923int vfs_rename_path(const char *old, const char *new)
    893924{
    894         sysarg_t rc;
    895         sysarg_t rc_orig;
     925        int rc;
     926        int rc_orig;
    896927        aid_t req;
    897928       
     
    955986 * @param length        New length
    956987 *
    957  * @return              EOK on success or a negative error code
     988 * @return              EOK on success or an error code
    958989 */
    959990int vfs_resize(int file, aoff64_t length)
     
    9691000/** Return a new file handle representing the local root
    9701001 *
    971  * @return      A clone of the local root file handle or a negative error code
     1002 * @return      A clone of the local root file handle or -1
    9721003 */
    9731004int vfs_root(void)
    9741005{
    975         fibril_mutex_lock(&root_mutex);
    976         int r;
    977         if (root_fd < 0)
    978                 r = ENOENT;
    979         else
    980                 r = vfs_clone(root_fd, -1, true);
     1006        fibril_mutex_lock(&root_mutex);
     1007        int fd;
     1008        if (root_fd < 0) {
     1009                fd = -1;
     1010        } else {
     1011                int rc = vfs_clone(root_fd, -1, true, &fd);
     1012                if (rc != EOK) {
     1013                        fd = -1;
     1014                }
     1015        }
    9811016        fibril_mutex_unlock(&root_mutex);
    982         return r;
     1017        return fd;
    9831018}
    9841019
     
    9901025 *
    9911026 * @param nroot The new local root file handle
    992  */
    993 void vfs_root_set(int nroot)
    994 {
     1027 *
     1028 * @return  Error code
     1029 */
     1030int vfs_root_set(int nroot)
     1031{
     1032        int new_root;
     1033        int rc = vfs_clone(nroot, -1, true, &new_root);
     1034        if (rc != EOK) {
     1035                return rc;
     1036        }
     1037
    9951038        fibril_mutex_lock(&root_mutex);
    9961039        if (root_fd >= 0)
    9971040                vfs_put(root_fd);
    998         root_fd = vfs_clone(nroot, -1, true);
     1041        root_fd = new_root;
    9991042        fibril_mutex_unlock(&root_mutex);
     1043
     1044        return EOK;
    10001045}
    10011046
     
    10051050 * @param[out] stat     Place to store file information
    10061051 *
    1007  * @return              EOK on success or a negative error code
     1052 * @return              EOK on success or an error code
    10081053 */
    10091054int vfs_stat(int file, struct stat *stat)
    10101055{
    1011         sysarg_t rc;
     1056        int rc;
    10121057        aid_t req;
    10131058       
     
    10191064                vfs_exchange_end(exch);
    10201065               
    1021                 sysarg_t rc_orig;
     1066                int rc_orig;
    10221067                async_wait_for(req, &rc_orig);
    10231068               
     
    10391084 * @param[out] stat     Place to store file information
    10401085 *
    1041  * @return              EOK on success or a negative error code
     1086 * @return              EOK on success or an error code
    10421087 */
    10431088int vfs_stat_path(const char *path, struct stat *stat)
    10441089{
    1045         int file = vfs_lookup(path, 0);
    1046         if (file < 0)
    1047                 return file;
    1048        
    1049         int rc = vfs_stat(file, stat);
     1090        int file;
     1091        int rc = vfs_lookup(path, 0, &file);
     1092        if (rc != EOK)
     1093                return rc;
     1094       
     1095        rc = vfs_stat(file, stat);
    10501096
    10511097        vfs_put(file);
     
    10591105 * @param[out] st       Buffer for storing information
    10601106 *
    1061  * @return              EOK on success or a negative error code
     1107 * @return              EOK on success or an error code
    10621108 */
    10631109int vfs_statfs(int file, struct statfs *st)
    10641110{
    1065         sysarg_t rc, ret;
     1111        int rc, ret;
    10661112        aid_t req;
    10671113
     
    10841130 * @param[out] st       Buffer for storing information
    10851131 *
    1086  * @return              EOK on success or a negative error code
     1132 * @return              EOK on success or an error code
    10871133 */
    10881134int vfs_statfs_path(const char *path, struct statfs *st)
    10891135{
    1090         int file = vfs_lookup(path, 0);
    1091         if (file < 0)
    1092                 return file;
    1093        
    1094         int rc = vfs_statfs(file, st);
     1136        int file;
     1137        int rc = vfs_lookup(path, 0, &file);
     1138        if (rc != EOK)
     1139                return rc;
     1140       
     1141        rc = vfs_statfs(file, st);
    10951142
    10961143        vfs_put(file);
     
    11031150 * @param file  File handle to synchronize
    11041151 *
    1105  * @return      EOK on success or a negative error code
     1152 * @return      EOK on success or an error code
    11061153 */
    11071154int vfs_sync(int file)
     
    11251172 * @param expect        File handle of the unlinked child
    11261173 *
    1127  * @return              EOK on success or a negative error code
     1174 * @return              EOK on success or an error code
    11281175 */
    11291176int vfs_unlink(int parent, const char *child, int expect)
    11301177{
    1131         sysarg_t rc;
     1178        int rc;
    11321179        aid_t req;
    11331180       
     
    11391186        vfs_exchange_end(exch);
    11401187       
    1141         sysarg_t rc_orig;
     1188        int rc_orig;
    11421189        async_wait_for(req, &rc_orig);
    11431190       
     
    11541201 * @param path          Old path to be unlinked
    11551202 *
    1156  * @return              EOK on success or a negative error code
     1203 * @return              EOK on success or an error code
    11571204 */
    11581205int vfs_unlink_path(const char *path)
    11591206{
    1160         int expect = vfs_lookup(path, 0);
    1161         if (expect < 0)
    1162                 return expect;
     1207        int expect;
     1208        int rc = vfs_lookup(path, 0, &expect);
     1209        if (rc != EOK)
     1210                return rc;
    11631211
    11641212        char *child;
    1165         int parent = get_parent_and_child(path, &child);
    1166         if (parent < 0) {
     1213        int parent;
     1214        rc = get_parent_and_child(path, &parent, &child);
     1215        if (rc != EOK) {
    11671216                vfs_put(expect);
    1168                 return parent;
    1169         }
    1170 
    1171         int rc = vfs_unlink(parent, child, expect);
     1217                return rc;
     1218        }
     1219
     1220        rc = vfs_unlink(parent, child, expect);
    11721221       
    11731222        free(child);
     
    11811230 * @param mp    File handle representing the mount-point
    11821231 *
    1183  * @return      EOK on success or a negative error code
     1232 * @return      EOK on success or an error code
    11841233 */
    11851234int vfs_unmount(int mp)
     
    11951244 * @param mpp   Mount-point path
    11961245 *
    1197  * @return      EOK on success or a negative error code
     1246 * @return      EOK on success or an error code
    11981247 */
    11991248int vfs_unmount_path(const char *mpp)
    12001249{
    1201         int mp = vfs_lookup(mpp, WALK_MOUNT_POINT | WALK_DIRECTORY);
    1202         if (mp < 0)
    1203                 return mp;
    1204        
    1205         int rc = vfs_unmount(mp);
     1250        int mp;
     1251        int rc = vfs_lookup(mpp, WALK_MOUNT_POINT | WALK_DIRECTORY, &mp);
     1252        if (rc != EOK)
     1253                return rc;
     1254       
     1255        rc = vfs_unmount(mp);
    12061256        vfs_put(mp);
    12071257        return rc;
     
    12131263 * @param path          Parent-relative path to be walked
    12141264 * @param flags         Flags influencing the walk
    1215  *
    1216  * @retrun              File handle representing the result on success or
    1217  *                      a negative error code on error
    1218  */
    1219 int vfs_walk(int parent, const char *path, int flags)
     1265 * @param[out] handle   File handle representing the result on success.
     1266 *
     1267 * @return              Error code.
     1268 */
     1269int vfs_walk(int parent, const char *path, int flags, int *handle)
    12201270{
    12211271        async_exch_t *exch = vfs_exchange_begin();
     
    12231273        ipc_call_t answer;
    12241274        aid_t req = async_send_2(exch, VFS_IN_WALK, parent, flags, &answer);
    1225         sysarg_t rc = async_data_write_start(exch, path, str_size(path));
     1275        int rc = async_data_write_start(exch, path, str_size(path));
    12261276        vfs_exchange_end(exch);
    12271277               
    1228         sysarg_t rc_orig;
     1278        int rc_orig;
    12291279        async_wait_for(req, &rc_orig);
    12301280
     
    12351285                return (int) rc;
    12361286       
    1237         return (int) IPC_GET_ARG1(answer);
     1287        *handle = (int) IPC_GET_ARG1(answer);
     1288        return EOK;
    12381289}
    12391290
     
    12471298 * @param buf           Data, @a nbytes bytes long
    12481299 * @param nbytes        Number of bytes to write
    1249  *
    1250  * @return              On success, non-negative number of bytes written
    1251  * @return              On failure, a negative error code
    1252  */
    1253 ssize_t vfs_write(int file, aoff64_t *pos, const void *buf, size_t nbyte)
     1300 * @param nwritten      Place to store number of bytes written
     1301 *
     1302 * @return              On success, EOK, @a *nwr is filled with number
     1303 *                      of bytes written
     1304 * @return              On failure, an error code
     1305 */
     1306int vfs_write(int file, aoff64_t *pos, const void *buf, size_t nbyte,
     1307    size_t *nwritten)
    12541308{
    12551309        ssize_t cnt = 0;
    1256         ssize_t nwritten = 0;
     1310        ssize_t nwr = 0;
    12571311        const uint8_t *bp = (uint8_t *) buf;
    12581312        int rc;
     
    12601314        do {
    12611315                bp += cnt;
    1262                 nwritten += cnt;
     1316                nwr += cnt;
    12631317                *pos += cnt;
    1264                 rc = vfs_write_short(file, *pos, bp, nbyte - nwritten, &cnt);
    1265         } while (rc == EOK && ((ssize_t )nbyte - nwritten - cnt) > 0);
    1266 
    1267         if (rc != EOK)
    1268                 return rc;
    1269 
     1318                rc = vfs_write_short(file, *pos, bp, nbyte - nwr, &cnt);
     1319        } while (rc == EOK && ((ssize_t )nbyte - nwr - cnt) > 0);
     1320
     1321        if (rc != EOK) {
     1322                *nwritten = nwr;
     1323                return rc;
     1324        }
     1325
     1326        nwr += cnt;
    12701327        *pos += cnt;
    1271         return nbyte;
     1328        *nwritten = nwr;
     1329        return EOK;
    12721330}
    12731331
     
    12831341 * @param[out] nread    Actual number of bytes written (0 or more)
    12841342 *
    1285  * @return              EOK on success or a negative error code
     1343 * @return              EOK on success or an error code
    12861344 */
    12871345int vfs_write_short(int file, aoff64_t pos, const void *buf, size_t nbyte,
    12881346    ssize_t *nwritten)
    12891347{
    1290         sysarg_t rc;
     1348        int rc;
    12911349        ipc_call_t answer;
    12921350        aid_t req;
Note: See TracChangeset for help on using the changeset viewer.