1Linux文件管理及目录操作21、Linux文件系统管理31.1Linux下VFS虚拟文件系统所谓VFS就是虚拟文件系统(VirtualFileSystemSwitch)。VFS的作用就是采用标准的Unix系统调用读写位于不同物理介质上的不同文件系统。VFS是一个可以让open()、read()、write()等系统调用不用关心底层的存储介质和文件系统类型就可以工作的粘合层。4而在Linux下,通过VFS,一个抽象的通用访问接口屏蔽了底层文件系统和物理介质的差异性。每一种类型的文件系统代码都隐藏了实现的细节。因此,对于VFS层和内核的其它部分而言,每一种类型的文件系统看起来都是一样的。5VFS虚拟文件系统UsrorsystemprogramsViismvrmfilestringscattouchFileorientedsystemcallsOpen()read()write()close()VFSabstractionlayerExt2/ext3FATNFSMinix61.2ext2文件系统结构对于一个磁盘分区来说,其被指定为相应的文件系统后,整个分区被分为1024、2048和4096字节大小的块。根据块使用的不同,可以分为:1、超级块2、Inode块3、数据块7超级块1、是整个文件系统的第一块空间。启动Unix操作系统后,发现某个文件系统无法使用,很有可能就是超级块出现了问题。为什么这个超级块有这么大的作用呢?主要是因为在超级块中保存了全局文件信息,如硬盘已用空间、数据块可用空间、inode结点信息等等。2、当操作系统启动后,系统内核会把超级块中的内容复制到内存中,并周期性的利用内存里的最新内容去更新硬盘上的超级块中的内容。8Ionde块Inode块中保存了一个文件系统中的全部Inode节点。也就是说,当系统创建了一个文件(或者添加了一个新设备)时,系统就会从这个块中给这个文件分配一个Inode结点。Ionde块是文件系统的索引,它是文件系统的最其本单元,是文件系统连接任何子目录、任何文件的桥梁。每个子目录和文件只有唯一的一个Inode块。它包括了文件系统中文件基本属性、存放数据的位置等相关信息。9数据块具体存放数据的位置区域。为了提高目录访问效率,Linux还维护了表达路径与Inode对应关系的dentry结构。它描述了路径信息并连接到节点Inode,它包括各种目录信息,还指向了Inode和超级块。101.3超级块结构超级块是用来描述整个文件系统信息的全局数据结构。超级块对象super_block结构体来表示,定义在文件linux/fs.h中,其数据结构在内核中的定义如下:11超级块结构structsuper_block{structlist_heads_list;/*指向超级块链表的指针*/dev_ts_dev;/*设备标识符*/unsignedlongs_blocksize;/*以字节为单位的块大小*/unsignedlongs_old_blocksize;/*以位为单位的旧的块大小*/unsignedchars_blocksize_bits;/*以位为单位的块大小*/unsignedchars_dirt;/*修改脏标志*/unsignedlonglongs_maxbytes;/*文件大小上限*/structfile_system_types_type;/*文件系统类型*/structsuper_operationss_op;/*超级块方法*/structdquot_operations*dq_op;/*磁盘限额方法*/structquotactl_ops*s_qcop;/*限额控制方法*/structexport_operations*s_export_op;/*到处方法*/unsignedlongs_flags;/*挂载标志*/unsignedlongs_magic;/*文件系统魔数*/structdentry*s_root;/*目录挂载点*/structrw_semaphores_umount;/*卸载信号量*/12超级块结构structsemaphores_lock;/*超级块信号量*/ints_count;/*引用计数*/ints_syncing;/*文件系统同步标志*/ints_need_sync_fs;/*尚未同步标志*/atomic_ts_active;/*活动引用计数*/void*s_security;/*安全模块*/structlist_heads_dirty;/*脏节点链表*/structlist_heads_io;/*回写链表*/structhlist_heads_anon;/*匿名目录项*/structlist_heads_files;/*被分配文件链表*/structblock_device*s_bdev;/*相关块设备*/structlist_heads_instances;/*该类型文件系统*/structquota_infos_dquot;/*限额相关选项*/chars_id[32];/*文本名字*/void*s_fs_info;/*文件系统特殊信号*/structsemaphores_vfs_rename_sem;/*重命名信号量*/};13魔数所谓魔数和魔字符串就是在代码中直接使用某一个数字或者字符串,而不是常量。譬如一个很简单的根据职位计算薪水的方法:intgetSalary(Stringtitle,intgrade){if(Programmer.equals(title))returngrade*500+700;elseif(Tester.equals(title))returngrade*500+800;elseif(Analyst.equals(title))returngrade*800+1000;}在这个方法里面,Programmer,Tester和Analyst是所谓的魔字符串(MagicString),而500,700,800和1000就是所谓的魔数(MagicNumber)了。141.4dentry结构Dentry表示一个目录或路径中的一个分量,其目的是加快文件访问效率。其数据结构在内核中的定义如下:15dentry结构structdentry{atomic_td_count;/*使用记数*/unsignedlongd_vfs_flags;/*目录缓存标志*/spinlock_td_lock;/*单目录项锁*/structinode*d_inode;/*相关索引及诶但*/structlist_headd_lru;/*未使用链表*/structlist_headd_child;/*副目录中目录项对象的链表*/structlist_headd_subdirs;/*子目录*/structlist_headd_alias;/*索引节点的别名链表*/unsignedlongd_time;/*重新声响的时间*/structdentry_operations*d_op;/*目录项操作表*/structsuper_block*d_sb;/*文件超级块*/unsignedintd_flags;/*目录项标识*/intd_mounted;/*可能是登陆点的目录项*/16dentry结构void*d_fsdata;/*文件系统特殊的数据*/structrcu_headd_rcu;/*RCU锁*/structdcookie_struct*d_cookie;/*cookie*/structdentry*d_parent;/*父目录的目录项对象*/structqstrd_name;/*目录项的名字?*/structhlist_noded_hash;/*散列表*/structhlist_head*d_bucket;/*散列表头*/unsignedchard_iname[DNAME_INLINE_LEN_MIN];/*短文件名*/};171.5Inode结构每个文件由两部分组成:一部份是Inode,另一部份是Block。Block用来存储数据。Inode用来存储数据索引信息,信息包括文件大小、属主、归属的用户组、读写权限等。操作系统根据用户指令,通过Inode值就能很快找到相对应的文件。18Inode结构structinode{structhlist_nodei_hash;/*哈希表*/structlist_headi_list;/*索引节点链表*/structlist_headi_dentry;/*目录项链表*/unsignedlongi_ino;/*节点号*/atomic_ti_count;/*引用记数*/umode_ti_mode;/*访问权限控制*/unsignedinti_nlink;/*硬链接数*/uid_ti_uid;/*使用者id*/gid_ti_gid;/*使用者id组*/kdev_ti_rdev;/*实设备标识符*/loff_ti_size;/*以字节为单位的文件大小*/structtimespeci_atime;/*最后访问时间*/structtimespeci_mtime;/*最后修改(modify)时间*/structtimespeci_ctime;/*最后改变(change)时间*/unsignedinti_blkbits;/*以位为单位的块大小*/19Inode结构unsignedlongi_blksize;/*以字节为单位的块大小*/unsignedlongi_version;/*版本号*/unsignedlongi_blocks;/*文件的块数*/unsignedshorti_bytes;/*使用的字节数*/spinlock_ti_lock;/*自旋锁*/structrw_semaphorei_alloc_sem;/*索引节点信号量*/structinode_operations*i_op;/*索引节点操作表*/structfile_operations*i_fop;/*默认的索引节点操作*/structsuper_block*i_sb;/*相关的超级块*/structfile_lock*i_flock;/*文件锁链表*/structaddress_space*i_mapping;/*相关的地址映射*/structaddress_spacei_data;/*设备地址映射*/structdquot*i_dquot[MAXQUOTAS];/*节点的磁盘限额*/structlist_headi_devices;/*块设备链表*/structpipe_inode_info*i_pipe;/*管道信息*/……};201.6数据块及文件数据块包含了真正的数据内容Type:dData:6417suzeL1024User:0Group:0Type:fData:9041Size:21User:0Group:0Link:2ThisisthefileXyzName...XyzAbcInode36941383918391Inode3694Data6417Inode8391Data904121数据块结构structfile{structlist_headf_list;//file链表structdentry*f_dentry;//文件的denty结构structvfsmount*f_vfsmnt;//文件系统挂载信息structfile_operations*f_op;//使用文件操作结构atomic_tf_count;//使用此结构的进程数unsignedintf_flags;//文件标志mode_tf_mode;//文件的打开模式intf_error;//loff_tf_pos;//文件操作指针的当前位置structfown_structf_owner;//文件拥有者unsignedintf_uid,f_gid;//文件的uid,gid……};222、Linux文件及目录管理操作232.1读取文件属性在对文件执行相应操