Chinaunix首页 | 论坛 | 博客
  • 博客访问: 10298
  • 博文数量: 5
  • 博客积分: 165
  • 博客等级: 入伍新兵
  • 技术积分: 50
  • 用 户 组: 普通用户
  • 注册时间: 2011-05-16 16:11
文章分类
文章存档

2012年(5)

我的朋友
最近访客

分类: LINUX

2012-11-08 18:11:13

在Linux中,进程是通过文件描述符(file descriptors,简称fd)而不是文件名来访问文件的,文件描述符实际上是一个整数。Linux中规定每个进程能最多能同时使用NR_OPEN个文件描述符,这个值在fs.h中定义,为1024*1024(2.0版中仅定义为256)。

每个文件都有一个32位的数字来表示下一个读写的 字节位置,这个数字叫做文件位置。每次打开一个文件,除非明确要求,否则文件位置都被置为0,即文件的开始处,此后的读或写操作都将从文件的开始处执行, 但你可以通过执行系统调用LSEEK(随机存储)对这个文件位置进行修改。Linux中专门用了一个数据结构file来保存打开文件的文件位置,这个结构 称为打开的文件描述(open file description)。这个数据结构的设置是煞费苦心的,因为它与进程的联系非常紧密,可以说这是VFS中一个比较难于理解的数据结构。


file结构中主要保存了文件位置,此外,还把指向该文件索引节点的指针也放在其中。file结构形成一个双链表,称为系统打开文件表,其最大长度是NR_FILE,在fs.h中定义为8192。

file结构在include\linux\fs.h中定义如下:

  1. struct file   
  2.   
  3. {  
  4.   
  5.  struct list_head        f_list;    /*所有打开的文件形成一个链表*/  
  6.   
  7.  struct dentry           *f_dentry; /*指向相关目录项的指针*/  
  8.   
  9.  struct vfsmount         *f_vfsmnt; /*指向VFS安装点的指针*/  
  10.   
  11.  struct file_operations  *f_op;     /*指向文件操作表的指针*/  
  12.   
  13.  mode_t f_mode;                                  /*文件的打开模式*/  
  14.   
  15.  loff_t f_pos;                                   /*文件的当前位置*/  
  16.   
  17.  unsigned short f_flags;                         /*打开文件时所指定的标志*/  
  18.   
  19.  unsigned short f_count;                           /*使用该结构的进程数*/  
  20.   
  21.  unsigned long f_reada, f_ramax, f_raend, f_ralen, f_rawin;  
  22.   
  23.  /*预读标志、要预读的最多页面数、上次预读后的文件指针、预读的字节数以及预读的页面数*/  
  24.   
  25.  int f_owner;                  /* 通过信号进行异步I/O数据的传送*/  
  26.   
  27.  unsigned int         f_uid, f_gid;  /*用户的UID和GID*/  
  28.   
  29.  int                 f_error;       /*网络写操作的错误码*/  
  30.   
  31.    
  32.   
  33.  unsigned long f_version;           /*版本号*/  
  34.   
  35.  void *private_data;                      /* tty驱动程序所需 */  
  36.   
  37. };  




内核中,对应于每个进程都有一个文件描述符表,表示这个进程打开的所有文件。文件描述表中每一项都是一个指针,指向一个用于 描述打开的文件的数据块———file对象,file对象中描述了文件的打开模式,读写位置等重要信息,当进程打开一个文件时,内核就会创建一个新的 file对象。需要注意的是,file对象不是专属于某个进程的,不同进程的文件描述符表中的指针可以指向相同的file对象,从而共享这个打开的文件。 file对象有引用计数,记录了引用这个对象的文件描述符个数,只有当引用计数为0时,内核才销毁file对象,因此某个进程关闭文件,不影响与之共享同 一个file对象的进程.

file对象中包含一个指针,指向dentry对象。dentry对象代表一个独立的文件路径,如果一个文件路径被打开多次,那么会建立多个file对象,但它们都指向同一个dentry对象。

dentry对象中又包含一个指向inode对象的指针。inode对象代表一个独立文件。因为存在硬链接与符号链接,因此不同的dentry 对象可以指向相同的inode对象.inode 对象包含了最终对文件进行操作所需的所有信息,如文件系统类型、文件的操作方法、文件的权限、访问日期等。

打开文件后,进程得到的文件描述符实质上就是文件描述符表的下标,内核根据这个下标值去访问相应的文件对象,从而实现对文件的操作。


注意,同一个进程多次打开同一个文件时,内核会创建多个file对象。
当进程使用fork系统调用创建一个子进程后,子进程将继承父进程的文件描述符表,因此在父进程中打开的文件可以在子进程中用同一个描述符访问。


inode 或i节点是指对文件的索引。如一个系统,所有文件是放在磁盘或flash上,就要编个目录来说明每个文件在什么地方,有什么属性,及大小等。就像书本的目 录一样,便于查找和管理。这目录是操作系统需要的,用来找文件或叫管理文件。许多操作系统都用到这个概念,如linux, 某些嵌入式文件系统等。当然,对某个系统来说,有许多i节点。所以对i节点本身也是要进行管理的。

 

    在linux中,内核通过inode来找到每个文件,但一个文件可以被许多用户同时打开或一个用户同时打开多次。这就有一个问题,如何管理文件的当前位 移量,因为可能每个用户打开文件后进行的操作都不一样,这样文件位移量也不同,当然还有其他的一些问题。所以linux又搞了一个文件描述符(file descriptor)这个东西,来分别为每一个用户服务。每个用户每次打开一个文件,就产生一个文件描述符,多次打开就产生多个文件描述符,一一对应, 不管是同一个用户,还是多个用户。该文件描述符就记录了当前打开的文件的偏移量等数据。所以一个i节点可以有0个或多个文件描述符。多个文件描述符可以对 应一个i节点。

 

  1. struct inode {  
  2.   struct list_headi_hash;  
  3.   struct list_headi_list;  
  4.   struct list_headi_dentry;  
  5.   struct list_headi_dirty_buffers;  
  6.   unsigned longi_ino; /*每一个inode都有一个序号,经由super block结构和其序号,我们可以很轻易的找到这个inode。*/  
  7.   atomic_t i_count; /*在Kernel里,很多的结构都会记录其reference count,以确保如果某个结构正在使用,它不会被不小心释放掉,i_count就是其reference count。*/  
  8.   kdev_t i_dev; /* inode所在的device代码 */  
  9.   umode_t i_mode; /* inode的权限 */  
  10.   nlink_t i_nlink; /* hard link的个数 */  
  11.   uid_t i_uid; /* inode拥有者的id */  
  12.   gid_t i_gid; /* inode所属的群组id */  
  13.   kdev_t i_rdev; /* 如果inode代表的是device的话,那此字段将记录device的代码 */  
  14.   off_t i_size; /* inode所代表的档案大小 */  
  15.   time_t i_atime; /* inode最近一次的存取时间 */  
  16.   time_t i_mtime; /* inode最近一次的修改时间 */  
  17.   time_t i_ctime; /* inode的产生时间 */  
  18.   unsigned long i_blksize; /* inode在做IO时的区块大小 */  
  19.   unsigned long i_blocks; /* inode所使用的block数,一个block为512 byte*/  
  20.   unsigned long i_version; /* 版本号码 */  
  21.   unsigned short i_bytes;  
  22.   struct semaphore i_sem;  
  23.   struct rw_semaphore i_truncate_sem;  
  24.   struct semaphore i_zombie;  
  25.   struct inode_operations *i_op;  
  26.   struct file_operations *i_fop;/* former ->i_op->default_file_ops */  
  27.   struct super_block *i_sb; /* inode所属档案系统的super block */  
  28.   wait_queue_head_t i_wait;  
  29.   struct file_lock *i_flock; /* 用来做file lock */  
  30.   struct address_space *i_mapping;  
  31.   struct address_space i_data;  
  32.   struct dquot *i_dquot [MAXQUOTAS];  
  33.   /* These three should probably be a union */  
  34.   struct pipe_inode_info *i_pipe;  
  35.   struct block_device *i_bdev;  
  36.   struct char_device *i_cdev;  
  37.   unsigned longi_dnotify_mask; /* Directory notify events */  
  38.   struct dnotify_struct *i_dnotify; /* for directory notifications */  
  39.   unsigned long i_state; /* inode目前的状态,可以是I_DIRTY,I_LOCK和 I_FREEING的OR组合 */  
  40.   unsigned int i_flags; /* 记录此inode的参数 */  
  41.   unsigned char i_sock; /* 用来记录此inode是否为socket */  
  42.   atomic_t i_write count;  
  43.   unsigned int i_attr_flags; /* 用来记录此inode的属性参数 */  
  44.   __u32 i_generation;  
  45.   union {  
  46.   struct minix_inode_info minix_i;  
  47.   struct ext2_inode_info ext2_i;  
  48.   struct ext3_inode_info ext3_i;  
  49.   struct hpfs_inode_info hpfs_i;  
  50.   struct ntfs_inode_info ntfs_i;  
  51.   struct msdos_inode_info msdos_i;  
  52.   struct umsdos_inode_info umsdos_i;  
  53.   struct iso_inode_info isofs_i;  
  54.   struct sysv_inode_info sysv_i;  
  55.   struct affs_inode_info affs_i;  
  56.   struct ufs_inode_info ufs_i;  
  57.   struct efs_inode_info efs_i;  
  58.   struct romfs_inode_info romfs_i;  
  59.   struct shmem_inode_info shmem_i;  
  60.   struct coda_inode_info coda_i;  
  61.   struct smb_inode_info smbfs_i;  
  62.   struct hfs_inode_info hfs_i;  
  63.   struct adfs_inode_info adfs_i;  
  64.   struct qnx4_inode_info qnx4_i;  
  65.   struct reiserfs_inode_info reiserfs_i;  
  66.   struct bfs_inode_info bfs_i;  
  67.   struct udf_inode_info udf_i;  
  68.   struct ncp_inode_info ncpfs_i;  
  69.   struct proc_inode_info proc_i;  
  70.   struct socketsocket_i;  
  71.   struct usbdev_inode_info usbdev_i;  
  72.   struct jffs2_inode_infojffs2_i;  
  73.   void *generic_ip;  
  74.   } u;  
  75.   };  
 

http://blog.csdn.net/zbszhangbosen/article/details/7535928

http://www.cnblogs.com/itech/archive/2012/05/15/2502284.html

http://www.cnblogs.com/wblyuyang/archive/2012/11/04/2754032.html

阅读(1249) | 评论(0) | 转发(0) |
0

上一篇:大牛博客

下一篇:linux 组件

给主人留下些什么吧!~~