File System

706__·2021년 2월 16일
0

Operating System

목록 보기
1/2
post-thumbnail

Homework

1. Make a Virtual Floopy disk

$ dd bs=1024 count=1440 if=/dev/zero of=myfd

myfd 이름의 1.44MB 크기의 가상 플로피 디스크를 생성

dd → Disk에 Data를 쓰는 명령어

bs → Block Size

  • bs = 1024 -> 1 Block이 1024 Byte
  • Block은 File System Block이 아닌 dd 명령의 데이터 전송 단위

count → 기록할 Block 수

  • count = 1440 → 1440 Block 쓰기
  • 1440 * 1024 = 1.44MB 의미

if → 데이터를 읽을 입력 파일

/dev/zero → 읽을 때 0을 주는 특수 file

of → 출력 파일


2. Format

$ mkfs -t ext2 myfd

myfd를 ext2 File System으로 Format


3. Mount

$ mkdir temp
$ mount -o loop myfd temp

temp 임시 Directory에 myfd를 mount 한다. 
myfd는 실제 Disk가 아닌 Disk Image가 들어 있는 파일이므로 **-o loop** 옵션을 사용해야 한다

이 명령어는 myfd Disk를 /temp Directory에 연결하며, /temp를 통해 "myfd" disk에 access할 수 있다


4. Make some files

$ cd temp
$ echo korea > f1

이 명령어를 통해 temp Directory 안에 f1 파일을 만들 수 있다


5. Read

$ cd ..
$ umount temp
$ xxd -g1 myfd > x

umount 명령어를 통해 myfd Disk에서 변경 사항을 읽을 수 있다

"g1" 옵션은 myfd의 각 Byte를 분리하여 읽을 수 있게 한다

$ vi x 
$ :1

vi 를 통해 파일을 읽을 때, 첫 줄부터 시작하고 싶다면 :1 을 입력하면 된다


6. Read Superblock

Superblock은 Offset 1024 (400h) 에서 시작한다.

  • Superblock을 찾아서 현재 Disk의 총 inode의 수, 총 Block 수, magic 번호, Block Size, first data block을 읽는다.
  • 모든 Multi-byte number는 little endian으로 저장.
  • 실제 값 계산 위해서 Byte 순서를 거꾸로 해야 한다.
$ typedef struct
  { 
	u32 m_inodes_count;  // 0-3
	u32 m_blocks_count;  // 4-7
	u32 m_first_data_block;  // 14-17 
		                       // block location of superblock.
	u32 m_log_block_size;    // 18-1B. block size=1024*2^(m_log⁡_block_size))
	u16 m_magic;  // 38-39
	} SuperBlock;

m_inodes_count

  • 0x0 ~ 0x3
  • 0x000000b8
  • 10진수로 계산 → 184
  • 이 Disk에 총 184개의 Inode가 존재함

m_blocks_count

  • 0x4 ~ 0x7
  • 0x000005a0
  • 10진수로 계산 → 1,440
  • 이 시스템을 구성하는 Block의 수가 1,440개
  • count = 1440 옵션과 동일

m_magic

  • 0x38 ~ 0x39
  • 0xef53
  • File system EXT2

10242mlogblocksize1024 * 2 ^ {mlogblocksize}

  • 0x00000000
  • 10진수로 계산 → 0
  • 즉, 1024201024 * 2^0이므로 1024
  • 한 Block의 Size는 1024 Byte
  • bs = 1024 옵션과 동일

m_first_data_block

  • 0x14 ~ 0x17
  • 0x00000001
  • 10진수로 계산 → 1
  • 한 Block이 1024 Byte이므로 1024 * 1 = 1024 = 0x400이 Superblock의 위치

7. Read the Group Descriptor

  • SuperBlock 다음 Block이 Group Descriptor
  • 즉, Group Descriptor는 0x800에 위치

1 Block당 0x400이므로 첫번째 Block이 0x400이면 두번째 Block은 0x400 * 2 = 0x800

  • Superblock이 0 Block이면 Group Descriptor는 1 Block부터 시작
  • Block X의 Address → X * Block_Size
$ typedef struct
  { 
	u32 m_block_bitmap;  // block location of DBM
	u32 m_inode_bitmap;  // block location of IBM
	u32 m_inode_table;   // block location of inode table
	} GroupDescriptor;

u32 -> 4 Byte

DBM

  • m_block_bitmap
  • 0x00 ~ 0x03
  • 0x00000008
  • 10진수로 계산 → 8
  • Data Block Bitmap이 위치한 Block

IBM

  • m_inode_bitmap
  • 0x04 ~ 0x07
  • 0x00000009
  • 10진수로 계산 → 9
  • Inode Bitmap이 위치한 Block

Inode Table

  • m_inode_table
  • 0x08 ~ 0x0B
  • 0x0000000a
  • 10진수로 계산 → 10
  • Inode Table이 위치한 Block

8. Read the DBM, IBM

  • 사용 중인 Inode 번호와 Block 번호를 찾는다
  • Superblock, GroupDescriptor, IBM, DBM, Inode Table 등 모든 Meta-Block 위치를 보여주는 myfd Disk의 Layout 그린다

DBM

  • 8번째 Block에 위치하므로 0x400 * 8 = 0x2000

    DBM은 현재 어떤 Block이 사용 중인지 0 / 1로 나타냄

  • FFFF FFFF FF7F → BIN에서 11111111 11111111 11111111 11111111 11111111 01111111
  • 숫자는 오른쪽부터 읽으므로 48번째 Block이 비어 있음을 의미
  • 총 47개의 Block이 사용 중임을 알 수 있다

IBM

  • 9번째 Block에 위치하므로 0x400 * 9 = 0x2400

    IBM은 현재 어떤 Inode 번호가 사용되고 있는지를 의미함

  • FF 0F → 11111111 00001111
  • 숫자는 오른쪽부터 읽으므로 1번부터 12번까지 1을 가짐
  • 1번부터 12번의 Inode를 사용 중임을 알 수 있다

Inode Table

  • 10번째 Block에 위치하므로 0x400 * 10 = 0x2800
  • 각 Inode는 128 Byte의 크기를 갖는다
  • Superblock에서 m_inodes_count = 184였으므로, 총 128 * 184 = 0x5C00
  • 총 184개의 Inode는 5C00만큼의 Byte를 가지므로 2400 + 5C00 = 8400으로 0x2800 ~ 0x8400까지 Inode Table의 영역이 된다
  • 각 Inode를 확인하고 싶을 경우, Inode Table 영역인 5C00 % B8 = 80으로 0x80 (80h) 단위로 끊어 읽으면 된다

2번 Inode

  • root Directory 파일의 Block 위치가 기록되어 있다
  • 한 Inode에서, 40 ~ 100 Byte까지는 해당 Inode 번호를 갖는 파일이, Disk에서 위치하는 Block을 16진수 형태로 나타냄
  • 위의 root Directory를 보면, 0x21, 즉 33번째 Block에 root Directory 파일이 저장되어 있음
  • 33번째 Block의 위치인 0x8400은 Inode Table의 영역 직후이다

  • f1 파일은 12번 Inode를 통해 정보 확인이 가능함
  • 0x2800부터 1번 Inode를 시작하므로 12번째 Inode는 0x2800 + 0x80 * B = 0X2D80이 된다
  • f1 파일은 0x2f, 즉 47번째 Block에 저장되어 있으므로 0xBC00을 확인하면 된다
  • 파일에 입력한 Korea 텍스트를 확인할 수 있었다
  • 33번째 Block : root Directory
  • 44번째 Block : f1

9. Read the Inode Table

  • root Directory 파일의 Block Location을 찾는다.
  • root Directory 파일의 Byte Size / Blcok Size / Owner를 찾는다.

