Skip to content

Add block/disk IO functionality #18

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

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open

Add block/disk IO functionality #18

wants to merge 7 commits into from

Conversation

csssuf
Copy link
Owner

@csssuf csssuf commented Aug 8, 2017

The commits in this PR that aren't directly used by 281cef1 add functionality that is basically necessary for making effective use of the block/disk IO protocols.

csssuf added 2 commits August 4, 2017 15:43
This is immediately useful for checking partition types/GUIDs for block
and disk I/O, but is also useful elsewhere.
@csssuf csssuf requested a review from bgilbert August 8, 2017 01:08
csssuf added 3 commits August 7, 2017 19:26
Some function calls require image handles in place of the
LoadedImageProtocol struct, so track it for library consumers that may
want to use it.

// The read buffer must be aligned to the value of `media.io_align`. UEFI doesn't provide
// any sort of memalign, so in order to be safe, if we need to be aligned on any boundary
// greater than 2, use `allocate_pages` to obtain a 4K-aligned address instead of
Copy link

Choose a reason for hiding this comment

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

Greater than 1, surely.

) {
Status::Success => Ok(slice::from_raw_parts_mut(buffer, num_bytes)),
e => {
bs.free_pool(buffer);
Copy link

Choose a reason for hiding this comment

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

This will presumably be unhappy if the buffer was allocated with allocate_pages.

num_pages += 1;
}

buffer = bs.allocate_pages(num_pages).map(|buf| buf as *mut u8);
Copy link

Choose a reason for hiding this comment

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

The comment block says the caller needs to free this with allocate_pool, which could end badly.

@csssuf csssuf force-pushed the disk-io branch 2 times, most recently from dc994ca to 50e2139 Compare August 10, 2017 20:21
@csssuf csssuf mentioned this pull request Aug 11, 2017

/// Read `num_bytes` bytes from the disk starting at block `start`. The returned slice includes
/// memory allocated with `allocate_pool` or `allocate_pages`, and it is the caller's
/// responsibility to free it with the appropriate function based on `must_align()`.

Choose a reason for hiding this comment

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

This does not make a great API. Is allocate_pool an important optimization? It seems like it'd be cleaner to always use allocate_pages.

Copy link
Owner Author

Choose a reason for hiding this comment

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

I agree. I would prefer to use allocate_pool wherever possible, simply because free_pages requires the caller to specify how many pages to free, which also isn't a great API. Mixing them definitely isn't ideal though. Realistically it shouldn't be the responsibility of the library consumer to manage memory allocated with allocate_pages, but until the new allocator APIs are more stable there's not a simple solution.

There are two ways to deal with it here in the short term:

  • Write a simple allocator for rust-uefi to use internally that doesn't attempt to also be the language's allocator; or
  • For the block I/O protocol, always allocate memory with allocate_pages and just force library consumers to deal with the unpleasant deallocation.

Which would be preferable?

}

/// Read `num_blocks` blocks from the disk starting at block `start`. The returned slice
/// includes memory allocated with `allocate_pool`, and it is the caller's responsibility to

Choose a reason for hiding this comment

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

Not completely true right now.


/// Read `num_bytes` bytes from the disk starting at block `start`. The returned slice includes
/// memory allocated with `allocate_pages`, and it is the caller's responsibility to free it
/// with `free_pages` based on `required_pages` or `required_pages_block`.

Choose a reason for hiding this comment

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

With free_read?

if self.must_align() {
bs.free_pages(buffer, self.required_pages(read_size));
} else {
bs.free_pool(buffer);

Choose a reason for hiding this comment

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

Nope.

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