From: Christoph Hellwig <hch@infradead.org>
To: NeilBrown <neil@brown.name>
Cc: Matthew Wilcox <willy@infradead.org>,
fstests@vger.kernel.org, linux-fsdevel@vger.kernel.org,
Chuck Lever <cel@kernel.org>,
linux-btrfs@vger.kernel.org
Subject: Re: [PATCH] fstests: generic: Add test of seek in directories
Date: Mon, 31 Aug 2026 06:16:18 -0700 [thread overview]
Message-ID: <apV-omM4s58KtkRz@infradead.org> (raw)
In-Reply-To: <178791556100.3510150.18132687067056760170@noble.neil.brown.name>
On Fri, Aug 28, 2026 at 09:12:41PM +1000, NeilBrown wrote:
> If you happened to know the sizes of the all the names in the directory,
> you could make a sequence of getdents calls which each return precisely
> 1 entry, You could then use lseek to determine the seek offset at every
> point.
No, you can't. Despite the historic naming d_off is not an offset, but
a cookie. You can not arithmetics on it.
> Linux getdents64 makes this a bit simpler by returning exactly that same
> number (the seek offset to the next name) in the d_off field.
>
> So posix certainly allows, indirectly, seeking to each d_off.
Posix and Linux allow to seekdir to each cookie returned from telldir,
it does not allow to do arithmetics on it.
>
> Posix refers to one directory entry "immediately following" another
> which clearly implies a well defined sequence (if you exclude names
> added and removed during the read).
I think you're talking about posix_getdents here, which isn't really
Posix as we know it, but was added in the 2024 edition without actually
having relevant implementation so far. It does however implement
the syscall-level API in most modern Unixes. It does not mention
d_off at all, just the lseek-able file offset, though.
> I think a strong argument for Linux needing something is that NFS needs
> working directory offsets to be able to support READDIR, because there
> is no "OPEN" request for directories.
I don't think anyone disputes the need for stable directory offsets,
and we should (*knock on wood*) have implementation of native
file systems that fail this.
What the test tries to force is a specific behavior for rename onto
existing file names, replacing the original file name entry with
a new one of the same name. The test expects that to reuse the
previous d_off, which is not required by any real or de facto standard.
> I know less about btrfs. It appears to always add new names to the end
> of the directory listing. When you rename over an existing name, that
> existing name is relocated to the end. I can only guess why it might do
> that. I have no idea if it "needs" to do that.
btrfs doesn't manage freespace for the d_off space (doing so is quite
complicated and requires a lot of code in XFS for example), so it
simply uses a monotonically increasing counter for the value reported
in d_off. This simplifies things a lot, and should work well on 64-bit
systems were you are basically impossible to round out of d_off values.
It might be a lot more problematic on 32-bit systems because the
seekdir/telldir cookie is a long and not a guaranteed 64-bit value.
> Fun fact: This behaviour of btrfs (which I think is perfectly defensible
> for new names) resulted in generic/736 (which I think is an unreasonable
> test to impose) which btrfs "fixed" with a mechanism that doesn't work
> over NFS. i.e. it doesn't work if you close and re-open the file for
> each getdents call.
> If I mount a btrfs filesystem over nfs with rsize=4096, then generic/736
> fails.
That code and the tests looks a bit questionable, as readdir by
definition can't every complete in other file systems either if you add
new entries faster than the pace of readdir calls. I.e. if you replace
the rename there with link calls adding new entries you run into the
same issue with every file system.
> The link you provided says:
> If a sequence of calls to posix_getdents() is made that reads from
> offset zero to end-of-file and a file is removed from or added to the
> directory between the first and last of those calls, whether the
> sequence of calls returns an entry for that file is unspecified.
>
> which unfortunately doesn't cover what happens when a file is renamed.
> When renamed to a non-existing name, it might be reasonable to describe
> this as "removed from" and "added to" so its appearance could be
> unspecified.
> When renamed to an existing name, I don't think it reasonable to
> describe the target name a being either "removed from" or "added to" the
> directory.
If we are talking about files, it is very clear that the target over
which is renamed is removed from the directory. And if the source
was outside the directory it also is very clearly added. The only
gray area is a source file that already was in the same directory.
next prev parent reply other threads:[~2026-08-31 13:16 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-27 23:36 fstests: Verify behaviour of "seek" in a directory NeilBrown
2026-08-27 23:36 ` [PATCH] fstests: generic: Add test of seek in directories NeilBrown
2026-08-28 4:13 ` Matthew Wilcox
2026-08-28 11:12 ` NeilBrown
2026-08-28 14:55 ` Theodore Tso
2026-08-30 22:22 ` NeilBrown
2026-08-31 1:37 ` Theodore Tso
2026-08-31 13:16 ` Christoph Hellwig [this message]
2026-09-01 1:05 ` NeilBrown
2026-09-01 9:18 ` Christoph Hellwig
2026-08-30 23:13 ` Chuck Lever
2026-08-31 12:59 ` Christoph Hellwig
2026-08-31 22:47 ` NeilBrown
2026-09-01 9:09 ` Christoph Hellwig
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=apV-omM4s58KtkRz@infradead.org \
--to=hch@infradead.org \
--cc=cel@kernel.org \
--cc=fstests@vger.kernel.org \
--cc=linux-btrfs@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=neil@brown.name \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox