导航:首页 > 文件类型 > linux文件结构体

linux文件结构体

发布时间:2023-04-05 06:04:38

linux文件描述符fd和struct file结构体

简单归纳 : fd 只是一个整数,在 open 时产生。起到一个索引的作用,进程通过 PCB 中的 文件描述符表 找到该 fd 所指向的文件指针 filp 。

⑵ linux文件系统采用哪种物理结构,有什么优点和缺点

一、顺序结构

优点:

1、支持顺序存取和随机存取。

2、顺序存取速度快。

3、所需的磁盘寻道次数和寻道时间最少。

缺点:

1、需要为每个文件预留若干物理块以满足文件增长的部分需要。

2、不利于文件插入和删除。

二、链式结构

优点:

1、提高了磁盘空间利用率,不需要为每个文件预留物理块。

2、有利于文件插入和删除。

3、有利于文件动态扩充。

缺点:

1、存取速度慢,不适于随机存取。

2、当物理块间的连接指针出错时,数据丢失。

3、更多的寻道次数和寻道时间。

4、链接指针占用一定的空间,降低了空间利用率。

三、索引结构

优点:

1、不需要为每个文件预留物理块。

2、既能顺序存取,又能随机存取。

3、满足了文件动态增长、插入删除的要求。

缺点:

1、较多的寻道次数和寻道时间。

2、索引表本身带来了系统开销。如:内外存空间,存取时间等。

拓展资料:

文件存取方法:

顺序存取:顺序存取是按照文件的逻辑地址顺序存取。

固定长记录的顺序存取是十分简单的。读操作总是读出上一次读出的文件的下一个记录,同时,自动让文件记录读指针推进,以指向下一次要读出的记录位置。如果文件是可读可写的。再设置一个文件记录指针,它总指向下一次要写入记录的存放位置,执行写操作时,将一个记录写到文件 末端。允许对这种文件进行前跳或后退N(整数)个记录的操作。顺序存取主要用于磁带文件,但也适用于磁盘上的顺序文件。

可变长记录的顺序文件,每个记录的长度信息存放于记录前面一个单元中,它的存取操作分两步进行。读出时,根据读指针值先读出存放记录长度的单元 。然后,得到当前记录长后再把当前记录一起写到指针指向的记录位置,同时,调整写指针值 。

由于顺序文件是顺序存取的,可采用成组和分解操作来加速文件的输入输出。


直接存取(随机存取法):

很多应用场合要求以任意次序直接读写某个记录。例如,航空订票系统,把特定航班的所有信息用航班号作标识,存放在某物理块中,用户预订某航班时,需要直接将该航班的信息取出。直接存取方法便适合于这类应用,它通常用于磁盘文件。

为了实现直接存取,一个文件可以看作由顺序编号的物理块组成的,这些块常常划成等长,作为定位和存取的一个最小单位,如一块为1024字节、4096字节,视系统和应用而定。于是用户可以请求读块22、然后,写块48,再读块9等等。直接存取文件对读或写块的次序没有限制。用户提供给操作系统的是相对块号,它是相对于文件开始位置的一个位移量,而绝对块号则由系统换算得到。


索引存取:

第三种类型的存取是基于索引文件的索引存取方法。由于文件中的记录不按它在文件中的位置,而按它的记录键来编址,所以,用户提供给操作系统记录键后就可查找到所需记录。通常记录按记录键的某种顺序存放,例如,按代表健的字母先后次序来排序。对于这种文件,除可采用按键存取外,也可以采用顺序存取或直接存取的方法。信息块的地址都可以通过查找记录键而换算出。实际的系统中,大都采用多级索引,以加速记录查找过程。

⑶ linux驱动程序结构框架及工作原理分别是什么

一、Linux device driver 的概念x0dx0ax0dx0a系统调用是操作系统内核和应用程序之间的接口,设备驱动程序是操作系统内核和机器硬件之间的接口。设备驱动程序为应用程序屏蔽了硬件的细节,这样在应用程序看来,硬件设备只是一个设备文件,应用程序可以象操作普通文件一样对硬件设备进行操作。设备驱动程序是内核的一部分,它完成以下的功能:x0dx0ax0dx0a1、对设备初始化和释放;x0dx0ax0dx0a2、把数据从内核传送到硬件和从硬件读取数据;x0dx0ax0dx0a3、读取应用程序传送给设备文件的数据和回送应用程序请求的数据;x0dx0ax0dx0a4、检测和处理设备出现的错误。x0dx0ax0dx0a在Linux操作系统下有三类主要的设备文件类型,一是字符设备,二是块设备,三是网络设备。字符设备和块设备的主要区别是:在对字符设备发出读/写请求时,实际的硬件I/O一般就紧接着发生了,块设备则不然,它利用一块系统内存作缓冲区,当用户进程对设备请求能满足用户的要求,就返回请求的数据,如果不能,就调用请求函数来进行实际的I/O操作。块设备是主要针对磁盘等慢速设备设计的,以免耗费过多的CPU时间来等待。x0dx0ax0dx0a已经提到,用户进程是通过设备文件来与实际的硬件打交道。每个设备文件都都有其文件属性(c/b),表示是字符设备还是块设备?另外每个文件都有两个设备号,第一个是主设备号,标识驱动程序,第二个是从设备号,标识使用同一个设备驱动程序的不同的硬件设备,比如有两个软盘,就可以用从设备号来区分他们。设备文件的的主设备号必须与设备驱动程序在登记时申请的主设备号一致,否则用户进程将无法访问到驱动程序。x0dx0ax0dx0a最后必须提到的是,在用户进程调用驱动程序时,系统进入核心态,这时不再是抢先式调度。也就是说,系统必须在你的驱动程序的子函数返回后才能进行其他的工作。如果你的驱动程序陷入死循环,不幸的是你只有重新启动机器了,然后就是漫长的fsck。x0dx0ax0dx0a二、实例剖析x0dx0ax0dx0a我们来写一个最简单的字符设备驱动程序。虽然它什么也不做,但是通过它可以了解Linux的设备驱动程序的工作原理。把下面的C代码输入机器,你就会获得一个真正的设备驱动程序。x0dx0ax0dx0a由于用户进程是通过设备文件同硬件打交道,对设备文件的操作方式不外乎就是一些系统调用,如 open,read,write,close?, 注意,不是fopen, fread,但是如何把系统调用和驱动程序关联起来呢?这需要了解一个非常关键的数据结构:x0dx0ax0dx0aSTruct file_operatiONs {x0dx0ax0dx0aint (*seek) (struct inode * ,struct file *, off_t ,int);x0dx0ax0dx0aint (*read) (struct inode * ,struct file *, char ,int);x0dx0ax0dx0aint (*write) (struct inode * ,struct file *, off_t ,int);x0dx0ax0dx0aint (*readdir) (struct inode * ,struct file *, struct dirent * ,int);x0dx0ax0dx0aint (*select) (struct inode * ,struct file *, int ,select_table *);x0dx0ax0dx0aint (*ioctl) (struct inode * ,struct file *, unsined int ,unsigned long);x0dx0ax0dx0aint (*mmap) (struct inode * ,struct file *, struct vm_area_struct *);x0dx0ax0dx0aint (*open) (struct inode * ,struct file *);x0dx0ax0dx0aint (*release) (struct inode * ,struct file *);x0dx0ax0dx0aint (*fsync) (struct inode * ,struct file *);x0dx0ax0dx0aint (*fasync) (struct inode * ,struct file *,int);x0dx0ax0dx0aint (*check_media_change) (struct inode * ,struct file *);x0dx0ax0dx0aint (*revalidate) (dev_t dev);x0dx0ax0dx0a}x0dx0ax0dx0a这个结构的每一个成员的名字都对应着一个系统调用。用户进程利用系统调用在对设备文件进行诸如read/write操作时,系统调用通过设备文件的主设备号找到相应的设备驱动程序,然后读取这个数据结构相应的函数指针,接着把控制权交给该函数。这是linux的设备驱动程序工作的基本原理。既然是这样,则编写设备驱动程序的主要工作就是编写子函数,并填充file_operations的各个域。x0dx0ax0dx0a下面就开始写子程序。x0dx0ax0dx0a#include 基本的类型定义x0dx0ax0dx0a#include 文件系统使用相关的头文件x0dx0ax0dx0a#include x0dx0ax0dx0a#include x0dx0ax0dx0a#include x0dx0ax0dx0aunsigned int test_major = 0;x0dx0ax0dx0astatic int read_test(struct inode *inode,struct file *file,char *buf,int count)x0dx0ax0dx0a{x0dx0ax0dx0aint left; 用户空间和内核空间x0dx0ax0dx0aif (verify_area(VERIFY_WRITE,buf,count) == -EFAULT )x0dx0ax0dx0areturn -EFAULT;x0dx0ax0dx0afor(left = count ; left > 0 ; left--)x0dx0ax0dx0a{x0dx0ax0dx0a__put_user(1,buf,1);x0dx0ax0dx0abuf++;x0dx0ax0dx0a}x0dx0ax0dx0areturn count;x0dx0ax0dx0a}x0dx0ax0dx0a这个函数是为read调用准备的。当调用read时,read_test()被调用,它把用户的缓冲区全部写1。buf 是read调用的一个参数。它是用户进程空间的一个地址。但是在read_test被调用时,系统进入核心态。所以不能使用buf这个地址,必须用__put_user(),这是kernel提供的一个函数,用于向用户传送数据。另外还有很多类似功能的函数。请参考,在向用户空间拷贝数据之前,必须验证buf是否可用。这就用到函数verify_area。为了验证BUF是否可以用。x0dx0ax0dx0astatic int write_test(struct inode *inode,struct file *file,const char *buf,int count)x0dx0ax0dx0a{x0dx0ax0dx0areturn count;x0dx0ax0dx0a}x0dx0ax0dx0astatic int open_test(struct inode *inode,struct file *file )x0dx0ax0dx0a{x0dx0ax0dx0aMOD_INC_USE_COUNT; 模块计数加以,表示当前内核有个设备加载内核当中去x0dx0ax0dx0areturn 0;x0dx0ax0dx0a}x0dx0ax0dx0astatic void release_test(struct inode *inode,struct file *file )x0dx0ax0dx0a{x0dx0ax0dx0aMOD_DEC_USE_COUNT;x0dx0ax0dx0a}x0dx0ax0dx0a这几个函数都是空操作。实际调用发生时什么也不做,他们仅仅为下面的结构提供函数指针。x0dx0ax0dx0astruct file_operations test_fops = {?x0dx0ax0dx0aread_test,x0dx0ax0dx0awrite_test,x0dx0ax0dx0aopen_test,x0dx0ax0dx0arelease_test,x0dx0ax0dx0a};x0dx0ax0dx0a设备驱动程序的主体可以说是写好了。现在要把驱动程序嵌入内核。驱动程序可以按照两种方式编译。一种是编译进kernel,另一种是编译成模块(moles),如果编译进内核的话,会增加内核的大小,还要改动内核的源文件,而且不能动态的卸载,不利于调试,所以推荐使用模块方式。x0dx0ax0dx0aint init_mole(void)x0dx0ax0dx0a{x0dx0ax0dx0aint result;x0dx0ax0dx0aresult = register_chrdev(0, "test", &test_fops); 对设备操作的整个接口x0dx0ax0dx0aif (result < 0) {x0dx0ax0dx0aprintk(KERN_INFO "test: can't get major number\n");x0dx0ax0dx0areturn result;x0dx0ax0dx0a}x0dx0ax0dx0aif (test_major == 0) test_major = result; /* dynamic */x0dx0ax0dx0areturn 0;x0dx0ax0dx0a}x0dx0ax0dx0a在用insmod命令将编译好的模块调入内存时,init_mole 函数被调用。在这里,init_mole只做了一件事,就是向系统的字符设备表登记了一个字符设备。register_chrdev需要三个参数,参数一是希望获得的设备号,如果是零的话,系统将选择一个没有被占用的设备号返回。参数二是设备文件名,参数三用来登记驱动程序实际执行操作的函数的指针。x0dx0ax0dx0a如果登记成功,返回设备的主设备号,不成功,返回一个负值。x0dx0ax0dx0avoid cleanup_mole(void)x0dx0ax0dx0a{x0dx0ax0dx0aunregister_chrdev(test_major,"test");x0dx0ax0dx0a}x0dx0ax0dx0a在用rmmod卸载模块时,cleanup_mole函数被调用,它释放字符设备test在系统字符设备表中占有的表项。x0dx0ax0dx0a一个极其简单的字符设备可以说写好了,文件名就叫test.c吧。x0dx0ax0dx0a下面编译 :x0dx0ax0dx0a$ gcc -O2 -DMODULE -D__KERNEL__ -c test.c _c表示输出制定名,自动生成.o文件x0dx0ax0dx0a得到文件test.o就是一个设备驱动程序。x0dx0ax0dx0a如果设备驱动程序有多个文件,把每个文件按上面的命令行编译,然后x0dx0ax0dx0ald ?-r ?file1.o ?file2.o ?-o ?molename。x0dx0ax0dx0a驱动程序已经编译好了,现在把它安装到系统中去。x0dx0ax0dx0a$ insmod ?_f ?test.ox0dx0ax0dx0a如果安装成功,在/proc/devices文件中就可以看到设备test,并可以看到它的主设备号。要卸载的话,运行 :x0dx0ax0dx0a$ rmmod testx0dx0ax0dx0a下一步要创建设备文件。x0dx0ax0dx0amknod /dev/test c major minorx0dx0ax0dx0ac 是指字符设备,major是主设备号,就是在/proc/devices里看到的。x0dx0ax0dx0a用shell命令x0dx0ax0dx0a$ cat /proc/devicesx0dx0ax0dx0a就可以获得主设备号,可以把上面的命令行加入你的shell script中去。x0dx0ax0dx0aminor是从设备号,设置成0就可以了。x0dx0ax0dx0a我们现在可以通过设备文件来访问我们的驱动程序。写一个小小的测试程序。x0dx0ax0dx0a#include x0dx0ax0dx0a#include x0dx0ax0dx0a#include x0dx0ax0dx0a#include x0dx0ax0dx0amain()x0dx0ax0dx0a{x0dx0ax0dx0aint testdev;x0dx0ax0dx0aint i;x0dx0ax0dx0achar buf[10];x0dx0ax0dx0atestdev = open("/dev/test",O_RDWR);x0dx0ax0dx0aif ( testdev == -1 )x0dx0ax0dx0a{x0dx0ax0dx0aprintf("Cann't open file \n");x0dx0ax0dx0aexit(0);x0dx0ax0dx0a}x0dx0ax0dx0aread(testdev,buf,10);x0dx0ax0dx0afor (i = 0; i < 10;i++)x0dx0ax0dx0aprintf("%d\n",buf[i]);x0dx0ax0dx0aclose(testdev);x0dx0ax0dx0a}x0dx0ax0dx0a编译运行,看看是不是打印出全1 x0dx0ax0dx0a以上只是一个简单的演示。真正实用的驱动程序要复杂的多,要处理如中断,DMA,I/O port等问题。这些才是真正的难点。上述给出了一个简单的字符设备驱动编写的框架和原理,更为复杂的编写需要去认真研究LINUX内核的运行机制和具体的设备运行的机制等等。希望大家好好掌握LINUX设备驱动程序编写的方法。

⑷ linux下的FILE结构体详细定义是什么样的啊,求助

首先你建立你的ctags 索引文件吧。 ctags -R . 注意 -R 后边空格再加‘.’ 。然后就可以使用快捷键 ctrl + ] 或者 在可视模式下 :ts + 你要查找得函数或结构体 定义 大概就是这样 好久没用了。。 具体 详细的用花 请google ctags 用法吧

⑸ linux c 结构体怎么赋值

在 username() 和 password() 两个函数中使用的 x 是从哪里来的? 显然不是通过调用的时候传入的,那么,他们的专值在 username() 里 和 password() 里是否一致属? 我估计两次的 x 不一致,比方说赋值 username时,x = 3, 而在 下一步走到 password 里的时候, x = 5 了,那当然就不对了。所以你应该贴上来和 x 有关的代码。

⑹ linux kernel 文件系统编程接口

进程读写文件之前需要 打开文件 ,得到 文件描述符 ,然后 通过文件描述符读写文件 .

内核提供了两个打开文件的系统调用 open openat .

打开文件的主要步骤如下:
(1)需要 在父目录的数据中查找文件对应的目录项 , 从目录项得到索引节点的编号,然后在内存中创建索引节点的副本 .因为各种文件系统类型的物理结构不同,所以需要提供索引节点操作集合的 lookup 方法和文件操作集合的 open 方法.
(2)需要分配文件的一个打开实例-- file 结构体,关联到文件的索引节点.
(3)在进程的打开文件表中 分配一个文件描述符 , 把文件描述符和打开实例的映射添加到进程的打开文件表 中.

进程可通过使用系统调用 close 关闭文件.
系统调用close的执行流程如下:
(1)解除打开文件表和file实例的关联.
(2)在close_on_exec位图中清楚文件描述符对应的位.
(3)释放文件描述符,在文件描述符位图中清除文件描述符对应的位.
(4)调用函数fput释放file实例:把引用计数减1,如果引用计数是0,那么把file实例添加到链表delayed_fput_list中,然后调用延迟工作项delayed_fput_work.
延迟工作项delayed_fput_work的处理函数是flush_delayed_fput,遍历链表delayed_fput_list,针对每个file实例,调用函数__fput来加以释放.

创建不同类型的文件,需要使用不同的命令.
(1) 普通文件 :touch FILE ,这条命令本来用来更新文件的访问时间和修改时间,如果文件不存在,创建文件.
(2) 目录 :mkdir DIRECTORY .
(3) 符号链接(软链接) :ln -s TARGET LINK_NAME 或ln --symbolic TARGET LINK_NAME .
(4) 字符或块设备文件 :mknod NAME TYPE [MAJOR MINOR] .
(5) 命名管道 :mkpipe NAME .
(6) 硬连接 :命令"ln TARGETLINK_NAME ".给已经存在的文件增加新的名称,文件的索引节点有一个硬链接计数,如果文件有n个名称,那么硬链接计数是n.

创建文件需要在文件系统中 分配一个索引节点 ,然后 在父目录的数据中增加一个目录项来保存文件的名称和索引节点编号 .

删除文件的命令如下:
(1)删除任何类型文件:unlink FILE .
(2)rm FILE ,默认不删除目录,如果使用"-r""-R"或"-recursive",可以删除目录和目录的内容.
(3)删除目录:rmdir DICTIONARY .
内核提供了unlink,unlinkat用来删除文件的名称,如果文件的硬链接计数变成0,并且没有进程打开这个文件,那么删除文件.提供了rmdir删除目录.

删除文件需要从父目录的数据中删除文件对应的目录项, 把文件的索引节点的硬链接计数减1(一个文件可以有多个名称,Linux把文件名称称为硬链接),如果索引节点的硬链接计数变成0,那么释放索引节点 .因为各种文件系统的物理结构不同,所以需要提供索引节点操作集合的 unlink 方法.

设置文件权限的命令如下:
(1)chmod [OPTION]... MODE[, MODE]... FILE...
mode : 权限设定字串,格式[ugoa...][[+-=][rwxX]...][,...]
其中:

(2)chmod [OPTION]... OCTAL-MODE FILE...
参数OCTAL-MODE是八进制数值.
系统调用chmod负责修改文件权限.

修改文件权限需要修改文件的索引节点的文件模式字段,文件模式字段包含文件类型和访问权限.因为各种文件系统类型的索引节点不同,所以需要提供索引节点操作集合的 setattr 方法.

访问外部存储设备的速度很慢,为了避免每次读写文件时访问外部存储设备, 文件系统模块为每个文件在内存中创建一个缓存 ,因为 缓存的单位是页 ,所以称为 页缓存 .
(1) 索引节点的成员i_mapping 指向地址空间结构体(address_space).进程在打开文件的时候, 文件打开实例(file结构体)的成员f_mapping 也会指向文件的地址空间.
(2)每个文件有一个地址空间结构体 address_space ,成员 page_tree 的类型是结构体radix_tree_root:成员 gfp_mask是分配内存页的掩码,成员rnode指向基数树的根节点 .
(3)使用基数树管理页缓存,把文件的页索引映射到内存页的页描述符.

每个文件都有一个地址空间结构体address_space,用来建立数据缓存(在内存中为某种数据创建的缓存)和数据来源(即存储设备)之间的关联.结构体address_space如下:

地址空间操作结合address_space_operations的主要成员如下:

页缓存的常用操作函数如下:
(1)函数find_get_page根据文件的页索引在页缓存中查找内存页.

(2)函数find_or_create_page根据文件的页索引在页缓存中查找内存页,如果没有找到内存页,那么分配一个内存页,然后添加到页缓存中.

(3)函数add_to_page_cache_lru把一个内存页添加到页缓存和LRU链表中.

(4)函数delete_from_page_cache从页缓存中删除一个内存页.

进程读文件的方式有3种:
(1)调用内核提供的 读文件的系统调用 .
(2)调用glibc库封装的读文件的 标准I/O流函数 .
(3)创建基于文件的内存映射,把 文件的一个区间映射到进程的虚拟地址空间,然后直接读内存 .
第2种方式在用户空间创建了缓冲区,能减少系统调用的次数,提高性能.第3种方式可以避免系统调用,性能最高.

读文件的主要步骤如下:
(1)调用具体文件系统类型提供的文件操作集合的read和read_iter方法来读文件.
(2) read或read_iter方法根据页索引在文件的页缓存中查找页,如果没有找到,那么调用具体文件系统类型提供的地址空间集合的readpage方法来从存储设备读取文件页到内存中 .
为了提高读文件的速度,从存储设备读取文件页到内存中的时候,除了读取请求的文件页,还会预读后面的文件页.如果进程按顺序读文件,预读文件页可以提高读文件的速度;如果进程随机读文件,预读文件页对提高读文件的速度帮助不大.

进程写文件的方式有3种:
(1)调用内核提供的 写文件的系统调用 .
(2)调用glibc库封装的写文件的 标准I/O流函数 .
(3)创建基于文件的内存映射,把 文件的一个区间映射到进程的虚拟空间,然后直接写内存 .
第2种方式在用户空间创建了缓冲区,能够减少系统调用的次数,提高性能.第3种方式可以避免系统调用,性能最高.

写文件的主要步骤如下:
(1)调用具体文件系统类型提供的文件操作集合的write或write_iter方法来写文件.
(2)write或write_iter方法调用文件的地址空间操作集合的 write_begin 方法, 在页缓存查找页,如果页不存在就分配页;然后把数据从用户缓冲区复制到页缓存的页中 ;最后调用文件的地址空间操作集合的 write_end 方法.

进程写文件时,内核的文件系统模块把数据写到文件的页缓存,没有立即写回到存储设备.文件系统模块会定期把脏页写回到存储设备,进程也可以调用系统调用把脏页强制写回到存储设备.

管理员可以执行命令"sync",把内存中所有修改过的文件元数据和文件数据写回到存储设备.
内核提供了 sync , syncfs , fsync , fdatasync , sync_file_range 等系统调用用于文件写回.

