Linux 内核传绝对路径显示文件inode或目录dentry

来源:互联网 发布:java调用方法 编辑:程序博客网 时间:2024/06/11 16:26

      这几天自学了Linux文件系统方面的知识,对这些知识进行总结。错误之处还请大家提出宝贵意见~~

      在Linux操作系统中,我们都知道“一切皆文件” ,Linux中的文件类型有:1. 普通文件   2.目录文件  3.管道文件  4.设备文件,包括字符设备(以字符为单位进行输入/ 输出操作)和块设备(以块为单位,每块有固定字节数是512字节的整数倍,~~还不知道什么原因)5,。符号链接(内容指向一个文件系统的路径,系统会对这个操作转移到它所指向的文件上,而不是对本文件的操作) 6.socket 文件(与管道文件不同的是,管道支持本机上不同进程间的通信,而socket 除此之外还支持不同主机间进程的通信)

      在此, 我只对目录和常规文件进行细致学习:

             Linux 系统中每个文件都含有一个inode 结构体,该结构体包含文件的所有信息,如:i_ino 是表示文件的唯一标号,i_mode 表示文件的访问权限……

             每个目录文件都包含一个dentry 结构体,该结构体中含有目录的所有信息,如d_mounted 表示目录的安装点……    而在dentry 结构体中含有一个数据成员为 d_inode ,该成员的实质指向 struct inode 结构体,还是因为“ Linux 下一切皆文件 ” 所致。

            存在以上结构体时还不能对这些文件进行访问,因为缺少 struct file 结构体,该结构体本身存在Linux 中,但与以上介绍的结构体之间没有关系,只有当对文件进行打开(内核中 filp_open()为打开文件操作)操作后,三者之间才有了联系,file 结构体中的 f_dentry 成员指向struct  dentry 结构体。之间的联系如下图所示:



给内核传递参数(绝对路径),对文件(inode)和目录(dentry)的信息进行显示

代码部分:

 /// \file path.c

/*
  ------------------------------------
  Create date : 2015-04-21 19:14
  Modified date: 2015-04-21 20:04
  Author : zyy
  Email : 121672309@qq.com
  ------------------------------------
*/


#include<linux/module.h>
#include<linux/fs.h>
#include<linux/kernel.h>
#include<linux/init.h>
#include<asm/unistd.h>
#include<asm/uaccess.h>
#include<linux/types.h>
#include<linux/fcntl.h>
#include<linux/dirent.h>
#include<linux/kdev_t.h>


static char *absolute_path;
module_param_named(path,absolute_path,charp,0644);
MODULE_PARM_DESC(absolute_path,"absolute path : type=charp\n");




static int __init path_init(void)
{
     struct inode *inode=NULL;
     struct dentry *dentry=NULL;
     struct file *file=NULL;
     file=filp_open(absolute_path,O_DIRECTORY,0);
printk("\n\n********************\n\n");
if(IS_ERR(file))
{
     file=filp_open(absolute_path,O_RDONLY,0444);
          if(IS_ERR(file))
 {
     printk("The path %s is error!\n",absolute_path);
 return 0;
 }
          inode=file->f_dentry->d_inode;
          printk("This is a file , show my information : \n");
          printk("1.inode number : %ld\n",inode->i_ino);
 printk("2.access right : %o\n",inode->i_mode);
 printk("3.reference count : %d\n",inode->i_count.counter);
 printk("4.hard link count : %u\n",inode->i_nlink);
 printk("5.user Id : %d\n",inode->i_uid);
 printk("6.group Id : %d\n",inode->i_uid);
          printk("7.version : %lu\n",(long unsigned int)inode->i_version);
 printk("8.file size(byte) : %d\n",(int)inode->i_size);
 printk("9.block count : %lu\n",inode->i_blocks);
 printk("10.file state : %lu\n",inode->i_state);
 return 0;
}   
else
{
 dentry=file->f_dentry;
 printk("This is a diretory , show my information : \n");
          printk("1.direntry count : %d\n",dentry->d_count);
 printk("2.dentry flag : %u\n",dentry->d_flags);
 printk("3.hash table number : %u\n",dentry->d_name.hash);
 printk("4.directory name : %s\n",dentry->d_name.name);
 printk("5.name length : %u\n",dentry->d_name.len);
 printk("6.short name : %s\n",dentry->d_iname);
          printk("7.time : %lu\n",dentry->d_time);
          return 0;
}
}






static void __exit path_exit(void)
{
   printk("\n\n********************\n\n");
   printk("Goodbye!\n");
   return ;
}


module_init(path_init);
module_exit(path_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("121672309@qq.com");



makefile部分:

#path
obj-m:=path.o
current:=$(shell pwd)
kernel:=$(shell uname -r)
path:=/usr/src/linux-headers-$(kernel)
all:
make -C $(path) M=$(current) modules
clean:
make -C $(path) M=$(current) clean



扩展:

        在C语言中有三类指针:空指针(NULL)、有效指针、错误指针(无效指针,当指针指向内核空间的最后一页时)

        Linux 中有用户空间和内核空间之分,0~3G为用户空间,3~4G为内核空间(0x C0000000~0x ffffffff),而内核空间中最后4k,也就是一个页面大小并不能使用,这4k存放所有的出错信息,并用宏定义存储。如:#define  EPERM  1   表示操作不被允许的错误 ,像这样的宏定义共4095个,占4kb大小。因此当文件指针指向这4k 时说明你的文件必然出错,该指针无效。

       代码中的IS_ERR()就是用来判断指针是否出错,若出错返回1,否则返回0,常用IS_ERR()用来判断内核函数的返回值是不是一个有效指针。IS_ERR()和PTR_ERR()可显示出错代码。






                                            

0 0
原创粉丝点击