ext2.h源码分析(二)

2021SC@SDUSC 

        以下是系统调用ioctl()的操作命令,通过以下参数来对常规的系统调用进行扩充,其作用类似“补漏”,所有比较细小的、不需要专门设置一个系统调用的操作都归入ioctl。而且在对特殊设备的驱动进行适配时,也常常通过增设新的ioctl命令来实现。

#define EXT2_IOC_GETVERSION FS_IOC_GETVERSION 
#define EXT2_IOC_SETVERSION FS_IOC_SETVERSION 
#define EXT2_IOC_GETRSVSZ   _IOR('f', 5, long) 
#define EXT2_IOC_SETRSVSZ   _IOW('f', 6, long) 
#define EXT2_IOC32_GETVERSION FS_IOC32_GETVERSION//ioctl commands in 32 bit emulation 
#define EXT2_IOC32_SETVERSION FS_IOC32_SETVERSION

        磁盘上inode结构包括文件的基本信息如创建者、创建时间等等,文件的读写权限等,以及文件的时间戳:ctime指inode上一次变动的时间,mtime指文件内容上一次变动的时间,atime指文件上一次打开的时间。 

        一个inode指向一个文件,但多个文件名可以指向一个inode,文件名与inode之间的关系可以分为硬链接和软连接两种。硬链接是对原文件的inode的备份,删除一个文件名不会影响另一个文件名;而软连接是一个文件名指向另一个文件名的路径,当被依赖的文件名被删除时,就会造成访问失败。

struct ext2_inode {
	__le16	i_mode;		/* File mode */
	__le16	i_uid;		/* Low 16 bits of Owner Uid */
	__le32	i_size;		/* Size in bytes */
	__le32	i_atime;	/* Access time */
	__le32	i_ctime;	/* Creation time */
	__le32	i_mtime;	/* Modification time */
	__le32	i_dtime;	/* Deletion Time */
	__le16	i_gid;		/* Low 16 bits of Group Id */
	__le16	i_links_count;	/* Links count */
	__le32	i_blocks;	/* Blocks count */
	__le32	i_flags;	/* File flags */
	union {
		struct {
			__le32  l_i_reserved1;
		} linux1;
		struct {
			__le32  h_i_translator;
		} hurd1;
		struct {
			__le32  m_i_reserved1;
		} masix1;
	} osd1;				
	__le32	i_block[EXT2_N_BLOCKS];
	__le32	i_generation;	
	__le32	i_file_acl;	
	__le32	i_dir_acl;	
	__le32	i_faddr;	
	union {
		struct {
			__u8	l_i_frag;	
			__u8	l_i_fsize;	
			__u16	i_pad1;
			__le16	l_i_uid_high;	
			__le16	l_i_gid_high;	
			__u32	l_i_reserved2;
		} linux2;
		struct {
			__u8	h_i_frag;	
			__u8	h_i_fsize;	
			__le16	h_i_mode_high;
			__le16	h_i_uid_high;
			__le16	h_i_gid_high;
			__le32	h_i_author;
		} hurd2;
		struct {
			__u8	m_i_frag;	
			__u8	m_i_fsize;	
			__u16	m_pad1;
			__u32	m_i_reserved2[2];
		} masix2;
	} osd2;				
};

        这是mount()系统调用的参数,mount是挂载文件系统的函数,文件系统只有被挂载才能使用。

#define EXT2_MOUNT_OLDALLOC	        0x000002
#define EXT2_MOUNT_GRPID	        0x000004
#define EXT2_MOUNT_DEBUG	        0x000008
#define EXT2_MOUNT_ERRORS_CONT		0x000010 
#define EXT2_MOUNT_ERRORS_RO		0x000020
#define EXT2_MOUNT_ERRORS_PANIC		0x000040 
#define EXT2_MOUNT_MINIX_DF		0x000080  
#define EXT2_MOUNT_NOBH			0x000100 
#define EXT2_MOUNT_NO_UID32		0x000200 
#define EXT2_MOUNT_XATTR_USER		0x004000  
#define EXT2_MOUNT_POSIX_ACL		0x008000 
#define EXT2_MOUNT_XIP			0x010000  
#define EXT2_MOUNT_USRQUOTA		0x020000  
#define EXT2_MOUNT_GRPQUOTA		0x040000  
#define EXT2_MOUNT_RESERVATION		0x080000  
#define EXT2_MOUNT_DAX			0x100000  
#define clear_opt(o, opt)		o &= ~EXT2_MOUNT_##opt
#define set_opt(o, opt)			o |= EXT2_MOUNT_##opt
#define test_opt(sb, opt)		(EXT2_SB(sb)->s_mount_opt & \ EXT2_MOUNT_##opt)
#define EXT2_DFL_MAX_MNT_COUNT		20	
#define EXT2_DFL_CHECKINTERVAL		0	
#define EXT2_ERRORS_CONTINUE		1	
#define EXT2_ERRORS_RO			2	
#define EXT2_ERRORS_PANIC		3	
#define EXT2_ERRORS_DEFAULT		EXT2_ERRORS_CONTINUE

        每个文件系统都有一个超级块结构,超级块是文件系统用于记录和管理信息的地方,当磁盘文件系统被挂载到操作系统上时,超级块也会被读入内存中生成新的超级块。利用内存中的超级块,可以找到各个文件所对应的inode。