把文件写回到存储设备的时机如下:
(1)周期回写.
(2)当脏页的数量达到限制的时候,强制回写.
(3)进程调用sync和syncfs等系统调用.

对于类似内存的块设备,例如NVDIMM设备,不需要把文件从存储设备复制到页缓存.DAX绕过页缓存,直接访问存储设备,对于基于文件的内存映射,直接把存储设备映射到进程的虚拟地址空间.
调用系统调用mmap创建基于文件的内存映射,把文件的一个区间映射到进程的虚拟地址空间,这会调用具体文件系统类型提供的文件操作集合的mmap方法.mmap方法针对设置了标志位S_DAX的索引节点,处理方法如下:
(1)给虚拟内存区域设置标志位VM_MIXEDMAP和VM_HUGEPAGE.
(2)设置虚拟内存操作集合,提供fault,huge_fault,page_mkwrite和pfn_mkwrite方法.

⑺ Linux目录结构

Windows操作系统抄的目录结构,是以盘符为单位,C盘、D盘、E盘等等,数据存储在各个盘符之下,而Linux操作系统最顶层只有一个根目录root,所有文件都存储在这一个根目录之下。
Windows操作系统若插入一个外部设备(U盘等),在系统中是多了一个盘符H,对H盘的操作就是对外部设备的操作。Linux操作系统是在根目录root下有一个名叫mnt的子目录,在这个目录下,会出现一个目录,假设为sdcard,称之为挂载点,对它的操作就是对外部设备的操作。
Windows操作系统某用户登录系统后,对所有文件都具有增删改查的权限,即:可以操作任意目录,假设将C盘下Windows目录删除,则会导致系统异常,安全性较差。Linux操作系统对权限要求比较严格,用户登录后并非对所有目录具有增删改查权限,默认的当前目录为根目录下的home目录下的soft01,称之为主目录,对这个目录具有最高权限,其余目录文件一般都是只读的,不能随意删除,这样就保证了安全性。

⑻ linux中什么是文件结构体

struct file结构体定义在include/linux/fs.h中定义。文件结构体代表一个打开的文件,系统中的每个打开的文件在内核空间都有一个关联的 struct file。它由内核在打开文件时创建,并传递给在文件上进行操作的任何函数。在文件的所有实例都关闭后,内核释放这个数据结构。在内核创建和驱动源码中,struct file的指针通常被命名为file或filp。

⑼ linux文件系统基础知识

linux文件系统基础知识汇总

1、linux文件系统分配策略

块分配( block allocation ) 和 扩展分配 ( extent allocation )

块分配:磁盘上的文件块根据需要分配给文件,避免了存储空间的浪费。但当文件扩充时,会造成文件中文件块的不连续,从而导致过多的磁盘寻道时间。

每一次文件扩展时,块分配算法就需要写入文件块的结构信息,也就是 meta-dada 。meta-data总是与文件一起写入存储设备,改变文件的操作要等到所有meta-data的操作都完成后才能进行,

因此,meta-data的操作会明显降低整个文件系统的性能。

扩展分配: 文件创建时,一次性分配一连串连续的块,当文件扩展时,也一次分配很多块。meta-data在文件创建时写入,当文件大小没有超过所有已分配文件块大小时,就不用写入meta-data,直到需要再分配文件块的时候。

扩展分配采用成组分配块的方式,减少了SCSI设备写数据的时间,在读取顺序文件时具有良好的性能,但随机读取文件时,就和块分配类似了。

文件块的组或块簇 ( block cluster) 的大小是在编译时确定的。簇的大小对文件系统的性能有很大的影响。

注: meta-data 元信息:和文件有关的信息,比如权限、所有者以及创建、访问或更改时间等。

2、文件的记录形式

linux文家系统使用索引节点(inode)来记录文件信息。索引节点是一种数据结构,它包含了一个文件的长度、创建及修改时间、权限、所属关系、磁盘中的位置等信息。

一个文件系统维护了一个索引节点的数组,每个文件或目录都与索引节点数组中的唯一的元素对应。每个索引节点在数组中的索引号,称为索引节点号。

linux文件系统将文件索引节点号和文件名同时保存在目录中,所以,目录只是将文件的名称和它的索引节点号结合在一起的一张表,目录中每一对文件名称和索引节点号称为一个连接。

对于一个文件来说,有一个索引节点号与之对应;而对于一个索引节点号,却可以对应多个文件名。

连接分为软连接和硬连接,其中软连接又叫符号连接。

硬连接: 原文件名和连接文件名都指向相同的物理地址。目录不能有硬连接;硬连接不能跨文件系统(不能跨越不同的分区),文件在磁盘中只有一个拷贝。

由于删除文件要在同一个索引节点属于唯一的连接时才能成功,因此硬连接可以防止不必要的误删除。

软连接: 用 ln -s 命令建立文件的符号连接。符号连接是linux特殊文件的.一种,作为一个文件,它的数据是它所连接的文件的路径名。没有防止误删除的功能。

3、文件系统类型:

ext2 : 早期linux中常用的文件系统

ext3 : ext2的升级版,带日志功能

RAMFS : 内存文件系统,速度很快

NFS : 网络文件系统,由SUN发明,主要用于远程文件共享

MS-DOS : MS-DOS文件系统

VFAT : Windows 95/98 操作系统采用的文件系统

FAT : Windows XP 操作系统采用的文件系统

NTFS : Windows NT/XP 操作系统采用的文件系统

HPFS : OS/2 操作系统采用的文件系统

PROC : 虚拟的进程文件系统

ISO9660 : 大部分光盘所采用的文件系统

ufsSun : OS 所采用的文件系统

NCPFS : Novell 服务器所采用的文件系统

SMBFS : Samba 的共享文件系统

XFS : 由SGI开发的先进的日志文件系统,支持超大容量文件

JFS :IBM的AIX使用的日志文件系统

ReiserFS : 基于平衡树结构的文件系统

udf: 可擦写的数据光盘文件系统

4、虚拟文件系统VFS

linux支持的所有文件系统称为逻辑文件系统,而linux在传统的逻辑文件系统的基础上增加料一个蓄念文件系统( Vitual File System ,VFS) 的接口层。

虚拟文件系统(VFS) 位于文件系统的最上层,管理各种逻辑文件系统,并可以屏蔽各种逻辑文件系统之间的差异,提供统一文件和设备的访问接口。

5、文件的逻辑结构

文件的逻辑结构可分为两大类: 字节流式的无结构文件 和 记录式的有结构文件。

由字节流(字节序列)组成的文件是一种无结构文件或流式文件 ,不考虑文件内部的逻辑结构,只是简单地看作是一系列字节的序列,便于在文件的任意位置添加内容。

由记录组成的文件称为记录式文件 ,记录是这种文件类型的基本信息单位,记录式文件通用于信息管理。

6、文件类型

普通文件 : 通常是流式文件

目录文件 : 用于表示和管理系统中的全部文件

连接文件 : 用于不同目录下文件的共享

设备文件 : 包括块设备文件和字符设备文件,块设备文件表示磁盘文件、光盘等,字符设备文件按照字符操作终端、键盘等设备。

管道(FIFO)文件 : 提供进程建通信的一种方式

套接字(socket) 文件: 该文件类型与网络通信有关

7、文件结构: 包括索引节点和数据

索引节点 : 又称 I 节点,在文件系统结构中,包含有关相应文件的信息的一个记录,这些信息包括文件权限、文件名、文件大小、存放位置、建立日期等。文件系统中所有文件的索引节点保存在索引节点表中。

数据 : 文件的实际内容。可以是空的,也可以非常大,并且拥有自己的结构。

8、ext2文件系统

ext2文件系统的数据块大小一般为 1024B、2048B 或 4096B

ext2文件系统采用的索引节点(inode):

索引节点采用了多重索引结构,主要体现在直接指针和3个间接指针。直接指针包含12个直接指针块,它们直接指向包含文件数据的数据块,紧接在后面的3个间接指针是为了适应文件的大小变化而设计的。

e.g: 假设数据块大小为1024B ,利用12个直接指针,可以保存最大为12KB的文件,当文件超过12KB时,则要利用单级间接指针,该指针指向的数据块保存有一组数据块指针,这些指针依次指向包含有实际数据的数据块,

假如每个指针占用4B,则每个单级指针数据块可保存 1024/4=256 个数据指针,因此利用直接指针和单级间接指针可保存 1024*12+1024*256=268 KB的文件。当文件超过268KB时,再利用二级间接指针,直到使用三级间接指针。

利用直接指针、单级间接指针、二级间接指针、三级间接指针可保存的最大文件大小为:

1024*12+1024*256+1024*256*256+1024*256*256*256=16843020 KB,约 16GB

若数据块大小为2048B,指针占4B,则最大文件大小为: 2048*12+2048*512+2048*512*512+2048*512*512*512=268,960,792 KB 约 268GB

若数据块大小为4096B,指针占4B,则最大文件大小为: 4096*12+4096*1024+4096*1024*1024+4096*1024*1024*1024=4,299,165,744 KB ,约 4TB

注: 命令 tune2fs -l /dev/sda5 可查看文件系统

ext2文件系统最大文件名长度: 255个字符

ext2文件系统的缺点:

ext2在写入文件内容的同时并没有同时写入文件meta-data, 其工作顺序是先写入文件的内容,然后等空闲时候才写入文件的meta-data。若发生意外,则文件系统就会处于不一致状态。

