Changeset 8d32152 in mainline for uspace/srv/fs/fat/fat_ops.c


Ignore:
Timestamp:
2008-10-25T15:02:14Z (16 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
6f2dfd1
Parents:
71f1cc1
Message:

Mark progress in fat_write().

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/fs/fat/fat_ops.c

    r71f1cc1 r8d32152  
    5151#include <futex.h>
    5252#include <sys/mman.h>
     53#include <align.h>
    5354
    5455#define BS_BLOCK                0
     
    107108        void *data;
    108109        size_t size;
     110        bool dirty;
    109111} block_t;
    110112
     
    848850}
    849851
     852static void fat_fill_gap(fat_node_t *nodep, off_t start, off_t stop)
     853{
     854        /* TODO */
     855}
     856
    850857void fat_write(ipc_callid_t rid, ipc_call_t *request)
    851858{
    852         ipc_answer_0(rid, ENOTSUP);
     859        dev_handle_t dev_handle = (dev_handle_t)IPC_GET_ARG1(*request);
     860        fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request);
     861        off_t pos = (off_t)IPC_GET_ARG3(*request);
     862        fat_node_t *nodep = (fat_node_t *)fat_node_get(dev_handle, index);
     863        size_t bytes;
     864        block_t *b, *bb;
     865        uint16_t bps;
     866        unsigned spc;
     867        off_t clst_boundary;
     868       
     869        if (!nodep) {
     870                ipc_answer_0(rid, ENOENT);
     871                return;
     872        }
     873       
     874        /* XXX remove me when you are ready */
     875        {
     876                ipc_answer_0(rid, ENOTSUP);
     877                fat_node_put(nodep);
     878                return;
     879        }
     880
     881        ipc_callid_t callid;
     882        size_t len;
     883        if (!ipc_data_write_receive(&callid, &len)) {
     884                fat_node_put(nodep);
     885                ipc_answer_0(callid, EINVAL);
     886                ipc_answer_0(rid, EINVAL);
     887                return;
     888        }
     889
     890        /*
     891         * In all scenarios, we will attempt to write out only one block worth
     892         * of data at maximum. There might be some more efficient approaches,
     893         * but this one greatly simplifies fat_write(). Note that we can afford
     894         * to do this because the client must be ready to handle the return
     895         * value signalizing a smaller number of bytes written.
     896         */
     897        bytes = min(len, bps - pos % bps);
     898
     899        bb = block_get(dev_handle, BS_BLOCK, BS_SIZE);
     900        bps = uint16_t_le2host(FAT_BS(bb)->bps);
     901        spc = FAT_BS(bb)->spc;
     902        block_put(bb);
     903       
     904        clst_boundary = ROUND_UP(nodep->size, bps * spc);
     905        if (pos < clst_boundary) {
     906                /*
     907                 * This is the easier case - we are either overwriting already
     908                 * existing contents or writing behind the EOF, but still within
     909                 * the limits of the last cluster. The node size may grow to the
     910                 * next block size boundary.
     911                 */
     912                if (pos > nodep->size)
     913                        fat_fill_gap(nodep, nodep->size, pos);
     914                b = fat_block_get(nodep, pos / bps);
     915                (void) ipc_data_write_finalize(callid, b->data + pos % bps,
     916                    bytes);
     917                b->dirty = true;                /* need to sync block */
     918                if (pos + bytes > nodep->size) {
     919                        nodep->size = pos + bytes;
     920                        nodep->dirty = true;    /* need to sync node */
     921                }
     922                block_put(b);
     923                fat_node_put(nodep);
     924                ipc_answer_1(rid, EOK, bytes); 
     925                return;
     926        } else {
     927                /*
     928                 * This is the more difficult case. We must allocate new
     929                 * clusters for the node and zero them out.
     930                 */
     931                unsigned nclsts;
     932               
     933                nclsts = (ROUND_UP(pos + bytes, bps * spc) - clst_boundary) /
     934                    bps * spc;
     935
     936        }
     937       
    853938}
    854939
Note: See TracChangeset for help on using the changeset viewer.