Lines Matching +full:no +full:- +full:can +full:- +full:fd
1 // SPDX-License-Identifier: GPL-2.0
25 /// Signal-driven I/O is enabled.
28 /// Close-on-exec flag is set.
99 /// File can be both read and written.
112 /// Instances of this type are reference-counted. The reference count is incremented by the
116 /// Whenever a process opens a file descriptor (fd), it stores a pointer to the file in its fd
123 /// Whenever a process has an fd to a file, it may use something called a "light refcount" as a
125 /// `fdput`. The idea behind light refcounts is that if the fd is not closed between the calls to
127 /// files_struct` holds a reference until the fd is closed. This means that it's safe to access the
130 /// The requirement that the fd is not closed during a light refcount applies globally across all
131 /// threads - not just on the thread using the light refcount. For this reason, light refcounts are
133 /// that other unrelated threads cannot suddenly start using the fd and close it. Therefore,
148 /// `fdget`. With `fdget`, you may avoid incrementing the refcount as long as the current fd table
149 /// is not shared; it is okay if there are other fd tables that also reference the same `struct
150 /// file`. However, `fdget_pos` can only avoid taking the `f_pos_lock` if the entire `struct file`
151 /// is not shared, as different processes with an fd to the same `struct file` share the same
161 /// * `&File` references don't own a reference count. They can only exist as long as the reference
162 /// count stays positive, and can only be created when there is some mechanism in place to ensure
165 /// * The Rust borrow-checker normally ensures this by enforcing that the `ARef<File>` from which
171 /// * You can think of `fdget` as using an fd to look up an `ARef<File>` in the `struct
172 /// files_struct` and create an `&File` from it. The "fd cannot be closed" rule is like the Rust
193 // SAFETY: The type invariants guarantee that `File` is always ref-counted. This implementation
213 /// To obtain a thread-safe [`File`], use the [`assume_no_fdget_pos`] conversion.
229 // SAFETY: The type invariants guarantee that `LocalFile` is always ref-counted. This implementation
257 pub fn fget(fd: u32) -> Result<ARef<LocalFile>, BadFdError> { in fget()
258 // SAFETY: FFI call, there are no requirements on `fd`. in fget()
259 let ptr = ptr::NonNull::new(unsafe { bindings::fget(fd) }).ok_or(BadFdError)?; in fget()
263 // INVARIANT: This file is in the fd table on this thread, so either all `fdget_pos` calls in fget()
278 pub unsafe fn from_raw_file<'a>(ptr: *const bindings::file) -> &'a LocalFile { in from_raw_file()
282 // INVARIANT: The caller guarantees that there are no problematic `fdget_pos` calls. in from_raw_file()
286 /// Assume that there are no active `fdget_pos` calls that prevent us from sharing this file.
288 /// This makes it safe to transfer this file to other threads. No checks are performed, and
293 /// statically that there are no `fdget_pos` calls on the current thread. For example, you
301 pub unsafe fn assume_no_fdget_pos(me: ARef<LocalFile>) -> ARef<File> { in assume_no_fdget_pos()
302 // INVARIANT: There are no `fdget_pos` calls on the current thread, and by the type in assume_no_fdget_pos()
312 pub fn as_ptr(&self) -> *mut bindings::file { in as_ptr()
317 pub fn cred(&self) -> &Credential { in cred()
332 pub fn flags(&self) -> u32 { in flags()
352 pub unsafe fn from_raw_file<'a>(ptr: *const bindings::file) -> &'a File { in from_raw_file()
356 // INVARIANT: The caller guarantees that there are no problematic `fdget_pos` calls. in from_raw_file()
365 fn deref(&self) -> &LocalFile { in deref()
369 // By the type invariants, there are no `fdget_pos` calls that did not take the in deref()
385 /// The fd stored in this struct must correspond to a reserved file descriptor of the current task.
387 fd: u32, field
400 pub fn get_unused_fd_flags(flags: u32) -> Result<Self> { in get_unused_fd_flags()
401 // SAFETY: FFI call, there are no safety requirements on `flags`. in get_unused_fd_flags()
402 let fd: i32 = unsafe { bindings::get_unused_fd_flags(flags) }; in get_unused_fd_flags() localVariable
403 to_result(fd)?; in get_unused_fd_flags()
406 fd: fd as u32, in get_unused_fd_flags()
413 pub fn reserved_fd(&self) -> u32 { in reserved_fd()
414 self.fd in reserved_fd()
423 // SAFETY: `self.fd` was previously returned by `get_unused_fd_flags`. We have not yet used in fd_install()
424 // the fd, so it is still valid, and `current` still refers to the same task, as this type in fd_install()
429 // Additionally, the file is known to not have any non-shared `fdget_pos` calls, so even if in fd_install()
432 unsafe { bindings::fd_install(self.fd, file.as_ptr()) }; in fd_install()
444 // SAFETY: By the type invariants of this type, `self.fd` was previously returned by in drop()
445 // `get_unused_fd_flags`. We have not yet used the fd, so it is still valid, and `current` in drop()
447 unsafe { bindings::put_unused_fd(self.fd) }; in drop()
453 /// Used for methods that can only fail with [`EBADF`].
459 fn from(_: BadFdError) -> Error { in from()
465 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { in fmt()