Linux操作系统下的NTFS_第1页
Linux操作系统下的NTFS_第2页
Linux操作系统下的NTFS_第3页
Linux操作系统下的NTFS_第4页
Linux操作系统下的NTFS_第5页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、一、文件系统在操作系统中,文件系统用来组织、管理计算机中的所有文件,对文件存储器空间进行组织和分配,为用户提供文件的操作手段和存取控制。文件系统由三部分组成:与文件管理有关的软件、被管理的文件以及实施文件管理所需的数据结构。文件系统隐藏了系统中最为复杂的硬件设备特性,为用户及操作系统的其他子系统提供一个统一、简洁的接口。通过文件系统,用户可以方便地建立文件,存入、读出、修改、转储文件,控制文件的存取,当用户不再使用时撤销文件等。不同类型的操作系统可能使用不同类型的文件系统,比如DOS系统使用的是FAT12或者FAT16文件系统、Windows 2000/XP使用的是FAT32文件系统,Wind

2、ows NT使用的是NTFS文件系统。通常情况下,不同类型的操作系统由于实现方法的不同,它们的文件系统之间一般不能相互访问。二、Linux文件系统在Linux中,每个分区都是一个文件系统,都有自己的目录层次结构。Linux的一个重要特征就是支持多种不同类型的逻辑文件系统。如Minix、CramFS、Ext2、Ext3、RamFS、RomFS、NFS、FAT12、FAT16、FAT32、NTFS、SysV、ReiserFS等。几乎所有的逻辑文件系统都可以运行在Linux下使用。Linux之所以能够支持多种不同的逻辑文件系统类型,是因为它采用了虚拟文件系统(VFS)机制。VFS作为各种逻辑文件系统

3、与操作系统其他模块的接口,将不同逻辑文件系统的的实现细节隐藏起来,从而对操作系统的其他模块和应用程序而言,所有的逻辑文件系统都是一样的。VFS之所以能衔接各种不同类型的逻辑文件系统,是因为它定义了各种逻辑文件系统都支持的基本抽象接口和数据结构,同时各种逻辑文件系统也将自己的诸如“文件如何打开”“目录如何定义”等概念在形式上与VFS的定义保持一致。三、虚拟文件系统VFS虚拟文件系统(VFS)是Linux内核的一个子系统,提供了一个通用文件系统模型,该通用模型概括了各种文件系统的一般特性和行为,并为内核其他子系统和应用程序提供一致性的文件系统接口。虚拟文件系统(VFS)位于文件系统的最上层,管理各

4、种逻辑文件系统,并屏蔽它们之间的差异。就用户使用角度而言,完全觉察不到各种逻辑文件系统的差异,进而可以使用同样的命令或操作来管理不同逻辑文件系统下的文件。同时,虚拟文件系统采用内存节点缓冲区、内存目录项缓冲区、数据块缓冲区等方法,减少对外部设备频繁的I/O操作,从而提高系统性能。图3-1演示了Linux文件系统的层次结构。图3-1 Linux文件系统的层次模型虚拟文件系统VFS模型由下列4个对象类型组成。1)超级块(super_block)对象:存放已安装文件系统的有关信息。对于基于磁盘文件的文件系统,这类对象通常对应于存放在磁盘上的文件系统控制块。每一个逻辑文件系统都对应一个超级块对象。2)

5、索引节点(inode)对象:存放关于具体文件的一般信息。对基于磁盘的文件系统,这类对象通常对应于存放在磁盘上的文件控制块。每个索引节点对象都有一个索引节点号,这个索引节点号唯一地标识文件系统中的文件。在逻辑文件系统中,每一个文件都对应一个inode对象。3)目录项(dentry)对象:存放目录项(也就是文件的特定名称)与对应文件进行链接的各种信息。每个磁盘文件系统都以自己特有的方式将该类信息存在磁盘上。4)文件(file)对象:代表进程已打开的一个文件。存放已打开的文件与进程之间进行交互的信息,这些信息仅当进程访问文件期间才存于主存中。文件对象在执行系统调用open()时创建,在执行系统调用c

6、lose()时撤销。每一个对象都包含一个operation对象,它描述了内核针对各对象可以使用的方法,这些operation对象分别是super_operation对象、inode_operation对象、dentry_operation对象、file_operation对象。1超级块对象当内核对一个逻辑文件系统进行初始化和注册时,调用文件系统提供的函数为其分配一个VFS超级块,并从磁盘文件读取逻辑文件系统超级块中的信息填充进来。也就是说,VFS超级块是各个逻辑文件系统安装时才建立的,并在这些逻辑文件系统卸载时被自动删除,可见VFS超级块仅存在于主存中。VFS超级块的数据结构如下。struct

7、 super_blockstruct list_head s_list; /指向超级块链表的指针kdev_t s_dev; /文件系统所在设备的标识符unsigned long s_blocksize; /以字节为单位的盘块大小 unsigned long s_old_blocksizes /基本块设备驱动程序中提到的以字节为单位的块大小unsigned char s_blocksize_bits; /以2的幂次表示的盘块的大小unsigned long long s_maxbytes; /文件大小上限unsigned char s_dirt; /修改(脏)标志struct file_syst

8、em_type * s_type; /文件系统类型,指向file_system_type结构的指针struct super_operations * s_op; /超级块方法,指向超级块操作函数集的指针 struct dquot_operations * dq_op; /磁盘限额处理方法 struct quotactl_ops * s_qcop; /磁盘限额管理方法 struct export_operations s_export_op; /网络文件系统使用的输出操作unsigned long s_flags; /安装标志unsigned long s_magic; /文件系统的魔数stru

9、ct dentry * s_root; /指向根目录的目录项对象的指针struct rw_semaphore s_umount; /卸载信号量struct semaphore s_lock; /超级块信号量int s_count; /超级块引用计数 int s_syncing; /表示对超级块的索引节点进行同步的标志int s_need_sync_fs; /表示对超级块的已安装文件系统进行同步的标志atomic_t s_active; /刺激引用计数器void * s_security; /指向超级块安全数据结构的指针struct xattr_handler * s_xattr; /指向超级块

10、扩展属性结构的指针struct list_head s_inodes; /所有索引节点的链表struct list_head s_dirty; /脏节点Inode链表struct list_head s_io; /等待被写入磁盘的索引节点链表struct hlist_head s_anon; /用于处理远程网络文件系统的匿名目录项的链表 struct list_head s_files; /文件对象的链表 struct block_device * s_bdev; /指向块设备驱动程序描述符的指针struct list_head s_instances; /用于给定文件系统类型的超级块对象链表

11、的指针struct quota_info s_dquot; /磁盘限额描述符int s_frozen; /冻结文件系统时使用的标志(强制置于一致状态)wait_queue_head_t s_wait_unfrozen;/进程挂起的等待队列,直到文件系统被解冻 char s_id; /包含超级块的块设备名称void * s_fs_info; /指向特定文件系统的超级块信息的指针 struct semaphore s_vfs_rename_sem; /当VFS通过目录重命名文件时使用的信号量u32 s_time_gran; /时间戳的粒度(纳秒级)该结构中的成员s_fs_info是实现支持多文件系

12、统的关键,它指向Linux所支持的各种逻辑文件系统超级块的特有信息。例如当安装Ext2文件系统时,s_fs_info将指向一个ext2_sb_info结构,ext2_sb_info结构包含了Ext2文件系统超级块的特有信息。超级块操作对象的数据结构如下。struct super_operationsstruct inode * (* alloc_inode)(struct super_block * sb); /为索引节点对象分配空间,包括具体文件系统的数据所需要的空间。void (* write_super)(struct super_block * super); /用指定对象的内容更新文

13、件系统的超级块。void (* put_super)(struct super_block * super); /释放通过传递的参数指定的超级块对象(因为相应的文件系统被卸载)。void (* read_inode)(struct inode * inode); /用磁盘上的数据填充以参数传递过来的索引节点对象的字段;索引节点对象的i_ino字段标识从磁盘上要读取的具体文件系统的索引节点。void (* dirty_inode)(struct inode * inode); /当索引节点标识为修改(脏)时调用。void (* write_inode)(struct inode * inode,

14、 int flag); /用通过传递参数指定的索引节点对象的内容更新一个文件系统的索引节点。索引节点对象的i_ino字段标识所涉及磁盘上文件系统的索引节点。flag参数表示I/O操作是否同步。void (* put_inode)(struct inode *); /释放索引节点时调用(减少该节点引用计数器值)以执行具体文件系统操作。void (* delete_inode)(struct inode *); /在必须撤销索引节点时调用。删除内存中的VFS索引节点和磁盘上的文件数据及元数据。2索引节点对象文件系统处理文件所需要的所有信息都放在一个名为索引节点的数据结构中。文件名可以随时更改,但是

15、索引节点对文件是唯一的,并且随文件的存在而存在。内存中的索引节点对象由一个inode数据结构组成,其字段如表3-1所示。表3-1 索引节点对象的字段类型字段说明struct hlist_nodei_hash用于散列链表的指针struct list_headi_list用于描述索引节点当前状态的链表的指针struct list_headi_sb_list用于超级块的索引节点链表的指针struct list_headi_dentry引用索引节点的目录项对象链表的头unsigned longi_ino索引节点号atomic_ti_count引用计数器umode_ti_mode文件类型与访问权限uns

