Skip to content

Commit

Permalink
Merge pull request torvalds#311 from wedsonaf/fd
Browse files Browse the repository at this point in the history
Define a file descriptor reservation/commit/rollback abstraction.
  • Loading branch information
ojeda authored May 28, 2021
2 parents 6eec399 + 49d4ada commit 843de5c
Showing 1 changed file with 46 additions and 0 deletions.
46 changes: 46 additions & 0 deletions rust/kernel/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,49 @@ impl Deref for FileRef {
self.0.deref()
}
}

/// A file descriptor reservation.
///
/// This allows the creation of a file descriptor in two steps: first, we reserve a slot for it,
/// then we commit or drop the reservation. The first step may fail (e.g., the current process ran
/// out of available slots), but commit and drop never fail (and are mutually exclusive).
pub struct FileDescriptorReservation {
fd: u32,
}

impl FileDescriptorReservation {
/// Creates a new file descriptor reservation.
pub fn new(flags: u32) -> Result<Self> {
let fd = unsafe { bindings::get_unused_fd_flags(flags) };
if fd < 0 {
return Err(Error::from_kernel_errno(fd));
}
Ok(Self { fd: fd as _ })
}

/// Returns the file descriptor number that was reserved.
pub fn reserved_fd(&self) -> u32 {
self.fd
}

/// Commits the reservation.
///
/// The previously reserved file descriptor is bound to `file`.
pub fn commit(self, file: File) {
// SAFETY: `self.fd` was previously returned by `get_unused_fd_flags`, and `file.ptr` is
// guaranteed to have an owned ref count by its type invariants.
unsafe { bindings::fd_install(self.fd, file.ptr) };

// `fd_install` consumes both the file descriptor and the file reference, so we cannot run
// the destructors.
core::mem::forget(self);
core::mem::forget(file);
}
}

impl Drop for FileDescriptorReservation {
fn drop(&mut self) {
// SAFETY: `self.fd` was returned by a previous call to `get_unused_fd_flags`.
unsafe { bindings::put_unused_fd(self.fd) };
}
}

0 comments on commit 843de5c

Please sign in to comment.