首页 > 系统相关 >Linux文件系统(以ext2为例)

Linux文件系统(以ext2为例)

时间:2023-12-25 20:36:50浏览次数:43  
标签:文件 shr ext2 为例 Linux 磁盘 inode block struct

所有的计算机程序都需要存储和检索信息。长期存储信息有三个基本要求:

  1. 能够存储大量信息。
  2. 存储必须持久化。
  3. 多个进程可以并发访问这些信息。

这些任务一般由磁盘来进行。虽然固态硬盘在近年逐渐流行,但传统磁盘依然是存储大量数据的首选。本文只针对磁盘,不对固态硬盘进行讨论。

使用磁盘来存储数据,必须要解决三个基本问题:

  1. 检索问题(路径问题),即如何快速找到信息。
  2. 权限问题,例如防止一个用户读取其他用户的信息。
  3. 存储问题,例如如何知道磁盘的哪些区域是空闲的。

在用户角度,使用磁盘的基本单元即是一个个文件。磁盘上的文件是受操作系统管理的,从总体上看,操作系统处理磁盘上的文件的部分称为文件系统(file system)。本文会先从磁盘本身的角度讨论其基本的物理结构和存储原理,再从操作系统的角度讨论其对文件的组织和管理,即文件系统。

硬件->磁盘

物理结构

磁盘是现代电子计算机中唯一的机械设备,大体来看,其主要由 5 个部分组成:

  • 盘面 是实际存储数据的部分。盘面的表面是具有磁性的,以 N/S 级来表示一个基本位,在计算机中,这些基本位被解释为 0/1,磁盘以此实现数据的存储。一个最基本的磁盘会包含至少一个盘面,一些容量较大的磁盘会包含多个盘面。盘面越多、盘面的带磁基本单位分布越密集,磁盘的容量越大。磁盘的正反两面均可被使用。
  • 主轴 下面的马达会驱动盘面进行高速旋转,以支持到达盘面各个部分。
  • 磁头和磁头臂 磁头是对盘面进行读写的部件,磁头会放电以改变盘面某些部分的磁性,以此来完成写入操作;或者检测盘面当前的磁性状态,以此来完成读操作。磁头臂带动磁头进行移动。
  • 磁头停靠点 磁盘不工作时,磁头会停靠在此处。

Linux文件系统(以ext2为例)_Linux

磁头在运动时,不与盘面直接接触,而是距离盘面有极小的空隙。为了防止磁盘工作时收到空气中微粒的干扰,磁盘的生产和使用环境都是密封、无尘的。

存储构成与逻辑抽象

在谈论磁盘的存储时,只关注盘面本身的逻辑布局。在逻辑上,认为一个盘面包含两个存储构成:

  • 磁道(柱面) 以磁盘圆心为中心,将盘面划分为数个同心圆,每两个同心圆之间形成的环形区域被称为磁道(track)。当具有多个盘面时,这些盘面是同时旋转的,所有盘面上同一相对位置的磁道被称为柱面(cylinder)。
  • 扇区 扇区(sector)是访问磁盘的最基本单元,每个扇区的能存储的数据容量都是相同的,一般为 512Byte 或 4KB。各个磁道的同心圆的半径不同,可以控制带磁存储单元的密度以控制扇区容量相同。在磁盘上读写数据,首先要定位到一个扇区

Linux文件系统(以ext2为例)_Linux_02

承上,为了找到一个扇区,首先要确定扇区在哪个盘面,即使用哪个磁头,然后确定扇区所在的磁道,最后定位到扇区,这种寻址方式被称为 CHS 寻址

在逻辑上,将上述磁盘的环形磁道进行展开并拼接,可以将磁盘看做一个线性的结构

Linux文件系统(以ext2为例)_ext2_03

在上图中,最终将磁盘抽象成了一个以扇区为基本单位的数组,这个数组以扇区的序号为下标,这个下标被称作逻辑扇区地址或者逻辑块地址(LBA)。操作系统可以将物理上的 CHS 地址与逻辑上的 LBA 地址进行相互转化。

扇区的寻址,终归是要磁盘进行机械运动实际找到这个位置,所以机械运动是影响磁盘效率的最主要因素。机械运动越少,磁盘效率越高;机械运动越多,磁盘效率越低。在软件设计层面,开发者要有意识地将相关数据存放在一起,以减少磁盘的机械运动,提高磁盘效率。