$ typedef struct // inode
	{
	u16 m_mode; // 0-1
	**u16 m_uid; // 2-3**
	**u32 m_size; // 4-7**
	u32 m_atime; // 8-B
	u32 m_ctime; // C-F
	u32 m_mtime; // 10-13
	u32 m_dtime; // 14-17
	u16 m_gid; // 18-19
	u16 m_links_count; // 1A-1B
	**u32 m_blocks; // 1C-1F. shows num of data blocks for this file in units of 512 bytes**
	u32 m_flags; // 20-23
	u32 m_reserved1; // 24-27
	**u32 m_block[15]; // block location of this file**
	u32 m_generation;
	u32 m_file_acl;
	u32 m_dir_acl;
	u32 m_faddr;
	u32 m_reserved2[3];
	} Inode;

u32는 4 Byte 차지
u16은 2 Byte 차지

Inode Table

Inode Table은 10번째 Block부터 시작하며 1 Block은 0x400 (= 1024 Byte)

  • 즉, 0x2800에 Inode 1 번에 대한 정보가 기록되어 있다
  • 각각의 Inode는 Inode Table에서 0x80 (= 128 Byte) 차지
  • root Directory File은 Inode 2번에 위치하므로 0x2880 ~ 0x28FF

Inode Table의 Block Location

  • Inode Struct를 참고하여, Block Location을 나타내는 m_block은 0x28 ~ 0x2C에 위치
  • 2번 Inode의 위치인 0x2880을 기준으로, m_blocks[15] → 0x00000021
  • 즉, root Directory File의 Location은 0x400 * 0x21 = 0x8400

Inode Table의 Byte Size

  • Inode Struct를 참고하여, Byte Size를 나타내는 m_size는 0x4 ~ 0x7에 위치
  • m_size → 0x00000400
  • 10진수로 계산 → 1,024 Bytes

Inode Table의 Block Size

  • Inode Struct를 참고하여, Block Size를 나타내는 m_blocks는 0x1C ~ 0x1F에 위치
  • m_blocks → 0x00000002
  • 10진수로 계산 → 2이며, 단위가 512 Bytes 이므로 1024 Bytes

Inode Table의 Owner

  • Inode Struct를 참고하여, Owner를 나타내는 uid field는 0x2 ~ 0x3에 위치
  • m_uid → 0x0000이므로 uid 0인 root 사용자

10. Read the root Directory File

  • Member files의 개수를 찾는다.
  • Member files들의 Inode 번호와 File 이름을 찾는다.
  • Inode Table로 이동해서 각 Member file의 Block Location을 찾는다.
$ **typedef struct // directory
	{
	u32 m_inode;
	u16 m_rec_len;
	u08 m_name_len;
	u08 m_file_type;
	char m_name[255];
	} DirectoryEntry;**
  • rec_len씩 Directory File을 끊어보았다.
  • Inode Number → 주황색, Record Length → 빨간색, File name → 초록색
  • Member File들은 총 4개가 존재하는 것을 확인했다.

Member File들의 Block Location은 0x2800 + 0x80 * (N - 1) → N : Inode 번호

  • file .와 ..는 Inode 2인 root Directory File

lost+found의 Inode Table

  • Inode Number 11 → N = 11
  • Block Location : 0x2800 + 0x80 * 10 = 0x2D00
  • lost+found의 Block Location은 0x00000022 * 0x400 = 0x8800

f1의 Inode Table

  • Inode Number 12 → N = 12
  • Block Location : 0x2800 + 0x80 * 11 = 0x2D80
  • f1의 Block Location은 0x0000002f * 0x400 = 0xBC00

11. Read the Member file

lost+found directory file

Inode NumberRecord LengthFile name
11 (0xb)12 (0x2e).
21012 (0x3f4)..
  • lost+found 파일 내부에 .와 .. 파일이 존재한다
  • . 파일은 Inode 11인 자신을 나타낸다
  • .. 파일은 Inode 2인 root Directory file을 나타낸다

f1

  • f1은 file type 번호가 1인 Regular File로, f1의 data인 "korea"가 저장되어 있다
  • f1의 file type은 1인 Regular File
$ **typedef struct // directory
	{
	u32 m_inode;
	u16 m_rec_len;
	u08 m_name_len;
	u08 m_file_type;
	char m_name[255];
	} DirectoryEntry;**

