Rev 3500 | Rev 3503 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3500 | Rev 3501 | ||
---|---|---|---|
Line 847... | Line 847... | ||
847 | 847 | ||
848 | fat_node_put(nodep); |
848 | fat_node_put(nodep); |
849 | ipc_answer_1(rid, EOK, (ipcarg_t)bytes); |
849 | ipc_answer_1(rid, EOK, (ipcarg_t)bytes); |
850 | } |
850 | } |
851 | 851 | ||
- | 852 | /** Fill the gap between EOF and a new file position. |
|
- | 853 | * |
|
- | 854 | * @param nodep FAT node with the gap. |
|
- | 855 | * @param mcl First cluster in an independent cluster chain that will |
|
- | 856 | * be later appended to the end of the node's own cluster |
|
- | 857 | * chain. If pos is still in the last allocated cluster, |
|
- | 858 | * this argument is ignored. |
|
- | 859 | * @param pos Position in the last node block. |
|
- | 860 | */ |
|
852 | static void |
861 | static void |
853 | fat_fill_gap(fat_node_t *nodep, fat_cluster_t mclst, off_t pos) |
862 | fat_fill_gap(fat_node_t *nodep, fat_cluster_t mcl, off_t pos) |
854 | { |
863 | { |
- | 864 | uint16_t bps; |
|
- | 865 | unsigned spc; |
|
- | 866 | block_t *bb, *b; |
|
- | 867 | off_t o, boundary; |
|
- | 868 | ||
- | 869 | bb = block_get(nodep->idx->dev_handle, BS_BLOCK, BS_SIZE); |
|
- | 870 | bps = uint16_t_le2host(FAT_BS(bb)->bps); |
|
- | 871 | spc = FAT_BS(bb)->spc; |
|
- | 872 | block_put(bb); |
|
- | 873 | ||
- | 874 | boundary = ROUND_UP(nodep->size, bps * spc); |
|
- | 875 | ||
- | 876 | /* zero out already allocated space */ |
|
- | 877 | for (o = nodep->size - 1; o < pos && o < boundary; |
|
- | 878 | o = ALIGN_DOWN(o + bps, bps)) { |
|
- | 879 | b = fat_block_get(nodep, o / bps); |
|
- | 880 | memset(b->data + o % bps, 0, bps - o % bps); |
|
- | 881 | b->dirty = true; /* need to sync node */ |
|
- | 882 | block_put(b); |
|
- | 883 | } |
|
- | 884 | ||
855 | /* TODO */ |
885 | if (o >= pos) |
- | 886 | return; |
|
- | 887 | ||
- | 888 | /* zero out the initial part of the new cluster chain */ |
|
- | 889 | for (o = boundary; o < pos; o += bps) { |
|
- | 890 | b = _fat_block_get(nodep->idx->dev_handle, mcl, |
|
- | 891 | (o - boundary) / bps); |
|
- | 892 | memset(b->data, 0, min(bps, pos - o)); |
|
- | 893 | b->dirty = true; |
|
- | 894 | block_put(b); |
|
- | 895 | } |
|
856 | } |
896 | } |
857 | 897 | ||
858 | static int |
898 | static int |
859 | fat_alloc_clusters(unsigned nclsts, fat_cluster_t *mcl, fat_cluster_t *lcl) |
899 | fat_alloc_clusters(unsigned nclsts, fat_cluster_t *mcl, fat_cluster_t *lcl) |
860 | { |
900 | { |
Line 874... | Line 914... | ||
874 | fat_node_t *nodep = (fat_node_t *)fat_node_get(dev_handle, index); |
914 | fat_node_t *nodep = (fat_node_t *)fat_node_get(dev_handle, index); |
875 | size_t bytes; |
915 | size_t bytes; |
876 | block_t *b, *bb; |
916 | block_t *b, *bb; |
877 | uint16_t bps; |
917 | uint16_t bps; |
878 | unsigned spc; |
918 | unsigned spc; |
879 | off_t clst_boundary; |
919 | off_t boundary; |
880 | 920 | ||
881 | if (!nodep) { |
921 | if (!nodep) { |
882 | ipc_answer_0(rid, ENOENT); |
922 | ipc_answer_0(rid, ENOENT); |
883 | return; |
923 | return; |
884 | } |
924 | } |
Line 911... | Line 951... | ||
911 | bb = block_get(dev_handle, BS_BLOCK, BS_SIZE); |
951 | bb = block_get(dev_handle, BS_BLOCK, BS_SIZE); |
912 | bps = uint16_t_le2host(FAT_BS(bb)->bps); |
952 | bps = uint16_t_le2host(FAT_BS(bb)->bps); |
913 | spc = FAT_BS(bb)->spc; |
953 | spc = FAT_BS(bb)->spc; |
914 | block_put(bb); |
954 | block_put(bb); |
915 | 955 | ||
916 | clst_boundary = ROUND_UP(nodep->size, bps * spc); |
956 | boundary = ROUND_UP(nodep->size, bps * spc); |
917 | if (pos < clst_boundary) { |
957 | if (pos < boundary) { |
918 | /* |
958 | /* |
919 | * This is the easier case - we are either overwriting already |
959 | * This is the easier case - we are either overwriting already |
920 | * existing contents or writing behind the EOF, but still within |
960 | * existing contents or writing behind the EOF, but still within |
921 | * the limits of the last cluster. The node size may grow to the |
961 | * the limits of the last cluster. The node size may grow to the |
922 | * next block size boundary. |
962 | * next block size boundary. |
Line 941... | Line 981... | ||
941 | */ |
981 | */ |
942 | int status; |
982 | int status; |
943 | unsigned nclsts; |
983 | unsigned nclsts; |
944 | fat_cluster_t mcl, lcl; |
984 | fat_cluster_t mcl, lcl; |
945 | 985 | ||
946 | nclsts = (ROUND_UP(pos + bytes, bps * spc) - clst_boundary) / |
986 | nclsts = (ROUND_UP(pos + bytes, bps * spc) - boundary) / |
947 | bps * spc; |
987 | bps * spc; |
948 | /* create an independent chain of nclsts clusters in all FATs */ |
988 | /* create an independent chain of nclsts clusters in all FATs */ |
949 | status = fat_alloc_clusters(nclsts, &mcl, &lcl); |
989 | status = fat_alloc_clusters(nclsts, &mcl, &lcl); |
950 | if (status != EOK) { |
990 | if (status != EOK) { |
951 | /* could not allocate a chain of nclsts clusters */ |
991 | /* could not allocate a chain of nclsts clusters */ |
Line 957... | Line 997... | ||
957 | /* zero fill any gaps */ |
997 | /* zero fill any gaps */ |
958 | fat_fill_gap(nodep, mcl, pos); |
998 | fat_fill_gap(nodep, mcl, pos); |
959 | b = _fat_block_get(dev_handle, lcl, (pos / bps) % spc); |
999 | b = _fat_block_get(dev_handle, lcl, (pos / bps) % spc); |
960 | (void) ipc_data_write_finalize(callid, b->data + pos % bps, |
1000 | (void) ipc_data_write_finalize(callid, b->data + pos % bps, |
961 | bytes); |
1001 | bytes); |
962 | b->dirty = true; |
1002 | b->dirty = true; /* need to sync block */ |
963 | block_put(b); |
1003 | block_put(b); |
964 | /* |
1004 | /* |
965 | * Append the cluster chain starting in mcl to the end of the |
1005 | * Append the cluster chain starting in mcl to the end of the |
966 | * node's cluster chain. |
1006 | * node's cluster chain. |
967 | */ |
1007 | */ |
968 | fat_append_clusters(nodep, mcl); |
1008 | fat_append_clusters(nodep, mcl); |
969 | nodep->size = pos + bytes; |
1009 | nodep->size = pos + bytes; |
970 | nodep->dirty = true; |
1010 | nodep->dirty = true; /* need to sync node */ |
971 | fat_node_put(nodep); |
1011 | fat_node_put(nodep); |
972 | ipc_answer_1(rid, EOK, bytes); |
1012 | ipc_answer_1(rid, EOK, bytes); |
973 | return; |
1013 | return; |
974 | } |
1014 | } |
975 | } |
1015 | } |