linux内核模块
来源:互联网 发布:centos 删除硬盘分区 编辑:程序博客网 时间:2024/04/30 10:10
#include <linux/module.h>
#include <linux/string.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/parser.h>
#include <linux/random.h>
#include <linux/buffer_head.h>
#include <linux/exportfs.h>
#include <linux/smp_lock.h>
#include <linux/vfs.h>
#include <linux/seq_file.h>
#include <linux/mount.h>
#include <linux/log2.h>
#include <asm/uaccess.h>
#include "gt.h"
static struct super_block *m_sb = NULL;
static void gt_sync_super(struct super_block *sb,
struct rt_super_block *gs);
static void gt_put_super(struct super_block *sb){
struct gt_sb_info *sbi=GT_SB(sb);
brelse(sbi->s_sbh);
sb->s_fs_info=NULL;
kfree(sbi);
}
static struct kmem_cache *gt_inode_cachep;
static struct inode *gt_alloc_inode(struct super_block *sb){
struct gt_inode_info *gi;
gi=(struct gt_inode_info *)kmem_cache_alloc(gt_inode_cachep,GFP_KERNEL);
if(!gi)
return NULL;
return &gi->vfs_inode;
}
static void destroy_inodecache(void){
kmem_cache_destroy(gt_inode_cachep);
}
static void init_once(void *foo){
struct gt_inode_info *gi=(struct gt_inode_info *)foo;
inode_init_once(&gi->vfs_inode);
}
static int init_inodecache(void){
gt_inode_cachep=kmem_cache_create("gt_inode_cache",sizeof(struct gt_inode_info),0,(SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD),init_once);
if(gt_inode_cachep==NULL)
return -ENOMEM;
return 0;
}
static void gt_destroy_inode(struct inode *inode){
kmem_cache_free(gt_inode_cachep,GT_I(inode));
}
static int gt_write_inode(struct inode *inode,int wait){
brelse(gt_update_inode(inode));
return 0;
}
static void gt_delete_inode(struct inode *inode){
truncate_inode_pages(&inode->i_data,0);
GT_I(inode)->i_dtime=get_seconds();
inode->i_size=0;
gt_truncate(inode);
gt_free_inode(inode);
}
static int gt_statfs(struct dentry *dentry,struct kstatfs *buf){
struct gt_sb_info * sbi=GT_SB(dentry->d_sb);
struct rt_super_block *gs=sbi->s_gs;
buf->f_type=dentry->d_sb->s_magic;
buf->f_bsize=dentry->d_sb->s_blocksize;
buf->f_blocks=(gs->s_total_blocks_count-gs->s_cluster_start_position);
buf->f_bfree=gt_count_free_blocks(sbi);
buf->f_bavail=buf->f_bfree;
buf->f_ffree=gt_count_free_inodes(sbi);
buf->f_namelen=GT_NAME_LEN;
return 0;
}
static int gt_write_super(struct super_block *sb){
struct rt_super_block *gs;
lock_kernel();
gs=GT_SB(sb)->s_gs;
gs->s_create_time=cpu_to_le32(get_seconds());
gs->s_write_time = cpu_to_le32(get_seconds());
mark_buffer_dirty(GT_SB(sb)->s_sbh);
sync_dirty_buffer(GT_SB(sb)->s_sbh);
sb->s_dirt=0;
unlock_kernel();
}
static const struct super_operations gt_sops={
.alloc_inode =gt_alloc_inode,
.destroy_inode =gt_destroy_inode,
.write_inode =gt_write_inode,
.write_super =gt_write_super,
.put_super =gt_put_super,
.statfs =gt_statfs,
};
//myself
static int rt_write_one_block(unsigned long blocknr, void *block_addr)
{
if(!m_sb)
{
printk("unrun mount,%s error ", __func__);
return 0;
}
int ret = 0;
struct buffer_head *bh;
if(!(bh=__getblk(m_sb->s_bdev,blocknr,RT_BLOCK_SIZE))){
printk("get blk failed ");
return 0;
}
memcpy(bh->b_data, block_addr, RT_BLOCK_SIZE);
mark_buffer_dirty(bh);
ll_rw_block(WRITE, 1, &bh);
brelse(bh);
ret = 1;
return ret;
}
static int rt_read_one_block(unsigned long blocknr, void *block_addr)
{
if(!m_sb)
{
printk("unrun mount,%s error ", __func__);
return 0;
}
int ret = 0;
struct buffer_head *bh;
bh = __bread(m_sb->s_bdev, blocknr, RT_BLOCK_SIZE);
if (!bh)
{
printk("get blk failed ");
return 0;
}
memcpy(block_addr, bh->b_data, RT_BLOCK_SIZE);
ret = 1;
brelse(bh);
return ret;
}
//end myself
static int gt_fill_super(struct super_block *sb,void *data,int silent){
m_sb = sb;
struct buffer_head *bh;
struct buffer_head *bh1;
struct buffer_head *bh2;
struct rt_super_block *gs;
struct gt_sb_info *sbi;
struct inode *root;
unsigned long sb_block=1;
long ret=-EINVAL;
int blocksize=BLOCK_SIZE;
sbi=kzalloc(sizeof(struct gt_sb_info),GFP_KERNEL);
if(!sbi)
return -ENOMEM;
if(!sb_set_blocksize(sb,BLOCK_SIZE))
goto out_bad_hblock;
if(!(bh=sb_bread(sb,sb_block))){
printk("GT-fs:unable to read superblock\n");
goto failed_sbi;
}
gs=(struct rt_super_block *)(bh->b_data);
sbi->s_sbh=bh;
sbi->s_gs=gs;
sb->s_fs_info=sbi;
sb->s_magic=gs->s_magic;
// myself
char result[1024];
rt_read_one_block(500, result);
printk("s_magic = %d\n",(*(struct rt_super_block *)(result)).s_magic);
printk("s_total_blocks_count = %d\n",(*(struct rt_super_block *)(result)).s_total_blocks_count);
printk("s_ipoint_start_position = %d\n",(*(struct rt_super_block *)(result)).s_ipoint_start_position);
printk("s_ipoints_count = %d\n",(*(struct rt_super_block *)(result)).s_ipoints_count);
printk("s_ipoint_size = %d\n",(*(struct rt_super_block *)(result)).s_ipoint_size);
printk("s_cluster_map_start_position = %d\n",(*(struct rt_super_block *)(result)).s_cluster_map_start_position);
printk("s_cluster_map_count = %d\n",(*(struct rt_super_block *)(result)).s_cluster_map_count);
printk("s_cluster_start_position = %d\n",(*(struct rt_super_block *)(result)).s_cluster_start_position);
printk("s_cluster_size = %d\n",(*(struct rt_super_block *)(result)).s_cluster_size);
printk("s_cluster_count = %d\n",(*(struct rt_super_block *)(result)).s_cluster_count);
//rt_write_one_block(500, result);
/*
if(!(bh1=__bread(sb->s_bdev,200,1024))){
printk("GT-fs:unable to read block 1024\n");
goto failed_sbi;
}
printk("s_magic = %d\n",(*(struct rt_super_block *)(bh1->b_data)).s_magic);
printk("s_total_blocks_count = %d\n",(*(struct rt_super_block *)(bh1->b_data)).s_total_blocks_count);
printk("s_ipoint_start_position = %d\n",(*(struct rt_super_block *)(bh1->b_data)).s_ipoint_start_position);
printk("s_ipoints_count = %d\n",(*(struct rt_super_block *)(bh1->b_data)).s_ipoints_count);
printk("s_ipoint_size = %d\n",(*(struct rt_super_block *)(bh1->b_data)).s_ipoint_size);
printk("s_cluster_map_start_position = %d\n",(*(struct rt_super_block *)(bh1->b_data)).s_cluster_map_start_position);
printk("s_cluster_map_count = %d\n",(*(struct rt_super_block *)(bh1->b_data)).s_cluster_map_count);
printk("s_cluster_start_position = %d\n",(*(struct rt_super_block *)(bh1->b_data)).s_cluster_start_position);
printk("s_cluster_size = %d\n",(*(struct rt_super_block *)(bh1->b_data)).s_cluster_size);
printk("s_cluster_count = %d\n",(*(struct rt_super_block *)(bh1->b_data)).s_cluster_count);
printk("sb->s_bdev->bd_dev = %d\n",sb->s_bdev->bd_dev);
printk("sb->s_blocksize = %d\n",sb->s_blocksize);
if(!(bh2=__getblk(sb->s_bdev,200,1024))){
printk("GT-fs:unable to read 100 block\n");
goto failed_sbi;
}
memcpy(bh2->b_data, bh->b_data, 1024);
mark_buffer_dirty(bh2);
ll_rw_block(WRITE, 1, &bh2);
brelse(bh2);
*/
// end myself
if(sb->s_magic !=GT_SUPER_MAGIC)
goto cantfind_gt;
blocksize=RT_BLOCK_SIZE;
sb->s_op=>_sops;
root=gt_iget(sb,GT_ROOT_INO);
if(IS_ERR(root)){
ret=PTR_ERR(root);
printk(KERN_ERR "GT-fs: can't find root inode\n");
goto failed_mount;
}
if (!S_ISDIR(root->i_mode) || !root->i_blocks || !root->i_size) {
iput(root);
printk(KERN_ERR "isdir?%d,root->i_blocks=%d,root->i_size=%d\n",S_ISDIR(root->i_mode) , root->i_blocks, root->i_size);
printk(KERN_ERR "GT-fs: corrupt root inode\n");
goto failed_mount;
}
sb->s_root = d_alloc_root(root);
if (!sb->s_root) {
iput(root);
printk(KERN_ERR "GT: get root inode failed\n");
ret = -ENOMEM;
goto failed_mount;
}
return 0;
cantfind_gt:
printk("VFS: Can't find an gt filesystem on dev %s.\nmagic on dev is %d and magic of GT is %d\n",sb->s_id,sb->s_magic,GT_SUPER_MAGIC);
failed_mount:
brelse(bh);
out_bad_hblock:
printk("GT-fs:blocksize too small for device\n");
failed_sbi:
sb->s_fs_info=NULL;
kfree(sbi);
return ret;
}
/*
static void gt_sync_super(struct super_block *sb,struct rt_super_block *gs){
gs->s_free_blocks_count = cpu_to_le32(gt_count_free_blocks(sb));
gs->s_free_inodes_count = cpu_to_le32(gt_count_free_inodes(sb));
gs->s_wtime = cpu_to_le32(get_seconds());
mark_buffer_dirty(GT_SB(sb)->s_sbh);
sync_dirty_buffer(GT_SB(sb)->s_sbh);
sb->s_dirt = 0;
}
*/
static int gt_get_sb(struct file_system_type *fs_type,
int flags,const char *dev_name,void *data,struct vfsmount *mnt){
return get_sb_bdev(fs_type,flags,dev_name,data,gt_fill_super,mnt);
}
static struct file_system_type gt_fs_type ={
.owner =THIS_MODULE,
.name ="rtfs",
.get_sb =gt_get_sb,
.kill_sb =kill_block_super,
.fs_flags =FS_REQUIRES_DEV,
};
static int __init init_gt_fs(void){
int err=init_inodecache();
if(err)
return err;
err=register_filesystem(>_fs_type);
if(err)
goto out;
return 0;
out:
destroy_inodecache();
return err;
}
static void __exit exit_gt_fs(void){
unregister_filesystem(>_fs_type);
destroy_inodecache();
}
module_init(init_gt_fs)
module_exit(exit_gt_fs)
- Linux内核模块:模块参数
- Linux 内核模块
- linux内核模块加载
- Linux内核模块
- Linux内核模块编程
- Linux内核模块编程
- Linux内核模块使用指南
- linux内核模块解析
- Linux内核驱动模块
- linux内核模块编译
- linux 添加内核模块
- linux内核模块解析
- linux内核模块常用命令
- Linux内核模块编程
- linux内核模块编程
- linux 内核模块
- Linux 内核模块编程
- Linux内核模块概述
- ERROR: the user data image is used by another emulator. aborting错误!
- iPhone游戏开发纵谈
- 配置msSQL中遇到的问题[Microsoft][ODBC SQL Server Driver][SQL Server]
- VB.Net 获取或者转换时间不受系统时间格式影响
- multi_bin 相关
- linux内核模块
- Jasper Repor 异常总结
- 使用Google 的 Closure Compiler来压缩javascript
- Android之Service(转)
- 学习笔记.
- 磁盘格式化程序
- S3C6410 Copybit Android 模块设计心得
- 一个程序员的创业失败教训
- #define A (* (volatile unsigned long *) 详解