Linux文件系统(一)文件系统概述

Linux文件系统

Linux文件系统(一)文件系统概述

Linux文件系统(二)磁盘文件系统

Linux文件系统(三)虚拟文件系统

Linux文件系统(四)文件缓存

Linux文件系统(一)文件系统概述

一、文件系统的功能规划

文件系统是用来管理磁盘空间,存储文件的一套软件,它需要满足下面几个特点

  • 文件系统要有严格的组织形式,使得文件能以块为单位存储

  • 文件系统需要索引区,用来查找存储文件的多个块存放在哪个区域

    img

  • 如果文件系统的某个文件时热点文件,最近经常被访问,那么文件系统应该有缓存层

  • 文家应该用文件节夹的形式组织起来,方便管理和查询

    img

  • Linux内核在内存中应该维护一套数据结构,来维护对应进程打开的文件

二、文件系统相关的命令

对于一块磁盘,首先需要格式化才能存放文件,Linux下常用的文件系统格式为 ext3 和 ext4

可以使用命令 fdisk -l 查看磁盘的分区情况

# fdisk -l


Disk /dev/vda: 21.5 GB, 21474836480 bytes, 41943040 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x000a4c75


   Device Boot      Start         End      Blocks   Id  System
/dev/vda1   *        2048    41943006    20970479+  83  Linux


Disk /dev/vdc: 107.4 GB, 107374182400 bytes, 209715200 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

例如上面 vda,大小为 21.5 G,有一个分区 vda1

vdc,大小为 107.4 G,没有被分区

可以使用 mkfs.ext3mkfs.ext4 进行格式化

mkfs.ext4 /dev/vdc

执行完命令后,vdc 会建立一个分区,格式化为 ext4 格式

也可以选择不把一个磁盘格式化为一个分区,而是分为好几个分区,然后分别格式化

首先通过 fdisk 启动一个交互程序

fdisk /dev/vdc

输入 p 可以显示当前的分区信息

输入 n (new)新建一个分区,它会让你选择创建一个主分区 primary,还是扩展分区 extended。我们一般都会选择 primary

接下来会让你输入分区号,如果原来没有分区,那么应该时从 1 开始的,直接按回车默认也行

接下来,可以一路选择默认值,直到让你输入分区的大小,通过 +sizeM 或者 +sizeK 的方式,默认值是整块磁盘都用上。可以输入 +5620M 来创建一个 5G 的分区。这时候输入 p 就可以看到分区信息,然后再输入 w 将分区信息写入磁盘中

分区结束后,可能会出现 vdc1,vdc2 等多个分区,这时候可以通过 mkfs.ext3 /dev/vdc1 将第一个分区格式化为 ext3 格式。通过 mkfd.ext4 /dev/vdc2 将第二个分区格式化为 ext2 格式

格式化后需要挂载到某个目录下,才能访问

mount /dev/vdc1 / 根目录 / 用户 A 目录 / 目录 1

需要卸载可以通过下面命令

umount / 根目录 / 用户 A 目录 / 目录 1

Linux下一切皆文件。可以使用 ls -l 查看文件的类型

  • -:普通文件
  • d:文件夹
  • c:字符设备文件
  • b:块设备文件
  • s:socket文件
  • l:软链接文件
# ls -l
lrwxrwxrwx 1 root root   61 Dec 14 19:53 instance -> /var/lib/cloud/instances

三、文件系统相关的调用

操作文件可以通过下面的方法

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>


int main(int argc, char *argv[])
{


  int fd = -1;
  int ret = 1;
  int buffer = 1024;
  int num = 0;


  if((fd=open("./test", O_RDWR|O_CREAT|O_TRUNC))==-1)
  {
    printf("Open Error\n");
    exit(1);
  }


  ret = write(fd, &buffer, sizeof(int));
  if( ret < 0)
  {
    printf("write Error\n");
    exit(1);
  }
  printf("write %d byte(s)\n",ret);


  lseek(fd, 0L, SEEK_SET);
  ret= read(fd, &num, sizeof(int));
  if(ret==-1)
  {
    printf("read Error\n");
    exit(1);
  }
  printf("read %d byte(s),the number is %d\n", ret, num);


  close(fd);


  return 0;
}

  • open:打开一个文件
  • write:往文件里写内容
  • lseek:移动文件指针
  • read:读取文件内容
  • close:关闭文件

获取文件信息可以通过下面三个系统调用

int stat(const char *pathname, struct stat *statbuf); //无法处理软链接
int fstat(int fd, struct stat *statbuf);
int lstat(const char *pathname, struct stat *statbuf); //可以返回符号链接的内容

struct stat {
  dev_t     st_dev;         /* ID of device containing file */
  ino_t     st_ino;         /* Inode number */
  mode_t    st_mode;        /* File type and mode */
  nlink_t   st_nlink;       /* Number of hard links */
  uid_t     st_uid;         /* User ID of owner */
  gid_t     st_gid;         /* Group ID of owner */
  dev_t     st_rdev;        /* Device ID (if special file) */
  off_t     st_size;        /* Total size, in bytes */
  blksize_t st_blksize;     /* Block size for filesystem I/O */
  blkcnt_t  st_blocks;      /* Number of 512B blocks allocated */
  struct timespec st_atim;  /* Time of last access */
  struct timespec st_mtim;  /* Time of last modification */
  struct timespec st_ctim;  /* Time of last status change */
};

  • stat:通过文件路径获取文件的 stat 信息,无法查看软链接文件
  • fstat:通过文件描述符获取文件信息
  • lstat:通过文件路径获取文件信息,当文件为软链接的时候,获取该链接的文件信息

可以通过下面的方法来读取目录下文件

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>


int main(int argc, char *argv[])
{
  struct stat sb;
  DIR *dirp;
  struct dirent *direntp;
  char filename[128];
  if ((dirp = opendir("/root")) == NULL) {
    printf("Open Directory Error%s\n");
    exit(1);
  }
  while ((direntp = readdir(dirp)) != NULL){
    sprintf(filename, "/root/%s", direntp->d_name);
    if (lstat(filename, &sb) == -1)
    {
      printf("lstat Error%s\n");
      exit(1);
    }


    printf("name : %s, mode : %d, size : %d, user id : %d\n", direntp->d_name, sb.st_mode, sb.st_size, sb.st_uid);


  }
  closedir(dirp);


  return 0
}

  • opendir:打开一个目录
  • readdir:读取目录下的项
  • closedir:关闭一个目录
  • dirent:表示目录下一个项

四、总结

  • 在文件系统上,需要维护文件严格的格式,需要通过 mkfd.ext4 来讲分区格式化为 ext4 格式
  • 每一磁盘保存文件都需要一个索引,来维护对应文件存储在磁盘上的位置
  • 文件通过文件夹组织起来,方便管理
  • 为了快速读取文件,内核分配了一块空间作为缓存,让一些数据块存储在缓存里面
  • 在内核中,要有一套数据结构来表示进程打开的文件
  • 在内核态,每个打开的文件都有一个文件描述符,文件相关的操作都需要通过这个文件描述符找到对应的文件

img

发布了107 篇原创文章 · 获赞 197 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/weixin_42462202/article/details/102529686