userlibandfileserver/fileserver/sfat32/sl_mnt.cpp
branchRCL_3
changeset 42 a179b74831c9
parent 41 0ffb4e86fcc9
child 43 c1f20ce4abcf
equal deleted inserted replaced
41:0ffb4e86fcc9 42:a179b74831c9
  1608 //-----------------------------------------------------------------------------------------
  1608 //-----------------------------------------------------------------------------------------
  1609 
  1609 
  1610 /**
  1610 /**
  1611     Overwrite as many contiguous file clusters as possible.
  1611     Overwrite as many contiguous file clusters as possible.
  1612 */
  1612 */
  1613 void CFatMountCB::DoWriteToClusterListL(TEntryPos& aPos,TInt aLength,const TAny* aSrc,const RMessagePtr2& aMessage,TInt anOffset, TUint aLastcluster, TUint& aBadcluster, TUint& aGoodcluster)
  1613 void CFatMountCB::DoWriteToClusterListL(TEntryPos& aPos,TInt aLength,const TAny* aSrc,const RMessagePtr2& aMessage,TInt anOffset, TUint aLastcluster, TUint& aBadcluster, TUint& aGoodcluster, TUint aFlag)
  1614     {
  1614     {
  1615 
  1615 
  1616     __PRINT(_L("CFatMountCB::DoWriteToClusterListL"));
  1616     __PRINT(_L("CFatMountCB::DoWriteToClusterListL"));
  1617     __ASSERT_ALWAYS(aPos.Cluster()>=KFatFirstSearchCluster,User::Leave(KErrCorrupt));
  1617     __ASSERT_ALWAYS(aPos.Cluster()>=KFatFirstSearchCluster,User::Leave(KErrCorrupt));
  1618 
  1618 
  1620 
  1620 
  1621     const TInt clusterRelativePos=ClusterRelativePos(aPos.iPos);
  1621     const TInt clusterRelativePos=ClusterRelativePos(aPos.iPos);
  1622     const TInt maxClusters=((aLength+clusterRelativePos-1)>>ClusterSizeLog2())+1;
  1622     const TInt maxClusters=((aLength+clusterRelativePos-1)>>ClusterSizeLog2())+1;
  1623     const TInt clusterListLen=FAT().CountContiguousClustersL(aPos.iCluster,endCluster,maxClusters);
  1623     const TInt clusterListLen=FAT().CountContiguousClustersL(aPos.iCluster,endCluster,maxClusters);
  1624     const TInt writeLength=Min(aLength,(clusterListLen<<ClusterSizeLog2())-clusterRelativePos);
  1624     const TInt writeLength=Min(aLength,(clusterListLen<<ClusterSizeLog2())-clusterRelativePos);
  1625     TInt64 dataStart=FAT().DataPositionInBytes(aPos.iCluster)+clusterRelativePos;
  1625     TInt64 dataStart=FAT().DataPositionInBytesL(aPos.iCluster)+clusterRelativePos;
  1626 
  1626 
  1627     TRAPD(r, iRawDisk->WriteL(dataStart,writeLength,aSrc,aMessage,anOffset));
  1627     TRAPD(r, iRawDisk->WriteL(dataStart,writeLength,aSrc,aMessage,anOffset, aFlag));
  1628 
  1628 
  1629     if(r == KErrNone) // Write succeded
  1629     if(r == KErrNone) // Write succeded
  1630         {
  1630         {
  1631         aPos.iPos+=writeLength;
  1631         aPos.iPos+=writeLength;
  1632         aPos.iCluster=endCluster;
  1632         aPos.iCluster=endCluster;
  1651             cluster--;
  1651             cluster--;
  1652 
  1652 
  1653         if((aPos.iPos != 0) && (badcluster == aPos.iCluster) && (aLastcluster == 0) && (aPos.iCluster == cluster))
  1653         if((aPos.iPos != 0) && (badcluster == aPos.iCluster) && (aLastcluster == 0) && (aPos.iCluster == cluster))
  1654             { //Copy the contents already present in this cluster to new cluster allocated.
  1654             { //Copy the contents already present in this cluster to new cluster allocated.
  1655             const TInt sizeToRead = aPos.iPos - ((aPos.iPos >> ClusterSizeLog2()) << ClusterSizeLog2());
  1655             const TInt sizeToRead = aPos.iPos - ((aPos.iPos >> ClusterSizeLog2()) << ClusterSizeLog2());
  1656             dataStart = FAT().DataPositionInBytes(aPos.iCluster) + ClusterRelativePos((aPos.iPos - sizeToRead));
  1656             dataStart = FAT().DataPositionInBytesL(aPos.iCluster) + ClusterRelativePos((aPos.iPos - sizeToRead));
  1657 
  1657 
  1658 
  1658 
  1659             //-- Allocate the buffer required to copy the contents from bad cluster
  1659             //-- Allocate the buffer required to copy the contents from bad cluster
  1660             RBuf8 clustBuf;
  1660             RBuf8 clustBuf;
  1661             CleanupClosePushL(clustBuf);
  1661             CleanupClosePushL(clustBuf);
  1680 
  1680 
  1681             FOREVER
  1681             FOREVER
  1682                 {
  1682                 {
  1683                 //Calculate and copy the contents to new cluster.
  1683                 //Calculate and copy the contents to new cluster.
  1684                 aPos.iCluster = goodcluster;
  1684                 aPos.iCluster = goodcluster;
  1685                 dataStart = FAT().DataPositionInBytes(aPos.iCluster) + ClusterRelativePos(aPos.iPos - sizeToRead);
  1685                 dataStart = FAT().DataPositionInBytesL(aPos.iCluster) + ClusterRelativePos(aPos.iPos - sizeToRead);
  1686 
  1686 
  1687                 r = LocalDrive()->Write(dataStart, clustBuf);
  1687                 r = LocalDrive()->Write(dataStart, clustBuf);
  1688                 if(r == KErrNone)
  1688                 if(r == KErrNone)
  1689                     { // Copied contents to new cluster so fix up the chain and mark the cluster as bad.
  1689                     { // Copied contents to new cluster so fix up the chain and mark the cluster as bad.
  1690                     FAT().WriteL(goodcluster, FAT().ReadL(badcluster));
  1690                     FAT().WriteL(goodcluster, FAT().ReadL(badcluster));
  1737     User::Leave(KErrCorrupt);
  1737     User::Leave(KErrCorrupt);
  1738     }
  1738     }
  1739 
  1739 
  1740 //-----------------------------------------------------------------------------------------
  1740 //-----------------------------------------------------------------------------------------
  1741 
  1741 
  1742 void CFatMountCB::WriteToClusterListL(TEntryPos& aPos,TInt aLength,const TAny* aSrc,const RMessagePtr2& aMessage,TInt anOffset, TUint& aBadcluster, TUint& aGoodcluster)
  1742 void CFatMountCB::WriteToClusterListL(TEntryPos& aPos,TInt aLength,const TAny* aSrc,const RMessagePtr2& aMessage,TInt anOffset, TUint& aBadcluster, TUint& aGoodcluster, TUint aFlag)
  1743 //
  1743 //
  1744 // Overwrite cluster list.
  1744 // Overwrite cluster list.
  1745 //
  1745 //
  1746     {
  1746     {
  1747 
  1747 
  1759 
  1759 
  1760     TUint offset=0;
  1760     TUint offset=0;
  1761     TInt previouscluster=0;
  1761     TInt previouscluster=0;
  1762     FOREVER
  1762     FOREVER
  1763         {
  1763         {
  1764         DoWriteToClusterListL(aPos,length-offset,aSrc,aMessage,anOffset+offset, previouscluster, aBadcluster, aGoodcluster);
  1764         DoWriteToClusterListL(aPos,length-offset,aSrc,aMessage,anOffset+offset, previouscluster, aBadcluster, aGoodcluster, aFlag);
  1765         if (offset == (aPos.iPos-startPos))
  1765         if (offset == (aPos.iPos-startPos))
  1766             continue;
  1766             continue;
  1767         offset=aPos.iPos-startPos;
  1767         offset=aPos.iPos-startPos;
  1768         __ASSERT_ALWAYS(aPos.iPos>startPos,User::Leave(KErrCorrupt));
  1768         __ASSERT_ALWAYS(aPos.iPos>startPos,User::Leave(KErrCorrupt));
  1769         previouscluster=aPos.iCluster;
  1769         previouscluster=aPos.iCluster;
  1774         }
  1774         }
  1775     }
  1775     }
  1776 
  1776 
  1777 //-----------------------------------------------------------------------------------------
  1777 //-----------------------------------------------------------------------------------------
  1778 
  1778 
  1779 void CFatMountCB::DoReadFromClusterListL(TEntryPos& aPos,TInt aLength,const TAny* aTrg,const RMessagePtr2& aMessage,TInt anOffset) const
  1779 void CFatMountCB::DoReadFromClusterListL(TEntryPos& aPos,TInt aLength,const TAny* aTrg,const RMessagePtr2& aMessage,TInt anOffset, TUint aFlag) const
  1780 //
  1780 //
  1781 // Read from as many contiguous file clusters as possible
  1781 // Read from as many contiguous file clusters as possible
  1782 //
  1782 //
  1783     {
  1783     {
  1784 
  1784 
  1788 
  1788 
  1789     const TInt clusterRelativePos=ClusterRelativePos(aPos.iPos);
  1789     const TInt clusterRelativePos=ClusterRelativePos(aPos.iPos);
  1790     const TInt maxClusters=((aLength+clusterRelativePos-1)>>ClusterSizeLog2())+1;
  1790     const TInt maxClusters=((aLength+clusterRelativePos-1)>>ClusterSizeLog2())+1;
  1791     const TInt clusterListLen=FAT().CountContiguousClustersL(aPos.iCluster,endCluster,maxClusters);
  1791     const TInt clusterListLen=FAT().CountContiguousClustersL(aPos.iCluster,endCluster,maxClusters);
  1792     const TInt readLength=Min(aLength,(clusterListLen<<ClusterSizeLog2())-clusterRelativePos);
  1792     const TInt readLength=Min(aLength,(clusterListLen<<ClusterSizeLog2())-clusterRelativePos);
  1793     const TInt64 dataStart=FAT().DataPositionInBytes(aPos.iCluster)+clusterRelativePos;
  1793     const TInt64 dataStart=FAT().DataPositionInBytesL(aPos.iCluster)+clusterRelativePos;
  1794 
  1794 
  1795     TRAPD(r, iRawDisk->ReadL(dataStart,readLength,aTrg,aMessage,anOffset));
  1795     TRAPD(r, iRawDisk->ReadL(dataStart,readLength,aTrg,aMessage,anOffset, aFlag));
  1796 
  1796 
  1797     if(r == KErrNone) // Read succeded
  1797     if(r == KErrNone) // Read succeded
  1798         {
  1798         {
  1799         aPos.iPos+=readLength;
  1799         aPos.iPos+=readLength;
  1800         aPos.iCluster=endCluster;
  1800         aPos.iCluster=endCluster;
  1815     User::Leave(KErrCorrupt);
  1815     User::Leave(KErrCorrupt);
  1816     }
  1816     }
  1817 
  1817 
  1818 //-----------------------------------------------------------------------------------------
  1818 //-----------------------------------------------------------------------------------------
  1819 
  1819 
  1820 void CFatMountCB::ReadFromClusterListL(TEntryPos& aPos,TInt aLength,const TAny* aTrg,const RMessagePtr2& aMessage,TInt anOffset) const
  1820 void CFatMountCB::ReadFromClusterListL(TEntryPos& aPos,TInt aLength,const TAny* aTrg,const RMessagePtr2& aMessage,TInt anOffset, TUint aFlag) const
  1821 //
  1821 //
  1822 // Read from cluster list
  1822 // Read from cluster list
  1823 //
  1823 //
  1824     {
  1824     {
  1825 
  1825 
  1835         }
  1835         }
  1836 
  1836 
  1837     TInt offset=0;
  1837     TInt offset=0;
  1838     FOREVER
  1838     FOREVER
  1839         {
  1839         {
  1840         DoReadFromClusterListL(aPos,aLength-offset,aTrg,aMessage,anOffset+offset);
  1840         DoReadFromClusterListL(aPos,aLength-offset,aTrg,aMessage,anOffset+offset, aFlag);
  1841         offset=aPos.iPos-startPos;
  1841         offset=aPos.iPos-startPos;
  1842         if ((offset<aLength))
  1842         if ((offset<aLength))
  1843             {
  1843             {
  1844             __ASSERT_ALWAYS(FAT().GetNextClusterL(aPos.iCluster),User::Leave(KErrCorrupt));
  1844             __ASSERT_ALWAYS(FAT().GetNextClusterL(aPos.iCluster),User::Leave(KErrCorrupt));
  1845             }
  1845             }
  3152 
  3152 
  3153     if(aCluster < KFatFirstSearchCluster || aCluster >= UsableClusters()+KFatFirstSearchCluster)
  3153     if(aCluster < KFatFirstSearchCluster || aCluster >= UsableClusters()+KFatFirstSearchCluster)
  3154         User::Leave(KErrCorrupt);
  3154         User::Leave(KErrCorrupt);
  3155 
  3155 
  3156     TBuf8<sizeof(TCheckedUid)> uidBuf;
  3156     TBuf8<sizeof(TCheckedUid)> uidBuf;
  3157     iRawDisk->ReadCachedL(FAT().DataPositionInBytes(aCluster),sizeof(TCheckedUid),uidBuf);
  3157     iRawDisk->ReadCachedL(FAT().DataPositionInBytesL(aCluster),sizeof(TCheckedUid),uidBuf);
  3158     __ASSERT_DEBUG(uidBuf.Length()==sizeof(TCheckedUid),Fault(EFatReadUidFailed));
  3158     __ASSERT_DEBUG(uidBuf.Length()==sizeof(TCheckedUid),Fault(EFatReadUidFailed));
  3159     TCheckedUid uid(uidBuf);
  3159     TCheckedUid uid(uidBuf);
  3160     anEntry.iType=uid.UidType();
  3160     anEntry.iType=uid.UidType();
  3161     }
  3161     }
  3162 
  3162 
  3228         if (pos<(clusterListLen<<ClusterSizeLog2()))
  3228         if (pos<(clusterListLen<<ClusterSizeLog2()))
  3229             {
  3229             {
  3230 			//  Read the remaining length or the entire cluster block whichever is smaller
  3230 			//  Read the remaining length or the entire cluster block whichever is smaller
  3231 			TInt readLength = Min(aLength-readTotal,(clusterListLen<<ClusterSizeLog2())-pos);
  3231 			TInt readLength = Min(aLength-readTotal,(clusterListLen<<ClusterSizeLog2())-pos);
  3232 			__ASSERT_DEBUG(readLength>0,Fault(EReadFileSectionFailed));
  3232 			__ASSERT_DEBUG(readLength>0,Fault(EReadFileSectionFailed));
  3233 			TInt64 dataAddress=(FAT().DataPositionInBytes(cluster))+pos;
  3233 			TInt64 dataAddress=(FAT().DataPositionInBytesL(cluster))+pos;
  3234 			iRawDisk->ReadL(dataAddress,readLength,aTrg,aMessage,readTotal);
  3234 			iRawDisk->ReadL(dataAddress,readLength,aTrg,aMessage,readTotal, 0);
  3235 			readTotal += readLength;
  3235 			readTotal += readLength;
  3236 
  3236 
  3237 			if (readTotal == aLength)
  3237 			if (readTotal == aLength)
  3238 				return;
  3238 				return;
  3239 
  3239 
  3257 void CFatMountCB::RawReadL(TInt64 aPos,TInt aLength,const TAny* aTrg,TInt anOffset,const RMessagePtr2& aMessage) const
  3257 void CFatMountCB::RawReadL(TInt64 aPos,TInt aLength,const TAny* aTrg,TInt anOffset,const RMessagePtr2& aMessage) const
  3258 //
  3258 //
  3259 // Read aLength of data from disk directly to thread relative descriptor
  3259 // Read aLength of data from disk directly to thread relative descriptor
  3260 //
  3260 //
  3261     {
  3261     {
  3262     iRawDisk->ReadL(aPos,aLength,aTrg,aMessage,anOffset);
  3262     iRawDisk->ReadL(aPos,aLength,aTrg,aMessage,anOffset, 0);
  3263     }
  3263     }
  3264 
  3264 
  3265 //-----------------------------------------------------------------------------------------
  3265 //-----------------------------------------------------------------------------------------
  3266 
  3266 
  3267 void CFatMountCB::RawWriteL(TInt64 aPos,TInt aLength,const TAny* aSrc,TInt anOffset,const RMessagePtr2& aMessage)
  3267 void CFatMountCB::RawWriteL(TInt64 aPos,TInt aLength,const TAny* aSrc,TInt anOffset,const RMessagePtr2& aMessage)
  3272     CheckWritableL();
  3272     CheckWritableL();
  3273 
  3273 
  3274 	//-- check if we are trying to write to the FAT directly and wait until FAT scan thread finishes in this case.
  3274 	//-- check if we are trying to write to the FAT directly and wait until FAT scan thread finishes in this case.
  3275     FAT().RequestRawWriteAccess(aPos, aLength);
  3275     FAT().RequestRawWriteAccess(aPos, aLength);
  3276 
  3276 
  3277     iRawDisk->WriteL(aPos,aLength,aSrc,aMessage,anOffset);
  3277     iRawDisk->WriteL(aPos,aLength,aSrc,aMessage,anOffset, 0);
  3278     //-- Note: FAT directory cache will be invalidated in MountL()
  3278     //-- Note: FAT directory cache will be invalidated in MountL()
  3279     }
  3279     }
  3280 
  3280 
  3281 //-----------------------------------------------------------------------------------------
  3281 //-----------------------------------------------------------------------------------------
  3282 /**
  3282 /**
  3432 
  3432 
  3433     //__PRINT2(_L("CFatMountCB::MakeLinAddrL, cl:%d, pos:%d"), aPos.iCluster, aPos.iPos);
  3433     //__PRINT2(_L("CFatMountCB::MakeLinAddrL, cl:%d, pos:%d"), aPos.iCluster, aPos.iPos);
  3434     if (!IsRootDir(aPos))
  3434     if (!IsRootDir(aPos))
  3435         {
  3435         {
  3436         TInt relPos=ClusterRelativePos(aPos.iPos);
  3436         TInt relPos=ClusterRelativePos(aPos.iPos);
  3437         return FAT().DataPositionInBytes(aPos.iCluster)+relPos;
  3437         return FAT().DataPositionInBytesL(aPos.iCluster)+relPos;
  3438         }
  3438         }
  3439     if (aPos.iPos+StartOfRootDirInBytes()>=RootDirEnd())
  3439     if (aPos.iPos+StartOfRootDirInBytes()>=RootDirEnd())
  3440         User::Leave(KErrDirFull); // Past last root dir entry
  3440         User::Leave(KErrDirFull); // Past last root dir entry
  3441     return StartOfRootDirInBytes()+aPos.iPos;
  3441     return StartOfRootDirInBytes()+aPos.iPos;
  3442     }
  3442     }
  4068         r = LocalDrive()->Caps(caps);
  4068         r = LocalDrive()->Caps(caps);
  4069         if ( r != KErrNone )
  4069         if ( r != KErrNone )
  4070             User::LeaveIfError(r);
  4070             User::LeaveIfError(r);
  4071         if ( caps().iType&EMediaRam )
  4071         if ( caps().iType&EMediaRam )
  4072             {
  4072             {
  4073             realPosition = FAT().DataPositionInBytes( aPos.iCluster );
  4073             realPosition = FAT().DataPositionInBytesL( aPos.iCluster );
  4074             aPos.iCluster = I64LOW((realPosition - aInfo.iStartBlockAddress)>>ClusterSizeLog2());
  4074             aPos.iCluster = I64LOW((realPosition - aInfo.iStartBlockAddress)>>ClusterSizeLog2());
  4075             blockMapEntry.SetStartBlock( aPos.iCluster );
  4075             blockMapEntry.SetStartBlock( aPos.iCluster );
  4076             }
  4076             }
  4077         else
  4077         else
  4078             blockMapEntry.SetStartBlock( aPos.iCluster - 2);
  4078             blockMapEntry.SetStartBlock( aPos.iCluster - 2);