在重新启动系统的时候,linux会启动 fsk ( file system check) 的程序,扫描整个文件系统并试图修复,但不提供保证。

9、ext3文件系统:

ext3基于ext2的代码,所以磁盘格式与ext2相同,使用相同的元数据。

ext2文件系统无损转化为ext3文件系统: tune2fs -j /dev/sda6

日志块设备( Journaling block device layer,JBD)完成ext3文件系统日志功能。JBD不是ext3文件系统所特有的,它的设计目标是为了向一个块设备添加日志功能。

当一个文件修改执行时,ext3文件系统代码将通知JBD,称为一个事务(transaction)。发生意外时,日志功能具有的重放功能,能重新执行中断的事务。

日志中的3种数据模式:

1)、data=writeback :不处理任何形式的日志数据,给用户整体上的最高性能

2)、data=odered :只记录元数据日志,但将元数据和数据组成一个单元称为事务(transaction) 。此模式保持所句句的可靠性与文件系统的一致性,性能远低于data=writeback模式,但比data=journal模式快

3)、data=journal :提供完整的数据及元数据日志,所有新数据首先被写入日志,然后才被定位。意外发生过后,日志可以被重放,将数据与元数据带回一致状态。这种模式整体性能最慢,但数据需要从磁盘读取和写入磁盘时却是3种模式中最快的。

ext3文件系统最大文件名长度: 255个字符

ext3文件系统的优点:可用性、数据完整性、速度、兼容性

10、ReiserFS文件系统

ReiserFS文件系统是由Hans Reiser和他领导的开发小组共同开发的,整个文件系统完全是从头设计的,是一个非常优秀的文件系统。也是最早用于Linux的日志文件系统之一。

ReiserFS的特点

先进的日志机制

ReiserFS有先进的日志(Journaling/logging)功能 机制。日志机制保证了在每个实际数据修改之前,相应的日志已经写入硬盘。文件与数据的安全性有了很大提高。

高效的磁盘空间利用

Reiserfs对一些小文件不分配inode。而是将这些文件打包,存放在同一个磁盘分块中。而其它文件系统则为每个小文件分别放置到一个磁盘分块中。

独特的搜寻方式

ReiserFS基于快速平衡树(balanced tree)搜索,平衡树在性能上非常卓越,这是一种非常高效的算法。ReiserFS搜索大量文件时,搜索速度要比ext2快得多。Reiserfs文件 系统使用B*Tree存储文件,而其它文件系统使用B+Tree树。B*Tree查询速度比B+Tree要快很多。Reiserfs在文件定位上速度非常 快。

在实际运用中,ReiserFS 在处理小于 4k 的文件时,比ext2 快 5 倍;带尾文件压缩功能(默认)的ReiserFS 比ext2文件系统多存储6%的数据。

支持海量磁盘

ReiserFS是一个非常优秀的文件系统,一直被用在高端UNIX系统上,可轻松管理上百G的文件系统,ReiserFS文件系统最大支持的文件系统尺寸为16TB。这非常适合企业级应用中。

优异的性能

由于它的高效存储和快速小文件I/O特点,使用ReiserFs文件系统的PC,在启动X窗口系统时,所花的时间要比在同一台机器上使用ext2文 件系统少1/3。另外,ReiserFS文件系统支持单个文件尺寸为4G的文件,这为大型数据库系统在linux上的应用提供了更好的选择。

;

⑽ Linux常见文件结构体有哪些

linux虚拟文件系统核心数主要有以下几个数据结构: * 超级块结构(struct super_block {...} ) 该结构保存了一个被安装在内linux系统上的文容件系统的信息。对于基于磁盘的文件系统,该结构一般和保存在磁盘上的"文件系统控制块"对应。

阅读全文

与linux文件结构体相关的资料

热点内容
win10改变文件格式 浏览:475
linux中的物理地址和虚拟地址 浏览:493
有哪些app可以接游戏订单 浏览:472
苹果硬盘数据恢复要多少钱 浏览:394
js绑定下拉框数据库数据 浏览:448
cad文件怎么复制到另一个文件里边 浏览:858
dxp钻孔文件 浏览:631
iphone大悦城换机 浏览:538
找结婚对象上什么网站 浏览:974
学生信息管理系统程序设计报告 浏览:640
微信文件怎么删除怎么恢复 浏览:407
编程程序怎么复制 浏览:467
文件更改 浏览:327
冰点文件路径 浏览:730
软件一点开文件就关闭 浏览:88
网络如何把人捧红 浏览:961
软件传输文件 浏览:184
密码记录器ios 浏览:412
两个电脑数据怎么一样 浏览:829
顺丰有什么买东西的app 浏览:377

友情链接