Changeset 8a40c49 in mainline
- Timestamp:
- 2011-06-11T18:40:44Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- cefd3ec
- Parents:
- da2f8d10
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/fat/fat_ops.c
rda2f8d10 r8a40c49 39 39 #include "fat_dentry.h" 40 40 #include "fat_fat.h" 41 #include "fat_directory.h" 41 42 #include "../../vfs/vfs.h" 42 43 #include <libfs.h> … … 1219 1220 } 1220 1221 } else { 1221 unsigned bnum;1222 1222 aoff64_t spos = pos; 1223 1223 char name[FAT_LFN_NAME_SIZE]; 1224 uint8_t lfn_utf16[FAT_LFN_MAX_COUNT * FAT_LFN_ENTRY_SIZE];1225 size_t lfn_offset;1226 size_t lfn_size;1227 bool long_entry = false;1228 int long_entry_count = 0;1229 1224 fat_dentry_t *d; 1230 uint8_t checksum=0;1231 1225 1232 1226 assert(nodep->type == FAT_DIRECTORY); … … 1234 1228 assert(BPS(bs) % sizeof(fat_dentry_t) == 0); 1235 1229 1236 /* 1237 * Our strategy for readdir() is to use the position pointer as 1238 * an index into the array of all dentries. On entry, it points 1239 * to the first unread dentry. If we skip any dentries, we bump 1240 * the position pointer accordingly. 1241 */ 1242 bnum = (pos * sizeof(fat_dentry_t)) / BPS(bs); 1243 while (bnum < nodep->size / BPS(bs)) { 1244 aoff64_t o; 1245 1246 rc = fat_block_get(&b, bs, nodep, bnum, 1247 BLOCK_FLAGS_NONE); 1248 if (rc != EOK) 1249 goto err; 1250 for (o = pos % (BPS(bs) / sizeof(fat_dentry_t)); 1251 o < BPS(bs) / sizeof(fat_dentry_t); 1252 o++, pos++) { 1253 d = ((fat_dentry_t *)b->data) + o; 1254 switch (fat_classify_dentry(d)) { 1255 case FAT_DENTRY_SKIP: 1256 case FAT_DENTRY_FREE: 1257 long_entry_count = 0; 1258 long_entry = false; 1259 continue; 1260 case FAT_DENTRY_LAST: 1261 long_entry_count = 0; 1262 long_entry = false; 1263 rc = block_put(b); 1264 if (rc != EOK) 1265 goto err; 1266 goto miss; 1267 case FAT_DENTRY_LFN: 1268 if (long_entry) { 1269 /* We found long entry */ 1270 long_entry_count--; 1271 if ((FAT_LFN_ORDER(d) == long_entry_count) && 1272 (checksum == FAT_LFN_CHKSUM(d))) { 1273 /* Right order! */ 1274 fat_lfn_copy_entry(d, lfn_utf16, &lfn_offset); 1275 } else { 1276 /* Something wrong with order. Skip this long entries set */ 1277 long_entry_count = 0; 1278 long_entry = false; 1279 } 1280 } else { 1281 if (FAT_IS_LFN(d)) { 1282 /* We found Last long entry! */ 1283 if (FAT_LFN_COUNT(d) <= FAT_LFN_MAX_COUNT) { 1284 long_entry = true; 1285 long_entry_count = FAT_LFN_COUNT(d); 1286 lfn_size = (FAT_LFN_ENTRY_SIZE * 1287 (FAT_LFN_COUNT(d) - 1)) + fat_lfn_size(d); 1288 lfn_offset = lfn_size; 1289 fat_lfn_copy_entry(d, lfn_utf16, &lfn_offset); 1290 checksum = FAT_LFN_CHKSUM(d); 1291 } 1292 } 1293 } 1294 break; 1295 default: 1296 case FAT_DENTRY_VALID: 1297 if (long_entry && 1298 (checksum == fat_dentry_chksum(d->name))) { 1299 rc = fat_lfn_convert_name(lfn_utf16, lfn_size, (uint8_t*)name, FAT_LFN_NAME_SIZE); 1300 if (rc!=EOK) 1301 fat_dentry_name_get(d, name); 1302 } 1303 else 1304 fat_dentry_name_get(d, name); 1305 1306 long_entry_count = 0; 1307 long_entry = false; 1308 rc = block_put(b); 1309 if (rc != EOK) 1310 goto err; 1311 goto hit; 1312 } 1313 } 1314 rc = block_put(b); 1315 if (rc != EOK) 1316 goto err; 1317 bnum++; 1318 } 1319 miss: 1320 rc = fat_node_put(fn); 1321 async_answer_0(callid, rc != EOK ? rc : ENOENT); 1322 async_answer_1(rid, rc != EOK ? rc : ENOENT, 0); 1323 return; 1230 fat_directory_t di; 1231 fat_directory_open(nodep, &di); 1232 di.pos = pos; 1233 1234 rc = fat_directory_read(&di, name, &d); 1235 if (rc == EOK) goto hit; 1236 if (rc == ENOENT) goto miss; 1324 1237 1325 1238 err: … … 1329 1242 return; 1330 1243 1244 miss: 1245 rc = fat_directory_close(&di); 1246 if (rc!=EOK) 1247 goto err; 1248 rc = fat_node_put(fn); 1249 async_answer_0(callid, rc != EOK ? rc : ENOENT); 1250 async_answer_1(rid, rc != EOK ? rc : ENOENT, 0); 1251 return; 1252 1331 1253 hit: 1254 pos = di.pos; 1255 rc = fat_directory_close(&di); 1256 if (rc!=EOK) 1257 goto err; 1332 1258 (void) async_data_read_finalize(callid, name, str_size(name) + 1); 1333 bytes = (pos - spos) + 1;1259 bytes = (pos - spos); 1334 1260 } 1335 1261
Note:
See TracChangeset
for help on using the changeset viewer.