Linux文件系统(以ext2为例)_文件系统_04

除了上述的硬件外,磁盘还具有几个重要的寄存器,比如控制寄存器用来控制 IO 的方向,地址寄存器存储目标数据所在的 LBA 地址等。除此之外还有数据寄存器和状态寄存器,这里不再讨论。

软件->文件系统

现行 Linux 系统有很多主流的文件系统,例如 ext2、ext3、ext4、xfs等。这里不再讨论各个文件系统之间的区别及优劣,而是直接以 ext2 阐述操作系统对磁盘的组织。

对磁盘的分区

磁盘的容量是庞大的,仅仅是现代的个人电脑上搭载的硬盘的容量也有的超过了 1TB。为了有效地对磁盘做管理,操作系统的策略为:分治,具体做法是对磁盘进行分区,只要分别管理好各个磁盘分区,便能管理好整个磁盘。最常见的磁盘分区操作即是在 windows 机器中的、用户对磁盘的手动分区(假设只搭载了一块磁盘)。对 Linux 机器的磁盘分区的具体操作并非本文的话题,这里不进行讨论。

windows 中的磁盘分区:

Linux文件系统(以ext2为例)_Linux_05

在每个分区中的最开始都包含了一个 boot block,这个块用来存放引导程序和数据,所以又被称为引导块。分区的其他部分由数个 block group 组成,只要管理好各个 block group,就能管理好整个分区。block group 又可再被细分。

Linux文件系统(以ext2为例)_文件系统_06

block group结构

block group是讨论文件系统的关键,对文件系统的讨论,本质是对 block group 的讨论。如上图所示,在 ext2 中,block group 被划分为以下几个部分:

  • data blocks 文件的属性信息也属于文件的一部分。在 Linux 中,文件的属性信息和数据内容是分开存放的,data blocks 即是存放文件内容的地方。data blocks 中包含了很多小的 data block 数据块,每个 data block 都有其编号。一个 data block 的大小一般为 4KB,是文件内容存储的最小单位,当一个文件的大小大于 4KB 时,会占据多个 data block。
  • block bitmap 在一个分区中,会有很多 data block,blcok bitmap 用来标识哪些数据块已经被使用,哪些数据块未被使用。block bitmap 本身是一个位图结构,删除文件时,不需要修改数据块内容,只需要修改 block bitmap 中对应位置的状态即可。
  • inode table 文件除了文件名之外的所有属性信息被存放在一个被称为 inode 的结构中,每个 inode 都有一个唯一的编号,被称为 inode 编号。在操作系统中,一个 inode 编号就代表了一个文件,操作系统只认识 inode。一个 inode 只在当前分区内有效,不能跨分区。inode table 是存放 inode 的地方。在命令行层面,使用ls -i命令或者stat命令查看文件的 inode 编号。
[@shr Fri Dec 01 20:07:09 12.1_signal_test]$ stat test.cpp 
  File: ‘test.cpp’
  Size: 2287      	Blocks: 8          IO Block: 4096   regular file
Device: fd01h/64769d	Inode: 1704012     Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1001/     shr)   Gid: ( 1001/     shr)
Access: 2023-12-01 10:47:34.720573248 +0800
Modify: 2023-12-01 10:47:34.663571756 +0800
Change: 2023-12-01 10:47:34.663571756 +0800
 Birth: -
[@shr Fri Dec 01 20:07:13 12.1_signal_test]$ ll -i test.cpp 
1704012 -rw-rw-r-- 1 shr shr 2287 Dec  1 10:47 test.cpp
[@shr Fri Dec 01 20:07:16 12.1_signal_test]$

一个有效的 inode 会记录当前文件的数据块的存放位置,即文件所占的各个数据区块的索引,如下图所示,这种数据存取方法被称为索引式文件系统(indexed allocation)

Linux文件系统(以ext2为例)_文件链接_07

当要读取文件数据时,只要拿到其 inode,即可找到所有数据存放区块的位置进行读取。

  • inode bitmap 与 block bitmap 的作用一样,inode bitmap 用来标识哪些 inode 编号已经被使用(有效),哪些 inode 编号未被使用(无效)。inode bitmap 本身是一个位图结构。
  • group descriptor table 是紧跟 super block 之后的一个区块,记录了当前 block group 的整体使用情况和状态,以及某些区块的起始地址。
  • super block 是记录整个分区(文件系统)相关信息的地方,没有 super block 就没有这个文件系统。记录的信息主要有:
  • 数据块与 inode 的总量与使用情况
  • 数据块与 inode 的大小
  • 文件系统的最近挂载时间、最近一次写入数据的时间等

使用dumpe2fs命令查看 ext2/ext3/ext4 文件系统的详细信息,使用-h选项只列出 super block 的部分:

[@shr Tue Dec 05 23:16:43 ~]$ sudo dumpe2fs -h /dev/vda1 
dumpe2fs 1.42.9 (28-Dec-2013)
Filesystem volume name:   <none>
Last mounted on:          / #上一次被挂载的位置
Filesystem UUID:          4b499d76-769a-40a0-93dc-4a31a59add28
Filesystem magic number:  0xEF53
Filesystem revision #:    1 (dynamic)
Filesystem features:      has_journal ext_attr resize_inode dir_index filetype needs_recovery extent 64bit flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
Filesystem flags:         signed_directory_hash 
Default mount options:    user_xattr acl
Filesystem state:         clean
Errors behavior:          Continue
Filesystem OS type:       Linux
Inode count:              2621440 #inode总数
Block count:              10485499 #数据区块总数
Reserved block count:     440360
Free blocks:              9580404 #空闲数据区块的数量
Free inodes:              2538435 #空闲 inode 数量
First block:              0
Block size:               4096 #每个数据块的大小
Fragment size:            4096
Group descriptor size:    64 #组描述符的大小
Reserved GDT blocks:      1019
Blocks per group:         32768 #每个 group 中数据块的总量
Fragments per group:      32768
Inodes per group:         8192 #每个 group 中 inode 的总量
Inode blocks per group:   512 #每个 group 中 inode block 的数量
Flex block group size:    16
Filesystem created:       Thu Mar  7 14:38:36 2019 #文件系统的创建时间
Last mount time:          Fri Dec 16 13:37:48 2022 #上一次被挂载的时间
Last write time:          Fri Dec 16 13:37:47 2022
Mount count:              48
Maximum mount count:      -1
Last checked:             Thu Mar  7 14:38:36 2019
Check interval:           0 (<none>)
Lifetime writes:          199 GB
Reserved blocks uid:      0 (user root)
Reserved blocks gid:      0 (group root)
First inode:              11
Inode size:	    		      256
Required extra isize:     28
Desired extra isize:      28
Journal inode:            8
First orphan inode:       26243
#…………(省略)…………

由上述信息,现在可以从系统角度理解对文件进行操作的过程:

  • 创建文件时,系统会首先找到一个空闲的 inode 并将其分配给新文件,将新文件的属性信息放到 inode 中,然后根据新文件的大小为其找到数个空闲的 data blcok,将数据放到 data block 中,inode 将 data block 的编号进行保存以便后续查找。
  • 删除文件时,系统会将其 inode 的状态置为空闲,并将其占据的所有 data block 的状态置为空闲。
  • 查找文件时,系统会根据文件的 inode 编号找到对应的 inode,并可以根据 inode 中的信息找到文件的数据存储位置。系统只认识 inode
  • 修改文件时,系统会找到文件的 inode,将新的内容信息写入到文件对应的 data block,将新的属性信息写入到 inode。在这个过程中,如果文件增大,系统可以为文件分配新的 data block。

格式化

在一个磁盘分区被使用之前,各种属性信息都要被提前规划和写入,这即是磁盘的格式化。inode 的大小和数量,data block 的大小和数量等信息都是在格式化时被确定的,且格式化后不能被修改。

格式化会将分区的所有属性信息刷新,区块都会被标记为空闲状态,在用户角度,整个分区会体现为被清空。

对目录文件的理解

上文一直在强调,文件系统识别一个文件的方式是识别其 inode,而站在用户角度,用户只关心文件名,在操作文件时也是以文件名标识一个文件的,所以系统必须可以由文件名得到其对应的文件 inode,这个工作是由文件所在的目录文件进行的。

