Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 5 Oct 2023 18:53:04 -0700
From:      Rick Macklem <rick.macklem@gmail.com>
To:        Alan Somers <asomers@freebsd.org>
Cc:        Mark Johnston <markj@freebsd.org>, freebsd-hackers@freebsd.org, rmacklem@freebsd.org
Subject:   Re: copy_file_range() doesn't update the atime of an empty file
Message-ID:  <CAM5tNy70AmgrsLmYPqgiDkPAP10msv77o8E_DzCmiO0LycEnfg@mail.gmail.com>
In-Reply-To: <CAM5tNy4k%2BfZYC8MVJO5gGf9%2Bo=Fi0sL8ER_kckrwZmi6Fwt9ow@mail.gmail.com>
References:  <ZR2FUeIhO7DIQIpj@nuc> <CAOtMX2h7QLqLHPm-gUMDJKeR8oyAXssn2vxkJ8xNgBBT6Cc3bw@mail.gmail.com> <CAM5tNy72tPBLHM8mkhqkUu64GuLUiZuKFJ%2B2JFsOzVgA1hm0eA@mail.gmail.com> <CAM5tNy5nLWf9c%2BnsdxJsU-M9Q3p_VVc%2BnpuY6uwbZPwM6EwhKg@mail.gmail.com> <CAM5tNy4%2BZZTYQ4QuD_sapx3q%2BQ%2Bwz9uNu6CGL17JFsjN13i0Sg@mail.gmail.com> <CAOtMX2jSXLnhjN1JDxk9N_NCjjjKWxguhsb05F4ww9mKwcbSsg@mail.gmail.com> <CAM5tNy4k%2BfZYC8MVJO5gGf9%2Bo=Fi0sL8ER_kckrwZmi6Fwt9ow@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Thu, Oct 5, 2023 at 3:30=E2=80=AFPM Rick Macklem <rick.macklem@gmail.com=
> wrote:
>
> On Thu, Oct 5, 2023 at 8:41=E2=80=AFAM Alan Somers <asomers@freebsd.org> =
wrote:
> >
> > I don't think that Linux is a good model to copy from, where atime is
> > concerned.  It long ago gave up on POSIX-compliance for atime by
> > default.  In this case, I think it's better to stick as closely as we
> > can to read(2).  Preserving the existing behavior of tools like cat,
> > too, is worthwhile I think.
> I have no problem with Mark's patch being applied for the default
> local fs case.  NFSv4.2 will not be able to comply with this unless
> (as will be the case for the FreeBSD server) the NFSv4.2 server
> happens to change atime after Mark's patch is applied to the
> FreeBSD NFSv4.2 server (the Linux NFSv4.2 server will not).
I have come up with a NFSv4.2 client patch that explicitly sets atime
for the input file in the same compound RPC as the Copy.  It works for
a FreeBSD server without Mark's patch.  If a NFSv4.2 server does not
do it, we can argue that the server ignores the Setattr of atime.

