Changeset 8d32152 in mainline
- Timestamp:
- 2008-10-25T15:02:14Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 6f2dfd1
- Parents:
- 71f1cc1
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/fat/fat_ops.c
r71f1cc1 r8d32152 51 51 #include <futex.h> 52 52 #include <sys/mman.h> 53 #include <align.h> 53 54 54 55 #define BS_BLOCK 0 … … 107 108 void *data; 108 109 size_t size; 110 bool dirty; 109 111 } block_t; 110 112 … … 848 850 } 849 851 852 static void fat_fill_gap(fat_node_t *nodep, off_t start, off_t stop) 853 { 854 /* TODO */ 855 } 856 850 857 void fat_write(ipc_callid_t rid, ipc_call_t *request) 851 858 { 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 853 938 } 854 939
Note:
See TracChangeset
for help on using the changeset viewer.