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有更多的了解,不过只有知识还是不够的,希望之後可以实际的操作这些系统试试看。


<<:  [Day30] 浅谈重构(refactoring)与两把刷子

>>:  连续 30 天 玩玩看 ProtoPie - Day 30

Day 29 - ios 开发实作 (今天还要继续吃吗APP-3)

今天会使用到foreach,所以开头我们先来学一下要怎麽使用Foreach。 Foreach 什麽时...

Day 17 - 利用程序码制造出韵律,随机性 - angleMode / random / noise

了解旋转、圆形与极座标的概念 如何利用弦波函数产生韵律感 利用噪声产生连续的乱数 如何使用噪声产生...

【领域展开 13 式】 有了骨头与皮肤,再搞清楚主要肌群 Menu 层级与操作

网站架构是骨头,布景主题是皮肤,Menu 是大肌肉 昨天【领域展开 12 式】 安装 Soledad...

Day 4. 关於.NET後端(2)

开开始学後端的人多少会听到ASP.NET、.NET Framework、.NET Core,但不清楚...

【第十四天 - 堆叠型 SQL注入】

Q1. 什麽是 堆叠型 SQL注入? 堆叠型 SQL注入也称为 堆查询注入,英文为 stacked ...