struct ext2_super_block {
	__le32	s_inodes_count;	
	__le32	s_blocks_count;		
	__le32	s_r_blocks_count;	
	__le32	s_free_blocks_count;	
	__le32	s_free_inodes_count;
	__le32	s_first_data_block;	
	__le32	s_log_block_size;	
	__le32	s_log_frag_size;	
	__le32	s_blocks_per_group;	
	__le32	s_frags_per_group;	
	__le32	s_inodes_per_group;	
	__le32	s_mtime;		
	__le32	s_wtime;		
	__le16	s_mnt_count;		
	__le16	s_max_mnt_count;	
	__le16	s_magic;		
	__le16	s_state;		
	__le16	s_errors;		
	__le16	s_minor_rev_level; 	
	__le32	s_lastcheck;		
	__le32	s_checkinterval;	
	__le32	s_creator_os;		
	__le32	s_rev_level;		
	__le16	s_def_resuid;		
	__le16	s_def_resgid;		
	__le32	s_first_ino; 	
	__le16   s_inode_size; 	
	__le16	s_block_group_nr; 
	__le32	s_feature_compat; 
	__le32	s_feature_incompat; 
	__le32	s_feature_ro_compat; 	
	__u8	s_uuid[16];		
	char	s_volume_name[16]; 
	char	s_last_mounted[64]; 
	__le32	s_algorithm_usage_bitmap;
	__u8	s_prealloc_blocks;
	__u8	s_prealloc_dir_blocks;
	__u16	s_padding1;
        __u8	s_journal_uuid[16];
	__u32	s_journal_inum;	
	__u32	s_journal_dev;	
	__u32	s_last_orphan;		
	__u32	s_hash_seed[4];		
	__u8	s_def_hash_version;	
	__u8	s_reserved_char_pad;
	__u16	s_reserved_word_pad;
	__le32	s_default_mount_opts;
 	__le32	s_first_meta_bg; 	
	__u32	s_reserved[190];	
};

        修订级别,可以确定文件系统是否支持只有在这种文件系统特定修订下才有的特性,即兼容性,是否支持新的特征。
#define EXT2_GOOD_OLD_REV 0 /* The good old (original) format */
#define EXT2_DYNAMIC_REV 1  /* V2 format w/ dynamic inode sizes */
#define EXT2_CURRENT_REV EXT2_GOOD_OLD_REV
#define EXT2_MAX_SUPP_REV EXT2_DYNAMIC_REV
#define EXT2_GOOD_OLD_INODE_SIZE 128

       dentry是文件的逻辑属性,它指向的是文件的inode而非其在磁盘上的物理地址,只存在于内存中,是为了提高查找速度而后设计的。如下所示,一个有效的dentry结构必定有一个inode结构,所有的dentry结构组成了完整的目录树。 ext2_dir_entry_2是较新的版本。

 

struct ext2_dir_entry {
	__le32	inode;			/* Inode number */
	__le16	rec_len;		/* Directory entry length */
	__le16	name_len;		/* Name length */
	char	name[];			/* File name, up to EXT2_NAME_LEN */
};
struct ext2_dir_entry_2 {
	__le32	inode;		
	__le16	rec_len;		
	__u8	name_len;		
	__u8	file_type;
	char	name[];			
};

         从磁盘读入的索引节点中的信息是原始的、未加工的,称为raw_inode。而内存中的索引节点分为两部分,一部分属于VFS层,适用于所有的文件系统;另一部分属于具体的某个文件系统类型,如下所示。

        在ext2_inode_info结构中i_data[15]是最重要的数据,其中存放着一些指针,直接或间接的指向磁盘中存储该文件内容的所有块,指针共有15项,前12个为直接指针,后三个分别为“一次间接指针”、“二次间接指针”、“三次间接指针”。

struct ext2_inode_info {
	__le32	i_data[15];
	__u32	i_flags;
	__u32	i_faddr;
	__u8	i_frag_no;
	__u8	i_frag_size;
	__u32	i_file_acl; __u16 i_state;
	__u32	i_dir_acl;
	__u32	i_dtime;
	__u32	i_block_group;
	struct ext2_block_alloc_info *i_block_alloc_info;
	__u32	i_dir_start_lookup;
#ifdef CONFIG_EXT2_FS_XATTR
	struct rw_semaphore xattr_sem;
#endif
	rwlock_t i_meta_lock;
	struct mutex truncate_mutex;
	struct inode	vfs_inode;
	struct list_head i_orphan;	
#ifdef CONFIG_QUOTA
	struct dquot *i_dquot[MAXQUOTAS];
#endif
};

        之后的代码都是具体的文件操作方法的原型,例如inode的读写、新节点的分配等等。之后分析其具体实现方法。

extern int ext2_bg_has_super(struct super_block *sb, int group);
extern unsigned long ext2_bg_num_gdb(struct super_block *sb, int group);
extern ext2_fsblk_t ext2_new_block(struct inode *, unsigned long, int *);
extern ext2_fsblk_t ext2_new_blocks(struct inode *, unsigned long,
				unsigned long *, int *);
extern int ext2_data_block_valid(struct ext2_sb_info *sbi, ext2_fsblk_t start_blk,
				 unsigned int count);

                ......

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值