目录文件也是文件,有自己的属性信息和数据块。目录文件的数据块存储了 “文件名 - 文件 inode” 的映射,当用户提供文件名时,系统就可以根据对应文件的目录文件中存储的映射关系,找到对应文件的 inode,进而找到文件的数据块及各种信息。

#目录文件的详细信息
[@shr Wed Dec 06 15:27:42 ~]$ stat code/
  File: ‘code/’
  Size: 4096      	Blocks: 8          IO Block: 4096   directory
Device: fd01h/64769d	Inode: 657216      Links: 8
Access: (0775/drwxrwxr-x)  Uid: ( 1001/     shr)   Gid: ( 1001/     shr)
Access: 2023-12-06 15:27:37.599832599 +0800
Modify: 2023-11-19 20:29:27.894072234 +0800
Change: 2023-11-19 20:29:27.894072234 +0800
 Birth: -

现在的问题是,找到一个文件的 inode,就需要找到其所在的目录文件,而其所在的目录文件也是一个文件,要找到这个文件对应的 inode,就要找到其所在的目录文件……如此而行,直到找到根目录时,才可以得知根目录的下级文件的 inode,进而向下回溯,即:寻找一个文件 inode 的过程其实是一个递归的过程,先递进到根目录,再回溯到目标文件所在的目录文件,并找到目标文件的 inode。

事实上,环境变量 PWD 会存储当前所在的文件路径,当在当前路径进行操作文件时,系统可以直接从根目录向下拿到文件的 inode,无需进行递归操作。同时,一些缓存的存在也会加速文件寻找的过程。

文件系统的运行

Linux内存管理概述

因为文件系统的运行与内存管理有很大的关系,所以先对内存管理进行简单的概述。

从操作系统视角来看,物理内存被划分为了一个个小区域,这个区域被称为页框,认为页框是针对内存管理的概念;从磁盘来看,每个数据块被划分为了一个个被称为页帧的小区域,认为页帧是针对磁盘数据块的概念。每个页框与页帧的大小相同,一般为 4KB,每个磁盘中的页帧被加载到内存中时,都可以恰好填入一个页框中。数据加载是以页框和页帧为基本单位的,由局部性原理,这样做可以减少 IO 次数,提高效率。

Linux文件系统(以ext2为例)_磁盘_08

作为软硬件的管理者,操作系统可以直接看到物理内存和物理地址,为了方便对物理内存进行管理,操作系统会现将上述的页框单位抽象为一个数据结构 struct page,并将这些数据结构以 struct page mem_array[] 进行组织。由此,对内存的管理,即转化成了对 mem_array[] 数组的管理,访问一块物理内存,只需要拿到对应的 page 结构体,就能找到物理页框。

/*
linux内核中的struct page
linux-3.10.1\linux-3.10.1\include\linux\mm_types.h
*/
struct page {
	/* First double word block */
	unsigned long flags;		/* Atomic flags, some possibly
					 * updated asynchronously */
	struct address_space *mapping; /* If low bit clear, points to
					 * inode address_space, or NULL.
					 * If page mapped as anonymous
					 * memory, low bit is set, and
					 * it points to anon_vma object:
					 * see PAGE_MAPPING_ANON below.
					 */
	/* Second double word */
	struct {
		union {
			/*……此处省略……*/
		};