12. Hidden files

$ ls 
$ ls -a

-a 옵션을 추가하면 숨겨진 파일 (., ..)를 포함한 현재 Directory file 이 출력됨

13. Print Inode Number

$ ls -ai

-a 옵션에 i를 추가하면, 각 파일명 왼쪽에 Inode 번호가 출력됨

14. Make another file in Virtual Disk

  • rm 명령으로 이 파일을 삭제한다.
  • 삭제한 뒤 File system의 변화를 확인한다.
  • 삭제한 File system을 복구한다.
  • f2를 생성하기 전의 File system X와 생성한 후의 hw14 비교

DBM

  • 48번 Blcok이 사용 중으로 바뀌었다
  • 0111 1111 → 1111 1111

IBM

  • 13번 Inode가 사용 중을 바뀌었다
  • 0000 1111 → 0001 1111

Inode Table

  • 추가된 13번째 Inode의 위치인 0x2E00 (0x2800 + 0x80 * 0xC)의 기록
  • f2의 Block Location은 0x00000030 * 0x400 = 0xC000
  • 0xC000에 f2의 내용 "hello"가 잘 기록되었다

root Directory File

  • f2가 추가된 것을 확인할 수 있다
  • f1의 rec_len은 0x3D4 → 0xC로 변경되었는데, 이는 마지막 파일이 F1에서 F2로 변경되면서 F2에게 1024 Bytes에서 남은 len을 모두 할당하기 때문

f2의 정보

  • Inode Number → 0xD = 13
  • Record Length → 0x3C8 = 968 Bytes
  • Name Length → 2 Bytes
  • File type → 1 = Regular file

Mount

  • mount로 temp와 연결한 뒤 f2의 Inode Number가 13임을 확인하였다

Rm

  • f2를 삭제한 뒤에 다시 file system을 확인해본다

DBM, IBM

  • 48번 Block과 13번 Inode가 f2 생성 전 상태인 Empty로 변경되었다

Inode Table

  • node Table의 경우 f2 생성 전처럼 0으로 깨끗히 지워지진 않았다
  • m_ctime (마지막 변경 시간), m_dtime (삭제한 시간), m_links_count(해당 Inode를 참조하는 링크 수)가 변경되었다
  • file을 삭제하면 해당 파일의 Inode Table에 삭제된 시간, 즉 마지막 변경 시간이 기록되며 links_count가 0을 변경된다

root Directory file, Block Location

  • root Directory file과 Block Location엔 여전히 f2의 내용이 그대로 남아있다
  • file 내용 자체는 삭제해도 남아있으므로, file system을 editor를 통해 위에서 변경된 DBM, IBM, Inode Table의 내용을 삭제 전으로 바꿔놓을 경우 복구가 가능할 것이다

14 - 1. Make a new directory in the root directory

  • mkdir 명령으로 새로운 Directory d7 생성
  • root Directory file의 Disk File 목록을 표시한다
  • D7의 Inode Number를 확인한다
  • d7 디렉토리 생성 후 file system을 확인했다

root directory file

  • d7의 Inode Number는 0xD = 13

14 - 2. Show the Inode Content of d7

  • d7의 Block Location을 찾는다.
  • d7의 Block Content를 보인다.
  • d7 내에 어떤 File이 있는지 보인다.

Inode Table

  • 추가된 13번째 Inode의 Block Location은 0x2E00 (0x2800 + 0x80 * 0xC)
  • d7의 Block Location은 0x400 * 0x30 = 0xC000

Block Conent

Inode NumberName LengthFile TypeRecord LengthFile Name
13 (0xd)1directory (2)12 (0x2e).
22directory (2)1012 (0x3f4)..
  • d7 디렉토리 파일 내부에는 .와 ..이 있다.
  • . 파일은 Inode Number 13인 자신이다.
  • .. 파일은 Inode Number 2인 root Directory File이다

14 - 3. Run "mv f1 d7/f2"

변경된 내용을 보인다.

  • f1 파일을 d7 디렉토리 하위 f2의 이름으로 옮겼다

root Directory File

  • 변화가 없었다

Inode Table in d7

  • c_time (마지막 변경 시간), m_time (마지막 수정 시간)만 변경되었다

Block Content

f2가 추가되었다

  • Inode Number → 0xC : 12
  • Record Length → 0x3E8 : 1000 Bytes
  • Name Length → 2 Bytes
  • File type → 1 = Regular file

이동 전 f1의 Inode Number 12를 그대로 가져온 것을 확인했다


15. Examine the file system in the hard disk (/dev/sda3)

  • Hard Disk (/dev/sda3)의 File System을 찾아본다

SuperBlock

  • SuperBlock의 Block_number = 0
  • 한 Block Size : 1024*222^2 = 4 KB (0x1000)
  • 다음 Block인 GroupDescriptor의 Block Number = 1, Block Location = 0x1000 * 1 = 0x1000

GroupDescriptor

  • Inode Table의 Block Number = 0x1DE → 478
  • Inode Table Location은 0x1000 * 0x1DE = 0x1DE000

Inode Table

  • root Directory file의 Block Number는 0x3D9 → 985
  • root Directory file의 Location은 0x1000 * 0x3D9 = 0x3D9000

root Directory File

  • Directory의 Struct 중 Record Length를 계산해서 파일을 구분하였다
  • File name → 초록색
  • 이는 실제 root Directory에 존재하는 파일 이름이다
  • 이를 ASCII 코드로 해석하면 다음 동일한 20개의 파일명을 알 수 있다

16. Write a Program that opens a Disk devies formatted with EXT2

  • EXT2로 포맷된 Disk 장치를 연다.
  • SuperBlock, GroupDescriptor, IBM, DBM, Inode Table을 읽어오고 표시하는 프로그램을 작성한다.
  • root Directory File, Inode Number, Block Location 위치에 File 이름을 표시한다.
  • open(), lseek(), read() 함수 사용한다.
$ struct superblock{
	int total_inode_num;
	int total_block_num;
	.........
	};
	int x; char buf[1024]; struct superblock *sb;
	x=open("myfd", O_RDONLY, 00777); //open a virtual disk
	lseek(x, 1024, SEEK_SET); // move the file pointer to offset 1024 where the
	// superblock starts
	read(x, buf, 1024); // read the superblock into buf
	sb=(struct superblock *)buf; // interpret the data in buf as "struct superblock"
	printf("total inode num:%x, total_block_num:%x, ...",
	sb->total_inode_num, sb->total_block_num, ....);

  • Block 하나의 크기는 SuperBlock에 기록된 m_log_block_size 이용
  • GroupDescripter는 SuperBlock의 다음 블록임을 이용

  • DBM, IBM의 시작점은 각각 GroupDescriptor의 Block_bitmap, Inode_bitmap 이용
  • DBM, IBM은 첫 16 Bytes만 출력

  • root directory의 Inode Table만 출력
  • Inode 하나의 크기는 128 Bytes
  • root directory의 Inode Number는 2번
  • 즉, root directory의 Inode는 Inode Table 시작점에 128 Bytes 를 더한 값에서 시작

  • root directory block에서 root directory 내부 파일의 inode 번호를 알아낸 후, 각 파일의 inode 위치로 이동하여
    block 번호를 가져와야하기에 새로운 inode struct를 선언.
  • root directory block은 한 블록이기에 one_block_size만큼 탐색.
  • loop를 한 번 돌때마다 i에 방금 출력한 파일의 record length만큼 더함.
  • 마지막 파일의 record length에 남은 block size가 모두 할당되기 때문에 빈 data가 출력되지 않음
  • 포인터 x를 출력 중인 파일의 Inode로 이동
  • root directory의 Inode 시작점에, 출력 중인 파일의 Inode – 2한 결과에 inode 크기 128bytes를 곱한 값을 더함.
  • Block Location은 Inode Struce의 'Block' 항목, 즉 Block number에 one_block_size를 곱한 값

0개의 댓글