- 파일 경로를 보고 정렬해주는 방법 (단순하나, 별로...)
- inode 번호를 보고 정렬해주기 (fragmentation 경우 별로이나, 대부분 이 방식을 쓴다.)
- physical block 순으로 정렬하기 (다 좋은데 root 권한이 있어야 한다.)
inode 번호 대로 정렬하는 것은 stat() system call을 통해 사용할 수 있다.
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
int get_inode(int fd)
{
struct stat buf;
int ret;
ret = fstat(fd, &buf);
if (ret < 0) {
perror("stat");
return -1;
}
return buf.st_ino;
}
physical block 순으로 정렬하기 위해서는 ioctl() system call을 사용한다. 아래처럼 FIBMAP을 주면 해당하는 논리 블럭의 physical block 번호를 block에 넣어준다.
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <linux/fs.h>
int get_inode(int fd)
{
struct stat buf;
int ret;
ret = fstat(fd, &buf);
if (ret < 0) {
perror("stat");
return -1;
}
return buf.st_blocks;
}
int get_block(int fd, int logical_block)
{
if (ioctl(fd, FIBMAP, &logical_block) < 0) {
perror ("ioctl"); return -1;
}
return logical_block;
}
앞서 봤던 inode 값을 리턴하는 함수에서 buf.st_ino를 buf.st_blocks로 바꾸면 논리 블럭 갯수를 반환한다. 예를 들어 어떤 파일이 8개의 논리 블로으로 구성되어 8을 리턴했으면 이 파일은 0~7번의 논리 블럭을 가지고 있는 것이다. 그래서 이 0~7번을 ioctl 함수를 통해 각각에 대한 physical block의 번호를 받을 수 있고 이 값을 가지고 I/O 요청을 최적화할 수 있다.
FIBMAP은 LBN나 PBN를 알려주지 못합니다. 단지 해당 파티션의 파일시스템의 첫번째 block으로 부터 몇번째 block인지만 알려 줄 뿐이지요. LBA는 디스크 기준으로 몇번째 섹터인가인데 앞으 경우와 매치가 되지 않습니다. FIBMAP의 이름 자체도 File Inode BitMAP이 아닐까 생각해 봅니다.
ReplyDeleteFIB이 PBN을 알려주는 것이 아니라, ioctl에 FIB값을 주면 FIB-PBN 맵에서 찾아 해당하는 PBN을 넘겨주는 것으로 기록한 것인데요, ioctl을 통해 구한 PBN이 Physical Block Number가 아니라면 Robert Love에게 메일을 보내봐야겠군요 :)
ReplyDelete아, 다시 살펴보니 Jae-hyeok님 말씀이 맞는것 같네요(!). Love가 'physical block number'라고 썼는데, 파일 시스템에서의 block number를 통해 물리적인 layout을 가늠할 수 있다는 의미로 사용한 것 같네요. 'physical block order'가 낫겠네요.
ReplyDelete