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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章