16、igned inti_nlink硬链接数目uid_ti_uid所有者标识符gid_ti_gid组标识符dev_ti_rdev实设备标识符loff_ti_size文件的字节数struct timespeci_atime上次访问文件的时间struct timespeci_mtime上次写文件的时间struct timespeci_ctime上次修改索引节点的时间unsigned inti_blkbits块的位数unsigned longi_blksize块的字节数unsigned longi_version版本号(每次使用后自动递增)unsigned longi_blocks文件的块数unsign

17、ed shorti_bytes文件中最后一个块的字节数unsigned chari_sock如果文件是一个套接字则为非零spinlock_ti_lock保护索引节点一些字段的自旋锁struct semaphorei_sem索引节点信号量struct rw_semaphorei_alloc_sem在直接I/O文件操作的避免出现竞争条件的读/写信号量struct inode_operations *i_op索引节点的操作struct file_operations *i_fop缺省文件操作struct super_block *i_sb指向超级块的指针struct file_lock *i_flo

18、ck指向文件锁链表的指针struct address_space *i_mapping指向address_space对象的指针struct address_spacei_data文件的address_space对象struct dquot * i_dquot索引节点磁盘限符struct list_headi_devices用于具体的字符或块设备索引节点链表的指针struct pipe_inode_info *i_pipe如果文件是一个管道则使用它struct block_device *i_bdev指向块设备驱动程序的指针struct cdevice *i_cdev指向字符设备驱动程序的指针I

19、nti_cindex拥有一组次设备号的设备文件的索引_ _u32i_generation索引节点版本号(由某些文件系统使用)unsigned longi_dnotify_mask目录通知事件的位掩码struct dnotify_mask *i_ dnotify用于目录通知unsigned longi_state索引节点的状态标志unsigned longdirtied_when索引节点的弄脏时间(以节拍为单位)unsigned inti_flags文件系统的安装标志atomic_ti_writecount用于写进程的引用计数器void *i_security指向索引节点安全结构的指针void

20、*u.generic_ip指向私有数据的指针seqcount_ti_size_seqcountSMP系统为i_size字段获取一致值时使用的顺序计数器与索引节点对象关联的方法也叫索引节点操作,它们由inode_operations结构来描述,该结构的地址存放在i_op字段中。struct inode_operationscreate(dir, entry, mode, nameidata) /在某个目录下,为与目录项对象相关的普通文件创建一个新的磁盘索引节点lookup(dir, dentry, nameidata) /为包含在一个目录项对象中的文件名对应的索引节点查找目录link(old_d

21、entry, dir, new_dentry) /创建一个新的名为new_dentry的硬链接,它指向dir目录下名为old_dentry的文件unlink(dir, dentry) /从一个目录中删除目录项对象所指定文件的硬链接symlink(dir, dentry, symname) /在某个目录下,为与目录项对象相关的符号链接创建一个新的索引节点mkdir(dir, dentry, mode) /在某个目录下,为与目录项对象相关的目录创建一个新的索引节点rmdir(dir, dentry) /从一个目录中删除子目录,子目录的名称包含在目录项对象中mknod(dir, dentry, mo

22、de, rdev) /在某个目录中为与目录项对象相关的特定文件创建一个新的磁盘索引节点。其中的参数mode和rdev分别表示文件的类型和设备的主次设备号rename(old_dir, old_dentry, new_dir, new_dentry) /将old_dir目录下由old_dentry标识的文件移到new_dir目录下。文件名包含在new_dentry指向的目录项对象中readlink(dentry, buffer, buflen) /将目录项所指定的符号链接中对应的文件路径名拷贝到buffer所指定的用户态内存区follow_link(inode, nameidata) / 解析索

23、引节点对象所指定的符号链接,如果该符号链接是一个相对路径名,则从第二个参数所指定的目录开始进行查找put_link(dentry, nameidata) /释放由follow_link方法分配的用于解析符号链接的所有临时数据结构truncate(inode) /修改与索引节点相关的文件长度。在调用该方法之前,必须将inode对象的i_size字段设为需要的新长度值permission(inode, mask, nameidata) /检查是否允许对索引节点所指的文件进行指定模式的访问setattr(dentry, iattr) /在触及索引节点属性后通知一个“修改事件”getattr(mnt,

24、 dentry, kstat) /由一些文件系统用于读取索引节点属性setxattr(dentry, name, value, size, flags) /为索引节点设置“扩展属性”getxattr(dentry, name, buffer, size) /获取索引节点的扩展属性listxattr(dentry, buffer, size) /获取扩展属性名称的整个链表remove(dentry, name) /删除索引节点的扩展属性3文件项对象4目录对象四、VFS系统调用的实现1open()open()系统调用的服务例程为sys_open()函数,该函数接收的参数为:要打开文件的路径名fil

25、ename、访问模式的一些标志flags,以及如果该文件被创建所需要的许可权位掩码。如果该系统调用成功,就返回一个文件描述符,也就是指向文件对象的指针数组current-files-fd中分配给新文件的索引;否则,返回-1.下面描述一下sys_open()函数的操作,它执行如下操作:(1)调用getname()从进程地址空间读取该文件的路径名。(2)调用get_unused_fd()在current-files-fd中查找一个空的位置。相应的索引(新文件描述符)存放在fd局部变量中。(3)调用filp_open()函数,传递给它的参数为路径名、访问模式标志以及许可权位掩码。这个函数依次执行下列

26、步骤:a)把访问模式标志拷贝到namei_flags标志中,但是,用特殊的格式对访问模式标志O_RDONLY、O_WRONLY和O_RDWR进行编码;如果文件访问需要读特权,那么只设置namei_flags标志的下标为0的位(最低位);类似地,如果文件访问需要写特权,就只设置下标为1的位。b)调用open_namei(),传递给它的参数为路径名、修改的访问模式标志以及局部nameidata数据结构的地址。该函数以下列方式执行查找操作:如果访问模式标志中没有设置O_CREAT,则不设置LOOKUP_PARENT标志而设置LOOKUP_OPEN标志后开始查找。如果在访问模式标志中设置了O_CREA

27、T,则以LOOKUP_PARENT、LOOKUP_OPEN和LOOKUP_CREATE标志的设置开始查找。一旦path_lookup()函数成功返回,则检查请求的文件是否存在。如果不存在,则调用父索引节点的create方法分配一个新的磁盘索引节点。c)调用dentry_open()函数,传递给它的参数为访问模式标志、目录想对象的地址以及由查找操作确定的已安装文件系统对象。该函数依次执行下列操作:分配一个新的文件对象。根据传递给open()系统调用的访问模式标志初始化文件对象的f_flags和f_mode字段。根据作为参数传递来的目录项对象的地址和已安装文件系统对象的地址初始化文件对象的f_fe

28、ntey和f_vfsmnt字段。把f_op字段设置为相应索引节点对象i_fop字段的内容。把文件对象插入到文件系统超级块的s_files字段所指向的打开文件的链表。如果文件操作的open方法被定义,则调用它。调用file_ra_state_init()初始化预读的数据结构。如果O_DIRECT标志被设置,则检查直接I/O操作是否可以作用于文件。返回文件对象的地址。(4)把current-files-fdfd置为dentry_open()返回的文件对象的地址。(5)返回fd。2read()read()系统调用需要三个参数:文件描述符fd、内存区的地址buf(该缓冲区包含要传送的数据)以及一个数c

29、ount(指定应该传送多少字节)。read()把数据从文件传送到缓冲区,返回所成功传送的字节数,或者发送一个错误条件的信号并返回-1。返回值小于count并不意味着发生错误。即使请求的字节没有全部被传送,也总是允许内核终止系统调用,因此用户应用程序必须检查返回值并重新发出系统调用(如果必要)。读操作总是发生在由当前文件指针所指定的文件偏移处(文件对象的f_pos字段),通过把所传送的字节数加到文件指针上而更新文件指针。read()的服务例程sys_read()函数执行以下步骤:(1)调用fget_light()从fd获取相应文件对象的地址file。(2)如果file-f_mode中的标志不允许

30、所请求的读操作,则返回一个错误码-EBADF。(3)如果文件对象没有read()或aio_read()文件操作,则返回一个错误码-EINVAL。(4)调用access_ok()粗略地检查buf和count参数。(5)调用rw_verify_area()对要访问的文件部分检查是否有冲突的强制锁。如果有,则返回一个错误码,如果该锁已经被F_SETLKW命令请求,那么就挂起当前进程。(6)调用file-f_op-read方法来传送数据;否则,调用file-f_op-aio_read方法。这两个方法都返回实际传送的字节数。另一方面的作用是,文件指针被适当地更新。(7)调用fput_light()释放文

