A
A
alxsmrn2017-11-05 18:33:22
linux
alxsmrn, 2017-11-05 18:33:22

Why are pointers different?

I wanted to build the following kernel module

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/blkdev.h>
#include <linux/cdev.h>
#include <linux/kthread.h>
#include <linux/interrupt.h>
#include <linux/bio.h>
#include <linux/blkdev.h>
#include <linux/types.h>
#include <linux/major.h>
#include <linux/file.h>
#include <linux/slab.h>
#include <linux/kdev_t.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <asm/uaccess.h>
#include <linux/types.h>
#include <linux/buffer_head.h>
#include <linux/delay.h>
#include <linux/workqueue.h>
#include <linux/sched.h>
#include <linux/mm.h>

#define PARTITION_NAME "/dev/sda1"

#define DELAY(); \
  printk(KERN_INFO "filter: FUNCTION=%s LINE=%d\n", __FUNCTION__, __LINE__); \
        set_current_state(TASK_UNINTERRUPTIBLE); \
        schedule_timeout(HZ * 5);

struct block_device *bd;

make_request_fn *orig_mrqfn;

static void filter_mrqfn(struct request_queue *rq, struct bio *b)
{
  orig_mrqfn(rq, b); /* calling the original make_request_fn() */
}

/*
 * set_mrqfn() - Change the original make_request_fn() to our
 * modules request function
 */
static void set_mrqfn(void)
{
  int ret;
  struct super_block *sb =  bd->bd_super;
  printk(KERN_DEBUG "filter: %s\n", __FUNCTION__);

  DELAY();
  /* lock filesystem to prevent any further changes */
  sb = freeze_bdev(bd);
  if (sb)
    printk(KERN_INFO "filter: freez block device\n");
  DELAY();

  if (bd->bd_disk->queue->make_request_fn == filter_mrqfn) {
    printk(KERN_INFO "filter: modules request function is already active\n");
  } else {
    /* save the pointer to the original make_request_fn() */
    orig_mrqfn = bd->bd_disk->queue->make_request_fn;
    /* replace the original with our modules request function */
    bd->bd_disk->queue->make_request_fn = filter_mrqfn;
  }

  /* unlock filesystem */
  thaw_bdev(bd, sb);
}

/*
 * restore_mrqfn() - Restore the original make_request_fn()
 */
static void restore_mrqfn(void)
{
  struct super_block *sb =  bd->bd_super;
  printk(KERN_DEBUG "filter: %s\n", __FUNCTION__);

  if (orig_mrqfn) {
    /* lock filesystem to prevent any further changes */
    freeze_super(sb);

    /* restore the original request function */
    bd->bd_disk->queue->make_request_fn = orig_mrqfn;

    /* unlock filesystem */
    thaw_super(sb);
  }
  orig_mrqfn = NULL;
}

static int __init filter_init(void)
{
  printk(KERN_DEBUG "filter: %s\n", __FUNCTION__);

  orig_mrqfn = NULL;

  // Read block device from path
  bd = blkdev_get_by_path(PARTITION_NAME, FMODE_READ, NULL);

  if (IS_ERR(bd)) {
    printk(KERN_ERR "filter: failed to get block device\n");
    return 0;
  }

  set_mrqfn();

  return 0;
}

static void __exit filter_exit(void)
{
  printk(KERN_DEBUG "filter: %s\n", __FUNCTION__);

  restore_mrqfn();

  if (!IS_ERR(bd)) {
    blkdev_put(bd, FMODE_READ);
  }
}

module_init(filter_init);
module_exit(filter_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Me");

Here is the github https://gist.github.com/prashants/3839380
When building, it writes
make -C /usr/src/linux-headers-4.10.0-28-generic SUBDIRS=/home/llex/trash modules
make[1] : entering directory '/usr/src/linux-headers-4.10.0-28-generic'
CC [M] /home/llex/trash/filter.o
/home/llex/trash/filter.c: In function ' set_mrqfn':
/home/llex/trash/filter.c:59:42: warning: comparison of distinct pointer types lacks a cast
if (bd->bd_disk->queue->make_request_fn == filter_mrqfn) {
^
/home/llex /trash/filter.c:65:39: error: assignment from incompatible pointer type [-Werror=incompatible-pointer-types]
bd->bd_disk->queue->make_request_fn = filter_mrqfn;
^
/home/llex/trash/filter.c:48:6: warning: unused variable 'ret' [-Wunused-variable]
int ret;
^
cc1: some warnings being treated as errors
scripts/Makefile.build:301: error executing recipe for target '/home/llex/trash/filter.o'
make[2]: *** [/home/llex/trash/ filter.o] Error 1
Makefile:1524: error executing recipe for target "_module_/home/llex/trash"
make[1]: *** [_module_/home/llex/trash] Error 2
make[1]: exiting directory "/usr/src/linux-headers-4.10.0-28-generic"
Makefile:7: error executing recipe for target "default"
make: *** [default] Error 2
Kernel 4.10.
What could be wrong?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
J
jcmvbkbc, 2017-11-06
@jcmvbkbc

make_request_fn is defined as
accordingly, your filter_mrqfn function should return blk_qc_t.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question