Skip to content

Commit

Permalink
Expose major and minor device numbers
Browse files Browse the repository at this point in the history
  • Loading branch information
albertofaria committed Jul 6, 2021
1 parent 500eb50 commit e5488bb
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 12 deletions.
4 changes: 2 additions & 2 deletions kbdus/include-private/kbdus/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ int kbdus_device_validate_and_adjust_config(struct kbdus_device_config *config);
*
* SLEEPING: This function might sleep.
*/
struct kbdus_device *kbdus_device_create(
const struct kbdus_device_config *config, int first_minor);
struct kbdus_device *
kbdus_device_create(const struct kbdus_device_config *config);

/**
* \brief Destroys a device.
Expand Down
20 changes: 19 additions & 1 deletion kbdus/include/kbdus.h
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,25 @@ struct kbdus_device_config
uint8_t recoverable;

/** \cond PRIVATE */
uint8_t reserved_[71];
uint8_t reserved_1_[3];
/** \endcond */

/**
* \brief The device's major number.
*
* Directionality: OUT on create.
*/
uint32_t major;

/**
* \brief The device's minor number.
*
* Directionality: OUT on create.
*/
uint32_t minor;

/** \cond PRIVATE */
uint8_t reserved_2_[60];
/** \endcond */
};

Expand Down
6 changes: 4 additions & 2 deletions kbdus/src/control.c
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,9 @@ static int __kbdus_control_ioctl_create_device_(

config->device.id = kbdus_control_next_id_;

config->device.major = kbdus_device_get_major();
config->device.minor = (u32)(index * DISK_MAX_PARTS);

// copy modified configuration back to user space

if (copy_to_user(config_usrptr, config, sizeof(*config)) != 0)
Expand All @@ -456,8 +459,7 @@ static int __kbdus_control_ioctl_create_device_(

// create device

device_wrapper->device =
kbdus_device_create(&config->device, index * DISK_MAX_PARTS);
device_wrapper->device = kbdus_device_create(&config->device);

if (IS_ERR(device_wrapper->device))
{
Expand Down
12 changes: 7 additions & 5 deletions kbdus/src/device.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,11 @@ static bool

// ensure that reserved space is zeroed out

static const char zero[sizeof(config->reserved_)];
static const char zero_1[sizeof(config->reserved_1_)];
static const char zero_2[sizeof(config->reserved_2_)];

valid = memcmp(config->reserved_, zero, sizeof(zero)) == 0;
valid = (memcmp(config->reserved_1_, zero_1, sizeof(zero_1)) == 0)
&& (memcmp(config->reserved_2_, zero_2, sizeof(zero_2)) == 0);

// operations -- supports_fua_write implies supports_flush

Expand Down Expand Up @@ -686,8 +688,8 @@ int kbdus_device_validate_and_adjust_config(struct kbdus_device_config *config)
return 0;
}

struct kbdus_device *kbdus_device_create(
const struct kbdus_device_config *config, int first_minor)
struct kbdus_device *
kbdus_device_create(const struct kbdus_device_config *config)
{
struct kbdus_device *device;
int ret_error;
Expand Down Expand Up @@ -769,7 +771,7 @@ struct kbdus_device *kbdus_device_create(
device->disk->flags |= GENHD_FL_NO_PART_SCAN;

device->disk->major = kbdus_device_major_;
device->disk->first_minor = (int)first_minor;
device->disk->first_minor = (int)config->minor;
device->disk->fops = &kbdus_device_ops_;
device->disk->queue = device->queue;

Expand Down
18 changes: 16 additions & 2 deletions libbdus/include/bdus.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,12 @@ struct bdus_ctx
* value of this field.
*/
void *private_data;

/** \brief The device's major number. */
const uint32_t major;

/** \brief The device's minor number. */
const uint32_t minor;
};

/**
Expand Down Expand Up @@ -790,6 +796,10 @@ bool bdus_run_0_1_0_(
const struct bdus_ops *ops, const struct bdus_attrs *attrs,
void *private_data);

bool bdus_run_0_1_1_(
const struct bdus_ops *ops, const struct bdus_attrs *attrs,
void *private_data);

/**
* \brief Runs a driver for a new block device with the specified callbacks and
* attributes.
Expand All @@ -815,13 +825,17 @@ static inline bool bdus_run(
const struct bdus_ops *ops, const struct bdus_attrs *attrs,
void *private_data)
{
return bdus_run_0_1_0_(ops, attrs, private_data);
return bdus_run_0_1_1_(ops, attrs, private_data);
}

bool bdus_rerun_0_1_0_(
uint64_t dev_id, const struct bdus_ops *ops, const struct bdus_attrs *attrs,
void *private_data);

bool bdus_rerun_0_1_1_(
uint64_t dev_id, const struct bdus_ops *ops, const struct bdus_attrs *attrs,
void *private_data);

/**
* \brief Runs a driver for an *existing* block device with the specified
* callbacks and attributes.
Expand Down Expand Up @@ -869,7 +883,7 @@ static inline bool bdus_rerun(
uint64_t dev_id, const struct bdus_ops *ops, const struct bdus_attrs *attrs,
void *private_data)
{
return bdus_rerun_0_1_0_(dev_id, ops, attrs, private_data);
return bdus_rerun_0_1_1_(dev_id, ops, attrs, private_data);
}

/* -------------------------------------------------------------------------- */
Expand Down
16 changes: 16 additions & 0 deletions libbdus/src/bdus.c
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,8 @@ static bool bdus_execute_driver_(
.attrs = attrs,
.is_rerun = is_rerun,
.private_data = private_data,
.major = device_config->major,
.minor = device_config->minor,
};

// log attribute adjustment
Expand Down Expand Up @@ -685,6 +687,13 @@ BDUS_EXPORT_ bool bdus_run_0_1_0_(
return success;
}

BDUS_EXPORT_ bool bdus_run_0_1_1_(
const struct bdus_ops *ops, const struct bdus_attrs *attrs,
void *private_data)
{
return bdus_run_0_1_0_(ops, attrs, private_data);
}

/* -------------------------------------------------------------------------- */
/* driver development -- bdus_rerun() */

Expand Down Expand Up @@ -1060,6 +1069,13 @@ BDUS_EXPORT_ bool bdus_rerun_0_1_0_(
return success;
}

BDUS_EXPORT_ bool bdus_rerun_0_1_1_(
uint64_t dev_id, const struct bdus_ops *ops, const struct bdus_attrs *attrs,
void *private_data)
{
return bdus_rerun_0_1_0_(dev_id, ops, attrs, private_data);
}

/* -------------------------------------------------------------------------- */
/* device management */

Expand Down
58 changes: 58 additions & 0 deletions tests/c/major-minor.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/* SPDX-License-Identifier: MIT */
/* -------------------------------------------------------------------------- */

// This test ensures that the major and minor device numbers available through
// struct bdus_ctx match those of the device's block special file.

/* -------------------------------------------------------------------------- */

#include <bdus.h>

#include <errno.h>
#include <stdbool.h>
#include <sys/stat.h>
#include <sys/sysmacros.h>

/* -------------------------------------------------------------------------- */

static int device_on_device_available(struct bdus_ctx *ctx)
{
struct stat st;

if (stat(ctx->path, &st) != 0)
return errno;

if (ctx->major == major(st.st_rdev) && ctx->minor == minor(st.st_rdev))
*(bool *)ctx->private_data = true;

return EIO;
}

static const struct bdus_ops device_ops = {
.on_device_available = device_on_device_available,
};

static const struct bdus_attrs device_attrs = {
.size = 1 << 30,
.logical_block_size = 512,
.dont_daemonize = true,
};

/* -------------------------------------------------------------------------- */

int main(void)
{
for (int iteration = 0; iteration < 10; ++iteration)
{
bool matches = false;

bdus_run(&device_ops, &device_attrs, &matches);

if (!matches)
return 1;
}

return 0;
}

/* -------------------------------------------------------------------------- */

0 comments on commit e5488bb

Please sign in to comment.