From: Christian Brauner <brauner@kernel.org>
To: Alice Ryhl <aliceryhl@google.com>
Cc: a.hindborg@samsung.com, alex.gaynor@gmail.com, arve@android.com,
benno.lossin@proton.me, bjorn3_gh@protonmail.com,
boqun.feng@gmail.com, cmllamas@google.com,
dan.j.williams@intel.com, dxu@dxuuu.xyz, gary@garyguo.net,
gregkh@linuxfoundation.org, joel@joelfernandes.org,
keescook@chromium.org, linux-fsdevel@vger.kernel.org,
linux-kernel@vger.kernel.org, maco@android.com, ojeda@kernel.org,
peterz@infradead.org, rust-for-linux@vger.kernel.org,
surenb@google.com, tglx@linutronix.de, tkjos@android.com,
viro@zeniv.linux.org.uk, wedsonaf@gmail.com, willy@infradead.org
Subject: Re: [PATCH 1/7] rust: file: add Rust abstraction for `struct file`
Date: Thu, 30 Nov 2023 13:36:06 +0100 [thread overview]
Message-ID: <20231130-zweig-mitleid-2ba3ef78145e@brauner> (raw)
In-Reply-To: <20231130121013.140671-1-aliceryhl@google.com>
On Thu, Nov 30, 2023 at 12:10:12PM +0000, Alice Ryhl wrote:
> Christian Brauner <brauner@kernel.org> writes:
> >> This is the backdoor. You use it when *you* know that the file is okay
> >
> > And a huge one.
> >
> >> to access, but Rust doesn't. It's unsafe because it's not checked by
> >> Rust.
> >>
> >> For example you could do this:
> >>
> >> let ptr = unsafe { bindings::fdget(fd) };
> >>
> >> // SAFETY: We just called `fdget`.
> >> let file = unsafe { File::from_ptr(ptr) };
> >> use_file(file);
> >>
> >> // SAFETY: We're not using `file` after this call.
> >> unsafe { bindings::fdput(ptr) };
> >>
> >> It's used in Binder here:
> >> https://github.com/Darksonn/linux/blob/dca45e6c7848e024709b165a306cdbe88e5b086a/drivers/android/rust_binder.rs#L331-L332
> >>
> >> Basically, I use it to say "C code has called fdget for us so it's okay
> >> to access the file", whenever userspace uses a syscall to call into the
> >> driver.
> >
> > Yeah, ok, because the fd you're operating on may be coming from fdget(). Iirc,
> > binder is almost by default used multi-threaded with a shared file descriptor
> > table? But while that means fdget() will usually bump the reference count you
> > can't be sure. Hmkay.
>
> Even if the syscall used `fget` instead of `fdget`, I would still be
> using `from_ptr` here. The `ARef` type only really makes sense when *we*
> have ownership of the ref-count, but in this case we don't own it. We're
> just given a promise that the caller is keeping it alive for us using
> some mechanism or another.
>
> >>>> +// SAFETY: It's OK to access `File` through shared references from other threads because we're
> >>>> +// either accessing properties that don't change or that are properly synchronised by C code.
> >>>
> >>> Uhm, what guarantees are you talking about specifically, please?
> >>> Examples would help.
> >>>
> >>>> +unsafe impl Sync for File {}
> >>
> >> The Sync trait defines whether a value may be accessed from several
> >> threads in parallel (using shared/immutable references). In our case,
> >
> > So let me put this into my own words and you correct me, please:
> >
> > So, this really just means that if I have two processes both with their own
> > fdtable and they happen to hold fds that refer to the same @file:
> >
> > P1 P2
> > struct fd fd1 = fdget(1234);
> > struct fd fd2 = fdget(5678);
> > if (!fd1.file) if (!fd2.file)
> > return -EBADF; return -EBADF;
> >
> > // fd1.file == fd2.file
> >
> > the only if the Sync trait is implemented both P1 and P2 can in parallel call
> > file->f_op->poll(@file)?
> >
> > So if the Sync trait isn't implemented then the compiler will prohibit that P1
> > and P2 at the same time call file->f_op->poll(@file)? And that's all that's
> > meant by a shared reference? It's really about sharing the pointer.
>
> Yeah, what you're saying sounds correct. For a type that is not Sync,
> you would need a lock around the call to `poll` before the compiler
> would accept the call.
>
> (Or some other mechanism to convince the compiler that no other thread
> is looking at the file at the same time. Of course, a lock is just one
> way to do that.)
>
> > The thing is that "shared reference" gets a bit in our way here:
> >
> > (1) If you have SCM_RIGHTs in the mix then P1 can open fd1 to @file and then
> > send that @file to P2 which now has fd2 refering to @file as well. The
> > @file->f_count is bumped in that process. So @file->f_count is now 2.
> >
> > Now both P1 and P2 call fdget(). Since they don't have a shared fdtable
> > none of them take an additional reference to @file. IOW, @file->f_count
> > may remain 2 all throughout the @file->f_op->*() operation.
> >
> > So they share a reference to that file and elide both the
> > atomic_inc_not_zero() and the atomic_dec_not_zero().
> >
> > (2) io_uring has fixed files whose reference count always stays at 1.
> > So all io_uring operations on such fixed files share a single reference.
> >
> > So that's why this is a bit confusing at first to read "shared reference".
> >
> > Please add a comment on top of unsafe impl Sync for File {}
> > explaining/clarifying this a little that it's about calling methods on the same
> > file.
>
> Yeah, I agree, the terminology gets a bit mixed up here because we both
> use the word "reference" for different things.
>
> How about this comment?
Sounds good.
next prev parent reply other threads:[~2023-11-30 12:36 UTC|newest]
Thread overview: 96+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-11-29 12:51 [PATCH 0/7] File abstractions needed by Rust Binder Alice Ryhl
2023-11-29 12:51 ` [PATCH 1/7] rust: file: add Rust abstraction for `struct file` Alice Ryhl
2023-11-29 15:13 ` Matthew Wilcox
2023-11-29 15:23 ` Peter Zijlstra
2023-11-29 17:08 ` Boqun Feng
2023-11-30 10:42 ` Peter Zijlstra
2023-11-30 15:25 ` Boqun Feng
2023-12-01 8:53 ` Peter Zijlstra
2023-12-01 9:19 ` Boqun Feng
2023-12-01 9:40 ` Peter Zijlstra
2023-12-01 10:36 ` Boqun Feng
2023-12-01 11:05 ` Peter Zijlstra
2023-12-01 9:00 ` Peter Zijlstra
2023-12-01 9:52 ` Boqun Feng
2023-11-29 16:42 ` Alice Ryhl
2023-11-29 16:45 ` Peter Zijlstra
2023-11-30 15:02 ` Benno Lossin
2023-11-29 17:06 ` Christian Brauner
2023-11-29 21:27 ` Alice Ryhl
2023-11-29 23:17 ` Benno Lossin
2023-11-30 10:48 ` Christian Brauner
2023-11-30 12:10 ` Alice Ryhl
2023-11-30 12:36 ` Christian Brauner [this message]
2023-11-30 14:53 ` Benno Lossin
2023-11-30 14:59 ` Greg Kroah-Hartman
2023-11-30 15:46 ` Benno Lossin
2023-11-30 15:56 ` Greg Kroah-Hartman
2023-11-30 15:58 ` Theodore Ts'o
2023-11-30 16:12 ` Benno Lossin
2023-12-01 1:16 ` Theodore Ts'o
2023-12-01 12:11 ` David Laight
2023-12-01 12:27 ` Alice Ryhl
2023-12-01 15:04 ` Theodore Ts'o
2023-12-01 15:14 ` Benno Lossin
2023-12-01 17:25 ` David Laight
2023-12-01 17:37 ` Benno Lossin
2023-11-29 12:51 ` [PATCH 2/7] rust: cred: add Rust abstraction for `struct cred` Alice Ryhl
2023-11-30 16:17 ` Benno Lossin
2023-12-01 9:06 ` Alice Ryhl
2023-12-01 10:27 ` Christian Brauner
2023-12-04 15:42 ` Alice Ryhl
2023-11-29 13:11 ` [PATCH 3/7] rust: security: add abstraction for secctx Alice Ryhl
2023-11-30 16:26 ` Benno Lossin
2023-12-01 10:48 ` Alice Ryhl
2023-12-02 10:03 ` Benno Lossin
2023-11-29 13:11 ` [PATCH 4/7] rust: file: add `FileDescriptorReservation` Alice Ryhl
2023-11-29 16:14 ` Christian Brauner
2023-11-29 16:55 ` Alice Ryhl
2023-11-29 17:14 ` Alice Ryhl
2023-11-30 9:12 ` Christian Brauner
2023-11-30 9:23 ` Alice Ryhl
2023-11-30 9:09 ` Christian Brauner
2023-11-30 9:17 ` Alice Ryhl
2023-11-30 10:51 ` Christian Brauner
2023-11-30 11:54 ` Alice Ryhl
2023-11-30 12:17 ` Benno Lossin
2023-11-30 12:33 ` Christian Brauner
2023-11-30 16:40 ` Benno Lossin
2023-12-01 11:32 ` Alice Ryhl
2023-11-29 13:12 ` [PATCH 5/7] rust: file: add `Kuid` wrapper Alice Ryhl
2023-11-29 16:28 ` Christian Brauner
2023-11-29 16:48 ` Peter Zijlstra
2023-11-30 12:46 ` Christian Brauner
2023-12-06 19:59 ` Kent Overstreet
2023-12-08 16:26 ` Peter Zijlstra
2023-12-08 19:58 ` Kent Overstreet
2023-12-08 5:28 ` comex
2023-12-08 16:19 ` Miguel Ojeda
2023-12-08 17:08 ` Nick Desaulniers
2023-12-08 17:37 ` Miguel Ojeda
2023-12-08 17:43 ` Boqun Feng
2023-12-08 20:43 ` Matthew Wilcox
2023-12-09 7:24 ` comex
2023-11-30 9:36 ` Alice Ryhl
2023-11-30 10:52 ` Christian Brauner
2023-11-30 10:36 ` Peter Zijlstra
2023-12-06 20:02 ` Kent Overstreet
2023-12-07 7:18 ` Greg Kroah-Hartman
2023-12-07 7:46 ` Kent Overstreet
2023-11-30 16:48 ` Benno Lossin
2023-11-29 13:12 ` [PATCH 6/7] rust: file: add `DeferredFdCloser` Alice Ryhl
2023-11-30 17:12 ` Benno Lossin
2023-12-01 11:35 ` Alice Ryhl
2023-12-02 10:16 ` Benno Lossin
2023-12-05 14:43 ` Alice Ryhl
2023-12-05 18:16 ` Alice Ryhl
2023-11-29 13:12 ` [PATCH 7/7] rust: file: add abstraction for `poll_table` Alice Ryhl
2023-11-30 17:42 ` Benno Lossin
2023-12-01 11:47 ` Alice Ryhl
2023-11-30 22:39 ` Boqun Feng
2023-12-01 11:50 ` Alice Ryhl
2023-11-30 22:50 ` Boqun Feng
2023-11-29 16:31 ` [PATCH 0/7] File abstractions needed by Rust Binder Christian Brauner
2023-11-29 16:48 ` Miguel Ojeda
2023-12-06 20:05 ` Kent Overstreet
2023-12-08 16:59 ` Miguel Ojeda
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20231130-zweig-mitleid-2ba3ef78145e@brauner \
--to=brauner@kernel.org \
--cc=a.hindborg@samsung.com \
--cc=alex.gaynor@gmail.com \
--cc=aliceryhl@google.com \
--cc=arve@android.com \
--cc=benno.lossin@proton.me \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun.feng@gmail.com \
--cc=cmllamas@google.com \
--cc=dan.j.williams@intel.com \
--cc=dxu@dxuuu.xyz \
--cc=gary@garyguo.net \
--cc=gregkh@linuxfoundation.org \
--cc=joel@joelfernandes.org \
--cc=keescook@chromium.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=maco@android.com \
--cc=ojeda@kernel.org \
--cc=peterz@infradead.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=surenb@google.com \
--cc=tglx@linutronix.de \
--cc=tkjos@android.com \
--cc=viro@zeniv.linux.org.uk \
--cc=wedsonaf@gmail.com \
--cc=willy@infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.