		union {
#if defined(CONFIG_HAVE_CMPXCHG_DOUBLE) && \
	defined(CONFIG_HAVE_ALIGNED_STRUCT_PAGE)
			/* Used for cmpxchg_double in slub */
			unsigned long counters;
#else
			/*……此处省略……*/
			unsigned counters;
#endif
			struct {
				union {
				/*……此处省略……*/
					atomic_t _mapcount;
					struct { /* SLUB */
						/*……此处省略……*/
					};
					int units;	/* SLOB */
				};
				atomic_t _count;		/* Usage count, see below. */
			};
		};
	};
	/* Third double word block */
	union {
		struct list_head lru;	/* Pageout list, eg. active_list
					 * protected by zone->lru_lock !
					 */
		struct {		/* slub per cpu partial pages */
			struct page *next;	/* Next partial slab */
#ifdef CONFIG_64BIT
			int pages;	/* Nr of partial slabs left */
			int pobjects;	/* Approximate # of objects */
#else
			short int pages;
			short int pobjects;
#endif
		};
		struct list_head list;	/* slobs list of pages */
		struct slab *slab_page; /* slab fields */
	};
	/* Remainder is not double word aligned */
	union {
		unsigned long private;
    /*……此处省略……*/
#if USE_SPLIT_PTLOCKS
		spinlock_t ptl;
#endif
		struct kmem_cache *slab_cache;	/* SL[AU]B: Pointer to slab */
		struct page *first_page;	/* Compound tail pages */
	};
/*……此处省略……*/

#if defined(WANT_PAGE_VIRTUAL)
	void *virtual;			/* Kernel virtual address (NULL if
					   not kmapped, ie. highmem) */
#endif /* WANT_PAGE_VIRTUAL */
#ifdef CONFIG_WANT_PAGE_DEBUG_FLAGS
	unsigned long debug_flags;	/* Use atomic bitops on this */
#endif

#ifdef CONFIG_KMEMCHECK

	void *shadow;
#endif

#ifdef LAST_NID_NOT_IN_PAGE_FLAGS
	int _last_nid;
#endif
}

#ifdef CONFIG_HAVE_ALIGNED_STRUCT_PAGE
	__aligned(2 * sizeof(unsigned long))
#endif
;

Linux文件系统的运行

上文说道,文件被加载后,其一部分属性信息会被放在 struct file 中,但也仅仅是一部分。当文件被加载时,内存中会有一个对应的 struct inode 被构建,struct inode 会拿取文件对应的 inode 块中的信息,其中存储了文件的所有属性信息。

/*
Linux内核中的 struct file, 其中保存了 struct inode 的指针
linux-3.10.1\linux-3.10.1\include\linux\fs.h
*/
struct file {
/*……此处省略……*/
	struct path		f_path;
#define f_dentry	f_path.dentry
	struct inode		*f_inode;	/* cached value */
	const struct file_operations	*f_op;
/*……此处省略……*/
};

/*
Linux内核中的 struct inode, 其中保存了文件的所有属性信息
*/
struct inode {
	umode_t			i_mode;
	unsigned short		i_opflags;
	kuid_t			i_uid;
	kgid_t			i_gid;
	unsigned int		i_flags;

	/*……此处省略……*/
	const struct inode_operations	*i_op;
	struct super_block	*i_sb;
	struct address_space	*i_mapping;

#ifdef CONFIG_SECURITY
	void			*i_security;
#endif

	/* Stat data, not accessed from path walking */
	unsigned long		i_ino;
	/*
	 * Filesystems may only read i_nlink directly.  They shall use the
	 * following functions for modification:
	 *
	 *    (set|clear|inc|drop)_nlink
	 *    inode_(inc|dec)_link_count
	 */
	union {
		const unsigned int i_nlink;
		unsigned int __i_nlink;
	};
	dev_t			i_rdev;
	loff_t			i_size;
	struct timespec		i_atime;
	struct timespec		i_mtime;
	struct timespec		i_ctime;
	spinlock_t		i_lock;	/* i_blocks, i_bytes, maybe i_size */
	unsigned short          i_bytes;
	unsigned int		i_blkbits;
	blkcnt_t		i_blocks;

#ifdef __NEED_I_SIZE_ORDERED
	seqcount_t		i_size_seqcount;
#endif

	/* Misc */
	unsigned long		i_state;
	struct mutex		i_mutex;
	/*……此处省略……*/
	u64			i_version;
	atomic_t		i_count;
	atomic_t		i_dio_count;
	atomic_t		i_writecount;
	const struct file_operations	*i_fop;	/* former ->i_op->default_file_ops */
	struct file_lock	*i_flock;
	struct address_space	i_data;
	/*……此处省略……*/
};

在内存中,被加载的文件的所有属性信息被放在 struct inode 中,内容被放在缓冲区中。缓冲区通过一棵字典树将数据块与实际的缓冲区内存进行关联,字典树可以根据数据块相对于文件的偏移量,定位到对应的 struct page

