Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset ed903174 in mainline for uspace/lib/libc/generic/vfs/vfs.c


Ignore:
Timestamp:
2010-02-10T23:51:23Z (12 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master
Children:
e70edd1
Parents:
b32c604
Message:

implement support for 64bit file offsets

  • the libc API is a small deviation from standard, but we have no reason to keep a strict backward compatibility with ancient code so far
    • the basic signed 64bit offset type is called off64_t
      • lseek() and fseek() take off64_t arguments (since the argument represents a relative offset)
      • ftell() returns off64_t values (since it is a wrapper of lseek())
      • vfs_seek() implementation supports negative offsets when SEEK_CUR and SEEK_END is used
    • aoff64_t is used for internal unsigned representation of sizes (in bytes, blocks, etc.) and absolute offsets
      • mmap() and ftruncate() take aoff64_t arguments (since the full range of the absolute file offset should be used here)
      • struct stat stores the file size as aoff64_t
    • in both cases the explicit range of the types shown in the names is helpful for proper filesystem and IPC interaction
    • note: size_t should be used only for representing in-memory sizes and offsets, not device and file-related information, and vice versa
      • the code base still needs a thorough revision with respect to this rule
    • PRIdOFF64 and PRIuOFF64 can be used for printing the offsets
  • VFS_OUT_LOOKUP returns the 64bit file size in two IPC arguments
    • since all 5 IPC arguments have already been taken, the fs_handle is returned as the return value (fs_handle has only 16 bits, thus the return value can be used for both indicating errors as negative values and returning positive handles)
  • VFS_OUT_READ and VFS_OUT_WRITE use aoff64_t absolute offsets split into two IPC arguments

replace bn_t with aoff64_t as a generic 64bit bytes/block counter type

note: filesystem drivers need to be revised with respect to make sure that all out-of-range checks are correct (especially w.r.t. file and block offsets)

File:
1 edited

Legend:

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

    rb32c604 red903174  
    3535#include <vfs/vfs.h>
    3636#include <vfs/canonify.h>
     37#include <macros.h>
    3738#include <stdlib.h>
    3839#include <unistd.h>
     
    434435}
    435436
    436 off_t lseek(int fildes, off_t offset, int whence)
    437 {
    438         ipcarg_t rc;
    439 
    440         futex_down(&vfs_phone_futex);
    441         async_serialize_start();
    442         vfs_connect();
    443        
    444         ipcarg_t newoffs;
    445         rc = async_req_3_1(vfs_phone, VFS_IN_SEEK, fildes, offset, whence,
    446             &newoffs);
    447 
    448         async_serialize_end();
    449         futex_up(&vfs_phone_futex);
    450 
     437off64_t lseek(int fildes, off64_t offset, int whence)
     438{
     439        futex_down(&vfs_phone_futex);
     440        async_serialize_start();
     441        vfs_connect();
     442       
     443        ipcarg_t newoff_lo;
     444        ipcarg_t newoff_hi;
     445        ipcarg_t rc = async_req_4_2(vfs_phone, VFS_IN_SEEK, fildes,
     446            LOWER32(offset), UPPER32(offset), whence,
     447            &newoff_lo, &newoff_hi);
     448       
     449        async_serialize_end();
     450        futex_up(&vfs_phone_futex);
     451       
    451452        if (rc != EOK)
    452                 return (off_t) -1;
    453        
    454         return (off_t) newoffs;
    455 }
    456 
    457 int ftruncate(int fildes, off_t length)
    458 {
    459         ipcarg_t rc;
    460        
    461         futex_down(&vfs_phone_futex);
    462         async_serialize_start();
    463         vfs_connect();
    464        
    465         rc = async_req_2_0(vfs_phone, VFS_IN_TRUNCATE, fildes, length);
    466         async_serialize_end();
    467         futex_up(&vfs_phone_futex);
     453                return (off64_t) -1;
     454       
     455        return (off64_t) MERGE_LOUP32(newoff_lo, newoff_hi);
     456}
     457
     458int ftruncate(int fildes, aoff64_t length)
     459{
     460        ipcarg_t rc;
     461       
     462        futex_down(&vfs_phone_futex);
     463        async_serialize_start();
     464        vfs_connect();
     465       
     466        rc = async_req_3_0(vfs_phone, VFS_IN_TRUNCATE, fildes,
     467            LOWER32(length), UPPER32(length));
     468        async_serialize_end();
     469        futex_up(&vfs_phone_futex);
     470       
    468471        return (int) rc;
    469472}
     
    479482       
    480483        req = async_send_1(vfs_phone, VFS_IN_FSTAT, fildes, NULL);
    481         rc = async_data_read_start(vfs_phone, (void *)stat, sizeof(struct stat));
     484        rc = async_data_read_start(vfs_phone, (void *) stat, sizeof(struct stat));
    482485        if (rc != EOK) {
    483486                ipcarg_t rc_orig;
     
    553556        if (!abs) {
    554557                free(dirp);
    555                 return ENOMEM;
     558                return NULL;
    556559        }
    557560       
Note: See TracChangeset for help on using the changeset viewer.