2023-08-09 19:14:47

by Jeffrey Layton

[permalink] [raw]
Subject: Re: [PATCH v7 05/13] fat: make fat_update_time get its own timestamp

On Thu, 2023-08-10 at 03:31 +0900, OGAWA Hirofumi wrote:
> Jeff Layton <[email protected]> writes:
>
> > On Thu, 2023-08-10 at 02:44 +0900, OGAWA Hirofumi wrote:
> > > Jeff Layton <[email protected]> writes:
> > >
> > That would be wrong. The problem is that we're changing how update_time
> > works:
> >
> > Previously, update_time was given a timestamp and a set of S_* flags to
> > indicate which fields should be updated. Now, update_time is not given a
> > timestamp. It needs to fetch it itself, but that subtly changes the
> > meaning of the flags field.
> >
> > It now means "these fields needed to be updated when I last checked".
> > The timestamp and i_version may now be different from when the flags
> > field was set. This means that if any of S_CTIME/S_MTIME/S_VERSION were
> > set that we need to attempt to update all 3 of them. They may now be
> > different from the timestamp or version that we ultimately end up with.
> >
> > The above may look to you like it would always cause I_DIRTY_SYNC to be
> > set on any ctime or mtime update, but inode_maybe_inc_iversion only
> > returns true if it actually updated i_version, and it only does that if
> > someone issued a ->getattr against the file since the last time it was
> > updated.
> >
> > So, this shouldn't generate any more DIRTY_SYNC updates than it did
> > before.
>
> Again, if you claim so, why generic_update_time() doesn't work same? Why
> only FAT does?
>
> Or I'm misreading generic_update_time() patch?
>

When you say it "doesn't work the same", what do you mean, specifically?
I had to make some allowances for the fact that FAT is substantially
different in its timestamp handling, and I tried to preserve existing
behavior as best I could.

--
Jeff Layton <[email protected]>


2023-08-09 20:26:27

by OGAWA Hirofumi

[permalink] [raw]
Subject: Re: [PATCH v7 05/13] fat: make fat_update_time get its own timestamp

Jeff Layton <[email protected]> writes:

> When you say it "doesn't work the same", what do you mean, specifically?
> I had to make some allowances for the fact that FAT is substantially
> different in its timestamp handling, and I tried to preserve existing
> behavior as best I could.

Ah, ok. I was misreading some.

inode_update_timestamps() checks IS_I_VERSION() now, not S_VERSION. So,
if adding the check of IS_I_VERSION() and (S_MTIME|S_CTIME|S_VERSION) to
FAT?

With it, IS_I_VERSION() would be false on FAT, and I'm fine.

I.e. something like

if ((flags & (S_VERSION|S_CTIME|S_MTIME)) && IS_I_VERSION(inode)
&& inode_maybe_inc_iversion(inode, false))
dirty_flags |= I_DIRTY_SYNC;

Thanks.
--
OGAWA Hirofumi <[email protected]>

2023-08-09 22:37:12

by Jeffrey Layton

[permalink] [raw]
Subject: Re: [PATCH v7 05/13] fat: make fat_update_time get its own timestamp

On Thu, 2023-08-10 at 05:14 +0900, OGAWA Hirofumi wrote:
> Jeff Layton <[email protected]> writes:
>
> > When you say it "doesn't work the same", what do you mean, specifically?
> > I had to make some allowances for the fact that FAT is substantially
> > different in its timestamp handling, and I tried to preserve existing
> > behavior as best I could.
>
> Ah, ok. I was misreading some.
>
> inode_update_timestamps() checks IS_I_VERSION() now, not S_VERSION. So,
> if adding the check of IS_I_VERSION() and (S_MTIME|S_CTIME|S_VERSION) to
> FAT?
>
> With it, IS_I_VERSION() would be false on FAT, and I'm fine.
>
> I.e. something like
>
> if ((flags & (S_VERSION|S_CTIME|S_MTIME)) && IS_I_VERSION(inode)
> && inode_maybe_inc_iversion(inode, false))
> dirty_flags |= I_DIRTY_SYNC;
>
> Thanks.

If you do that then the i_version counter would never be incremented.
But...I think I see what you're getting at.

Most filesystems that support the i_version counter have an on-disk
field for it. FAT obviously has no such thing. I suspect the i_version
bits in fat_update_time were added by mistake. FAT doesn't set
SB_I_VERSION so there's no need to do anything to the i_version field at
all.

Also, given that the mtime and ctime are always kept in sync on FAT,
we're probably fine to have it look something like this:

--------------------8<------------------
int fat_update_time(struct inode *inode, int flags)
{
int dirty_flags = 0;

if (inode->i_ino == MSDOS_ROOT_INO)
return 0;

fat_truncate_time(inode, NULL, flags);
if (inode->i_sb->s_flags & SB_LAZYTIME)
dirty_flags |= I_DIRTY_TIME;
else
dirty_flags |= I_DIRTY_SYNC;

__mark_inode_dirty(inode, dirty_flags);
return 0;
}
--------------------8<------------------

...and we should probably do that in a separate patch in advance of the
update_time rework, since it's really a different change.

If you're in agreement, then I'll plan to respin the series with this
fixed and resend.

Thanks for being patient!
--
Jeff Layton <[email protected]>