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

Changeset ed903174 in mainline for uspace/srv/vfs/vfs_ops.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/srv/vfs/vfs_ops.c

    rb32c604 red903174  
    3838#include "vfs.h"
    3939#include <ipc/ipc.h>
     40#include <macros.h>
     41#include <limits.h>
    4042#include <async.h>
    4143#include <errno.h>
     
    5355
    5456/* Forward declarations of static functions. */
    55 static int vfs_truncate_internal(fs_handle_t, dev_handle_t, fs_index_t, size_t);
     57static int vfs_truncate_internal(fs_handle_t, dev_handle_t, fs_index_t, aoff64_t);
    5658
    5759/**
     
    353355        vfs_lookup_res_t mp_res;
    354356        vfs_lookup_res_t mr_res;
    355         vfs_node_t *mp_node;
    356357        vfs_node_t *mr_node;
    357358        int phone;
     
    503504        int oflag = IPC_GET_ARG2(*request);
    504505        int mode = IPC_GET_ARG3(*request);
    505         size_t len;
    506506
    507507        /* Ignore mode for now. */
     
    887887{
    888888        int fd = (int) IPC_GET_ARG1(*request);
    889         off_t off = (off_t) IPC_GET_ARG2(*request);
    890         int whence = (int) IPC_GET_ARG3(*request);
    891 
    892 
     889        off64_t off =
     890            (off64_t) MERGE_LOUP32(IPC_GET_ARG2(*request), IPC_GET_ARG3(*request));
     891        int whence = (int) IPC_GET_ARG4(*request);
     892       
    893893        /* Lookup the file structure corresponding to the file descriptor. */
    894894        vfs_file_t *file = vfs_file_get(fd);
     
    897897                return;
    898898        }
    899 
    900         off_t newpos;
     899       
    901900        fibril_mutex_lock(&file->lock);
    902         if (whence == SEEK_SET) {
    903                 file->pos = off;
    904                 fibril_mutex_unlock(&file->lock);
    905                 ipc_answer_1(rid, EOK, off);
    906                 return;
    907         }
    908         if (whence == SEEK_CUR) {
    909                 if (file->pos + off < file->pos) {
     901       
     902        off64_t newoff;
     903        switch (whence) {
     904                case SEEK_SET:
     905                        if (off >= 0) {
     906                                file->pos = (aoff64_t) off;
     907                                fibril_mutex_unlock(&file->lock);
     908                                ipc_answer_1(rid, EOK, off);
     909                                return;
     910                        }
     911                        break;
     912                case SEEK_CUR:
     913                        if ((off >= 0) && (file->pos + off < file->pos)) {
     914                                fibril_mutex_unlock(&file->lock);
     915                                ipc_answer_0(rid, EOVERFLOW);
     916                                return;
     917                        }
     918                       
     919                        if ((off < 0) && (file->pos < (aoff64_t) -off)) {
     920                                fibril_mutex_unlock(&file->lock);
     921                                ipc_answer_0(rid, EOVERFLOW);
     922                                return;
     923                        }
     924                       
     925                        file->pos += off;
     926                        newoff = (file->pos > OFF64_MAX) ? OFF64_MAX : file->pos;
     927                       
    910928                        fibril_mutex_unlock(&file->lock);
    911                         ipc_answer_0(rid, EOVERFLOW);
     929                        ipc_answer_2(rid, EOK, LOWER32(newoff), UPPER32(newoff));
    912930                        return;
    913                 }
    914                 file->pos += off;
    915                 newpos = file->pos;
    916                 fibril_mutex_unlock(&file->lock);
    917                 ipc_answer_1(rid, EOK, newpos);
    918                 return;
    919         }
    920         if (whence == SEEK_END) {
    921                 fibril_rwlock_read_lock(&file->node->contents_rwlock);
    922                 size_t size = file->node->size;
    923                 fibril_rwlock_read_unlock(&file->node->contents_rwlock);
    924                 if (size + off < size) {
     931                case SEEK_END:
     932                        fibril_rwlock_read_lock(&file->node->contents_rwlock);
     933                        aoff64_t size = file->node->size;
     934                       
     935                        if ((off >= 0) && (size + off < size)) {
     936                                fibril_rwlock_read_unlock(&file->node->contents_rwlock);
     937                                fibril_mutex_unlock(&file->lock);
     938                                ipc_answer_0(rid, EOVERFLOW);
     939                                return;
     940                        }
     941                       
     942                        if ((off < 0) && (size < (aoff64_t) -off)) {
     943                                fibril_rwlock_read_unlock(&file->node->contents_rwlock);
     944                                fibril_mutex_unlock(&file->lock);
     945                                ipc_answer_0(rid, EOVERFLOW);
     946                                return;
     947                        }
     948                       
     949                        file->pos = size + off;
     950                        newoff = (file->pos > OFF64_MAX) ? OFF64_MAX : file->pos;
     951                       
     952                        fibril_rwlock_read_unlock(&file->node->contents_rwlock);
    925953                        fibril_mutex_unlock(&file->lock);
    926                         ipc_answer_0(rid, EOVERFLOW);
     954                        ipc_answer_2(rid, EOK, LOWER32(newoff), UPPER32(newoff));
    927955                        return;
    928                 }
    929                 newpos = size + off;
    930                 file->pos = newpos;
    931                 fibril_mutex_unlock(&file->lock);
    932                 ipc_answer_1(rid, EOK, newpos);
    933                 return;
    934         }
     956        }
     957       
    935958        fibril_mutex_unlock(&file->lock);
    936959        ipc_answer_0(rid, EINVAL);
    937960}
    938961
    939 int
    940 vfs_truncate_internal(fs_handle_t fs_handle, dev_handle_t dev_handle,
    941     fs_index_t index, size_t size)
     962int vfs_truncate_internal(fs_handle_t fs_handle, dev_handle_t dev_handle,
     963    fs_index_t index, aoff64_t size)
    942964{
    943965        ipcarg_t rc;
     
    945967       
    946968        fs_phone = vfs_grab_phone(fs_handle);
    947         rc = async_req_3_0(fs_phone, VFS_OUT_TRUNCATE, (ipcarg_t)dev_handle,
    948             (ipcarg_t)index, (ipcarg_t)size);
     969        rc = async_req_4_0(fs_phone, VFS_OUT_TRUNCATE, (ipcarg_t) dev_handle,
     970            (ipcarg_t) index, LOWER32(size), UPPER32(size));
    949971        vfs_release_phone(fs_phone);
    950972        return (int)rc;
     
    954976{
    955977        int fd = IPC_GET_ARG1(*request);
    956         size_t size = IPC_GET_ARG2(*request);
     978        aoff64_t size =
     979            (aoff64_t) MERGE_LOUP32(IPC_GET_ARG2(*request), IPC_GET_ARG3(*request));
    957980        int rc;
    958981
Note: See TracChangeset for help on using the changeset viewer.