炫意html5
最早CSS3和HTML5移动技术网站之一

文件系统 – Linux内核API get_super

get_super()函数可以实现在由参数*bdev所指定的块设备上获得超级块,并返回超级块数组的指针。在调用此函数时,该相应的文件系统必须已经被加载,或者该超级块已经占用了超级块数组的一项,否则返回NULL。

get_super文件包含

#include <linux/fs.h>

get_super函数定义

在内核源码中的位置:linux-3.19.3/fs/ super.c

函数定义格式:

struct super_block * get_super(struct block_device *bdev)

get_super输入参数说明

  • bdev:是block_device型结构体指针,用来指定所获取的是哪个设备上的超级块。

每个块设备用一个块设备结构体struct block_device进行描述,其定义见文件linux-3.19.3/include/linux/fs.h,如下:

struct block_device {
dev_t                     bd_dev;         //这是block_device的搜索编号
int                       bd_openers;     //打开该设备计数值
struct inode *           bd_inode;
struct super_block * bd_super;           //块设备文件系统超级块结构体,用来操作块文件系统
struct mutex              bd_mutex;       //打开/关闭互斥信号量
struct list_head          bd_inodes;      //设备节点链表
void *                   bd_claiming;
void *                   bd_holder;
int                       bd_holders;
bool                      bd_write_holder;
#ifdef CONFIG_SYSFS
struct list_head          bd_holder_list;
#endif
struct block_device *bd_contains;        //含有非分区块结构体
unsigned                  bd_block_size; //用来描述块大小,在申请队列中进行设置
struct hd_struct *       bd_part;        //硬件分区结构
/*被打开设备的分区次数及统计信息.*/
unsigned                  bd_part_count;
int                       bd_invalidated;
struct gendisk *         bd_disk;        //虚拟块设备下层的通用磁盘结构
stuct request_queue * bd_queue;
struct list_head          bd_list;
unsigned long             bd_private;     //私有数据
int                       bd_fsfreeze_count;
struct mutex              bd_fsfreeze_mutex;
};

get_super返回参数说明

  • get_super()函数的返回值是一个超级块super_block结构体,是在内存超级块(即super_block结构体)数组中搜索对应的超级块,并返回超级块数组的指针。如果不存在,则返回NULL。

结构体struct super_block其定义见文件linux-3.19.3/include/linux/fs.h,如下:

struct super_block {
struct list_head                 s_list;             /*指向超级块链表的指针*/
dev_t                            s_dev;              /*设备标识符*/
unsigned char                    s_blocksize_bits; /*以位为单位的块大小*/
unsigned long                    s_blocksize;        /*以字节为单位的块大小*/
unsigned long long      s_maxbytes;                  /*文件的最长长度*/
struct file_system_type          *s_type;           /*文件系统类型*/
const struct super_operations*s_op;                 /*超级块方法*/
struct dquot_operations          *dq_op;            /*磁盘限额处理的方法*/
struct quotactl_ops              *s_qcop;           /*磁盘限额管理的方法*/
const struct export_operations *s_export_op;        /*网络文件系统使用的输出操作*/
unsigned long                    s_flags;            /*安装标志*/
unsigned long                    s_magic;            /*文件系统的魔数*/
struct dentry                    *s_root;           /*文件系统根目录的目录项对象*/
struct rw_semaphore              s_umount;           /*卸载所用的信号量*/
int                              s_count;            /*引用计数器*/
atomic_t                         s_active;           /*次级引用计数器*/
#ifdef CONFIG_SECURITY
void        *s_security;                            /*指向超级块安全数据结构的指针*/
#endif
struct xattr_handler             **s_xattr;        /*指向超级块扩展属性结构的指针*/
struct list_head                 s_inodes;           /*所有索引节点的链表*/
struct hlist_head                s_anon; /*用于处理远程网络文件系统的匿名目录项的链表*/
struct list_head        s_mounts;
struct block_device     *s_bdev;
struct backing_dev_info          *s_bdi;
struct mtd_info         *s_mtd;
struct hlist_head       s_instances;   /*用于给定文件系统类型的超级块对象链表的指针*/
unsigned int            s_quota_types;
struct quota_info     s_dquot;                   /*磁盘限额的描述符*/
struct sb_writers     s_writers;
char s_id[32];                                     /*包含超级块的块设备名称*/
u8 s_uuid[16];                                        /*UUID*/
void                    *s_fs_info;                /*指向特定文件系统的超级块信息的指针*/
unsigned int            s_max_links;
fmode_t                  s_mode;
u32                     s_time_gran;              /*时间戳的最小单位)*/
struct mutex s_vfs_rename_mutex;                 /* Kludge */
char *s_subtype;
char *s_options;
...
...
...
};

get_super实例解析

编写测试文件:get_super.c

头文件声明如下:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/fs_struct.h>
#include <linux/path.h>
#include <linux/sched.h>
MODULE_LICENSE("GPL");

模块初始化函数:

int get_super_init(void)
{
struct super_block *sb;
struct super_block *sb1;
sb =current->fs->pwd.dentry->d_sb;      //获取当前文件所在的super_block描述符信息
struct block_device *bdev = sb->s_bdev; //获取当前文件对应的block_device描述符信息
printk("the Superblock's dev number is %d.\n", sb->s_dev);
//显示当前文件对应的dev number
sb1 = get_super(bdev);                  //获取bdev所对应的超级块
if(sb1 ! = NULL)                        //显示获取结果的dev number值
printk("After the \"get_super\", the superblock's dev number is %d.\n", sb1->s_dev);
else
printk(“Cannot be found! \n”);
return 0;
}

模块退出函数:

void get_super_exit(void)
{
printk("Goodbye get_super\n");
}

模块初始化及退出函数调用:

module_init(get_super_init);
module_exit(get_super_exit);

实例运行结果及分析:

首先编译模块,执行命令insmod get_super.ko插入模块,然后执行命令dmesg -c,会出现如图所示的结果。

Linux内核API get_super

结果分析:

在get_super函数中,首先打印出当前目录的super_block的编号,然后将这个结构体中的block_device当作参数传入了get_super函数中,应该得到的是当前目录的super_block结构体,而第二次打印出来的结构体编号与第一次相同,说明函数这两个super_block结构体表示的是同一个super_block。

炫意HTML5 » 文件系统 – Linux内核API get_super

Java基础教程Android基础教程