Changeset 16708 in vbox
- Timestamp:
- Feb 12, 2009 1:23:10 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DevATA.cpp
r16114 r16708 1352 1352 1353 1353 1354 static int ataReadSectors(ATADevState *s, uint64_t u64Sector, void *pvBuf, uint32_t cSectors) 1354 static void ataWarningDiskFull(PPDMDEVINS pDevIns) 1355 { 1356 int rc; 1357 LogRel(("PIIX3 ATA: Host disk full\n")); 1358 rc = VMSetRuntimeError(PDMDevHlpGetVM(pDevIns), 1359 false, "DevATA_DISKFULL", 1360 N_("Host system reported disk full. VM execution is suspended. You can resume after freeing some space")); 1361 AssertRC(rc); 1362 } 1363 1364 static void ataWarningFileTooBig(PPDMDEVINS pDevIns) 1365 { 1366 int rc; 1367 LogRel(("PIIX3 ATA: File too big\n")); 1368 rc = VMSetRuntimeError(PDMDevHlpGetVM(pDevIns), 1369 false, "DevATA_FILETOOBIG", 1370 N_("Host system reported that the file size limit of the host file system has been exceeded. VM execution is suspended. You need to move your virtual hard disk to a filesystem which allows bigger files")); 1371 AssertRC(rc); 1372 } 1373 1374 static void ataWarningISCSI(PPDMDEVINS pDevIns) 1375 { 1376 int rc; 1377 LogRel(("PIIX3 ATA: iSCSI target unavailable\n")); 1378 rc = VMSetRuntimeError(PDMDevHlpGetVM(pDevIns), 1379 false, "DevATA_ISCSIDOWN", 1380 N_("The iSCSI target has stopped responding. VM execution is suspended. You can resume when it is available again")); 1381 AssertRC(rc); 1382 } 1383 1384 /** 1385 * Suspend I/O operations on a controller. Also suspends EMT, because it's 1386 * waiting for I/O to make progress. The next attempt to perform an I/O 1387 * operation will be made when EMT is resumed up again (as the resume 1388 * callback below restarts I/O). 1389 * 1390 * @param pCtl Controller for which to suspend I/O. 1391 */ 1392 static void ataSuspendRedo(PATACONTROLLER pCtl) 1393 { 1394 PPDMDEVINS pDevIns = CONTROLLER_2_DEVINS(pCtl); 1395 PVMREQ pReq; 1396 int rc; 1397 1398 pCtl->fRedoIdle = true; 1399 rc = VMR3ReqCall(PDMDevHlpGetVM(pDevIns), VMREQDEST_ANY, &pReq, RT_INDEFINITE_WAIT, 1400 (PFNRT)PDMDevHlpVMSuspend, 1, pDevIns); 1401 AssertReleaseRC(rc); 1402 VMR3ReqFree(pReq); 1403 } 1404 1405 bool ataIsRedoSetWarning(ATADevState *s, int rc) 1406 { 1407 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s); 1408 Assert(!PDMCritSectIsOwner(&pCtl->lock)); 1409 if (rc == VERR_DISK_FULL) 1410 { 1411 ataWarningDiskFull(ATADEVSTATE_2_DEVINS(s)); 1412 ataSuspendRedo(pCtl); 1413 return true; 1414 } 1415 if (rc == VERR_FILE_TOO_BIG) 1416 { 1417 ataWarningFileTooBig(ATADEVSTATE_2_DEVINS(s)); 1418 ataSuspendRedo(pCtl); 1419 return true; 1420 } 1421 if (rc == VERR_BROKEN_PIPE || rc == VERR_NET_CONNECTION_REFUSED) 1422 { 1423 /* iSCSI connection abort (first error) or failure to reestablish 1424 * connection (second error). Pause VM. On resume we'll retry. */ 1425 ataWarningISCSI(ATADEVSTATE_2_DEVINS(s)); 1426 ataSuspendRedo(pCtl); 1427 return true; 1428 } 1429 return false; 1430 } 1431 1432 1433 static int ataReadSectors(ATADevState *s, uint64_t u64Sector, void *pvBuf, uint32_t cSectors, bool *fRedo) 1355 1434 { 1356 1435 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s); … … 1367 1446 STAM_REL_COUNTER_ADD(&s->StatBytesRead, cSectors * 512); 1368 1447 1448 if (RT_SUCCESS(rc)) 1449 *fRedo = false; 1450 else 1451 *fRedo = ataIsRedoSetWarning(s, rc); 1452 1369 1453 STAM_PROFILE_START(&pCtl->StatLockWait, a); 1370 1454 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS); … … 1374 1458 1375 1459 1376 static int ataWriteSectors(ATADevState *s, uint64_t u64Sector, const void *pvBuf, uint32_t cSectors )1460 static int ataWriteSectors(ATADevState *s, uint64_t u64Sector, const void *pvBuf, uint32_t cSectors, bool *fRedo) 1377 1461 { 1378 1462 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s); … … 1397 1481 STAM_REL_COUNTER_ADD(&s->StatBytesWritten, cSectors * 512); 1398 1482 1483 if (RT_SUCCESS(rc)) 1484 *fRedo = false; 1485 else 1486 *fRedo = ataIsRedoSetWarning(s, rc); 1487 1399 1488 STAM_PROFILE_START(&pCtl->StatLockWait, a); 1400 1489 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS); … … 1418 1507 1419 1508 1420 static void ataWarningDiskFull(PPDMDEVINS pDevIns)1421 {1422 int rc;1423 LogRel(("PIIX3 ATA: Host disk full\n"));1424 rc = VMSetRuntimeError(PDMDevHlpGetVM(pDevIns),1425 false, "DevATA_DISKFULL",1426 N_("Host system reported disk full. VM execution is suspended. You can resume after freeing some space"));1427 AssertRC(rc);1428 }1429 1430 1431 static void ataWarningFileTooBig(PPDMDEVINS pDevIns)1432 {1433 int rc;1434 LogRel(("PIIX3 ATA: File too big\n"));1435 rc = VMSetRuntimeError(PDMDevHlpGetVM(pDevIns),1436 false, "DevATA_FILETOOBIG",1437 N_("Host system reported that the file size limit of the host file system has been exceeded. VM execution is suspended. You need to move your virtual hard disk to a filesystem which allows bigger files"));1438 AssertRC(rc);1439 }1440 1441 1442 static void ataWarningISCSI(PPDMDEVINS pDevIns)1443 {1444 int rc;1445 LogRel(("PIIX3 ATA: iSCSI target unavailable\n"));1446 rc = VMSetRuntimeError(PDMDevHlpGetVM(pDevIns),1447 false, "DevATA_ISCSIDOWN",1448 N_("The iSCSI target has stopped responding. VM execution is suspended. You can resume when it is available again"));1449 AssertRC(rc);1450 }1451 1452 1453 1509 static bool ataReadSectorsSS(ATADevState *s) 1454 1510 { … … 1456 1512 uint32_t cSectors; 1457 1513 uint64_t iLBA; 1514 bool fRedo; 1458 1515 1459 1516 cSectors = s->cbElementaryTransfer / 512; … … 1461 1518 iLBA = ataGetSector(s); 1462 1519 Log(("%s: %d sectors at LBA %d\n", __FUNCTION__, cSectors, iLBA)); 1463 rc = ataReadSectors(s, iLBA, s->CTX_SUFF(pbIOBuffer), cSectors );1520 rc = ataReadSectors(s, iLBA, s->CTX_SUFF(pbIOBuffer), cSectors, &fRedo); 1464 1521 if (RT_SUCCESS(rc)) 1465 1522 { … … 1471 1528 else 1472 1529 { 1473 if (rc == VERR_DISK_FULL) 1474 { 1475 ataWarningDiskFull(ATADEVSTATE_2_DEVINS(s)); 1476 return true; 1477 } 1478 if (rc == VERR_FILE_TOO_BIG) 1479 { 1480 ataWarningFileTooBig(ATADEVSTATE_2_DEVINS(s)); 1481 return true; 1482 } 1483 if (rc == VERR_BROKEN_PIPE || rc == VERR_NET_CONNECTION_REFUSED) 1484 { 1485 /* iSCSI connection abort (first error) or failure to reestablish 1486 * connection (second error). Pause VM. On resume we'll retry. */ 1487 ataWarningISCSI(ATADEVSTATE_2_DEVINS(s)); 1488 return true; 1489 } 1530 if (fRedo) 1531 return fRedo; 1490 1532 if (s->cErrors++ < MAX_LOG_REL_ERRORS) 1491 1533 LogRel(("PIIX3 ATA: LUN#%d: disk read error (rc=%Rrc iSector=%#RX64 cSectors=%#RX32)\n", … … 1499 1541 ataCmdError(s, ID_ERR); 1500 1542 } 1501 /** @todo implement redo for iSCSI */1502 1543 return false; 1503 1544 } … … 1509 1550 uint32_t cSectors; 1510 1551 uint64_t iLBA; 1552 bool fRedo; 1511 1553 1512 1554 cSectors = s->cbElementaryTransfer / 512; … … 1514 1556 iLBA = ataGetSector(s); 1515 1557 Log(("%s: %d sectors at LBA %d\n", __FUNCTION__, cSectors, iLBA)); 1516 rc = ataWriteSectors(s, iLBA, s->CTX_SUFF(pbIOBuffer), cSectors );1558 rc = ataWriteSectors(s, iLBA, s->CTX_SUFF(pbIOBuffer), cSectors, &fRedo); 1517 1559 if (RT_SUCCESS(rc)) 1518 1560 { … … 1524 1566 else 1525 1567 { 1526 if (rc == VERR_DISK_FULL) 1527 { 1528 ataWarningDiskFull(ATADEVSTATE_2_DEVINS(s)); 1529 return true; 1530 } 1531 if (rc == VERR_FILE_TOO_BIG) 1532 { 1533 ataWarningFileTooBig(ATADEVSTATE_2_DEVINS(s)); 1534 return true; 1535 } 1536 if (rc == VERR_BROKEN_PIPE || rc == VERR_NET_CONNECTION_REFUSED) 1537 { 1538 /* iSCSI connection abort (first error) or failure to reestablish 1539 * connection (second error). Pause VM. On resume we'll retry. */ 1540 ataWarningISCSI(ATADEVSTATE_2_DEVINS(s)); 1541 return true; 1542 } 1568 if (fRedo) 1569 return fRedo; 1543 1570 if (s->cErrors++ < MAX_LOG_REL_ERRORS) 1544 1571 LogRel(("PIIX3 ATA: LUN#%d: disk write error (rc=%Rrc iSector=%#RX64 cSectors=%#RX32)\n", … … 1552 1579 ataCmdError(s, ID_ERR); 1553 1580 } 1554 /** @todo implement redo for iSCSI */1555 1581 return false; 1556 1582 } … … 4278 4304 4279 4305 4280 /**4281 * Suspend I/O operations on a controller. Also suspends EMT, because it's4282 * waiting for I/O to make progress. The next attempt to perform an I/O4283 * operation will be made when EMT is resumed up again (as the resume4284 * callback below restarts I/O).4285 *4286 * @param pCtl Controller for which to suspend I/O.4287 */4288 static void ataSuspendRedo(PATACONTROLLER pCtl)4289 {4290 PPDMDEVINS pDevIns = CONTROLLER_2_DEVINS(pCtl);4291 PVMREQ pReq;4292 int rc;4293 4294 pCtl->fRedoIdle = true;4295 rc = VMR3ReqCall(PDMDevHlpGetVM(pDevIns), VMREQDEST_ANY, &pReq, RT_INDEFINITE_WAIT,4296 (PFNRT)PDMDevHlpVMSuspend, 1, pDevIns);4297 AssertReleaseRC(rc);4298 VMR3ReqFree(pReq);4299 }4300 4301 4306 /** Asynch I/O thread for an interface. Once upon a time this was readable 4302 4307 * code with several loops and a different semaphore for each purpose. But … … 4453 4458 LogRel(("%s: Ctl#%d: redo entire operation\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl))); 4454 4459 ataAsyncIOPutRequest(pCtl, pReq); 4455 ataSuspendRedo(pCtl);4456 4460 break; 4457 4461 } … … 4558 4562 LogRel(("PIIX3 ATA: Ctl#%d: redo DMA operation\n", ATACONTROLLER_IDX(pCtl))); 4559 4563 ataAsyncIOPutRequest(pCtl, &ataDMARequest); 4560 ataSuspendRedo(pCtl);4561 4564 break; 4562 4565 }
Note:
See TracChangeset
for help on using the changeset viewer.