为了解决磁盘写入速度与内存速度的巨大差异带来的效率问题,Linux 使用异步处理的方式进行磁盘数据与内存数据的同步:当系统加载一个文件后,如果该文件没有被修改过,则在内存区段的文件数据会被标记为干净的(clean),如果被修改过了,则该内存区段的文件数据会被标记为脏的(dirty),系统会不定时地将脏数据写回到磁盘,以保持磁盘与内存数据的一致性。正常关机时,关机命令会主动调用 sync 将数据写回到磁盘;如若不正常关机,由于数据未被写入到磁盘,会花很多时间进行磁盘校验,也可能导致文件系统的损坏。

Linux文件系统(以ext2为例)_Linux_09

文件链接

软链接

软链接又称符号链接(symbolic link),是一种类似 Windows 的快捷方式功能的文件。在 Linux 中,使用ln -s [linked file name] [link file name]创建软链接。

[@shr Mon Dec 25 18:57:14 doc]$ ll
total 0
-rw-rw-r-- 1 shr shr 0 Dec 25 18:50 hello
[@shr Mon Dec 25 18:57:15 doc]$ 
[@shr Mon Dec 25 18:57:15 doc]$ ln -s hello hi
[@shr Mon Dec 25 18:57:26 doc]$ ll -i
total 0
1574642 -rw-rw-r-- 1 shr shr 0 Dec 25 18:50 hello
1574643 lrwxrwxrwx 1 shr shr 5 Dec 25 18:57 hi -> hello #软链接有自己的 inode
[@shr Mon Dec 25 18:57:29 doc]$ 

如上,软链接有自己的 inode,所以属于一个独立的文件。软链接的数据块存储的是所链接文件的路径,因此软链接可以跨文件系统。可以对一个不存在的文件进行软链接,直到对应的文件被创建,才能打开这个软链接。

软链接的作用相当于快捷方式,当对软链接文件进行读写时,系统会首先拿到软链接中存储的对应文件的路径,然后根据这个路径对被链接的文件进行读写。

硬链接

硬链接(hard link)是与软链接完全不同的一种链接方式,使用ln [linked file name] [link file name] 创建硬链接。

[@shr Mon Dec 25 18:59:20 doc]$ ll
total 4
-rw-rw-r-- 1 shr shr 6 Dec 25 18:59 hello
lrwxrwxrwx 1 shr shr 5 Dec 25 18:57 hi -> hello
[@shr Mon Dec 25 19:02:25 doc]$ ln hello hihi
[@shr Mon Dec 25 19:02:47 doc]$ ll -i
total 8
1574642 -rw-rw-r-- 2 shr shr 6 Dec 25 18:59 hello
1574643 lrwxrwxrwx 1 shr shr 5 Dec 25 18:57 hi -> hello
1574642 -rw-rw-r-- 2 shr shr 6 Dec 25 18:59 hihi #与hello的inode相同
[@shr Mon Dec 25 19:03:33 doc]$ 

如上,硬链接没有自己的 inode,因此不是一个独立的文件。承上,目录文件的数据块中存储了 文件名-inode 的映射,建立硬链接,其实是在目录文件中新增了一个 文件名-已存在的文件的 inode 的映射。每个 inode 的内部都有一个引用计数,这是因为一个 inode 可以被多个文件名映射,这个引用计数即为硬链接数

Linux文件系统(以ext2为例)_文件链接_10

硬链接是与 inode 强关联的,所以硬链接不能跨文件系统。此外,所有用户都不能对目录文件进行硬链接,这是为了避免回路问题,造成文件查找时的无限递归。

Linux文件系统(以ext2为例)_ext2_11

在 linux 中,每个目录文件内都有一个 . 目录文件和一个 .. 目录文件分别代表当前目录和上级目录,这两个文件其实是分别对当前目录文件和上级目录文件的硬链接。上文说道,用户不能对目录文件进行硬链接,但是操作系统可以,并且可以控制不进入 ... 文件进行搜索,这是安全的。

承上,当建立一个空的目录文件 /tmp/doc/ 时,基本上会有三个东西:

  • /tmp/doc/
  • /tmp/doc/.
  • /tmp/doc/..

其中 /tmp/doc//tmp/doc/. 是一样的,所以一个空的目录文件的硬链接数为 2。