31、件对象。(8)返回实际传送的字节数。3write()write()系统调用与read()非常相似。read()把数据从文件传送到缓冲区,而write()执行相反的操作。write()的服务例程是sys_write()函数,sys_write()与sys_read几乎执行相同的步骤。4close()close()系统调用接收的参数为要关闭文件的文件描述符fd。sys_close()服务例程执行以下操作:(1)获得存放在current-files-fdfd中的文件对象的地址;如果它是NULL,则返回一个出错码。(2)把current-files-fdfd置为NULL。释放文件描述符fd,这是通过清

32、除current-files中的open_fds和close_on_exec字段的相应位来进行的。(3)调用filp_close(),该函数执行以下操作:a)调用文件操作的flush方法(如果已定义)。b)释放文件上的任何强制锁。c)调用fput()释放文件对象。(4)返回0或者一个出错码。出错码可由flush方法或文件中的前一个写操作错误产生。五、文件系统的安装与卸载(1)文件系统类型注册通常,用户在为自己的系统编译内核时可以把Linux配置为能够识别所有需要的文件系统。但是,文件系统的源代码实际上要么包含在内核映像中,要么作为一个模块被动态装入。VFS必须对代码目前已在内核中的所有文件系统

33、的类型进行跟踪。这就是通过文件系统类型注册来实现的。每个注册的文件系统都用一个类型为file_system_type的对象来表示,该对象的所有字段如表5-1所示。表5-1 file_system_type对象的字段类型字段说明const char *name文件系统名Intfs_flags文件系统类型标志struct super_block * (*)()get_sb读超级块的方法void(*)()kill_sb删除超级块的方法struct module *owner指向实现文件系统的模块的指针file_system_type *next指向文件系统类型链表中下一个元素的指针struct li

34、st_headfs_supers具有相同文件系统类型的超级块对象链表的头所有文件系统类型的对象都插入到一个单向链表中,由变量file_systems指向链表的第一个元素,而结构中的next字段指向链表的下一个元素。在系统初始化期间,调用register_filesystem()函数来注册编译时指定的每个文件系统,该函数把相应的file_system_type对象插入到文件系统类型的链表中。get_fs_type()函数(接收文件系统名作为它的参数)扫描已注册的文件系统链表以查找文件系统类型的name字段,并返回指向相应的file_system_type对象(如果存在的话)的指针。(2)文件系统

35、安装在大多数传统的类Unix内核中,每个文件系统只能安装一次。假定存放在/dev/fd0软磁盘上的Ext2文件系统通过如下命令安装在/flp:mount t ext2 /dev/fd0 /flp在用mount命令卸载该文件系统前,所有其他作用于/dev/fd0的安装命令都会失败。然而,Linux有所不同:同一个文件系统被安装多次是可能的。如果一个文件系统被安装了n次,那么它的根目录就可通过n个安装点访问。尽管同一个文件系统可以通过不同的安装点来访问,但是文件系统是唯一的,仅有一个超级块对象。对于每个安装操作,内核必须在内存中保存安装点和安装标志,以及要安装文件系统与其他已安装文件系统之间的关系

36、。这样的信息宝现在已安装文件系统描述符中;每个描述符是一个具有vfsmount类型的数据结构,其字段如表5-2所示。类型字段说明struct list_headmnt_hash用于散列表链表的指针struct vfsmountmnt_parent指向父文件系统,这个文件系统安装在其上struct dentry *mnt_mountpoint指向这个文件系统安装点目录的dentrystruct dentry *mnt_root指向这个文件系统根目录的dentrystruct super_block *mnt_sb指向这个文件系统根目录的超级块对象struct list_headmnt_mount

37、s包含所有文件系统描述符链表的头(相对于这个文件系统)struct list_headmnt_child用于已安装文件系统链表mnt_mounts的指针atomic_tmnt_count引用计数器Intmnt_flags标志Intmnt_expiry_mark如果文件系统标记为到期,那么就设置该标志为true(如果设置了该标志,并且没有任何人使用它,那么就可以自动卸载这个文件系统)char *mnt_devname设备文件名struct list_headmnt_list已安装文件系统描述符的namespace链表的指针struct list_headmnt_fslink具体文件系统到期链表的指针struct namespace *mnt_namespace指向安装了文件系统的进程命名空间的指针下列函数处理已安装文件系统描述符:alloc_vfsmnt(name):分配和初始化一个已安装文件系统描述符free_vfsmnt(mnt):释放由mnt指向的已安装文件系统描述符lookup_mnt(mnt,dentry):在散列表中查找一个已安装文件系统描述符mount()系统调用被用来安装一个普通文件系统,它的服务例程sys_mount()作用于以下参数:文件系统所在的设备文件的路径名,或者为NULL(例如,当要安装

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论