688 return; |
688 return; |
689 }//if (drvInfo.iType==EMediaRam) |
689 }//if (drvInfo.iType==EMediaRam) |
690 |
690 |
691 #endif |
691 #endif |
692 |
692 |
693 |
693 //-- find out number of free clusters on the volume |
694 const TUint32 freeClusters = FAT().NumberOfFreeClusters(bSyncOp); |
694 TUint32 freeClusters = FAT().NumberOfFreeClusters(EFalse); //-- this is a _current_ amount of free clusters, this operation is non-blocking |
|
695 |
|
696 if(bSyncOp) |
|
697 {//-- the "::VolumeL()" query is synchronous, see if we can make it semi-synchronous |
|
698 const TUint32 KSyncScanThresholdMB = FatConfig().FAT32_SyncScanThresholdMB(); |
|
699 |
|
700 if(!KSyncScanThresholdMB) |
|
701 {//-- the free clusters scan threshold isn't set, the query is fully synchronous. |
|
702 //-- this call will block until FAT scan thread finishes |
|
703 __PRINT1(_L("CFatMountCB::VolumeL() drv:%d #1"), DriveNumber()); |
|
704 freeClusters = FAT().NumberOfFreeClusters(ETrue); //-- this will be _true_ amount of free clusters |
|
705 } |
|
706 else |
|
707 {//-- request number of free clusters enough to satisfy the threshold value |
|
708 const TUint32 KClustersRequired = (TUint32)((TUint64)KSyncScanThresholdMB << 20) >> ClusterSizeLog2(); |
|
709 __PRINT2(_L("CFatMountCB::VolumeL() drv:%d req clusters:%d"), DriveNumber(), KClustersRequired); |
|
710 (void)FAT().RequestFreeClusters(KClustersRequired); |
|
711 freeClusters = FAT().NumberOfFreeClusters(EFalse); //-- _current_ amount of free clusters, this operation is non-blocking |
|
712 } |
|
713 |
|
714 } |
|
715 |
695 aVolume.iFree = (TInt64)freeClusters << ClusterSizeLog2(); |
716 aVolume.iFree = (TInt64)freeClusters << ClusterSizeLog2(); |
696 __PRINT1(_L("CFatMountCB::VolumeL() free clusters:%d"), freeClusters); |
717 __PRINT2(_L("CFatMountCB::VolumeL() drv:%d, free clusters:%d"), DriveNumber(), freeClusters); |
697 |
718 |
698 |
719 |
699 if(drvInfo.iType==EMediaRam) |
720 if(drvInfo.iType==EMediaRam) |
700 {//-- a special case. RAM drive size is variable and adjustable. It should be calculated from aVolume.iFree and CMountCB::iFree |
721 {//-- a special case. RAM drive size is variable and adjustable. It should be calculated from aVolume.iFree and CMountCB::iFree |
701 ASSERT(iRamDrive); |
722 ASSERT(iRamDrive); |
1637 |
1658 |
1638 const TInt clusterRelativePos=ClusterRelativePos(aPos.iPos); |
1659 const TInt clusterRelativePos=ClusterRelativePos(aPos.iPos); |
1639 const TInt maxClusters=((aLength+clusterRelativePos-1)>>ClusterSizeLog2())+1; |
1660 const TInt maxClusters=((aLength+clusterRelativePos-1)>>ClusterSizeLog2())+1; |
1640 const TInt clusterListLen=FAT().CountContiguousClustersL(aPos.iCluster,endCluster,maxClusters); |
1661 const TInt clusterListLen=FAT().CountContiguousClustersL(aPos.iCluster,endCluster,maxClusters); |
1641 const TInt writeLength=Min(aLength,(clusterListLen<<ClusterSizeLog2())-clusterRelativePos); |
1662 const TInt writeLength=Min(aLength,(clusterListLen<<ClusterSizeLog2())-clusterRelativePos); |
1642 TInt64 dataStart=FAT().DataPositionInBytes(aPos.iCluster)+clusterRelativePos; |
1663 TInt64 dataStart=FAT().DataPositionInBytesL(aPos.iCluster)+clusterRelativePos; |
1643 |
1664 |
1644 TRAPD(r, iRawDisk->WriteL(dataStart,writeLength,aSrc,aMessage,anOffset, aFlag)); |
1665 TRAPD(r, iRawDisk->WriteL(dataStart,writeLength,aSrc,aMessage,anOffset, aFlag)); |
1645 |
1666 |
1646 if(r == KErrNone) // Write succeded |
1667 if(r == KErrNone) // Write succeded |
1647 { |
1668 { |
1668 cluster--; |
1689 cluster--; |
1669 |
1690 |
1670 if((aPos.iPos != 0) && (badcluster == aPos.iCluster) && (aLastcluster == 0) && (aPos.iCluster == cluster)) |
1691 if((aPos.iPos != 0) && (badcluster == aPos.iCluster) && (aLastcluster == 0) && (aPos.iCluster == cluster)) |
1671 { //Copy the contents already present in this cluster to new cluster allocated. |
1692 { //Copy the contents already present in this cluster to new cluster allocated. |
1672 const TInt sizeToRead = aPos.iPos - ((aPos.iPos >> ClusterSizeLog2()) << ClusterSizeLog2()); |
1693 const TInt sizeToRead = aPos.iPos - ((aPos.iPos >> ClusterSizeLog2()) << ClusterSizeLog2()); |
1673 dataStart = FAT().DataPositionInBytes(aPos.iCluster) + ClusterRelativePos((aPos.iPos - sizeToRead)); |
1694 dataStart = FAT().DataPositionInBytesL(aPos.iCluster) + ClusterRelativePos((aPos.iPos - sizeToRead)); |
1674 |
1695 |
1675 |
1696 |
1676 //-- Allocate the buffer required to copy the contents from bad cluster |
1697 //-- Allocate the buffer required to copy the contents from bad cluster |
1677 RBuf8 clustBuf; |
1698 RBuf8 clustBuf; |
1678 CleanupClosePushL(clustBuf); |
1699 CleanupClosePushL(clustBuf); |
1697 |
1718 |
1698 FOREVER |
1719 FOREVER |
1699 { |
1720 { |
1700 //Calculate and copy the contents to new cluster. |
1721 //Calculate and copy the contents to new cluster. |
1701 aPos.iCluster = goodcluster; |
1722 aPos.iCluster = goodcluster; |
1702 dataStart = FAT().DataPositionInBytes(aPos.iCluster) + ClusterRelativePos(aPos.iPos - sizeToRead); |
1723 dataStart = FAT().DataPositionInBytesL(aPos.iCluster) + ClusterRelativePos(aPos.iPos - sizeToRead); |
1703 |
1724 |
1704 r = LocalDrive()->Write(dataStart, clustBuf); |
1725 r = LocalDrive()->Write(dataStart, clustBuf); |
1705 if(r == KErrNone) |
1726 if(r == KErrNone) |
1706 { // Copied contents to new cluster so fix up the chain and mark the cluster as bad. |
1727 { // Copied contents to new cluster so fix up the chain and mark the cluster as bad. |
1707 FAT().WriteL(goodcluster, FAT().ReadL(badcluster)); |
1728 FAT().WriteL(goodcluster, FAT().ReadL(badcluster)); |
1805 |
1826 |
1806 const TInt clusterRelativePos=ClusterRelativePos(aPos.iPos); |
1827 const TInt clusterRelativePos=ClusterRelativePos(aPos.iPos); |
1807 const TInt maxClusters=((aLength+clusterRelativePos-1)>>ClusterSizeLog2())+1; |
1828 const TInt maxClusters=((aLength+clusterRelativePos-1)>>ClusterSizeLog2())+1; |
1808 const TInt clusterListLen=FAT().CountContiguousClustersL(aPos.iCluster,endCluster,maxClusters); |
1829 const TInt clusterListLen=FAT().CountContiguousClustersL(aPos.iCluster,endCluster,maxClusters); |
1809 const TInt readLength=Min(aLength,(clusterListLen<<ClusterSizeLog2())-clusterRelativePos); |
1830 const TInt readLength=Min(aLength,(clusterListLen<<ClusterSizeLog2())-clusterRelativePos); |
1810 const TInt64 dataStart=FAT().DataPositionInBytes(aPos.iCluster)+clusterRelativePos; |
1831 const TInt64 dataStart=FAT().DataPositionInBytesL(aPos.iCluster)+clusterRelativePos; |
1811 |
1832 |
1812 TRAPD(r, iRawDisk->ReadL(dataStart,readLength,aTrg,aMessage,anOffset, aFlag)); |
1833 TRAPD(r, iRawDisk->ReadL(dataStart,readLength,aTrg,aMessage,anOffset, aFlag)); |
1813 |
1834 |
1814 if(r == KErrNone) // Read succeded |
1835 if(r == KErrNone) // Read succeded |
1815 { |
1836 { |
3169 |
3190 |
3170 if(aCluster < KFatFirstSearchCluster || aCluster >= UsableClusters()+KFatFirstSearchCluster) |
3191 if(aCluster < KFatFirstSearchCluster || aCluster >= UsableClusters()+KFatFirstSearchCluster) |
3171 User::Leave(KErrCorrupt); |
3192 User::Leave(KErrCorrupt); |
3172 |
3193 |
3173 TBuf8<sizeof(TCheckedUid)> uidBuf; |
3194 TBuf8<sizeof(TCheckedUid)> uidBuf; |
3174 iRawDisk->ReadCachedL(FAT().DataPositionInBytes(aCluster),sizeof(TCheckedUid),uidBuf); |
3195 iRawDisk->ReadCachedL(FAT().DataPositionInBytesL(aCluster),sizeof(TCheckedUid),uidBuf); |
3175 __ASSERT_DEBUG(uidBuf.Length()==sizeof(TCheckedUid),Fault(EFatReadUidFailed)); |
3196 __ASSERT_DEBUG(uidBuf.Length()==sizeof(TCheckedUid),Fault(EFatReadUidFailed)); |
3176 TCheckedUid uid(uidBuf); |
3197 TCheckedUid uid(uidBuf); |
3177 anEntry.iType=uid.UidType(); |
3198 anEntry.iType=uid.UidType(); |
3178 } |
3199 } |
3179 |
3200 |
3245 if (pos<(clusterListLen<<ClusterSizeLog2())) |
3266 if (pos<(clusterListLen<<ClusterSizeLog2())) |
3246 { |
3267 { |
3247 // Read the remaining length or the entire cluster block whichever is smaller |
3268 // Read the remaining length or the entire cluster block whichever is smaller |
3248 TInt readLength = Min(aLength-readTotal,(clusterListLen<<ClusterSizeLog2())-pos); |
3269 TInt readLength = Min(aLength-readTotal,(clusterListLen<<ClusterSizeLog2())-pos); |
3249 __ASSERT_DEBUG(readLength>0,Fault(EReadFileSectionFailed)); |
3270 __ASSERT_DEBUG(readLength>0,Fault(EReadFileSectionFailed)); |
3250 TInt64 dataAddress=(FAT().DataPositionInBytes(cluster))+pos; |
3271 TInt64 dataAddress=(FAT().DataPositionInBytesL(cluster))+pos; |
3251 iRawDisk->ReadL(dataAddress,readLength,aTrg,aMessage,readTotal, 0); |
3272 iRawDisk->ReadL(dataAddress,readLength,aTrg,aMessage,readTotal, 0); |
3252 readTotal += readLength; |
3273 readTotal += readLength; |
3253 |
3274 |
3254 if (readTotal == aLength) |
3275 if (readTotal == aLength) |
3255 return; |
3276 return; |
3449 |
3470 |
3450 //__PRINT2(_L("CFatMountCB::MakeLinAddrL, cl:%d, pos:%d"), aPos.iCluster, aPos.iPos); |
3471 //__PRINT2(_L("CFatMountCB::MakeLinAddrL, cl:%d, pos:%d"), aPos.iCluster, aPos.iPos); |
3451 if (!IsRootDir(aPos)) |
3472 if (!IsRootDir(aPos)) |
3452 { |
3473 { |
3453 TInt relPos=ClusterRelativePos(aPos.iPos); |
3474 TInt relPos=ClusterRelativePos(aPos.iPos); |
3454 return FAT().DataPositionInBytes(aPos.iCluster)+relPos; |
3475 return FAT().DataPositionInBytesL(aPos.iCluster)+relPos; |
3455 } |
3476 } |
3456 if (aPos.iPos+StartOfRootDirInBytes()>=RootDirEnd()) |
3477 if (aPos.iPos+StartOfRootDirInBytes()>=RootDirEnd()) |
3457 User::Leave(KErrDirFull); // Past last root dir entry |
3478 User::Leave(KErrDirFull); // Past last root dir entry |
3458 return StartOfRootDirInBytes()+aPos.iPos; |
3479 return StartOfRootDirInBytes()+aPos.iPos; |
3459 } |
3480 } |
4098 r = LocalDrive()->Caps(caps); |
4119 r = LocalDrive()->Caps(caps); |
4099 if ( r != KErrNone ) |
4120 if ( r != KErrNone ) |
4100 User::LeaveIfError(r); |
4121 User::LeaveIfError(r); |
4101 if ( caps().iType&EMediaRam ) |
4122 if ( caps().iType&EMediaRam ) |
4102 { |
4123 { |
4103 realPosition = FAT().DataPositionInBytes( aPos.iCluster ); |
4124 realPosition = FAT().DataPositionInBytesL( aPos.iCluster ); |
4104 aPos.iCluster = I64LOW((realPosition - aInfo.iStartBlockAddress)>>ClusterSizeLog2()); |
4125 aPos.iCluster = I64LOW((realPosition - aInfo.iStartBlockAddress)>>ClusterSizeLog2()); |
4105 blockMapEntry.SetStartBlock( aPos.iCluster ); |
4126 blockMapEntry.SetStartBlock( aPos.iCluster ); |
4106 } |
4127 } |
4107 else |
4128 else |
4108 blockMapEntry.SetStartBlock( aPos.iCluster - 2); |
4129 blockMapEntry.SetStartBlock( aPos.iCluster - 2); |