Re: [PATCH rfc] nfsd: offer write delegation for O_WRONLY opens

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sun, Jul 7, 2024 at 1:21 PM Sagi Grimberg <sagi@xxxxxxxxxxx> wrote:
>
>
>
> On 07/07/2024 22:05, Rick Macklem wrote:
> > On Sun, Jul 7, 2024 at 4:07 AM Jeff Layton <jlayton@xxxxxxxxxx> wrote:
> >> On Sun, 2024-07-07 at 01:42 +0300, Sagi Grimberg wrote:
> >>> Many applications open files with O_WRONLY, fully intending to write
> >>> into the opened file. There is no reason why these applications should
> >>> not enjoy a write delegation handed to them.
> >>>
> >>> Cc: Dai Ngo <dai.ngo@xxxxxxxxxx>
> >>> Signed-off-by: Sagi Grimberg <sagi@xxxxxxxxxxx>
> >>> ---
> >>> Note: I couldn't find any reason to why the initial implementation chose
> >>> to offer write delegations only to NFS4_SHARE_ACCESS_BOTH, but it seemed
> >>> like an oversight to me. So I figured why not just send it out and see who
> >>> objects...
> >>>
> >>>   fs/nfsd/nfs4state.c | 10 +++++-----
> >>>   1 file changed, 5 insertions(+), 5 deletions(-)
> >>>
> >>> diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
> >>> index a20c2c9d7d45..69d576b19eb6 100644
> >>> --- a/fs/nfsd/nfs4state.c
> >>> +++ b/fs/nfsd/nfs4state.c
> >>> @@ -5784,15 +5784,15 @@ nfs4_set_delegation(struct nfsd4_open *open, struct nfs4_ol_stateid *stp,
> >>>         *  "An OPEN_DELEGATE_WRITE delegation allows the client to handle,
> >>>         *   on its own, all opens."
> >>>         *
> >>> -      * Furthermore the client can use a write delegation for most READ
> >>> -      * operations as well, so we require a O_RDWR file here.
> >>> -      *
> >>> -      * Offer a write delegation in the case of a BOTH open, and ensure
> >>> -      * we get the O_RDWR descriptor.
> >>> +      * Offer a write delegation in the case of a BOTH open (ensure
> >>> +      * a O_RDWR descriptor) Or WRONLY open (with a O_WRONLY descriptor).
> >>>         */
> >>>        if ((open->op_share_access & NFS4_SHARE_ACCESS_BOTH) == NFS4_SHARE_ACCESS_BOTH) {
> >>>                nf = find_rw_file(fp);
> >>>                dl_type = NFS4_OPEN_DELEGATE_WRITE;
> >>> +     } else if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE) {
> >>> +             nf = find_writeable_file(fp);
> >>> +             dl_type = NFS4_OPEN_DELEGATE_WRITE;
> >>>        }
> >>>
> >>>        /*
> >>
> >> I *think* the main reason we limited this before is because a write
> >> delegation is really a read/write delegation. There is no such thing as
> >> a write-only delegation.
> >>
> >> Suppose the user is prevented from doing reads against the inode (by
> >> permission bits or ACLs). The server gives out a WRITE delegation on a
> >> O_WRONLY open. Will the client allow cached opens for read regardless
> >> of the server's permissions? Or, does it know to check vs. the server
> >> if the client tries to do an open for read in this situation?
> > I was curious and tried a simple test yesterday, using the FreeBSD server
> > configured to issue a write delegation for a write-only open.
> > The test simply opened write-only first and then read-only, for a file
> > with mode 222. It worked as expected for both the Linux and FreeBSD
> > clients (ie. returned a failure for the read-only open).
> > I've attached the packet capture for the Linux client, in case you are
> > interested.
>
> Nice, thanks for testing!
>
> >
> > I do believe this is allowed by the RFCs. In fact I think the RFCs
> > allow a server
> > to issue a write delegation for a read open (not that I am convinced that is a
> > good idea). The main thing to check is what the ACE in the write delegation
> > reply looks like, since my understanding is that the client is expected to do
> > an Access unless the ACE allows access.
> > Here's a little snippet:
> >      nfsace4   permissions; /* Defines users who don't
> >                                need an ACCESS call as
> >                                part of a delegated
> >                                open. */
>
> Yes, I had the same understanding...
>
> >
> > Now, is it a good idea to do this?
> > Well, my opinion (as the outsider;-) is that the server should follow whatever
> > the client requests, as far as practicable. ie. The OPEN_WANT flags:
> >     const OPEN4_SHARE_ACCESS_WANT_NO_PREFERENCE     = 0x0000;
> >     const OPEN4_SHARE_ACCESS_WANT_READ_DELEG        = 0x0100;
> >     const OPEN4_SHARE_ACCESS_WANT_WRITE_DELEG       = 0x0200;
> >     const OPEN4_SHARE_ACCESS_WANT_ANY_DELEG         = 0x0300;
> >     const OPEN4_SHARE_ACCESS_WANT_NO_DELEG          = 0x0400;
> > If the client does not provide these (4.0 or 4.1/4.2, but no flags), then I
> > suppose I might be concerned that there is a buggy client out there that
> > would do what Jeff suggested (ie. assume it can open the file for reading
> > after getting a write delegation).
>
> Well, that is obviously not what the Linux client is asking for today,
> but even if it
> did, what would it set in the OPEN_WANT flags for O_WRONLY open? it would
> set OPEN4_SHARE_ACCESS_WANT_WRITE_DELEG.
I didn't think to mention that the client was a rather old 6.3 kernel.
If the Linux client is still not setting OPEN4_SHARE_ACCESS_WANT_xxx
flags, then maybe it should do so?
And maybe the client developers will be encouraged to set them, if the server
uses them?

I'll admit I had assumed they weren't there just because my kernel is
out of date.

rick

>
> I do agree that there is an argument to be made that Linux nfsd should not
> hand out any delegation that is not explicitly solicited by the client,
> but I don't see
> how this particular delegation against a wronly open is any different
> from any
> other type of delegation that Linux nfsd hands out today.





[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux