| 摘要该文以SCOUNIX3.2.4.1版本为例,分析其文件卷结构和磁盘块管理方式,并在此基础上讲述了误删文件恢复的方法。 我们知道,UNIX操作系统是以文件卷作为其文件系统的存储格式的。对于UNIX用户尤其是系统管理员而言,要想更好地掌握UNIX操作系统,熟悉文件卷的结构是很有必要的。由于SCOUNIX在全球的微机UNIX操作系统市场中所占份额最大,在我国更是处于垄断地位,而它的文件卷结构和磁盘块管理方式都和其它UNIXSYSTEMV不完全一样,介绍这方面信息的资料也很少。本文就以SCOUNIX3.2.4.1版本为例,彻底分析它的文件卷结构和磁盘块管理方式,并在此基础上,讲述一个数据恢复应用--恢复误删的文件。
一、文件卷的结构 文件卷是由大小相同的磁盘块序列组成的。在文件卷偏移量512字节处,有一个长度为512字节的超级块,其后是若干i节点块、位图索引块、位图块、数据块等,如图1所示。 图1 其中,位图索引块和位图块是SCOUNIX专有的,它们含有关于磁盘块管理的重要数据,一般情况下,位图块不止一个,它们的数量和块号是由位图索引块中的数据决定的。4.1版本中,磁盘块的大小是1024字节,因此引导块和超级块合占0号磁盘块。若块尺寸为512字节,则0号块是引导块,1号块是超级块。其中超级块含有文件卷的许多重要信息,如文件卷的大小、位图索引块的位置等。其数据结构放在文件中,具体结构如下: structfilsys { ushorts-isize; daddr-ts-fsize; shorts-nfree; daddr-tsfree[NICFREE]; … }; 其中:s-nfree、sfree[NICFREE]是SCOUNIX涉及磁盘块管理的两项重要数据,在其它UNIXSYSTEMV中也有这两项数据,但二者的含义不同。s-nfree是SCOUNIX的文件卷标志,恒为-1;sfree[NICFREE]是位图索引块地址表,表中的数据是位图索引块的块号,对于容量小于2GB的文件卷,只有sfree[0]含有数据。 我们来看一看子文件卷/dev/user的超级块内容: #hd-abx-s0x200-n0x200/dev/user 02001d060000a0860100ffff00001e060000 021000000000000000000000000000000000 * 02d000000000000000008d008c008b008a00 02e089008800870086008500840083008200 02f0810080007f007e007d007c00***007a00 030079007800770076007500740073007200 0310710070006f006e006d006c006b006a00 032069006800670066006500640063006200 0330610060005f005e005d005c005b005a00 034059005800570056005500540053005200 0350510050004f004e004d004c004b004a00 036049004800470046004500440043004200 0370410040003f003e003d003c003b003a00 038039003800370036003500340033003200 0390310030002f002e002c0010001d000000 03a00000000074650e310100900100000000 03b0747f0100866100000000000000000000 03c00000000010000000010000001d060000 03d01d06000000e014f10000000000000000 03e000000000000000000000000000000000 03f000000000c437184b217e18fd02000000 0400 从上可见,文件卷/dev/user只有一个位图索引块,其块号是0x61e它在文件卷中的偏移量是0x61e*0x400=0x187400字节。位图索引块的数据结构是长整型数组,数组中的数据是它所管理的位图块的块号。 下面是位图索引块0x61e的数据。 #hdalx-s0x187800-n0x400/dev/user 1878000000061d0000261d0000461d0000661d 1878100000861d0000a61d0000c61d0000e61d 1878200001061d0001261d0001461d0001661d 1878300001861d000000000000000000000000 18784000000000000000000000000000000000 * 187c00 由此可见,该位图索引块管理的位图块有0x61d,0x261d,……,0x1861d。位图块的数据结构可以看作是一个长度为1024字节的二进制数。该数中的每一位都是反映某个磁盘块使用情况的标志位。若该位为1,则表明该磁盘块未被使用,是空闲块;若该位为0,则表明该磁盘块已被使用。该标志位所代表的磁盘块的块号等于位图块号加上标志位在二进制数中的偏移量。下面是位图块0x61d的数据。 #hd-abx-s0x187400-n0x400/dev/user 187400001c00000000200080ff0000079cffff 187410f8ff80fffffffffffffffffffffffeff 1874200000ffff00000000000000000000ffff 187430ffffbfff000000000000f8ffffffffff 187440ffffffffffffffffffffffffffffffff * 187800
二、误删文件的恢复 在UNIX系统下,常常发生误删文件的情况,造成意外损失。其实,只要在文件恢复之前不向系统申请分配磁盘块和写数据,误删的文件是完全可以恢复的。因为删除一个文件,只是释放了该文件所占用的i节点和磁盘块资源,而记录文件数据的磁盘块的内容还未被清除。只要找到这些磁盘块,重建文件的i节点,便可恢复误删的文件了。
1.SCOUNIX分配磁盘块算法 由于一个磁盘块的大小为1024字节,所以一个位图块可以管理0x400*8=0x2000个磁盘块。那么,下一个位图块的块号就是0x61d 0x2000=0x261d。这与位图索引块中的数据是相符的。那么,位图块0x61d管理着块号为0x61d-0x261c的磁盘块。由以上数据可见,在这个位图块中,第一个被使用的磁盘块块号是0x61d,即位图块本身。第一个空闲块块号由0x187401处字节0x1c的第2位指示,是0x627。由于该位图块是文件卷中的第一个位图块,所以0x627号磁盘块也是文件卷中的第一个空闲块。当我们向系统申请磁盘块时,系统通过超级块、位图索引块、位图块来寻找那些标志位为1的块,然后将相应的标置位置0。当释放一个磁盘块时,系统就将相应的标志位置1。现在,我们就可以判断出文件卷中的每一个磁盘块是否被使用了。但是仅赁这些还不能完全恢复误删的文件,我们还得了解SCOUNIX分配磁盘块的算法。为了使一个文件所占用的磁盘块相对集中,SCOUNIX是按照特定的算法来选择空闲块分配给文件的。假设某文件所占用的最后一个磁盘块的块号为m,现在要再分配一磁盘块给该文件,若该文件是新文件则m=0。分配算法的流程图如图2。 图2 现在我们在文件卷/dev/user下创建一个新文件1.tmp,根据以上磁盘块分配算法,可以推测它将占据磁盘块0x627,那么0x187401处的字节的第2位将置0,变为0x18。 #cat>1.tmp 1234567^c #hd-abx-s0x187400-n0x400/dev/user 187400001800000000200080ff0000079cffff 187410f8ff80fffffffffffffffffffffffeff 1874200000ffff00000000000000000000ffff 187430ffffbfff000000000000f8ffffffffff 187440ffffffffffffffffffffffffffffffff * 187800 磁盘块0x627的内容如下: #hd-s0x189c00-n0x400/dev/user 189c00313233343536371a00000000000000001 234567…… 189c1000000000000000000000000000000000 …………… * 18a000 我们再把1.tmp删除,释放磁盘块0x62f,则0x187401处字节又成为0x1c。 #rm1.tmp #hd-abx-s0x187400-n0x400/dev/user 187400001c00000000200080ff0000079cffff 187410f8ff80fffffffffffffffffffffffeff 1874200000ffff00000000000000000000ffff 187430ffffbfff000000000000f8ffffffffff 187440ffffffffffffffffffffffffffffffff * 187800 磁盘块0x627的内容没有丢失: #hd-s0x189c00-n0x400/dev/user 189c00313233343536371a0000000000000000 1234567…… 189c1000000000000000000000000000000000 …………… * 18a000 由于系统每次分配磁盘块给文件时,都遵循这一算法,所以当文件被删除后,我们同样可以按照这一算法推算出原本属于该文件的磁盘块号,这样我们就能完全恢复误删的文件了。
2.误删文件的恢复 根据以上SCOUNIX文件卷结构和磁盘块管理的特点,笔者编制了一恢复误删文件的程序并投入使用,挽救了许多数据。限于篇幅,这里只给出软件的构思和磁盘块分配算法函数getNextFreeBlock(longBN)的源代码。软件构思是这样的,首先在被误删文件的文件卷下,创建一新文件,不向该文件写任何数据即关闭它,然后调用系统函数stat(char*path,structstat*buf)得到该文件的i节点,再根据磁盘块分配算法在文件卷上寻找将分配的空闲块,将块号填入i节点的磁盘块地址表并把相应位图块中的标志位置0;由于SCOUNIX把已分配磁盘块中未被使用的字节全部署0,所以我们只要找到一个尾部字节全部为0的磁盘块,就可以认为它是文件的最后一个磁盘块了,由这些磁盘块的数量和最后一个磁盘块中有效字节的长度,可以算出文件的字节长度,将此长度值也填入i节点,再把该i节点写回文件卷即可。i节点的数据结构在文件中,如下: structdinode { ushortdimode; shortdinlink; ushortdiuid; ushortdigid; off-tdisize; chardiaddr[40];/*磁盘块地址表*/ . . . }; 对于大文件的一次间址块、二次间址块和三次间址块的块号,只要稍做处理即可找到,这里不再赘述,留给读者思考。 函数getNextFreeBlock(longBN)的返回值是文件卷中下一个将要分配的空闲块的块号,失败时返回-1,表明已无空闲块可分配。输入参数是起始块号,若是分配给文件的第一块,则BN为0。源代码如下,其中BBIT存放的是文件卷位图索引块的数据。函数readABlock(longBN,void*buf)的功能是将文件卷的BN号磁盘块的内容读入缓冲区buf。 externlongBBIT[0x100]; longgetNextFreeBlock(longBN) { longlg; ushortuBuf[0x200]; inti,k,m,n; if(BN>superBlock,s-fsize) return-1; sync(); for(k=BN{ readABlock(BBIT[k],uBuf); for(m=(BBIT[k]{ n=(BBIT[k] m*0x10)>BN?0:(BN-BBIT[k]-m*0x10 1); while(n<0x10
| 上网速度更快更爽、更安全下载使用Firefox火狐浏览器
|
|