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

Changeset ed903174 in mainline for uspace/srv/fs/tmpfs/tmpfs_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/fs/tmpfs/tmpfs_ops.c

    rb32c604 red903174  
    2929/** @addtogroup fs
    3030 * @{
    31  */ 
     31 */
    3232
    3333/**
     
    4040#include "../../vfs/vfs.h"
    4141#include <ipc/ipc.h>
     42#include <macros.h>
     43#include <limits.h>
    4244#include <async.h>
    4345#include <errno.h>
     
    9395}
    9496
    95 static size_t tmpfs_size_get(fs_node_t *fn)
     97static aoff64_t tmpfs_size_get(fs_node_t *fn)
    9698{
    9799        return TMPFS_NODE(fn)->size;
     
    509511void tmpfs_read(ipc_callid_t rid, ipc_call_t *request)
    510512{
    511         dev_handle_t dev_handle = (dev_handle_t)IPC_GET_ARG1(*request);
    512         fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request);
    513         off_t pos = (off_t)IPC_GET_ARG3(*request);
    514 
     513        dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
     514        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
     515        aoff64_t pos =
     516            (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
     517       
    515518        /*
    516519         * Lookup the respective TMPFS node.
     
    528531        tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,
    529532            nh_link);
    530 
     533       
    531534        /*
    532535         * Receive the read request.
     
    535538        size_t size;
    536539        if (!async_data_read_receive(&callid, &size)) {
    537                 ipc_answer_0(callid, EINVAL);   
     540                ipc_answer_0(callid, EINVAL);
    538541                ipc_answer_0(rid, EINVAL);
    539542                return;
     
    542545        size_t bytes;
    543546        if (nodep->type == TMPFS_FILE) {
    544                 bytes = max(0, min(nodep->size - pos, size));
     547                bytes = min(nodep->size - pos, size);
    545548                (void) async_data_read_finalize(callid, nodep->data + pos,
    546549                    bytes);
     
    548551                tmpfs_dentry_t *dentryp;
    549552                link_t *lnk;
    550                 int i;
     553                aoff64_t i;
    551554               
    552555                assert(nodep->type == TMPFS_DIRECTORY);
     
    558561                 */
    559562                for (i = 0, lnk = nodep->cs_head.next;
    560                     i < pos && lnk != &nodep->cs_head;
     563                    (i < pos) && (lnk != &nodep->cs_head);
    561564                    i++, lnk = lnk->next)
    562565                        ;
     
    583586void tmpfs_write(ipc_callid_t rid, ipc_call_t *request)
    584587{
    585         dev_handle_t dev_handle = (dev_handle_t)IPC_GET_ARG1(*request);
    586         fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request);
    587         off_t pos = (off_t)IPC_GET_ARG3(*request);
    588 
     588        dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
     589        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
     590        aoff64_t pos =
     591            (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
     592       
    589593        /*
    590594         * Lookup the respective TMPFS node.
     
    647651void tmpfs_truncate(ipc_callid_t rid, ipc_call_t *request)
    648652{
     653        dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
     654        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
     655        aoff64_t size =
     656            (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
     657       
     658        /*
     659         * Lookup the respective TMPFS node.
     660         */
     661        unsigned long key[] = {
     662                [NODES_KEY_DEV] = dev_handle,
     663                [NODES_KEY_INDEX] = index
     664        };
     665        link_t *hlp = hash_table_find(&nodes, key);
     666        if (!hlp) {
     667                ipc_answer_0(rid, ENOENT);
     668                return;
     669        }
     670        tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,
     671            nh_link);
     672       
     673        if (size == nodep->size) {
     674                ipc_answer_0(rid, EOK);
     675                return;
     676        }
     677       
     678        if (size > SIZE_MAX) {
     679                ipc_answer_0(rid, ENOMEM);
     680                return;
     681        }
     682       
     683        void *newdata = realloc(nodep->data, size);
     684        if (!newdata) {
     685                ipc_answer_0(rid, ENOMEM);
     686                return;
     687        }
     688       
     689        if (size > nodep->size) {
     690                size_t delta = size - nodep->size;
     691                memset(newdata + nodep->size, 0, delta);
     692        }
     693       
     694        nodep->size = size;
     695        nodep->data = newdata;
     696        ipc_answer_0(rid, EOK);
     697}
     698
     699void tmpfs_close(ipc_callid_t rid, ipc_call_t *request)
     700{
     701        ipc_answer_0(rid, EOK);
     702}
     703
     704void tmpfs_destroy(ipc_callid_t rid, ipc_call_t *request)
     705{
    649706        dev_handle_t dev_handle = (dev_handle_t)IPC_GET_ARG1(*request);
    650707        fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request);
    651         size_t size = (off_t)IPC_GET_ARG3(*request);
    652 
    653         /*
    654          * Lookup the respective TMPFS node.
    655          */
     708        int rc;
     709
    656710        link_t *hlp;
    657711        unsigned long key[] = {
     
    666720        tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,
    667721            nh_link);
    668 
    669         if (size == nodep->size) {
    670                 ipc_answer_0(rid, EOK);
    671                 return;
    672         }
    673 
    674         void *newdata = realloc(nodep->data, size);
    675         if (!newdata) {
    676                 ipc_answer_0(rid, ENOMEM);
    677                 return;
    678         }
    679         if (size > nodep->size) {
    680                 size_t delta = size - nodep->size;
    681                 memset(newdata + nodep->size, 0, delta);
    682         }
    683         nodep->size = size;
    684         nodep->data = newdata;
    685         ipc_answer_0(rid, EOK);
    686 }
    687 
    688 void tmpfs_close(ipc_callid_t rid, ipc_call_t *request)
    689 {
    690         ipc_answer_0(rid, EOK);
    691 }
    692 
    693 void tmpfs_destroy(ipc_callid_t rid, ipc_call_t *request)
    694 {
    695         dev_handle_t dev_handle = (dev_handle_t)IPC_GET_ARG1(*request);
    696         fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request);
    697         int rc;
    698 
    699         link_t *hlp;
    700         unsigned long key[] = {
    701                 [NODES_KEY_DEV] = dev_handle,
    702                 [NODES_KEY_INDEX] = index
    703         };
    704         hlp = hash_table_find(&nodes, key);
    705         if (!hlp) {
    706                 ipc_answer_0(rid, ENOENT);
    707                 return;
    708         }
    709         tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,
    710             nh_link);
    711722        rc = tmpfs_destroy_node(FS_NODE(nodep));
    712723        ipc_answer_0(rid, rc);
Note: See TracChangeset for help on using the changeset viewer.