Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement device-mapper and bio for a simple dm_sworndisk module #19

Closed
wants to merge 4 commits into from

Conversation

cqs21
Copy link
Contributor

@cqs21 cqs21 commented Nov 22, 2023

No description provided.

@cqs21 cqs21 force-pushed the dev-dm branch 2 times, most recently from 518d874 to 9b2ef35 Compare January 22, 2024 07:56
@cqs21 cqs21 marked this pull request as ready for review January 22, 2024 07:59

void helper_bio_get(struct bio *bio)
{
bio_get(bio);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the indentation here four spaces? Seems a little longer than rust codes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The C kernel code uses tabs for indentation.

pub unsafe fn from_raw(ptr: *mut bindings::bio) -> Self {
// Get a reference to a `bio`, so it won't disappear. And `bio_put` is
// called when it's been dropped.
bindings::bio_get(ptr);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could the pointer be null? Seems not have any error handling here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This unsafe method assumes that users adhere to safety requirements.


let start_sector = region.start * BLOCK_SECTORS;
let nr_bytes = region.len() * BLOCK_SIZE;
if nr_bytes != buf_len {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why shouldn't this check be put at the front of the function before bio_alloc_bioset ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In order to avoid iterating the io_buffer twice.

}

// Clones a bio that shares the original bio's I/O buffer.
pub fn alloc_clone(&self) -> Result<Self> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The name alloc_clone with a &self which originated from C version might be misunderstood.
Try to be more descriptive like clone_with_shared_buffer().

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since bio_alloc_clone function is an existing C concept, choosing a name as close as reasonably possible to the C side should avoid confusion and improve readability when switching back and forth between the C and Rust sides.

}

/// A struct to carry the data for `bi_end_io`.
struct CallbackItem<T> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the name BioEndFn, BioCompleteFn, OnCompleteFn more descriptive and readable?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sense.


impl TargetType {
/// Provide an in-place constructor to register a new device mapper target.
pub fn register<T: TargetOperations>(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder how can we ensure dm_register_target and dm_unregister_target appear in pairs and are non-repeating?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If dm_register_target returns error, there is no need to call dm_unregister_target, and uninit memory will be freed by pin_init macros. Or else, dm_unregister_target will be called, when the TargetType is going to drop.

(*target).version = version;
(*target).features = features;

binding_target_operations!(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This macro needs a clear explanation.

/// and can be accessed by the `private` method.
pub struct Target<T: TargetOperations + Sized> {
opaque: Opaque<bindings::dm_target>,
_p: PhantomData<*mut T::Private>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PhantomData used here deserves a comment.

region: Range<BlockId>,
}

unsafe impl Send for RawDisk {}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing SAFETY comment here.

let handler = spawn(move || {
ReqQueue::handler(queue_cloned);
});

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

handler() is not a appropriate function name and a noun. Maybe wrap L303-L305 to spawn_req_handler() is more readable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants