Changeset a5de1ef in rtems for cpukit/libblock
- Timestamp:
- 01/05/08 06:57:17 (16 years ago)
- Branches:
- 4.10, 4.11, 4.9, 5, master
- Children:
- a61cc6c
- Parents:
- 74ee68d
- Location:
- cpukit/libblock
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
cpukit/libblock/include/rtems/flashdisk.h
r74ee68d ra5de1ef 58 58 uint32_t block_size; 59 59 uint32_t block_count; 60 uint32_t unavail_blocks; 60 61 uint32_t device_count; 61 62 uint32_t segment_count; … … 265 266 * RTEMS Flash Disk configuration table used to initialise the 266 267 * driver. 268 * 269 * The unavailable blocks count is the number of blocks less than the 270 * available number of blocks the file system is given. This means there 271 * will always be that number of blocks available when the file system 272 * thinks the disk is full. The compaction code needs blocks to compact 273 * with so you will never be able to have all the blocks allocated to the 274 * file system and be able to full the disk. 275 * 276 * The compacting segment count is the number of segments that are 277 * moved into a new segment. A high number will mean more segments with 278 * low active page counts and high used page counts will be moved into 279 * avaliable pages how-ever this extends the compaction time due to 280 * time it takes the erase the pages. There is no pont making this number 281 * greater than the maximum number of pages in a segment. 282 * 283 * The available compacting segment count is the level when compaction occurs 284 * when writing. If you set this to 0 then compaction will fail because 285 * there will be no segments to compact into. 286 * 287 * The info level can be 0 for off with error, and abort messages allowed. 288 * Level 1 is warning messages, level 1 is informational messages, and level 3 289 * is debugging type prints. The info level can be turned off with a compile 290 * time directive on the command line to the compiler of: 291 * 292 * -DRTEMS_FDISK_TRACE=0 267 293 */ 268 294 typedef struct rtems_flashdisk_config 269 295 { 270 uint32_t block_size; /**< The block size. */ 271 uint32_t device_count; /**< The number of devices. */ 272 const rtems_fdisk_device_desc* devices; /**< The device descriptions. */ 273 uint32_t flags; /**< Set of flags to control 274 driver. */ 275 uint32_t compact_segs; /**< Max number of segs to 276 compact in one pass. */ 277 uint32_t info_level; /**< Default info level. */ 296 uint32_t block_size; /**< The block size. */ 297 uint32_t device_count; /**< The number of devices. */ 298 const rtems_fdisk_device_desc* devices; /**< The device descriptions. */ 299 uint32_t flags; /**< Set of flags to control 300 driver. */ 301 uint32_t unavail_blocks; /**< Number of blocks not 302 available to the file sys. */ 303 uint32_t compact_segs; /**< Max number of segs to 304 compact in one pass. */ 305 uint32_t avail_compact_segs; /**< The number of segments 306 when compaction occurs 307 when writing. */ 308 uint32_t info_level; /**< Default info level. */ 278 309 } rtems_flashdisk_config; 279 310 -
cpukit/libblock/src/flashdisk.c
r74ee68d ra5de1ef 205 205 uint32_t pages_bad; /**< Number of pages detected as bad. */ 206 206 207 uint32_t failed; /**< The segment has failed. */ 208 207 209 uint32_t erased; /**< Counter to debugging. Wear support would 208 210 remove this. */ … … 216 218 rtems_fdisk_segment_ctl* head; 217 219 rtems_fdisk_segment_ctl* tail; 220 uint32_t count; 218 221 } rtems_fdisk_segment_ctl_queue; 219 222 … … 249 252 250 253 uint32_t compact_segs; /**< Max segs to compact at once. */ 254 uint32_t avail_compact_segs; /**< The number of segments when 255 compaction occurs when writing. */ 251 256 252 257 uint32_t block_size; /**< The block size for this disk. */ 253 258 rtems_fdisk_block_ctl* blocks; /**< The block to segment-page 254 259 mappings. */ 255 uint32_t block_count; /**< The number of available 256 blocks. */ 260 uint32_t block_count; /**< The number of avail. blocks. */ 261 uint32_t unavail_blocks; /**< The number of unavail blocks. */ 262 257 263 rtems_fdisk_device_ctl* devices; /**< The flash devices for this 258 264 disk. */ … … 444 450 { 445 451 queue->head = queue->tail = 0; 452 queue->count = 0; 453 } 454 455 /** 456 * Push to the head of the segment control queue. 457 */ 458 static void 459 rtems_fdisk_segment_queue_push_head (rtems_fdisk_segment_ctl_queue* queue, 460 rtems_fdisk_segment_ctl* sc) 461 { 462 if (sc) 463 { 464 sc->next = queue->head; 465 queue->head = sc; 466 467 if (queue->tail == 0) 468 queue->tail = sc; 469 queue->count++; 470 } 446 471 } 447 472 … … 460 485 queue->tail = 0; 461 486 487 queue->count--; 488 462 489 sc->next = 0; 463 490 … … 467 494 return 0; 468 495 } 469 470 /**471 * Push to the head of the segment control queue.472 */473 #if 0474 static void475 rtems_fdisk_segment_queue_push_head (rtems_fdisk_segment_ctl_queue* queue,476 rtems_fdisk_segment_ctl* sc)477 {478 if (sc)479 {480 if (queue->head)481 sc->next = queue->head;482 else483 {484 queue->tail = sc;485 sc->next = 0;486 }487 488 queue->head = sc;489 }490 }491 #endif492 496 493 497 /** … … 511 515 queue->head = queue->tail = sc; 512 516 } 517 518 queue->count++; 513 519 } 514 520 } … … 545 551 } 546 552 sc->next = 0; 553 queue->count--; 547 554 break; 548 555 } … … 573 580 sc->next = item; 574 581 *prev = sc; 582 queue->count++; 575 583 return; 576 584 } … … 590 598 rtems_fdisk_segment_queue_count (rtems_fdisk_segment_ctl_queue* queue) 591 599 { 600 return queue->count; 601 } 602 603 /** 604 * Count the number of elements on the list. 605 */ 606 static uint32_t 607 rtems_fdisk_segment_count_queue (rtems_fdisk_segment_ctl_queue* queue) 608 { 592 609 rtems_fdisk_segment_ctl* sc = queue->head; 593 610 uint32_t count = 0; … … 605 622 * See if a segment control is present on this queue. 606 623 */ 607 #if RTEMS_FDISK_TRACE608 624 static bool 609 625 rtems_fdisk_segment_queue_present (rtems_fdisk_segment_ctl_queue* queue, … … 621 637 return false; 622 638 } 623 #endif 624 625 /** 626 * Check if the buffer is erased. 627 */ 628 static bool 629 rtems_fdisk_is_erased (const void* buffer, uint32_t size) 630 { 631 const uint8_t* p = buffer; 632 uint32_t c; 633 for (c = 0; c < size; c++) 634 { 635 if (*p != 0xff) 636 return false; 637 } 638 return true; 639 640 /** 641 * Format a string with the queue status. 642 */ 643 static void 644 rtems_fdisk_queue_status (rtems_flashdisk* fd, 645 rtems_fdisk_segment_ctl* sc, 646 char queues[5]) 647 { 648 queues[0] = rtems_fdisk_segment_queue_present (&fd->available, sc) ? 'A' : '-'; 649 queues[1] = rtems_fdisk_segment_queue_present (&fd->used, sc) ? 'U' : '-'; 650 queues[2] = rtems_fdisk_segment_queue_present (&fd->erase, sc) ? 'E' : '-'; 651 queues[3] = rtems_fdisk_segment_queue_present (&fd->failed, sc) ? 'F' : '-'; 652 queues[4] = '\0'; 639 653 } 640 654 … … 645 659 rtems_fdisk_page_desc_erased (const rtems_fdisk_page_desc* pd) 646 660 { 647 return rtems_fdisk_is_erased (pd, sizeof (rtems_fdisk_page_desc)); 661 return ((pd->crc == 0xffff) && 662 (pd->flags == 0xffff) && 663 (pd->block == 0xffffffff)) ? true : false; 648 664 } 649 665 … … 1127 1143 "segment erase failed: %s (%d)", 1128 1144 sc->device, sc->segment, strerror (ret), ret); 1129 rtems_fdisk_segment_queue_push_tail (&fd->failed, sc); 1145 sc->failed = true; 1146 if (!rtems_fdisk_segment_queue_present (&fd->failed, sc)) 1147 rtems_fdisk_segment_queue_push_tail (&fd->failed, sc); 1130 1148 return ret; 1131 1149 } … … 1138 1156 sc->pages_used = 0; 1139 1157 sc->pages_bad = 0; 1158 1159 sc->failed = false; 1140 1160 1141 1161 /* … … 1184 1204 { 1185 1205 #if RTEMS_FDISK_TRACE 1186 rtems_fdisk_info (fd, " queue-seg:%02d-%03d: p=%d a=%d u=%d b=%d n=%s",1206 rtems_fdisk_info (fd, " queue-seg:%02d-%03d: p=%d a=%d u=%d b=%d f=%s n=%s", 1187 1207 sc->device, sc->segment, 1188 1208 sc->pages, sc->pages_active, sc->pages_used, sc->pages_bad, 1189 sc->next ? "set" : "null"); 1190 #endif 1191 1209 sc->failed ? "FAILED" : "no", sc->next ? "set" : "null"); 1210 #endif 1211 1212 /* 1213 * If the segment has failed then check the failed queue and append 1214 * if not failed. 1215 */ 1216 if (sc->failed) 1217 { 1218 if (!rtems_fdisk_segment_queue_present (&fd->failed, sc)) 1219 rtems_fdisk_segment_queue_push_tail (&fd->failed, sc); 1220 return; 1221 } 1222 1192 1223 /* 1193 1224 * Remove the queue from the available or used queue. … … 1208 1239 { 1209 1240 /* 1210 * Keep the used queue sorted on the least number 1211 * of pages. When we compact we want to move the 1212 * pages into a new segment and cover more than one 1213 * segment. 1241 * Keep the used queue sorted by the most number of used 1242 * pages. When we compact we want to move the pages into 1243 * a new segment and cover more than one segment. 1214 1244 */ 1215 1245 rtems_fdisk_segment_ctl* seg = fd->used.head; … … 1294 1324 { 1295 1325 rtems_fdisk_segment_ctl* dsc; 1296 1326 rtems_fdisk_segment_ctl* ssc; 1327 uint32_t dst_pages; 1328 uint32_t segments; 1329 uint32_t pages; 1330 1331 #if RTEMS_FDISK_TRACE 1332 rtems_fdisk_printf (fd, " compacting"); 1333 #endif 1334 1297 1335 dsc = rtems_fdisk_seg_most_available (&fd->available); 1298 1336 1299 if (dsc) 1300 { 1301 rtems_fdisk_segment_ctl* ssc = fd->used.head; 1302 uint32_t dst_pages = rtems_fdisk_seg_pages_available (dsc); 1303 uint32_t segments = 0; 1304 uint32_t pages = 0; 1305 1306 #if RTEMS_FDISK_TRACE 1307 rtems_fdisk_printf (fd, "dsc: %d-%d", dsc->device, dsc->segment); 1337 if (dsc == 0) 1338 { 1339 rtems_fdisk_error ("compacting: no available segments to compact too"); 1340 return EIO; 1341 } 1342 1343 ssc = fd->used.head; 1344 dst_pages = rtems_fdisk_seg_pages_available (dsc); 1345 segments = 0; 1346 pages = 0; 1347 1348 #if RTEMS_FDISK_TRACE 1349 rtems_fdisk_printf (fd, " dsc:%02d-%03d: most available", 1350 dsc->device, dsc->segment); 1308 1351 #endif 1309 1352 1310 1311 1312 1313 1314 1315 1316 1353 /* 1354 * Count the number of segments that have active pages that fit into 1355 * the destination segment. Also limit the number of segments that 1356 * we handle during one compaction. A lower number means less aggressive 1357 * compaction or less delay when compacting but it may mean the disk 1358 * will fill. 1359 */ 1317 1360 1318 while (ssc && 1319 ((pages + ssc->pages_active) < dst_pages) && 1320 ((compacted_segs + segments) < fd->compact_segs)) 1361 while (ssc && 1362 ((pages + ssc->pages_active) < dst_pages) && 1363 ((compacted_segs + segments) < fd->compact_segs)) 1364 { 1365 pages += ssc->pages_active; 1366 segments++; 1367 ssc = ssc->next; 1368 } 1369 1370 /* 1371 * We need a source segment and have pages to copy and 1372 * compacting one segment to another is silly. Compaction needs 1373 * to free at least one more segment. 1374 */ 1375 1376 if (!ssc || (pages == 0) || ((compacted_segs + segments) == 1)) 1377 break; 1378 1379 #if RTEMS_FDISK_TRACE 1380 rtems_fdisk_printf (fd, " ssc scan: %d-%d: p=%ld, seg=%ld", 1381 ssc->device, ssc->segment, 1382 pages, segments); 1383 #endif 1384 1385 rtems_fdisk_segment_queue_remove (&fd->available, dsc); 1386 1387 /* 1388 * We now copy the pages to the new segment. 1389 */ 1390 1391 while (pages) 1392 { 1393 uint32_t spage; 1394 int ret; 1395 1396 ssc = rtems_fdisk_segment_queue_pop_head (&fd->used); 1397 1398 if (ssc) 1321 1399 { 1322 pages += ssc->pages_active; 1323 segments++; 1324 ssc = ssc->next; 1400 uint32_t used = 0; 1401 uint32_t active = 0; 1402 for (spage = 0; spage < ssc->pages; spage++) 1403 { 1404 rtems_fdisk_page_desc* spd = &ssc->page_descriptors[spage]; 1405 1406 if (rtems_fdisk_page_desc_flags_set (spd, RTEMS_FDISK_PAGE_ACTIVE) && 1407 !rtems_fdisk_page_desc_flags_set (spd, RTEMS_FDISK_PAGE_USED)) 1408 { 1409 rtems_fdisk_page_desc* dpd; 1410 uint32_t dpage; 1411 1412 dpage = rtems_fdisk_seg_next_available_page (dsc); 1413 dpd = &dsc->page_descriptors[dpage]; 1414 1415 active++; 1416 1417 if (dpage >= dsc->pages) 1418 { 1419 rtems_fdisk_error ("compacting: %02d-%03d: " \ 1420 "no page desc available: %d", 1421 dsc->device, dsc->segment, 1422 rtems_fdisk_seg_pages_available (dsc)); 1423 dsc->failed = true; 1424 rtems_fdisk_queue_segment (fd, dsc); 1425 rtems_fdisk_segment_queue_push_head (&fd->used, ssc); 1426 return EIO; 1427 } 1428 1429 #if RTEMS_FDISK_TRACE 1430 rtems_fdisk_info (fd, "compacting: %02d-%03d-%03d=>%02d-%03d-%03d", 1431 ssc->device, ssc->segment, spage, 1432 dsc->device, dsc->segment, dpage); 1433 #endif 1434 ret = rtems_fdisk_seg_copy_page (fd, ssc->device, ssc->segment, 1435 spage + ssc->pages_desc, 1436 dsc->device, dsc->segment, 1437 dpage + dsc->pages_desc); 1438 if (ret) 1439 { 1440 rtems_fdisk_error ("compacting: %02d-%03d-%03d=>" \ 1441 "%02d-%03d-%03d: " \ 1442 "copy page failed: %s (%d)", 1443 ssc->device, ssc->segment, spage, 1444 dsc->device, dsc->segment, dpage, 1445 strerror (ret), ret); 1446 dsc->failed = true; 1447 rtems_fdisk_queue_segment (fd, dsc); 1448 rtems_fdisk_segment_queue_push_head (&fd->used, ssc); 1449 return ret; 1450 } 1451 1452 *dpd = *spd; 1453 1454 ret = rtems_fdisk_seg_write_page_desc (fd, 1455 dsc->device, dsc->segment, 1456 dpage, dpd); 1457 1458 if (ret) 1459 { 1460 rtems_fdisk_error ("compacting: %02d-%03d-%03d=>" \ 1461 "%02d-%03d-%03d: copy pd failed: %s (%d)", 1462 ssc->device, ssc->segment, spage, 1463 dsc->device, dsc->segment, dpage, 1464 strerror (ret), ret); 1465 dsc->failed = true; 1466 rtems_fdisk_queue_segment (fd, dsc); 1467 rtems_fdisk_segment_queue_push_head (&fd->used, ssc); 1468 return ret; 1469 } 1470 1471 dsc->pages_active++; 1472 1473 /* 1474 * No need to set the used bit on the source page as the 1475 * segment will be erased. Power down could be a problem. 1476 * We do the stats to make sure everything is as it should 1477 * be. 1478 */ 1479 1480 ssc->pages_active--; 1481 ssc->pages_used++; 1482 1483 fd->blocks[spd->block].segment = dsc; 1484 fd->blocks[spd->block].page = dpage; 1485 1486 /* 1487 * Place the segment on to the correct queue. 1488 */ 1489 rtems_fdisk_queue_segment (fd, dsc); 1490 1491 pages--; 1492 } 1493 else 1494 used++; 1495 } 1496 1497 #if RTEMS_FDISK_TRACE 1498 rtems_fdisk_printf (fd, "ssc end: %d-%d: p=%ld, a=%ld, u=%ld", 1499 ssc->device, ssc->segment, 1500 pages, active, used); 1501 #endif 1502 if (ssc->pages_active != 0) 1503 { 1504 rtems_fdisk_error ("compacting: ssc pages not 0: %d", 1505 ssc->pages_active); 1506 } 1507 1508 ret = rtems_fdisk_erase_segment (fd, ssc); 1509 1510 if (ret) 1511 return ret; 1325 1512 } 1326 1327 /* 1328 * We need a source segment and have pages to copy and 1329 * compacting one segment to another is silly. Compaction needs 1330 * to free at least one more segment. 1331 */ 1332 1333 if (!ssc || (pages == 0) || ((compacted_segs + segments) == 1)) 1334 break; 1335 1336 #if RTEMS_FDISK_TRACE 1337 rtems_fdisk_printf (fd, "ssc scan: %d-%d: p=%ld, seg=%ld", 1338 ssc->device, ssc->segment, 1339 pages, segments); 1340 #endif 1341 1342 rtems_fdisk_segment_queue_remove (&fd->available, dsc); 1343 1344 /* 1345 * We now copy the pages to the new segment. 1346 */ 1347 1348 while (pages) 1349 { 1350 uint32_t spage; 1351 int ret; 1352 1353 ssc = rtems_fdisk_segment_queue_pop_head (&fd->used); 1354 1355 if (ssc) 1356 { 1357 uint32_t used = 0; 1358 uint32_t active = 0; 1359 for (spage = 0; spage < ssc->pages; spage++) 1360 { 1361 rtems_fdisk_page_desc* spd = &ssc->page_descriptors[spage]; 1362 1363 if (rtems_fdisk_page_desc_flags_set (spd, RTEMS_FDISK_PAGE_ACTIVE) && 1364 !rtems_fdisk_page_desc_flags_set (spd, RTEMS_FDISK_PAGE_USED)) 1365 { 1366 rtems_fdisk_page_desc* dpd; 1367 uint32_t dpage; 1368 1369 dpage = rtems_fdisk_seg_next_available_page (dsc); 1370 dpd = &dsc->page_descriptors[dpage]; 1371 1372 active++; 1373 1374 if (dpage >= dsc->pages) 1375 { 1376 rtems_fdisk_error ("compacting: %02d-%03d: " \ 1377 "no page desc available: %d", 1378 dsc->device, dsc->segment, 1379 rtems_fdisk_seg_pages_available (dsc)); 1380 rtems_fdisk_segment_queue_push_tail (&fd->failed, dsc); 1381 return EIO; 1382 } 1383 1384 #if RTEMS_FDISK_TRACE 1385 rtems_fdisk_info (fd, "compacting: %02d-%03d-%03d=>%02d-%03d-%03d", 1386 ssc->device, ssc->segment, spage, 1387 dsc->device, dsc->segment, dpage); 1388 #endif 1389 ret = rtems_fdisk_seg_copy_page (fd, ssc->device, ssc->segment, 1390 spage + ssc->pages_desc, 1391 dsc->device, dsc->segment, 1392 dpage + dsc->pages_desc); 1393 if (ret) 1394 { 1395 rtems_fdisk_error ("compacting: %02d-%03d-%03d=>" \ 1396 "%02d-%03d-%03d: " \ 1397 "copy page failed: %s (%d)", 1398 ssc->device, ssc->segment, spage, 1399 dsc->device, dsc->segment, dpage, 1400 strerror (ret), ret); 1401 rtems_fdisk_segment_queue_push_tail (&fd->failed, dsc); 1402 return ret; 1403 } 1404 1405 *dpd = *spd; 1406 1407 ret = rtems_fdisk_seg_write_page_desc (fd, 1408 dsc->device, dsc->segment, 1409 dpage, dpd); 1410 1411 if (ret) 1412 { 1413 rtems_fdisk_error ("compacting: %02d-%03d-%03d=>" \ 1414 "%02d-%03d-%03d: copy pd failed: %s (%d)", 1415 ssc->device, ssc->segment, spage, 1416 dsc->device, dsc->segment, dpage, 1417 strerror (ret), ret); 1418 rtems_fdisk_segment_queue_push_tail (&fd->failed, dsc); 1419 return ret; 1420 } 1421 1422 dsc->pages_active++; 1423 1424 /* 1425 * No need to set the used bit on the source page as the 1426 * segment will be erased. Power down could be a problem. 1427 * We do the stats to make sure everything is as it should 1428 * be. 1429 */ 1430 1431 ssc->pages_active--; 1432 ssc->pages_used++; 1433 1434 fd->blocks[spd->block].segment = dsc; 1435 fd->blocks[spd->block].page = dpage; 1436 1437 /* 1438 * Place the segment on to the correct queue. 1439 */ 1440 rtems_fdisk_queue_segment (fd, dsc); 1441 1442 pages--; 1443 } 1444 else 1445 used++; 1446 } 1447 1448 #if RTEMS_FDISK_TRACE 1449 rtems_fdisk_printf (fd, "ssc end: %d-%d: p=%ld, a=%ld, u=%ld", 1450 ssc->device, ssc->segment, 1451 pages, active, used); 1452 #endif 1453 if (ssc->pages_active != 0) 1454 { 1455 rtems_fdisk_error ("compacting: ssc pages not 0: %d", 1456 ssc->pages_active); 1457 } 1458 1459 ret = rtems_fdisk_erase_segment (fd, ssc); 1460 1461 if (ret) 1462 return ret; 1463 } 1464 } 1465 1466 compacted_segs += segments; 1467 } 1513 } 1514 1515 compacted_segs += segments; 1468 1516 } 1469 1517 … … 1517 1565 sc->pages_used = 0; 1518 1566 sc->pages_bad = 0; 1519 1567 1568 sc->failed = false; 1569 1520 1570 if (!sc->page_descriptors) 1521 1571 sc->page_descriptors = malloc (sc->pages_desc * fd->block_size); … … 1575 1625 1576 1626 if (ret) 1627 { 1577 1628 rtems_fdisk_error ("forcing page to used failed: %d-%d-%d", 1578 1629 device, segment, page); 1630 sc->failed = true; 1631 } 1579 1632 1580 1633 sc->pages_used++; … … 1665 1718 rtems_fdisk_page_desc* pd; 1666 1719 1720 #if RTEMS_FDISK_TRACE 1721 rtems_fdisk_info (fd, "read-block:%d", block); 1722 #endif 1723 1667 1724 /* 1668 1725 * Broken out to allow info messages when testing. 1669 1726 */ 1670 1727 1671 if (block >= fd->block_count)1672 { 1673 rtems_fdisk_error ("read-block: b ad block: %d", block);1728 if (block >= (fd->block_count - fd->unavail_blocks)) 1729 { 1730 rtems_fdisk_error ("read-block: block out of range: %d", block); 1674 1731 return EIO; 1675 1732 } … … 1691 1748 #if RTEMS_FDISK_TRACE 1692 1749 rtems_fdisk_info (fd, 1693 " read-block:%d=>%02d-%03d-%03d: p=%d a=%d u=%d b=%d n=%s: " \1750 " read:%d=>%02d-%03d-%03d: p=%d a=%d u=%d b=%d n=%s: " \ 1694 1751 "f=%04x c=%04x b=%d", 1695 1752 block, sc->device, sc->segment, bc->page, … … 1782 1839 int ret; 1783 1840 1841 #if RTEMS_FDISK_TRACE 1842 rtems_fdisk_info (fd, "write-block:%d", block); 1843 #endif 1784 1844 1785 1845 /* … … 1787 1847 */ 1788 1848 1789 if (block >= fd->block_count)1790 { 1791 rtems_fdisk_error ("write-block: b ad block: %d", block);1849 if (block >= (fd->block_count - fd->unavail_blocks)) 1850 { 1851 rtems_fdisk_error ("write-block: block out of range: %d", block); 1792 1852 return EIO; 1793 1853 } … … 1802 1862 sc = bc->segment; 1803 1863 pd = &sc->page_descriptors[bc->page]; 1864 1865 #if RTEMS_FDISK_TRACE 1866 rtems_fdisk_info (fd, " write:%02d-%03d-%03d: flag used", 1867 sc->device, sc->segment, bc->page); 1868 #endif 1804 1869 1805 1870 /* … … 1831 1896 { 1832 1897 #if RTEMS_FDISK_TRACE 1833 rtems_fdisk_info (fd, " write-block:%02d-%03d-%03d: " \1898 rtems_fdisk_info (fd, " write:%02d-%03d-%03d: " \ 1834 1899 "write used page desc failed: %s (%d)", 1835 1900 sc->device, sc->segment, bc->page, 1836 1901 strerror (ret), ret); 1837 1902 #endif 1838 } 1839 1840 sc->pages_active--; 1841 sc->pages_used++; 1842 1903 sc->failed = true; 1904 } 1905 else 1906 { 1907 sc->pages_active--; 1908 sc->pages_used++; 1909 } 1910 1843 1911 /* 1844 1912 * If possible reuse this segment. This will mean the segment … … 1858 1926 1859 1927 /* 1928 * Is it time to compact the disk ? 1929 * 1930 * We override the background compaction configruation. 1931 */ 1932 if (rtems_fdisk_segment_count_queue (&fd->available) <= 1933 fd->avail_compact_segs) 1934 rtems_fdisk_compact (fd); 1935 1936 /* 1860 1937 * Get the next avaliable segment. 1861 1938 */ … … 1886 1963 } 1887 1964 1965 #if RTEMS_FDISK_TRACE 1966 if (fd->info_level >= 3) 1967 { 1968 char queues[5]; 1969 rtems_fdisk_queue_status (fd, sc, queues); 1970 rtems_fdisk_info (fd, " write:%d=>%02d-%03d: queue check: %s", 1971 block, sc->device, sc->segment, queues); 1972 } 1973 #endif 1974 1888 1975 /* 1889 1976 * Find the next avaliable page in the segment. … … 1905 1992 1906 1993 #if RTEMS_FDISK_TRACE 1907 rtems_fdisk_info (fd, " write-block:%d=>%02d-%03d-%03d: "\1994 rtems_fdisk_info (fd, " write:%d=>%02d-%03d-%03d: write: " \ 1908 1995 "p=%d a=%d u=%d b=%d n=%s: f=%04x c=%04x b=%d", 1909 1996 block, sc->device, sc->segment, page, … … 1926 2013 strerror (ret), ret); 1927 2014 #endif 1928 rtems_fdisk_segment_queue_push_tail (&fd->failed, sc); 1929 return ret; 2015 sc->failed = true; 2016 } 2017 else 2018 { 2019 ret = rtems_fdisk_seg_write_page_desc (fd, sc->device, sc->segment, 2020 page, pd); 2021 if (ret) 2022 { 2023 #if RTEMS_FDISK_TRACE 2024 rtems_fdisk_info (fd, "write-block:%02d-%03d-%03d: " \ 2025 "write page desc failed: %s (%d)", 2026 sc->device, sc->segment, bc->page, 2027 strerror (ret), ret); 2028 #endif 2029 sc->failed = true; 2030 } 2031 else 2032 { 2033 sc->pages_active++; 2034 } 1930 2035 } 1931 2036 1932 ret = rtems_fdisk_seg_write_page_desc (fd, sc->device, sc->segment,1933 page, pd);1934 if (ret)1935 {1936 #if RTEMS_FDISK_TRACE1937 rtems_fdisk_info (fd, "write-block:%02d-%03d-%03d: " \1938 "write page desc failed: %s (%d)",1939 sc->device, sc->segment, bc->page,1940 strerror (ret), ret);1941 #endif1942 rtems_fdisk_segment_queue_push_tail (&fd->failed, sc);1943 return ret;1944 }1945 1946 sc->pages_active++;1947 1948 2037 rtems_fdisk_queue_segment (fd, sc); 1949 1950 return 0; 2038 return ret; 1951 2039 } 1952 2040 } … … 1955 2043 sc->device, sc->segment); 1956 2044 1957 rtems_fdisk_segment_queue_push_tail (&fd->failed, sc); 2045 sc->failed = true; 2046 rtems_fdisk_queue_segment (fd, sc); 1958 2047 1959 2048 return EIO; … … 2084 2173 data->block_size = fd->block_size; 2085 2174 data->block_count = fd->block_count; 2175 data->unavail_blocks = fd->unavail_blocks; 2086 2176 data->device_count = fd->device_count; 2087 2177 … … 2091 2181 data->blocks_used++; 2092 2182 2093 data->segs_available = rtems_fdisk_segment_ queue_count(&fd->available);2094 data->segs_used = rtems_fdisk_segment_ queue_count(&fd->used);2095 data->segs_failed = rtems_fdisk_segment_ queue_count(&fd->failed);2183 data->segs_available = rtems_fdisk_segment_count_queue (&fd->available); 2184 data->segs_used = rtems_fdisk_segment_count_queue (&fd->used); 2185 data->segs_failed = rtems_fdisk_segment_count_queue (&fd->failed); 2096 2186 2097 2187 data->segment_count = 0; … … 2142 2232 2143 2233 rtems_fdisk_printf (fd, "Block count\t%d", fd->block_count); 2144 count = rtems_fdisk_segment_queue_count (&fd->available); 2234 rtems_fdisk_printf (fd, "Unavail blocks\t%d", fd->unavail_blocks); 2235 count = rtems_fdisk_segment_count_queue (&fd->available); 2145 2236 total = count; 2146 rtems_fdisk_printf (fd, "Available queue\t%ld", count); 2147 count = rtems_fdisk_segment_queue_count (&fd->used); 2237 rtems_fdisk_printf (fd, "Available queue\t%ld (%ld)", 2238 count, rtems_fdisk_segment_queue_count (&fd->available)); 2239 count = rtems_fdisk_segment_count_queue (&fd->used); 2148 2240 total += count; 2149 rtems_fdisk_printf (fd, "Used queue\t%ld", count); 2150 count = rtems_fdisk_segment_queue_count (&fd->erase); 2241 rtems_fdisk_printf (fd, "Used queue\t%ld (%ld)", 2242 count, rtems_fdisk_segment_queue_count (&fd->used)); 2243 count = rtems_fdisk_segment_count_queue (&fd->erase); 2151 2244 total += count; 2152 rtems_fdisk_printf (fd, "Erase queue\t%ld", count); 2153 count = rtems_fdisk_segment_queue_count (&fd->failed); 2245 rtems_fdisk_printf (fd, "Erase queue\t%ld (%ld)", 2246 count, rtems_fdisk_segment_queue_count (&fd->erase)); 2247 count = rtems_fdisk_segment_count_queue (&fd->failed); 2154 2248 total += count; 2155 rtems_fdisk_printf (fd, "Failed queue\t%ld", count); 2249 rtems_fdisk_printf (fd, "Failed queue\t%ld (%ld)", 2250 count, rtems_fdisk_segment_queue_count (&fd->failed)); 2156 2251 2157 2252 count = 0; … … 2183 2278 char queues[5]; 2184 2279 2185 queues[0] = '-'; 2186 queues[1] = '-'; 2187 queues[2] = '-'; 2188 queues[3] = '-'; 2189 queues[4] = '\0'; 2190 2191 if (rtems_fdisk_segment_queue_present (&fd->available, sc)) 2192 queues[0] = 'A'; 2193 if (rtems_fdisk_segment_queue_present (&fd->used, sc)) 2194 queues[1] = 'U'; 2195 if (rtems_fdisk_segment_queue_present (&fd->erase, sc)) 2196 queues[2] = 'E'; 2197 if (rtems_fdisk_segment_queue_present (&fd->failed, sc)) 2198 queues[3] = 'F'; 2199 2280 rtems_fdisk_queue_status (fd, sc, queues); 2281 2200 2282 for (page = 0; page < sc->pages; page++) 2201 2283 { … … 2242 2324 } 2243 2325 } 2244 2326 2327 { 2328 rtems_fdisk_segment_ctl* sc = fd->used.head; 2329 int count = 0; 2330 rtems_fdisk_printf (fd, "Used List:"); 2331 while (sc) 2332 { 2333 rtems_fdisk_printf (fd, " %3d %02d:%03d u:%3ld", 2334 count, sc->device, sc->segment, sc->pages_used); 2335 sc = sc->next; 2336 count++; 2337 } 2338 } 2245 2339 fd->info_level = current_info_level; 2246 2340 … … 2383 2477 RTEMS_FLASHDISK_DEVICE_BASE_NAME "%" PRIu32, minor); 2384 2478 2385 fd->major = major; 2386 fd->minor = minor; 2387 fd->flags = c->flags; 2388 fd->compact_segs = c->compact_segs; 2389 fd->block_size = c->block_size; 2390 fd->info_level = c->info_level; 2479 fd->major = major; 2480 fd->minor = minor; 2481 fd->flags = c->flags; 2482 fd->compact_segs = c->compact_segs; 2483 fd->avail_compact_segs = c->avail_compact_segs; 2484 fd->block_size = c->block_size; 2485 fd->unavail_blocks = c->unavail_blocks; 2486 fd->info_level = c->info_level; 2391 2487 2392 2488 for (device = 0; device < c->device_count; device++) … … 2394 2490 c->block_size); 2395 2491 2396 sc = rtems_disk_create_phys(dev, c->block_size, blocks, 2492 sc = rtems_disk_create_phys(dev, c->block_size, 2493 blocks - fd->unavail_blocks, 2397 2494 rtems_fdisk_ioctl, name); 2398 2495 if (sc != RTEMS_SUCCESSFUL)
Note: See TracChangeset
for help on using the changeset viewer.