Changeset 0f57d0e in mainline for uspace/srv/fs/fat/fat_ops.c
- Timestamp:
- 2008-10-26T14:10:53Z (17 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- b1178d0
- Parents:
- 033ef7d3
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/fat/fat_ops.c
r033ef7d3 r0f57d0e 55 55 #include <align.h> 56 56 57 #define BS_BLOCK 058 #define BS_SIZE 51259 60 57 /** Futex protecting the list of cached free FAT nodes. */ 61 58 static futex_t ffn_futex = FUTEX_INITIALIZER; … … 64 61 static LIST_INITIALIZE(ffn_head); 65 62 66 #define min(a, b) ((a) < (b) ? (a) : (b))67 68 63 static int dev_phone = -1; /* FIXME */ 69 64 static void *dev_buffer = NULL; /* FIXME */ 70 65 71 /* TODO move somewhere else */ 72 typedef struct { 73 void *data; 74 size_t size; 75 bool dirty; 76 } block_t; 77 78 static block_t *block_get(dev_handle_t dev_handle, off_t offset, size_t bs) 66 block_t *block_get(dev_handle_t dev_handle, off_t offset, size_t bs) 79 67 { 80 68 /* FIXME */ … … 108 96 } 109 97 110 staticvoid block_put(block_t *block)98 void block_put(block_t *block) 111 99 { 112 100 /* FIXME */ 113 101 free(block->data); 114 102 free(block); 115 }116 117 #define FAT1 0118 119 #define FAT_BS(b) ((fat_bs_t *)((b)->data))120 121 #define FAT_CLST_RES0 0x0000122 #define FAT_CLST_RES1 0x0001123 #define FAT_CLST_FIRST 0x0002124 #define FAT_CLST_BAD 0xfff7125 #define FAT_CLST_LAST1 0xfff8126 #define FAT_CLST_LAST8 0xffff127 128 /* internally used to mark root directory's parent */129 #define FAT_CLST_ROOTPAR FAT_CLST_RES0130 /* internally used to mark root directory */131 #define FAT_CLST_ROOT FAT_CLST_RES1132 133 #define fat_block_get(np, off) \134 _fat_block_get((np)->idx->dev_handle, (np)->firstc, (off))135 136 static block_t *137 _fat_block_get(dev_handle_t dev_handle, fat_cluster_t firstc, off_t offset)138 {139 block_t *bb;140 block_t *b;141 unsigned bps;142 unsigned spc;143 unsigned rscnt; /* block address of the first FAT */144 unsigned fatcnt;145 unsigned rde;146 unsigned rds; /* root directory size */147 unsigned sf;148 unsigned ssa; /* size of the system area */149 unsigned clusters;150 fat_cluster_t clst = firstc;151 unsigned i;152 153 bb = block_get(dev_handle, BS_BLOCK, BS_SIZE);154 bps = uint16_t_le2host(FAT_BS(bb)->bps);155 spc = FAT_BS(bb)->spc;156 rscnt = uint16_t_le2host(FAT_BS(bb)->rscnt);157 fatcnt = FAT_BS(bb)->fatcnt;158 rde = uint16_t_le2host(FAT_BS(bb)->root_ent_max);159 sf = uint16_t_le2host(FAT_BS(bb)->sec_per_fat);160 block_put(bb);161 162 rds = (sizeof(fat_dentry_t) * rde) / bps;163 rds += ((sizeof(fat_dentry_t) * rde) % bps != 0);164 ssa = rscnt + fatcnt * sf + rds;165 166 if (firstc == FAT_CLST_ROOT) {167 /* root directory special case */168 assert(offset < rds);169 b = block_get(dev_handle, rscnt + fatcnt * sf + offset, bps);170 return b;171 }172 173 clusters = offset / spc;174 for (i = 0; i < clusters; i++) {175 unsigned fsec; /* sector offset relative to FAT1 */176 unsigned fidx; /* FAT1 entry index */177 178 assert(clst >= FAT_CLST_FIRST && clst < FAT_CLST_BAD);179 fsec = (clst * sizeof(fat_cluster_t)) / bps;180 fidx = clst % (bps / sizeof(fat_cluster_t));181 /* read FAT1 */182 b = block_get(dev_handle, rscnt + fsec, bps);183 clst = uint16_t_le2host(((fat_cluster_t *)b->data)[fidx]);184 assert(clst != FAT_CLST_BAD);185 assert(clst < FAT_CLST_LAST1);186 block_put(b);187 }188 189 b = block_get(dev_handle, ssa + (clst - FAT_CLST_FIRST) * spc +190 offset % spc, bps);191 192 return b;193 }194 195 /** Return number of blocks allocated to a file.196 *197 * @param dev_handle Device handle of the device with the file.198 * @param firstc First cluster of the file.199 *200 * @return Number of blocks allocated to the file.201 */202 static uint16_t203 _fat_blcks_get(dev_handle_t dev_handle, fat_cluster_t firstc)204 {205 block_t *bb;206 block_t *b;207 unsigned bps;208 unsigned spc;209 unsigned rscnt; /* block address of the first FAT */210 unsigned clusters = 0;211 fat_cluster_t clst = firstc;212 213 bb = block_get(dev_handle, BS_BLOCK, BS_SIZE);214 bps = uint16_t_le2host(FAT_BS(bb)->bps);215 spc = FAT_BS(bb)->spc;216 rscnt = uint16_t_le2host(FAT_BS(bb)->rscnt);217 block_put(bb);218 219 if (firstc == FAT_CLST_RES0) {220 /* No space allocated to the file. */221 return 0;222 }223 224 while (clst < FAT_CLST_LAST1) {225 unsigned fsec; /* sector offset relative to FAT1 */226 unsigned fidx; /* FAT1 entry index */227 228 assert(clst >= FAT_CLST_FIRST);229 fsec = (clst * sizeof(fat_cluster_t)) / bps;230 fidx = clst % (bps / sizeof(fat_cluster_t));231 /* read FAT1 */232 b = block_get(dev_handle, rscnt + fsec, bps);233 clst = uint16_t_le2host(((fat_cluster_t *)b->data)[fidx]);234 assert(clst != FAT_CLST_BAD);235 block_put(b);236 clusters++;237 }238 239 return clusters * spc;240 103 } 241 104 … … 250 113 node->refcnt = 0; 251 114 node->dirty = false; 252 }253 254 static uint16_t fat_bps_get(dev_handle_t dev_handle)255 {256 block_t *bb;257 uint16_t bps;258 259 bb = block_get(dev_handle, BS_BLOCK, BS_SIZE);260 assert(bb != NULL);261 bps = uint16_t_le2host(FAT_BS(bb)->bps);262 block_put(bb);263 264 return bps;265 115 } 266 116 … … 787 637 } 788 638 789 /** Fill the gap between EOF and a new file position.790 *791 * @param nodep FAT node with the gap.792 * @param mcl First cluster in an independent cluster chain that will793 * be later appended to the end of the node's own cluster794 * chain. If pos is still in the last allocated cluster,795 * this argument is ignored.796 * @param pos Position in the last node block.797 */798 static void799 fat_fill_gap(fat_node_t *nodep, fat_cluster_t mcl, off_t pos)800 {801 uint16_t bps;802 unsigned spc;803 block_t *bb, *b;804 off_t o, boundary;805 806 bb = block_get(nodep->idx->dev_handle, BS_BLOCK, BS_SIZE);807 bps = uint16_t_le2host(FAT_BS(bb)->bps);808 spc = FAT_BS(bb)->spc;809 block_put(bb);810 811 boundary = ROUND_UP(nodep->size, bps * spc);812 813 /* zero out already allocated space */814 for (o = nodep->size - 1; o < pos && o < boundary;815 o = ALIGN_DOWN(o + bps, bps)) {816 b = fat_block_get(nodep, o / bps);817 memset(b->data + o % bps, 0, bps - o % bps);818 b->dirty = true; /* need to sync node */819 block_put(b);820 }821 822 if (o >= pos)823 return;824 825 /* zero out the initial part of the new cluster chain */826 for (o = boundary; o < pos; o += bps) {827 b = _fat_block_get(nodep->idx->dev_handle, mcl,828 (o - boundary) / bps);829 memset(b->data, 0, min(bps, pos - o));830 b->dirty = true; /* need to sync node */831 block_put(b);832 }833 }834 835 static void836 fat_mark_cluster(dev_handle_t dev_handle, unsigned fatno, fat_cluster_t clst,837 fat_cluster_t value)838 {839 /* TODO */840 }841 842 static void843 fat_alloc_shadow_clusters(dev_handle_t dev_handle, fat_cluster_t *lifo,844 unsigned nclsts)845 {846 /* TODO */847 }848 849 static int850 fat_alloc_clusters(dev_handle_t dev_handle, unsigned nclsts, fat_cluster_t *mcl,851 fat_cluster_t *lcl)852 {853 uint16_t bps;854 uint16_t rscnt;855 uint16_t sf;856 block_t *bb, *blk;857 fat_cluster_t *lifo; /* stack for storing free cluster numbers */858 unsigned found = 0; /* top of the free cluster number stack */859 unsigned b, c, cl;860 861 lifo = (fat_cluster_t *) malloc(nclsts * sizeof(fat_cluster_t));862 if (lifo)863 return ENOMEM;864 865 bb = block_get(dev_handle, BS_BLOCK, BS_SIZE);866 bps = uint16_t_le2host(FAT_BS(bb)->bps);867 rscnt = uint16_t_le2host(FAT_BS(bb)->rscnt);868 sf = uint16_t_le2host(FAT_BS(bb)->sec_per_fat);869 block_put(bb);870 871 /*872 * Search FAT1 for unused clusters.873 */874 for (b = 0, cl = 0; b < sf; blk++) {875 blk = block_get(dev_handle, rscnt + b, bps);876 for (c = 0; c < bps / sizeof(fat_cluster_t); c++, cl++) {877 fat_cluster_t *clst = (fat_cluster_t *)blk->data + c;878 if (*clst == FAT_CLST_RES0) {879 /*880 * The cluster is free. Put it into our stack881 * of found clusters and mark it as non-free.882 */883 lifo[found] = cl;884 if (found == 0)885 *clst = FAT_CLST_LAST1;886 else887 *clst = lifo[found - 1];888 blk->dirty = true; /* need to sync block */889 if (++found == nclsts) {890 /* we are almost done */891 block_put(blk);892 /* update the shadow copies of FAT */893 fat_alloc_shadow_clusters(dev_handle,894 lifo, nclsts);895 *mcl = lifo[found - 1];896 *lcl = lifo[0];897 free(lifo);898 return EOK;899 }900 }901 }902 block_put(blk);903 }904 905 /*906 * We could not find enough clusters. Now we need to free the clusters907 * we have allocated so far.908 */909 while (found--)910 fat_mark_cluster(dev_handle, FAT1, lifo[found], FAT_CLST_RES0);911 912 free(lifo);913 return ENOSPC;914 }915 916 static void917 fat_append_clusters(fat_node_t *nodep, fat_cluster_t mcl)918 {919 }920 921 639 void fat_write(ipc_callid_t rid, ipc_call_t *request) 922 640 {
Note:
See TracChangeset
for help on using the changeset viewer.