Linux File System
- 각 file은 inode (information node)를 가지고 있다.
- inode는 file의 고유 번호이다.
- inode는 data structure의 모든 정보를 가지고 있다.
- inode들은 disk에 저장되어 있다.
inode가 가지고 있는 정보들
: file name, type, id, permission, size, data block addr .table...
Inode Sturcture

- 1~12번은 direct pointers로 1개당 1 block size
- 13번은 single indirect pointer로 block pointer의 집합체
- 14번은 double indirect pointer
- 15번은 triple indirect pointer
- 13~15는 제곱해서 안에 담겨있다고 생각하면 편하다.
File Types
- ordinary file : 일반 file (text, binary..)
- directory file : dir도 파일로 자신이 가진 파일에 대한 정보를 가진다.
- character special file : I/O 연산을 수행할 수 있도록 제공(byte 단위)
- block special file : 큰 영역의 용량의 data를 주고 받는다.(block 단위)
- FIFO file : pipe / unnamed pipe
- Symbolic link file : 다른 위치를 가리키는 file (ex. 바로가기)
Directory File
- directory 내의 파일들의 (inode#, filename) 형태로 순서쌍을 정보로 가지는 file
- directory 또한 file이기 때문에 inode를 가지고 있다.
File Descriptor
- kernel에서 file을 다루기 위해 kernel에서 file에게 할당해준 음이 아닌 정수
- 0 : stdin / 1 : stdout / 2 : stderr 로 고정되어 있다.
- file이 open되면 FDT의 3번부터 할당이 된다.
- process에서는 최대 1024개의 file만 open할 수 있다.
- 최대치는 ulimit -a를 입력하면 확인할 수 있다.
Basic File I/O
File open
#include <fcntl.h>
int open(const char *path, int oflag);
int open(const char *path, int oflag, mode_tmode);


- path : open 또는 create할 filename
- oflag : options
- mode : 접근 권한(file 생성 시)
- return : 성공 시 file descriptor / 실패 시 -1
File close
#include <unistd.h>
int close(int fd);
- fd : 닫을 file descriptor
- return : 성공 시 0 / 실패 시 -1
File creation
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int creat(const char *path, mode_tmode);
- file open으로도 표현이 가능하다.
- mode : 접근 권한
- return : 성공 시 file descriptor / 실패 시 -1
File seeking
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
- file의 size를 알고 싶다면 SEEK_END를 사용하면 된다.
- fd : file descriptor
- offset : 특정 위치에서 얼마나 떨어져 있는가
- whence : SEEK_SET, SEEK_CUR, SEEK_END
- return : 성공 시 변경된 offset / 실패 시 -1
File reading
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t nbyte);
- fd : file descriptor
- buf : buffer의 주소
- nbyte : 읽을 byte의 수
- return : 성공 시 읽은 byte의 수 / 실패 시 -1
- nbyte보다 return값이 적게 나온다면 file의 끝인 것을 알 수 있다.
File writing
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t nbyte);
- buffer 내부의 byte 수 만큼 write
- fd : file descriptor
- buf : buffer의 주소
- nbyte : 쓸 byte의 수
- return : 성공 시 쓴 byte의 수 / 실패 시 -1
- nbyte와 retunr byte 수가 일치해야 성공
File Table

- offset, 위치, 상태, vnode pointer등 모든 정보가 저장되어 있는 곳
- file system : disk에 위치한다.
- OS file table : kernel에 위치한다.
- vnode : inode와 동일한 역할을 한다.
Duplication of file
1) dup(fd)
#include <unistd.h>
int dup(int fd);
- fd : 복사할 file descriptor
- FDT에서 처음으로 안쓰는 빈자리를 찾아 같은 file table을 가리키게 한다.
- OS shell에서 각 process를 연결할 때 유용하게 사용한다.
- return : 성공 시 복사된 file의 fd / 실패 시 -1
2) dup2(fd1, fd2)
#include <unistd.h>
int dup(int fd);
- fd1 : 복사할 file descriptor
- fd2 : 이동하기를 원하는 file descriptor
- 특별하게 fd2 자리에 저장해야 할 때 사용한다.
- 만약 fd2자리에 file이 open되어 있었다면, 그 file을 닫고 계속 진행한다.
- return : 성공 시 복사된 file의 fd / 실패 시 -1
- return값과 fd2가 대부분의 경우 동일하다.
Link
- 쉽게 파일을 찾아가도록 하기 위해서 사용한다.

1) Symbolic link (soft link)
- link 자체로 target file에 대한 경로를 담고 있는 file이다.
- target이 지워지면 접근할 수 없고, link가 직접 target에 가야 알 수 있다.
ex.) "~~~" 해당 파일을 찾을 수 없습니다.
- soft link도 file이기 대문에 target과 link의 inode는 다르다.
2) Hard link
- target의 inode를 직접적으로 가리킨다. 즉, inode를 공유한다.
- file이 update되면 같이 update 된다.
- file이 지워지더라도 다른 hardlink는 file에 접근할 수 있다.
- inode는 둘 이상 공유될 수 있는 정보이다.
- inode에는 "reference count"라는 것이 존재하는데, 이는 해당 inode에 접근한 link의 수를 나타내는 것이다.
- hardlink가 1개 늘면 count도 1 증가 → inode의 count를 보면 hardlink의 수를 알 수 있다.
- hardlink를 지우면 count 1 감소 → count가 0이 되면 inde 제거
System Call & Symbolic link
Symbolic link를 따르지 않는 system call | Symbolic link를 따르는 system call |
---|
lchown, lstat, remove, readlink, rename, unlink | access, chdir, chmod, chown, creat, exec, link, mkdir, mkfifo, mknod, open, opendir, pathconf, stat, truncate |
Linux cmd
$ ln –s original_file symbolic_link_name
$ ln original_file hard_link_name
Hard link
#include <unistd.h>
int link(const char *existing, const char *new_link);
- exsiting : original file name
- new_link : inode를 공유할 file과의 link할 name
- return : 성공 시 0 / 실패 시 -1
Symbolic link
#include <unistd.h>
int symlink(const char *existing, const char *link_name);
- exsiting : original file name
- new_link : 가리키는 file과 link할 name
- return : 성공 시 0 / 실패 시 -1
Following link
#include <unistd.h>
int readlink(const char *path, void *buf, size_t bufsize);
- 해당 link하고 있는 원본 file을 알아내는 함수
- path : link name
- buf : buffer의 주소(original file name)
- bufsize : buffer 크기
- return : 성공 시 읽은 byte의 수 / 실패 시 -1
1) stat
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
int stat(const char *path, struct stat *buf);
- 경로를 이용하여 file에 대한 정보를 읽어온다.
- path : file의 path name
- buf : file의 정보를 담을 구조체의 주소
- return : 성공 시 0 / 실패 시 -1
1) lstat
int stat(const char *path, struct stat *buf);
- stat()과 거의 유사하지만 target이 아닌 link file의 정보를 읽어온다.
- path : link file의 path name
- buf : link file의 정보를 담을 구조체의 주소
- return : 성공 시 0 / 실패 시 -1
1) fstat
int stat(const char *path, struct stat *buf);
- file descriptor를 이용하여 접근한다.
- file을 열고 fd를 할당한 뒤 이를 이용해야 한다.
- fd : file descriptor
- buf : link file의 정보를 담을 구조체의 주소
- return : 성공 시 0 / 실패 시 -1
구조체에 담기는 정보

Process's Creator
- process가 생성될 때, process에는 user id가 할당된다.
- real user(user id) : process를 실행했을 때 명령어를 실행시킨 user
- effective user : process가 실행되면서 access할 file 등에 대한 권한을 가진 user
getuid / getgid
#include <sys/types.h>
#include <unistd.h>
uid_t getuid(void)
uid_t getgid(void)
- return : 성공 시 user id, group id / 실패 시 -1
geteuid / getegid
#include <sys/types.h>
#include <unistd.h>
uid_t geteuid(void)
uid_t getegid(void)
- 일반적으로 uid == euid지만 dynamic system에서 달라질 수 있다.
- return : 성공 시 effective user id, effective group id / 실패 시 -1
mount
- 시스템에 외부 장치나 storage 장치를 장착하는 system utility 접근 권한이 없더라도 순간 접근할 수 있도록 해준다.
- S_ISUID/S_ISGID bit나 S_ISVTX와 같이 sticky bit를 사용하는 경우 effective ID가 file의 owner의 id로 set될 수 있다.
$ chmod u+s a.out
$ chmod g+s a.out
Sticky bit(S_ISVTX)
- 어떤 directory에 대해 설정해줄 수 있는 bit
- 공용(모든 user가 접근 가능)에서 자신의 것은 수정 가능 / 자신이 생성하지 않은 것은 접근만 되고 수정/삭제가 불가능하게 하는 것.
- ex.) sticky bit를 set하는 방법
$ chmod o+t/test
File permission attribution


- file의 permission을 설정하는 방법
- 파일 종류 : directory / character device file / block device file / socket / Symbolic link
File access permission
#include<unistd.h>
int access(const char *path, int amode);
- file에 접근이 가능한가 check
- path : path name
- amode : R_OK / W_OK / X_OK / F_OK
- 각 read, write, execute, existence를 check
- return : 성공 시 0 / 실패 시 -1
Default Permission
- file default permission : 0666
- directory default permission : 0777
umask
#include<sys/types.h>
#include<sys/stat.h>
mode_t umask(mode_t cmask);
- defalut permmsion을 바꾸고 싶을 때 사용하는 함수
- cmask : 허용하지 않는 권한
- 허용하지 않는 값으로 설정한다.
- umask로 설정하면 이후로 바뀐 값이 default permission이 된다.
- return 이전의 umask
- ex.) umask = 0222 → default permission = 0644
File permission change
chmod / fchmod
#include<sys/types.h>
#include<sys/stat.h>
int chmod(const char *path, mode_t mode);
int fchmod(int fd, mode_t mode);

- file의 permission을 변경할 때 사용하는 함수
- path : file의 path name
- fd : file descriptor
- mode : OR(|)를 통해 적용
- return : 성공 시 0 / 실패 시 -1
Ownership change
chown / lchown / fchown
#include <unistd.h>
#include <sys/types.h>
int chown(const char *path, uid_t owner, gid_t group);
int lchown(const char *path, uid_t owner, gid_t group);
int fchown(int fd, uid_t owner, gid_t group);
- ownership을 변경할 때 사용하는 함수들
- lchown은 taget을 바꾸는 것이 아닌 link file의 ownership을 변경하는 것
- path : file의 path name
- owner : owner의 UID
- group : group의 GID
- fd : file descriptor
- return : 성공 시 0 / 실패 시 -1