硬链接最大的好处就是安全。假设对一个文件进行了 10 次硬链接,如果不小心将任何一个文件删除,这个文件的 inode 与数据块仍然存在,此时可以通过另一个文件名读取到正确的文件数据。此外,无论通过哪个文件名进行编辑文件,最终的结果都会写入到 inode 与对应的区块中,因此均能对数据进行修改。

标签:文件,shr,ext2,为例,Linux,磁盘,inode,block,struct
From: https://blog.51cto.com/158SHI/8971723

相关文章

  • 1.Linux是什么与如何学习
    第1章Linux是什么与如何学习历史部分略过。1.2.5Linux的内核版本Linux的内核版本编号有点类似如下的样子:3.10.0-123.el7.x86_64主版本.次版本.发布版本-修改版本虽然编号就是如上的方式来编的,不过依据Linux内核的发展期程,内核版本的定义有点不太相同奇数、偶数版......
  • Linux收包之数据L3层是如何流转的
    一、环境说明内核版本:Linux3.10内核源码地址:https://elixir.bootlin.com/linux/v3.10/source(包含各个版本内核源码,且网页可全局搜索函数)网卡:Intel的igb网卡网卡驱动源码目录:drivers/net/ethernet/intel/igb/二、L3层概览 本章主要介绍收包的流程,在L3层是如何处理的。......
  • linux 用户注销
    1.先用w命令查看当前登录系统的用户:[root@centos~]#w11:48:09up 3:13, 2users, loadaverage:0.00,0.01,0.00USER  TTY   FROM       LOGIN@ IDLE JCPU PCPUWHATroot  pts/0  218.17.167.82  11:47  0.00s......
  • linux生成ssh的一对公钥和私钥
    1.首先进入.SSH目录中Linux中,每个用户的根目录下都有一个.ssh目录,保存了ssh相关的key和一些记录文件。例如:cd~/ll-a 2. 使用ssh-keygen生成keyssh-keygen可以生成ssh协议所需要的公钥和私钥,例如:ssh-keygen-trsa然后回提示让你输入一些文件名啥的,别管那些,一路按E......
  • linux-DNS服务器
    一、1、理解区域(zone)DNS的每一个区域都是一个域---一个区域可以管辖多个子域、2、解析正向解析:通过域名解析出ip地址反向解析:根据ip地址解析出dns名称解析过程客户端dns(host文件)本地dns区域dns服务器缓存3、部署dns服务器一般使用传统BIND软件包或者unbound、......
  • linux编译器:gcc/g++的使用
    原文连接:https://blog.csdn.net/weixin_72060925/article/details/131274627原文链接:https://blog.csdn.net/qq_65207641/article/details/128629904一、编辑器与编译器的区别vim是代码编辑器,代码编辑器的功能是让我们输入代码的。所以从这个角度出发,我们常见的记事本也可以......
  • linux&windows通过脚本下载ftp文件
    windows@echooffREM登陆ftp下载文件setftpUser=test_usersetftpPass=123456setftpIP=192.168.1.205setftpFolder=/setLocalFolder=C:/Users/Administrator/DesktopsetftpFile=%temp%/TempFTP.txt>"%ftpFile%"(echo,%ftpUser%echo,%ftpPass%......
  • linux系统安装git
    在Linux系统上安装Git可以通过包管理器进行。下面是使用不同包管理器在常见的Linux发行版上安装Git的步骤:使用apt(Debian/Ubuntu)如果您的系统使用apt包管理器,可以使用以下命令安装Git:sudoaptupdatesudoaptinstallgit使用yum(CentOS/RHEL)对于使用yum......
  • 在CentOS Linux系统上安装Docker
    安装Docker在CentOSLinux系统上的步骤如下:更新系统软件包列表:sudoyumupdate安装所需的软件包以支持Docker:sudoyuminstall-yyum-utilsdevice-mapper-persistent-datalvm2添加Docker的官方GPG密钥:sudoyum-config-manager--add-repohttps://download.docke......
  • linux进阶(一)
    1、数据库----跨服务器传输文件scproot@ip:/oafilesystembackup/oadbbak/db-20230512040001-expdp.dmp/oadbbak----单表恢复impdpquery/密码@ecologydirectory=ecologydumpfile=db-20230512040001-expdp.dmptables=ecology.uf_cw_gzb_cwignore=yremap_schema=ecology:que......