So, with this patch (which I will be testing against assorted servers next
week (an ietf bakeathon testing event) and Mark's patch, the only case
that may need more work is ZFS?

rick
ps: I'll admit I still doubt anyone cares about atime being set, but the
      collective opinion seems to be that it should be set.

>
> ZFS..I have no idea. Someone else will need to test it (with block clonin=
g
> enabled).
>
> rick
> >
> > On Thu, Oct 5, 2023 at 7:53=E2=80=AFAM Rick Macklem <rick.macklem@gmail=
.com> wrote:
> > >
> > > Note that, although i'd prefer to keep copy_file_range(2) Linux compa=
tible,
> > > I would like to hear others chime in w.r.t. their preference.
> > >
> > > rick
> > >
> > > On Wed, Oct 4, 2023 at 4:39=E2=80=AFPM Rick Macklem <rick.macklem@gma=
il.com> wrote:
> > > >
> > > > Resent now that I am subscribed to freebsd-hackers@,
> > > >
> > > > On Wed, Oct 4, 2023 at 4:25=E2=80=AFPM Rick Macklem <rick.macklem@g=
mail.com> wrote:
> > > > >
> > > > > On Wed, Oct 4, 2023 at 8:40=E2=80=AFAM Alan Somers <asomers@freeb=
sd.org> wrote:
> > > > > >
> > > > > > CAUTION: This email originated from outside of the University o=
f Guelph. Do not click links or open attachments unless you recognize the s=
ender and know the content is safe. If in doubt, forward suspicious emails =
to IThelp@uoguelph.ca.
> > > > > >
> > > > > >
> > > > > > On Wed, Oct 4, 2023 at 8:31=E2=80=AFAM Mark Johnston <markj@fre=
ebsd.org> wrote:
> > > > > > >
> > > > > > > For a while, Jenkins has been complaining that one of the tmp=
fs tests is
> > > > > > > failing:
> > > > > > > https://ci.freebsd.org/job/FreeBSD-main-amd64-test/23814/test=
Report/junit/sys.fs.tmpfs/times_test/empty/
> > > > > > >
> > > > > > > This has been happening since commit
> > > > > > > 8113cc827611a88540736c92ced7d3a7020a1723, which converted cat=
(1) to use
> > > > > > > copy_file_range(2).  The test in question creates an empty fi=
le, waits
> > > > > > > for a second, then cat(1)s it and checks that the file's atim=
e was
> > > > > > > updated.  After the aforementioned commit, the atime is not u=
pdated.
> > > > > > >
> > > > > > > I believe the essential difference is that a zero-length read=
(2) results
> > > > > > > in a call to VOP_READ(), which results in an updated atime ev=
en if no
> > > > > > > bytes were read.  For instance, ffs_read() sets IN_ACCESS so =
long as the
> > > > > > > routine doesn't return an error.  (I'm not sure if the mtime =
is
> > > > > > > correspondingly updated upon a zero-length write.)
> > > > > > >
> > > > > > > copy_file_range() on the other hand elides calls to VOP_READ/=
VOP_WRITE
> > > > > > > when copylen is 0, so the atime doesn't get updated.  I wonde=
r if we
> > > > > > > could at least change it to call VOP_READ in that scenario, a=
s in the
> > > > > > > untested patch below.  Any thoughts?
> > > > > > >
> > > > > > > diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
> > > > > > > index 4e4161ef1a7f..d60608a6d3b9 100644
> > > > > > > --- a/sys/kern/vfs_vnops.c
> > > > > > > +++ b/sys/kern/vfs_vnops.c
> > > > > > > @@ -3499,7 +3499,7 @@ vn_generic_copy_file_range(struct vnode=
 *invp, off_t *inoffp,
> > > > > > >                         xfer -=3D (*inoffp % blksize);
> > > > > > >                 }
> > > > > > >                 /* Loop copying the data block. */
> > > > > > > -               while (copylen > 0 && error =3D=3D 0 && !eof =
&& interrupted =3D=3D 0) {
> > > > > > > +               while (error =3D=3D 0 && !eof && interrupted =
=3D=3D 0) {
> > > > > > >                         if (copylen < xfer)
> > > > > > >                                 xfer =3D copylen;
> > > > > > >                         error =3D vn_lock(invp, LK_SHARED);
> > > > > > > @@ -3511,7 +3511,7 @@ vn_generic_copy_file_range(struct vnode=
 *invp, off_t *inoffp,
> > > > > > >                             curthread);
> > > > > > >                         VOP_UNLOCK(invp);
> > > > > > >                         lastblock =3D false;
> > > > > > > -                       if (error =3D=3D 0 && aresid > 0) {
> > > > > > > +                       if (error =3D=3D 0 && (xfer =3D=3D 0 =
|| aresid > 0)) {
> > > > > > >                                 /* Stop the copy at EOF on th=
e input file. */
> > > > > > >                                 xfer -=3D aresid;
> > > > > > >                                 eof =3D true;
> > > > > > >
> > > > > >
> > > > > > From POSIX: "Note that a read() of zero bytes does not modify t=
he last
> > > > > > data access timestamp. A read() that requests more than zero by=
tes,
> > > > > > but returns zero, is required to modify the last data access
> > > > > > timestamp."
> > > > > >
> > > > > > While copy_file_range is not standardized, it ought to comport =
to
> > > > > > POSIX as closely as possible.  I think we should change it as y=
ou
> > > > > > suggest.
> > > > > Well, I'd like to maintain the syscall as "Linux compatible", whi=
ch was
> > > > > my original intent. (I consider Linux as the defacto standard for=
 *nix* like
> > > > > operating systems).
> > > > >
> > > > > I've been ignoring a recent request for support for non-regular f=
iles for
> > > > > this reason.  (I eventually intend to patch the man page to clari=
fy that
> > > > > it only works for regular files, which is what Linux does.)
> > > > >
> > > > > As such, the first step is to figure out if Linux updates atime w=
hen a
> > > > > copy_file_range() returns 0 bytes. I just did a test on Linux (ke=
rnel
> > > > > version 6.3)
> > > > > using a ext4 fs mounted "relatime" and doing a copy_file_range(2)=
 on it
> > > > > (using a trivial file copy program suing copy_file_range(2)) did =
not update
> > > > > atime. (I did modify the file via "cat /dev/null > file" so that =
the atime would
> > > > > be updated for "relatime". A similar test using "cp" did update t=
he atime.)
> > > > >
> > > > > Also, the above changes the "generic" copy loop, but changes will
> > > > > also be required (or at least tested) for ZFS when block cloning =
is
> > > > > enabled and NFSv4.2.  The NFSv4.2 RFC does not specify whether
> > > > > or not a "Copy" operation that returns 0 bytes updates atime
> > > > > (called TimeAccess in NFSv4.2).
> > > > > Oh, and the NFS protocol (up to and including NFSv4.2) cannot
> > > > > provide a POSIX compliant file system (the NFS client tries to ma=
ke
> > > > > it look close to POSIX compliant).  As such, expecting a copy_fil=
e_range(2)
> > > > > over NFSv4.2 to behave in a POSIX-like way may not make sense?
> > > > >
> > > > > Personally, I'd rather see copy_file_range(2) remain Linux compat=
ible.
> > > > > Does cat(1) really need to exhibit this behaviour or is it just r=
ead(2)
> > > > > that specifies this?
> > > > >
> > > > > rick



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAM5tNy70AmgrsLmYPqgiDkPAP10msv77o8E_DzCmiO0LycEnfg>