Re: A trivial I/O module - Error

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Paulo da Silva escreveu:

I further simplified this ...
Now, everything I have is reading a page after sector 1 (sector 0 also
fails).
Why does err come with -5?
What am I doing wrong?


/*
 * ptm_bio01.c
 *    Using bio:
*        Read data.
 */
#include <linux/module.h>       /* Needed by all modules */
#include <linux/kernel.h>       /* Needed for KERN_INFO */
#include <linux/init.h>         /* Needed for the macros */
#include <linux/blkdev.h>

#define MY_BLOCK_SIZE PAGE_SIZE
#define MODEFLAGS FMODE_READ
#define DEV "/dev/loop2"

MODULE_LICENSE("Dual BSD/GPL");

static struct bio *bio;
static struct page *page;
static struct block_device *bdev;

static void end_bio_read_sync(struct bio *bio, int err)
{    printk(KERN_INFO "Entering end_bio_read_sync ...\n");
      bio_put(bio);
      SetPageUptodate(page);
      unlock_page(page);
      if (err)
          printk(KERN_INFO "end_bio_read_sync: Error n. %d\n",err);
      printk(KERN_INFO "Exiting end_bio_read_sync ...\n");
}

/* static int __init ptm_bio01_init(void) */
/* I removed "__init" because initialization is all this module does */
static int ptm_bio01_init(void)
{  int err=0;
    int flags=MODEFLAGS;
    short *page_data;
    int secsperpage=PAGE_SIZE/MY_BLOCK_SIZE;
    int i;

    /* Get a block device */
    bdev = open_bdev_exclusive(DEV, flags, NULL);
    if (IS_ERR(bdev))
    {    err=PTR_ERR(bdev);
          printk(KERN_INFO "Could not open_bdev_exclusive\n");
          goto fail1;
    }

    /* Alloc a page */
    page=alloc_page(GFP_NOFS);
    if (!page)
    {    err=-ENOMEM;
          printk(KERN_INFO "Could not alloc_page\n");
          goto fail2;
    }

    bio=bio_alloc(GFP_KERNEL, secsperpage);
    if (!bio)
    {    err=-ENOMEM;
          printk(KERN_INFO "Could not allocate a bio R\n");
          goto fail3;
    }

    /* Read the page */
    bio->bi_sector=1;    /* Device address in 512 bytes sectors.
                   1 -> 512 bytes from beginning of disk. */
    bio->bi_bdev=bdev;
    for (i=0;i<secsperpage;++i)
    {    bio->bi_io_vec[i].bv_page=page;
          bio->bi_io_vec[i].bv_len=MY_BLOCK_SIZE;
          bio->bi_io_vec[i].bv_offset=i*MY_BLOCK_SIZE;
    }
    bio->bi_vcnt=secsperpage;    /* how many bio_vec's */
    bio->bi_idx=0;            /* current index into bvl_vec */
    bio->bi_size=PAGE_SIZE;        /* residual I/O count */

    bio->bi_end_io=end_bio_read_sync;
    bio->bi_rw=0;
    clear_bit(BIO_UPTODATE,&bio->bi_flags);
    bio_get(bio);
    lock_page(page);
    page_data=page_address(page);
    if (!page_data)
    {    unlock_page(page);
        err=-1;
        printk(KERN_INFO "Could not get the address of the page!!! Use
kmap(?)\n");
        goto fail4;
    }
    ClearPageUptodate(page);

    submit_bio(READ, bio);
    if (bio_flagged(bio, BIO_EOPNOTSUPP))
    {    err=-EOPNOTSUPP;
          printk(KERN_INFO "Could not submit_bio R\n");
          goto fail4;
    }
    lock_page(page);
    page_data=page_address(page);
    if (!page_data)
    {    err=-1;
        printk(KERN_INFO "Could not get the address of the page!!! Use
kmap(?)\n");
        goto fail4;
    }
    unlock_page(page);
    printk(KERN_INFO "Ending init!\n");

    return 0;

fail4:
    bio_put(bio);
fail3:
    __free_page(page);
    page=NULL;
fail2:
    close_bdev_exclusive(bdev,flags);
    bdev=NULL;
fail1:
    if (err)
        printk(KERN_INFO "Error n. %d\n",err);
    return err;
}

static void __exit ptm_bio01_exit(void)
{  int flags=MODEFLAGS; /* Must be the same as in init */
    if (atomic_read(&bio->bi_cnt))
    {    bio_put(bio);
    }
    if (page && atomic_read(&page->_count))
    {    __free_page(page);
    }
    if (bdev)
        close_bdev_exclusive(bdev,flags);
    printk(KERN_INFO "Going out ...\n");
}

module_init(ptm_bio01_init);
module_exit(ptm_bio01_exit);


--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx
Please read the FAQ at http://kernelnewbies.org/FAQ


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux