Hello forum users!
I need to write my own kernel module to use it as a target for device-mapper module. I used
this article as a start point. The code there is written for >=2.6 kernel version, but I need to have the same for 2.4 kernel.
I tried to change functions as the are declared in kernel headers. Now I have something like this:
Code:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/version.h>
#include <linux/fs.h>
#include <linux/device-mapper.h>
#include <linux/fs.h>
#include <linux/kdev_t.h>
#include <linux/mm.h>
struct Sddm_target
{
struct dm_dev *dev;
sector_t start;
};
static int sddm_target_map(struct dm_target *ti, struct buffer_head *bh, int rw, union map_info *map_context)
{
struct Sddm_target *mdt;
mdt = (struct Sddm_target *) ti->private;
bh->b_dev = mdt->dev->dev;
submit_bh(rw, bh);
return 0;
}
static int sddm_target_ctr(struct dm_target *ti, unsigned int argc, char **argv)
{
struct Sddm_target *mdt;
unsigned long start;
unsigned long len;
int err;
if (argc != 2)
{
ti->error = "Invalid argument count";
return -EINVAL;
}
mdt = (struct Sddm_target*)kmalloc(sizeof(struct Sddm_target), GFP_KERNEL);
if (mdt == NULL)
{
ti->error = "dm-basic_target: Cannot allocate linear context";
return -ENOMEM;
}
if (sscanf(argv[1], "%lu", &start) != 1)
{
ti->error = "dm-basic_target: Invalid deviceee sector";
kfree(mdt);
return -EINVAL;
}
mdt->start = (sector_t)start;
err = dm_get_device(ti, argv[0], ti->begin, ti->len, dm_table_get_mode(ti->table), &mdt->dev);
if (err)
{
ti->error = "dm-basic_target: Device lookup failed";
kfree(mdt);
return -EINVAL;
}
ti->private = mdt;
return 0;
}
static void sddm_target_dtr(struct dm_target *ti)
{
struct Sddm_target *mdt = (struct Sddm_target *) ti->private;
dm_put_device(ti, mdt->dev);
kfree(mdt);
}
static struct target_type sddm_target = {
.name = "sddm_target",
.version = {1,0,0},
.module = THIS_MODULE,
.ctr = sddm_target_ctr,
.dtr = sddm_target_dtr,
.map = sddm_target_map,
};
static int __init init_sddm_target(void)
{
int result;
result = dm_register_target(&sddm_target);
return 0;
}
static void __exit cleanup_sddm_target(void)
{
dm_unregister_target(&sddm_target);
}
module_init(init_sddm_target);
module_exit(cleanup_sddm_target);
MODULE_LICENSE("GPL");
And it almost works. Virlual device created, but when I try to mount it, I get several calls of sddm_target_map function and then the process hangs with the message:
kjoutnald starting. Commit interval 5 seconds
I know that it is a kind of filesystem checking, but I can't understand why does it hang. So, I need your help! Any kind of message can be helpful!
If it can be useful...
dm_dev structure in device-mapper.h kernel header was not implemented on that system (only prototype). So I completed it:
Code:
struct dm_dev
{
struct list_head list;
atomic_t count;
int mode;
kdev_t dev;
struct block_device *bdev;
}
My module didn't compile withoun it.