Yan.G WebServer Dev Engineer

linux file

2018-02-09

linux 文件系统

inode 和 block 概述#

  • 文件是存储在硬盘上的,硬盘的最小存储单位叫做扇区sector,每个扇区存储512字节。
  • 操作系统读取硬盘的时候,不会一个个扇区地读取,这样效率太低,而是一次性连续读取多个扇区,即一次性读取一个块block。
  • 这种由多个扇区组成的块,是文件存取的最小单位。块的大小,最常见的是4KB,即连续八个sector组成一个block。
  • 文件数据存储在块中,那么还必须找到一个地方存储文件的元信息,比如文件的创建者、文件的创建日期、文件的大小等等。
  • 这种存储文件元信息的区域就叫做inode,中文译名为索引节点,也叫i节点。因此,一个文件必须占用一个inode,但至少占用一个block。
  • 数据 → block

元信息 → inode

inode包含很多的文件元信息,但不包含文件名,例如:字节数、属主UserID、属组GroupID、读写执行权限、时间戳等。 而文件名存放在目录当中,但Linux系统内部不使用文件名,而是使用inode号码识别文件。对于系统来说文件名只是inode号码便于识别的别称。

  • 表面上,用户通过文件名打开文件,实际上,系统内部将这个过程分为三步:
    • 1.系统找到这个文件名对应的inode号码;
    • 2.通过inode号码,获取inode信息;
    • 3.根据inode信息,看用户是否具有访问的权限,有就指向对应的数据block,没有就返回权限拒绝。
  • 文件名也就是文件一个链接
  • 移动文件或重命名文件,只是改变文件名,不影响inode号码;
  • 打开一个文件以后,系统就以inode号码来识别这个文件,不再考虑文件名。
  • 所以文件名称不出来可以直接用 inode 删除
find ./* -inum 节点号 -delete
  • 软件可以平滑热更,因为系统通过inode号码,识别运行中的文件,不通过文件名。更新的时候,新版文件以同样的文件名,生成一个新的inode,不会影响到运行中的文件。等到下一次运行这个软件的时候,文件名就自动指向新版文件,旧版文件的inode则被回收。
  • 删除一个文件系统是根据inode 的引用次数判断是否删除,如果有程序在使用,系统就不会删除

查看 inode 信息

ls -i /etc/passwd
1082273 /etc/passwd

stat /etc/passwd

$ stat /etc/passwd
  文件:"/etc/passwd"
  大小:1218      	块:8          IO 块:4096   普通文件
设备:fd01h/64769d	Inode:1082273     硬链接:1
权限:(0644/-rw-r--r--)  Uid:(    0/    root)   Gid:(    0/    root)
最近访问:2020-06-23 17:31:01.074532572 +0800
最近更改:2020-05-12 17:30:27.045004616 +0800
最近改动:2020-05-12 17:30:27.047004684 +0800
创建时间:-
  • inode也会消耗硬盘空间,所以格式化的时候,操作系统自动将硬盘分成两个区域。一个是数据区,存放文件数据;
  • 另一个是inode区,存放inode所包含的信息。每个inode的大小,一般是128字节或256字节。通常情况下不需要关注单个inode的大小,而是需要重点关注inode总数。inode总数在格式化的时候就确定了
  • 因为inode 的数量是固定的,所以服务器要对磁盘做限额,被攻击了,服务就运行不了了
df -h /data/www
## 可以查询哪些文件比较占用空间
df -hT /data/www/
文件系统       类型  容量  已用  可用 已用% 挂载点
/dev/vda1      ext4   40G   34G  3.3G   92% /

df -i /data/www 
## 可以查看节点占用
文件系统         Inode 已用(I) 可用(I) 已用(I)% 挂载点
/dev/vda1      2621440  513465 2107975      20% /

inode 定义

struct inode {
	/* RCU path lookup touches following: */
	umode_t			i_mode;     //权限
	uid_t			i_uid;      //用户id
	gid_t			i_gid;      //组id
	const struct inode_operations	*i_op;
	struct super_block	*i_sb;
 
	spinlock_t		i_lock;	/* i_blocks, i_bytes, maybe i_size */
	unsigned int		i_flags;
	struct mutex		i_mutex;
 
	unsigned long		i_state;
	unsigned long		dirtied_when;	/* jiffies of first dirtying */
 
	struct hlist_node	i_hash;
	struct list_head	i_wb_list;	/* backing dev IO list */
	struct list_head	i_lru;		/* inode LRU list */
	struct list_head	i_sb_list;
	union {
		struct list_head	i_dentry;
		struct rcu_head		i_rcu;
	};
	unsigned long		i_ino;   //inode节点号
	atomic_t		i_count;
	unsigned int		i_nlink;
	dev_t			i_rdev;
	unsigned int		i_blkbits;
	u64			i_version;
	loff_t			i_size;   //文件大小
#ifdef __NEED_I_SIZE_ORDERED
	seqcount_t		i_size_seqcount;
#endif
	struct timespec		i_atime;  //最后一次访问(access)的时间
	struct timespec		i_mtime;  //最后一次修改(modify)的时间
	struct timespec		i_ctime;  //最后一次改变(change)的时间
	blkcnt_t		i_blocks;    //块数
	unsigned short          i_bytes;
	struct rw_semaphore	i_alloc_sem;
	const struct file_operations	*i_fop;	/* former ->i_op->default_file_ops */
	struct file_lock	*i_flock;
	struct address_space	*i_mapping;   //块地址映射
	struct address_space	i_data;
#ifdef CONFIG_QUOTA
	struct dquot		*i_dquot[MAXQUOTAS];
#endif
	struct list_head	i_devices;
	union {
		struct pipe_inode_info	*i_pipe;
		struct block_device	*i_bdev;
		struct cdev		*i_cdev;
	};
 
	__u32			i_generation;
 
#ifdef CONFIG_FSNOTIFY
	__u32			i_fsnotify_mask; /* all events this inode cares about */
	struct hlist_head	i_fsnotify_marks;
#endif
 
#ifdef CONFIG_IMA
	atomic_t		i_readcount; /* struct files open RO */
#endif
	atomic_t		i_writecount;
#ifdef CONFIG_SECURITY
	void			*i_security;
#endif
#ifdef CONFIG_FS_POSIX_ACL
	struct posix_acl	*i_acl;
	struct posix_acl	*i_default_acl;
#endif
	void			*i_private; /* fs or device private pointer */
}

可以查看 文件信息

file /etc/passwd

/etc/passwd: ASCII text

下一篇 linux file sort

Content