Changeset 4f1c0b4 in mainline
- Timestamp:
- 2008-11-05T22:28:54Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 9d20ea8
- Parents:
- 8334a427
- Location:
- uspace/srv/fs/fat
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/fat/fat_fat.c
r8334a427 r4f1c0b4 55 55 static futex_t fat_alloc_lock = FUTEX_INITIALIZER; 56 56 57 /** Read block from file located on a FAT file system. 58 * 59 * @param bs Buffer holding the boot sector of the file system. 60 * @param dev_handle Device handle of the file system. 61 * @param firstc First cluster used by the file. Can be zero if the file 62 * is empty. 63 * @param offset Offset in blocks. 64 * 65 * @return Block structure holding the requested block. 66 */ 67 block_t * 68 _fat_block_get(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t firstc, 69 off_t offset) 57 /** Walk the cluster chain. 58 * 59 * @param bs Buffer holding the boot sector for the file. 60 * @param dev_handle Device handle of the device with the file. 61 * @param firstc First cluster to start the walk with. 62 * @param penult If non-NULL, output argument hodling the 63 * the penultimate cluster visited. 64 * @param ult If non-NULL, output argument holding the 65 * ultimate cluster visited. 66 * @param max_clusters Maximum number of clusters to visit. 67 * 68 * @return Number of clusters seen during the walk. 69 */ 70 uint16_t 71 fat_cluster_walk(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t firstc, 72 fat_cluster_t *penult, fat_cluster_t *ult, uint16_t max_clusters) 70 73 { 71 74 block_t *b; 72 75 unsigned bps; 73 unsigned spc;74 76 unsigned rscnt; /* block address of the first FAT */ 75 unsigned fatcnt; 76 unsigned rde; 77 unsigned rds; /* root directory size */ 78 unsigned sf; 79 unsigned ssa; /* size of the system area */ 80 unsigned clusters; 77 uint16_t clusters = 0; 81 78 fat_cluster_t clst = firstc; 82 unsigned i; 83 84 bps = uint16_t_le2host(bs->bps); 85 spc = bs->spc; 79 80 bps = uint16_t_le2host(bs->bps); 86 81 rscnt = uint16_t_le2host(bs->rscnt); 87 fatcnt = bs->fatcnt; 88 rde = uint16_t_le2host(bs->root_ent_max); 89 sf = uint16_t_le2host(bs->sec_per_fat); 90 91 rds = (sizeof(fat_dentry_t) * rde) / bps; 92 rds += ((sizeof(fat_dentry_t) * rde) % bps != 0); 93 ssa = rscnt + fatcnt * sf + rds; 94 95 if (firstc == FAT_CLST_ROOT) { 96 /* root directory special case */ 97 assert(offset < rds); 98 b = block_get(dev_handle, rscnt + fatcnt * sf + offset); 99 return b; 100 } 101 102 clusters = offset / spc; 103 for (i = 0; i < clusters; i++) { 82 83 if (firstc == FAT_CLST_RES0) { 84 /* No space allocated to the file. */ 85 if (ult) 86 *ult = firstc; 87 return 0; 88 } 89 90 /* At this point, the meaning of penult is not well-defined. */ 91 if (penult) 92 *penult = FAT_CLST_RES0; 93 94 while (clst < FAT_CLST_LAST1 && clusters < max_clusters) { 104 95 unsigned fsec; /* sector offset relative to FAT1 */ 105 96 unsigned fidx; /* FAT1 entry index */ 106 97 107 assert(clst >= FAT_CLST_FIRST && clst < FAT_CLST_BAD);108 fsec = (clst * sizeof(fat_cluster_t)) / bps;109 fidx = clst % (bps / sizeof(fat_cluster_t));110 /* read FAT1 */111 b = block_get(dev_handle, rscnt + fsec);112 clst = uint16_t_le2host(((fat_cluster_t *)b->data)[fidx]);113 assert(clst != FAT_CLST_BAD);114 assert(clst < FAT_CLST_LAST1);115 block_put(b);116 }117 118 b = block_get(dev_handle, ssa + (clst - FAT_CLST_FIRST) * spc +119 offset % spc);120 121 return b;122 }123 124 /** Return number of blocks allocated to a file.125 *126 * @param bs Buffer holding the boot sector for the file.127 * @param dev_handle Device handle of the device with the file.128 * @param firstc First cluster of the file.129 * @param lastc If non-NULL, output argument holding the130 * last cluster.131 *132 * @return Number of blocks allocated to the file.133 */134 uint16_t135 _fat_blcks_get(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t firstc,136 fat_cluster_t *lastc)137 {138 block_t *b;139 unsigned bps;140 unsigned spc;141 unsigned rscnt; /* block address of the first FAT */142 unsigned clusters = 0;143 fat_cluster_t clst = firstc;144 145 bps = uint16_t_le2host(bs->bps);146 spc = bs->spc;147 rscnt = uint16_t_le2host(bs->rscnt);148 149 if (firstc == FAT_CLST_RES0) {150 /* No space allocated to the file. */151 if (lastc)152 *lastc = firstc;153 return 0;154 }155 156 while (clst < FAT_CLST_LAST1) {157 unsigned fsec; /* sector offset relative to FAT1 */158 unsigned fidx; /* FAT1 entry index */159 160 98 assert(clst >= FAT_CLST_FIRST); 161 if ( lastc)162 * lastc = clst; /* remember the lastcluster */99 if (penult) 100 *penult = clst; /* remember the penultimate cluster */ 163 101 fsec = (clst * sizeof(fat_cluster_t)) / bps; 164 102 fidx = clst % (bps / sizeof(fat_cluster_t)); … … 171 109 } 172 110 173 if (lastc) 174 *lastc = clst; 175 return clusters * spc; 176 } 111 if (ult) 112 *ult = clst; 113 114 return clusters; 115 } 116 117 /** Read block from file located on a FAT file system. 118 * 119 * @param bs Buffer holding the boot sector of the file system. 120 * @param dev_handle Device handle of the file system. 121 * @param firstc First cluster used by the file. Can be zero if the file 122 * is empty. 123 * @param offset Offset in blocks. 124 * 125 * @return Block structure holding the requested block. 126 */ 127 block_t * 128 _fat_block_get(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t firstc, 129 off_t offset) 130 { 131 block_t *b; 132 unsigned bps; 133 unsigned rscnt; /* block address of the first FAT */ 134 unsigned rde; 135 unsigned rds; /* root directory size */ 136 unsigned sf; 137 unsigned ssa; /* size of the system area */ 138 unsigned clusters, max_clusters; 139 fat_cluster_t lastc, clst = firstc; 140 141 bps = uint16_t_le2host(bs->bps); 142 rscnt = uint16_t_le2host(bs->rscnt); 143 rde = uint16_t_le2host(bs->root_ent_max); 144 sf = uint16_t_le2host(bs->sec_per_fat); 145 146 rds = (sizeof(fat_dentry_t) * rde) / bps; 147 rds += ((sizeof(fat_dentry_t) * rde) % bps != 0); 148 ssa = rscnt + bs->fatcnt * sf + rds; 149 150 if (firstc == FAT_CLST_ROOT) { 151 /* root directory special case */ 152 assert(offset < rds); 153 b = block_get(dev_handle, rscnt + bs->fatcnt * sf + offset); 154 return b; 155 } 156 157 max_clusters = offset / bs->spc; 158 clusters = fat_cluster_walk(bs, dev_handle, firstc, NULL, &lastc, 159 max_clusters); 160 assert(clusters == max_clusters); 161 162 b = block_get(dev_handle, ssa + (lastc - FAT_CLST_FIRST) * bs->spc + 163 offset % bs->spc); 164 165 return b; 166 } 167 177 168 178 169 /** Fill the gap between EOF and a new file position. … … 370 361 uint8_t fatno; 371 362 372 if (_fat_blcks_get(bs, dev_handle, nodep->firstc, &lcl) == 0) { 363 if (fat_clusters_get(bs, nodep->idx->dev_handle, nodep->firstc) == 0) { 364 /* No clusters allocated to the node yet. */ 373 365 nodep->firstc = host2uint16_t_le(mcl); 374 366 nodep->dirty = true; /* need to sync node */ -
uspace/srv/fs/fat/fat_fat.h
r8334a427 r4f1c0b4 58 58 typedef uint16_t fat_cluster_t; 59 59 60 #define fat_clusters_get(bs, dh, fc) \ 61 fat_cluster_walk((bs), (dh), (fc), NULL, NULL, (uint16_t) -1) 60 62 #define fat_block_get(bs, np, off) \ 61 63 _fat_block_get((bs), (np)->idx->dev_handle, (np)->firstc, (off)) 62 64 63 65 extern struct block *_fat_block_get(struct fat_bs *, dev_handle_t, 64 66 fat_cluster_t, off_t); 65 extern uint16_t _fat_blcks_get(struct fat_bs *, dev_handle_t, fat_cluster_t,66 fat_cluster_t * );67 extern uint16_t fat_cluster_walk(struct fat_bs *, dev_handle_t, fat_cluster_t, 68 fat_cluster_t *, fat_cluster_t *, uint16_t); 67 69 68 70 extern void fat_append_clusters(struct fat_bs *, struct fat_node *, -
uspace/srv/fs/fat/fat_ops.c
r8334a427 r4f1c0b4 114 114 fat_node_t *nodep = NULL; 115 115 unsigned bps; 116 unsigned spc; 116 117 unsigned dps; 117 118 … … 165 166 bs = block_bb_get(idxp->dev_handle); 166 167 bps = uint16_t_le2host(bs->bps); 168 spc = bs->spc; 167 169 dps = bps / sizeof(fat_dentry_t); 168 170 … … 185 187 * size of the directory by walking the FAT. 186 188 */ 187 nodep->size = bps * _fat_blcks_get(bs, idxp->dev_handle,188 uint16_t_le2host(d->firstc) , NULL);189 nodep->size = bps * spc * fat_clusters_get(bs, idxp->dev_handle, 190 uint16_t_le2host(d->firstc)); 189 191 } else { 190 192 nodep->type = FAT_FILE;
Note:
See TracChangeset
for help on using the changeset viewer.