📄 extfiltr.c
字号:
#include "flcustom.h"#ifdef TFFS_USE_EXT_FILTER#include "tffsdrv.h"#include <linux/slab.h> /* kmalloc() */#include <linux/fs.h>#include <linux/ext2_fs.h>#include "flsystem.h"#include "blockdev.h"#include "tffs2lnx.h"short fl_extfilter=FL_EXTFILTER_DEF;# ifdef MODULEMODULE_PARM(fl_extfilter,"h");MODULE_PARM_DESC(fl_extfilter,"Disable/enable EXT filter [0-1].");# endiftypedef struct{ BOOL fExt; unsigned long dwFirstSector; unsigned long dwSectorsPerPart; unsigned char bSectorsPerBlock; unsigned long dwSectorsPerGroup; unsigned long dwBlocksInBitmap; unsigned long dwBlocksInLastBitmap; unsigned char bSectorsPerBitmap; unsigned char bSectorsPerLastBitmap; unsigned short wGroups; unsigned char bGroupDescSectors; unsigned char bFirstUsableBlock; unsigned long*pBitmapSectors;}PartInfo;static unsigned char pTmpBuff[512];static PartInfo*pParts=NULL;static TheDiskInfo*pTheDiskInfo;#define ReadSector(part,sector) TffsRead( pTheDiskInfo->pDevices+(part>>DEV2PART_SHIFT),pTmpBuff,pParts[part].dwFirstSector+sector,1 )#define IsExt(pSuperBlock) (((pSuperBlock)->s_magic==0xef53) && ((pSuperBlock)->s_creator_os==0) && ((pSuperBlock)->s_rev_level==0 || (pSuperBlock)->s_rev_level==1))#define IsOldSuperBlock(pSuperBlock,pPart) ( (2<<((pSuperBlock)->s_log_block_size))==(pPart)->bSectorsPerBlock && (pPart)->dwSectorsPerGroup==(pSuperBlock)->s_blocks_per_group*(pPart)->bSectorsPerBlock )void ExtFilterInit(TheDiskInfo*diskInfo){ if(fl_extfilter && pParts==NULL) { pParts=kmalloc((diskInfo->noOfDevices<<DEV2PART_SHIFT)*sizeof(PartInfo),GFP_KERNEL); if(pParts) { memset(pParts,0,(diskInfo->noOfDevices<<DEV2PART_SHIFT)*sizeof(PartInfo)); pTheDiskInfo=diskInfo; } }}void ExtFilterRelease(void){ if(pParts) kfree(pParts);}BOOL SuperBlock2Part(struct ext2_super_block*pSuperBlock,PartInfo*pPart){ unsigned long dw; PrintkDebug("SuperBlock2Part: part 0x%x super block",pPart-pParts); /* fill partition info */ pPart->fExt=TRUE; pPart->bSectorsPerBlock=2<<pSuperBlock->s_log_block_size; pPart->dwSectorsPerGroup=pSuperBlock->s_blocks_per_group*pPart->bSectorsPerBlock; pPart->wGroups=(pSuperBlock->s_blocks_count-pSuperBlock->s_first_data_block)/pSuperBlock->s_blocks_per_group; if(pPart->wGroups*pSuperBlock->s_blocks_per_group < pSuperBlock->s_blocks_count-pSuperBlock->s_first_data_block) pPart->wGroups++; pPart->bGroupDescSectors=pPart->wGroups>>4; if(((pPart->wGroups>>4)<<4)!=pPart->wGroups) pPart->bGroupDescSectors++; pPart->bSectorsPerBitmap=pSuperBlock->s_blocks_per_group>>12; if( ((pSuperBlock->s_blocks_per_group>>12)<<12) != pSuperBlock->s_blocks_per_group) pPart->bSectorsPerBitmap++; dw=(pSuperBlock->s_blocks_count-pSuperBlock->s_first_data_block-(pPart->wGroups-1)*pPart->dwSectorsPerGroup); pPart->bSectorsPerLastBitmap=dw>>12; if(((dw>>12)<<12)!=dw) pPart->bSectorsPerLastBitmap++; pPart->dwBlocksInBitmap=pSuperBlock->s_blocks_per_group; pPart->dwBlocksInLastBitmap=dw; pPart->bFirstUsableBlock=pSuperBlock->s_first_data_block; /* fill groups info */ pPart->pBitmapSectors=kmalloc(sizeof(unsigned long)*pPart->wGroups,GFP_KERNEL); if(pPart->pBitmapSectors==NULL) pPart->fExt=FALSE; return pPart->fExt;}void GroupDesc2Part(struct ext2_group_desc*pGroupDesc,PartInfo*pPart,unsigned short wShift){ unsigned char b; PrintkDebug("GroupDesc2Part"); for(b=0;b<16 && b+wShift<pPart->wGroups;b++) { pPart->pBitmapSectors[b+wShift]=pGroupDesc[b].bg_block_bitmap*pPart->bSectorsPerBlock;/* PrintkDebug("GroupDesc2Part bitmap %u found in block 0x%lx sector 0x%lx",b+wShift,pGroupDesc[b].bg_block_bitmap,pPart->pBitmapSectors[b+wShift]); */ } PrintkDebug("GroupDesc2Part end");}void ExtFilterAddPartition(unsigned short wPart,unsigned long dwStartSector,unsigned long dwSectors){ PrintkDebug("ExtFilterAddPartition %u %lu %lu",wPart,dwStartSector,dwSectors); if(pParts && dwSectors>4 && fl_extfilter) { PartInfo*pPart=pParts+wPart; if(pPart->pBitmapSectors==NULL) { struct ext2_super_block*pSuperBlock=(struct ext2_super_block*)pTmpBuff; pPart->dwSectorsPerPart=dwSectors; pPart->dwFirstSector=dwStartSector; if(ReadSector(wPart,2)) { if(IsExt(pSuperBlock)) { PrintkDebug("ExtFilterAddPartition: part 0x%x is EXT",wPart); if(SuperBlock2Part(pSuperBlock,pPart)) { unsigned short wSector; /* I want to believe that the sizeof(ext2_group_desc) is always 32 */ for(wSector=0;wSector<pPart->bGroupDescSectors;wSector++) { if(ReadSector(wPart,4+wSector)) { GroupDesc2Part((struct ext2_group_desc*)pTmpBuff,pPart,wSector<<4); } else { pPart->fExt=0; kfree(pPart->pBitmapSectors); } } } } } } }}void ExtFilterRemovePartition(unsigned short wPart){ if(pParts) { PartInfo*pPart=pParts+wPart; if(pPart->pBitmapSectors!=NULL) { PrintkDebug("ExtFilterRemovePartition: part 0x%x",wPart); kfree(pPart->pBitmapSectors); } pPart->fExt=FALSE; }}void ExtFilter(unsigned short wPart,unsigned char*pBuff,unsigned long dwSector,unsigned long dwSectors){ if(pParts&&fl_extfilter) { PartInfo*pPart=pParts+wPart; unsigned long dwBBLastSector,dwSec; unsigned short wGroup; unsigned char bSectorsPerBitmap;/* PrintkDebug("ExtFilter: part 0x%x sector 0x%lx sectors 0x%lx",wPart,dwSector,dwSectors); */ if(dwSector<=2) /* superblock written */ { struct ext2_super_block*pSuperBlock; PrintkDebug("ExtFilter: part 0x%x super block",wPart); if(dwSector+dwSectors<=2) { PrintkDebug("ExtFilter: part 0x%x super block < 1024 return",wPart); return; /* write before super block */ } /* shift to super block */ pSuperBlock=(struct ext2_super_block*)(pBuff+((2-dwSector)<<9)); if(pPart->fExt) { if(!IsExt(pSuperBlock)) { PrintkDebug("ExtFilter: part 0x%x super block: sb removed",wPart); ExtFilterRemovePartition(wPart); return; } if(!IsOldSuperBlock(pSuperBlock,pPart)) { PrintkDebug("ExtFilter: part 0x%x super block: sb changed",wPart); ExtFilterRemovePartition(wPart); SuperBlock2Part(pSuperBlock,pPart); } } else { if(IsExt(pSuperBlock)) { PrintkDebug("ExtFilter: part 0x%x super block: sb found",wPart); SuperBlock2Part(pSuperBlock,pPart); } else return; } if(dwSector+dwSectors<=4) return; else { dwSector=4; dwSectors-=(4-dwSector); pBuff+=(4-dwSector)<<9; } } if(!pPart->fExt) { PrintkDebug("ExtFilter: part 0x%x not EXT, return",wPart); return; } if(dwSector>=4 && dwSector<4+pPart->bGroupDescSectors) /* group description written */ { unsigned short w;/* PrintkDebug("ExtFilter: part 0x%x group desc",wPart); */ for(w=dwSector;w<4+pPart->bGroupDescSectors && w<dwSector+dwSectors;w++) GroupDesc2Part((struct ext2_group_desc*)(pBuff+((w-dwSector)<<9)),pPart,(w-4)<<4); if(dwSector+dwSectors>=4+pPart->bGroupDescSectors) { pBuff+=(pPart->bGroupDescSectors)<<9; dwSectors-=pPart->bGroupDescSectors; dwSector+=pPart->bGroupDescSectors; } else return; } /* let's catch assess to block bitmap */ /* What's block group number? */ /* I want to believe that writing doesn't pass block group */ wGroup=(dwSector-pPart->bFirstUsableBlock*pPart->bSectorsPerBlock)/pPart->dwSectorsPerGroup; /* What's block bitmap length? */ bSectorsPerBitmap=(wGroup==pPart->wGroups-1)?pPart->bSectorsPerLastBitmap:pPart->bSectorsPerBitmap; /* Is block bitmap written? */ if(dwSector+dwSectors<=pPart->pBitmapSectors[wGroup] || pPart->pBitmapSectors[wGroup]+bSectorsPerBitmap<=dwSector) {/* PrintkDebug("ExtFilter: part 0x%x data: not bitmap, return",wPart); */ /* It is not - exit */ return; } /* yes, we are in block bitmap */ PrintkDebug("ExtFilter");/* PrintkDebug("ExtFilter: part 0x%x data: block bitmap %u written",wPart,wGroup); */ /* calculate first sector should be written to BB */ dwSec=(pPart->pBitmapSectors[wGroup]<dwSector)?dwSector:pPart->pBitmapSectors[wGroup]; /* calculate number of sectors should be written to BB */ dwBBLastSector=pPart->pBitmapSectors[wGroup]+bSectorsPerBitmap; if(dwBBLastSector>dwSector+dwSectors) dwBBLastSector=dwSector+dwSectors; /* process changed BB sectors */ for(;dwSec<dwBBLastSector;dwSec++) { unsigned short wValidBlocks,wBlock; unsigned char*pCurBuff; if(ReadSector(wPart,dwSec)) { pCurBuff=(unsigned char*)(((unsigned long)pBuff)+((dwSec-dwSector)<<9)); if(memcmp(pCurBuff,pTmpBuff,512)) { IOreq ioreq; char readTmp[512]; ioreq.irHandle=(pTheDiskInfo->pDevices+(wPart>>DEV2PART_SHIFT))->handle; ioreq.irData=readTmp; wValidBlocks=((wGroup==pPart->wGroups-1)?pPart->dwBlocksInLastBitmap:pPart->dwBlocksInBitmap)-((dwSec-pPart->pBitmapSectors[wGroup])<<12); wValidBlocks=(wValidBlocks>4096)?4096:wValidBlocks; /* no more then 1 sector of blocks */ for(wBlock=0;wBlock<wValidBlocks;wBlock+=32) { unsigned long o=((unsigned long*)pTmpBuff)[wBlock>>5],n=((unsigned long*)pCurBuff)[wBlock>>5]; if(o!=n) { unsigned char b; /* PrintkDebug("ExtFilter: %u -> %u",o,n); */ for(b=0;b<32 && wBlock+b<wValidBlocks;b++) { if( (o&(1L<<b)) > (n&(1L<<b)) ) { /* remove block */ ioreq.irLength=(b+wBlock+pPart->bFirstUsableBlock+wGroup*pPart->dwBlocksInBitmap)*pPart->bSectorsPerBlock+pPart->dwFirstSector; ioreq.irSectorCount=1; if(flAbsRead(&ioreq)!=flOK) { PrintkDebug("ExtFilter:flAbsRead fails"); fl_extfilter=0; return; } /* PrintkDebug("ExtFilter: remove block 0x%lx part 0x%x sector 0x%lx (%lu)", (unsigned long)(b+wBlock+pPart->bFirstUsableBlock),wPart,(unsigned long)ioreq.irLength,(unsigned long)ioreq.irSectorCount); */ ioreq.irSectorCount=pPart->bSectorsPerBlock; if(flAbsDelete(&ioreq)!=flOK) { PrintkDebug("ExtFilter:flAbsDelete fails: block 0x%lx part 0x%x sector 0x%lx (%lu)", (unsigned long)(b+wBlock+pPart->bFirstUsableBlock),wPart,(unsigned long)ioreq.irLength,(unsigned long)ioreq.irSectorCount); fl_extfilter=0; return; } } } } } } } else { fl_extfilter=0; } } }}#endif /* TFFS_USE_EXT_FILTER */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -