aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoursoir <chat@joursoir.net>2023-01-12 17:59:59 +0400
committerJoursoir <chat@joursoir.net>2023-01-15 18:14:59 +0400
commit904a1abd878380f9e56fe1c251e4c07c913249ce (patch)
tree0556f583966b5ac51b3d887e7fa3015ea494d4a1
parentb8cff732264f52ae67cc8e884da02a1cd730e98f (diff)
downloadsbdd-904a1abd878380f9e56fe1c251e4c07c913249ce.tar.gz
sbdd-904a1abd878380f9e56fe1c251e4c07c913249ce.tar.bz2
sbdd-904a1abd878380f9e56fe1c251e4c07c913249ce.zip
open and copy the characterictics of a target device
Task: 1
-rw-r--r--sbdd.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/sbdd.c b/sbdd.c
index 09d1925..8d8474f 100644
--- a/sbdd.c
+++ b/sbdd.c
@@ -21,6 +21,8 @@
#include <linux/spinlock_types.h>
#define SBDD_NAME "sbdd"
+#define SBDD_BDEV_MODE (FMODE_READ | FMODE_WRITE)
+#define TARGET_DEV "/dev/disk/by-id/ata-QEMU_HARDDISK_QM00001"
struct sbdd {
wait_queue_head_t exitwait;
@@ -30,6 +32,7 @@ struct sbdd {
sector_t capacity;
struct gendisk *gd;
struct request_queue *q;
+ struct block_device *bdev;
};
static struct sbdd __sbdd;
@@ -97,6 +100,8 @@ static struct block_device_operations const __sbdd_bdev_ops = {
static int sbdd_create(void)
{
int ret = 0;
+ unsigned short lblock_size;
+ unsigned int max_sectors;
/*
This call is somewhat redundant, but used anyways by tradition.
@@ -126,6 +131,20 @@ static int sbdd_create(void)
pr_info("allocating disk\n");
__sbdd.gd = alloc_disk(1);
+ /* Get a handle on the device */
+ pr_info("opening %s\n", TARGET_DEV);
+ __sbdd.bdev = blkdev_get_by_path(TARGET_DEV, SBDD_BDEV_MODE, THIS_MODULE);
+ if (!__sbdd.bdev || IS_ERR(__sbdd.bdev)) {
+ pr_err("blkdev_get_by_path(\"%s\") failed with %ld\n",
+ TARGET_DEV, PTR_ERR(__sbdd.bdev));
+ return -ENOENT;
+ }
+
+ /* Configure queue */
+ lblock_size = bdev_logical_block_size(__sbdd.bdev);
+ blk_queue_logical_block_size(__sbdd.q, lblock_size);
+ pr_info("\tlogical block size: %u\n", lblock_size);
+
/* Configure gendisk */
__sbdd.gd->queue = __sbdd.q;
__sbdd.gd->major = __sbdd_major;
@@ -133,7 +152,13 @@ static int sbdd_create(void)
__sbdd.gd->fops = &__sbdd_bdev_ops;
/* Represents name in /proc/partitions and /sys/block */
scnprintf(__sbdd.gd->disk_name, DISK_NAME_LEN, SBDD_NAME);
+ __sbdd.capacity = get_capacity(__sbdd.bdev->bd_disk);
set_capacity(__sbdd.gd, __sbdd.capacity);
+ pr_info("\tdevice capacity: %llu\n", __sbdd.capacity);
+
+ max_sectors = queue_max_hw_sectors(bdev_get_queue(__sbdd.bdev));
+ blk_queue_max_hw_sectors(__sbdd.q, max_sectors);
+ pr_info("\tmax sectors: %u\n", max_sectors);
/*
Allocating gd does not make it available, add_disk() required.
@@ -158,6 +183,11 @@ static void sbdd_delete(void)
del_gendisk(__sbdd.gd);
}
+ if (__sbdd.bdev) {
+ pr_info("release a handle on the %s\n", TARGET_DEV);
+ blkdev_put(__sbdd.bdev, SBDD_BDEV_MODE);
+ }
+
if (__sbdd.q) {
pr_info("cleaning up queue\n");
blk_cleanup_queue(__sbdd.q);