iT邦幫忙

2021 iThome 鐵人賽

DAY 30
1
自我挑戰組

當你凝視linux, linux也在凝視你系列 第 30

Day30 file system, inode

前言

時間終於過到了最後一天,昨天看了三個特別的虛擬文件系統,今天就看看實際存在的文件管理系統吧! 在行程運行時需要儲存一些私有資料跟信息,如何管理與檢索這些數據就是一個很重要的問題。

文件系統的基本概念

文件系統中有兩個非常重要的概念,分別是目錄與文件,文件為使用者提供了在磁碟上儲存資料跟方便讀寫的方法,讓使用者不用擔心文件的內容在磁碟裡的實際分配。

文件

一般來說,文件可以分為幾類

  1. 普通文件:包含用戶資料的常見文件
  2. 目錄文件:用於管理文件系統結構的系統文件,目錄可以看作是文件的一種。
  3. 特殊文件:Linux 系統豬有多種特殊文件,像是設備文件、sysfs node、procfs node。

作業系統也會保存文件相關的重要訊息,像是文件的創建時間、文件大小、創建者等等,這些附加的訊息又稱作文件屬性,或是metadata。在Linux 中可以利用stat查詢。

在Linux系統中可以利用 open() 創建文件, int fd = open("file name", O_CREAT| O_RDWR)open()的返回值是file descriptor(fd),是每個行程私有的,可以用來訪問該文件,文件被打開之後就可以利用 fd對文件進行讀寫的操作,利用 open()打開文件、利用close()關閉文件,利用read()讀取文件內容,用write()寫入文件。

ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, const void *buf, size_t count);

其中*buf代表緩衝區, count 代表讀寫操作想要操作多少 byte的資料,兩個函數都會返回成功讀/寫的byte量。
另外有幾個常見的函數

off_t lseek(int fd, off_t offset, int whence); 

lseek()用來時線文件的定位,offset 是偏移量,用來將文件偏移量定位到特定位置,whence 用來指定搜索方式。

static __attribute__((unused))
int stat(const char *path, struct stat *buf)
{
	int ret = sys_stat(path, buf);

	if (ret < 0) {
		SET_ERRNO(-ret);
		ret = -1;
	}
	return ret;
}

int sys_stat(const char *path, struct stat *buf)
{
	struct sys_stat_struct stat;
	long ret;

#ifdef __NR_newfstatat
	/* only solution for arm64 */
	ret = my_syscall4(__NR_newfstatat, AT_FDCWD, path, &stat, 0);
#else
	ret = my_syscall2(__NR_stat, path, &stat);
#endif
	buf->st_dev     = stat.st_dev;
	buf->st_ino     = stat.st_ino;
	buf->st_mode    = stat.st_mode;
	buf->st_nlink   = stat.st_nlink;
	buf->st_uid     = stat.st_uid;
	buf->st_gid     = stat.st_gid;
	buf->st_rdev    = stat.st_rdev;
	buf->st_size    = stat.st_size;
	buf->st_blksize = stat.st_blksize;
	buf->st_blocks  = stat.st_blocks;
	buf->st_atime   = stat.st_atime;
	buf->st_mtime   = stat.st_mtime;
	buf->st_ctime   = stat.st_ctime;
	return ret;
}

stat()是為了獲取文件的相關屬性,在呼叫stat()之後,會將所有的資訊保留在傳入的 struct stat *buf 結構中,如上面程式碼所示。
rename()則是用來修改文件的名字,Linux中也可以利用 rm command 刪除文件或是目錄,這是利用 unlink() 來實現的。

inode

inode 是索引節點(index node),是在Linux 系統內用來尋找實際資料的結構,每個文件或是目錄,實際上會指向一個inode 才能夠實際存取硬碟中的資料。
事實上,在檔案管理上,有三個重要的表格,分別是在記憶體中的inode table、在硬碟中的inode table、跟在記憶體中的file table。當使用open()打開檔案,若是記憶體中的inode table可以找到對應的inode,那就可以直接對資料進行存取,如果找不到的話,就會到硬碟中的inode table找尋相對應的inode並且讀取到記憶體中。

inode, file reference

When a file is opened using open(2), an available entry in the open file table is found, the inode of the file reference by the pathname is determined, that inode is loaded into the in-memory inode table, if not already loaded, the st_nlink count is increased and the inode entry is referenced in the file descriptor, flags are set and buffers are allocated. When closed, the reverse occurs.
The routines within the kernel are called the "file management system" and the "filesystem" is the organization on disk. These days there are a number of 'plugable' modules that can be loaded (modprobe(8)) into the file management system for different organizations on disk. For example, there are ext2/ext3/ext4 filesystem types, and each of them have a different module in the kernel's file management system; the same with ntfs, sbfs, nfs, vfat, jfs, etc.

感言

終於完成30天的挑戰,雖然中間有些因為時間或是個人行程的關係沒辦法好好的完成,但之後會把缺少的部分補完,缺少的部分如以下。

  • systemcall 調用的方法
  • 分段管理 分頁管理補完
  • Underscore vma 補充
  • TLB的問題補充
  • RMAP anonymous page
  • spinlock 上的 MCS qspinlock
  • EAS
  • 用semaphore 實作mutex 與 mutex的效能差異

這個三十天的挑戰,讓我對很多過去從來沒有了解Linux有更多的了解,不過只有知識還是不夠的,希望之後可以實際的操作這些系統試試看。


上一篇
Day29 procfs, sysfs, debugfs
系列文
當你凝視linux, linux也在凝視你30

尚未有邦友留言

立即登入留言