Skip to content

Conversation

@kohlschuetter
Copy link
Contributor

For many operations, we currently call VirtualFileSystem#getattr(Inode), which gets a full set of "stat" metadata for a given Inode.

In many cases however, we're only interested in the type of the Inode (e.g., directory, regular file, symlink, etc.). Certain VirtualFileSystem implementations may be able to retrieve that specific information significantly faster than the full metadata set.

Replace calls to vfs.getattr(Inode).type() with vfs.getStatType() where applicable, and provide default implementations for backwards compatibility.

Also don't retrieve Stat information at all where not required:

  1. In PseudoFS.checkAccess with ACE4_READ_ATTRIBUTES, and

  2. For OperationREAD, allow VirtualFileSystem to skip the Stat check (currently checking StatType but also file size), which is currently done per every call to "read":

Clarify the requirement of signaling "eof reached" as per NFSv4 spec, provide a new read() method to VirtualFileSystem with a corresponding callback function, and provide a default implementation for backwards compatibility.

@kofemann
Copy link
Member

Are there any benchmarks that justify this change? Almost all operations are subject to permission checks, thus, file attributes are almost always required. To reduce the number of filesystem calls, we use VfsCache which aggressively caches getattrs.

@kohlschuetter
Copy link
Contributor Author

The file type can (in many cases) be encoded directly in the Inode file handle, which means that the lookup is free.
Currently, we ask for "Stat" for every read and write, which is extremely suboptimal.

Caching can only go so far, especially when the file can be modified outside of nfs4j.

@kohlschuetter
Copy link
Contributor Author

fwiw, I'm working on a bigger change that improves read/write performance by 20%, and it's based on this code.
@kofemann Should we merge this first or do you want the entire change in this PR?

@kofemann
Copy link
Member

Hi @kohlschuetter , I definitely don't want to see a getXxx Method per attribute type. However, I can see the use case. Thus, I suggest updating the getattr method to accept an enum set of desired StatAttribute, similar to statx function and GETATTR operation. The file system implementations can optimize and return only those or more. The Stat class is already designed to return only a subset of the attributes.

@kohlschuetter
Copy link
Contributor Author

Yes, that's certainly doable.

The thing I'm concerned about is that in Stat the "type" is currently derived from the mode attribute. That's just how POSIX works.

However, mode has really two parts, one mutable (access rights) and one immutable (inode type, such as directory, dev, regular file, etc.).

When we check "is it a file or directory", we're really only interested in the immutable part. That information, once encoded in a trusted file handle, can be guaranteed to not change. The mutable access rights part however can change any minute, so we have to make a file system hit for that.

Since we currently cannot distinguish between "I want the type" vs "I want the mode", we still need that differentiating method (hence my explanation in the Javadoc for getStatType). If we use an EnumSet<Stat.StatAttribute>, we can only specify MODE (not TYPE), which means we effectively still have to hit the underlying file system for no reason.

If we go that route, then it's best to introduce a StatAttribute of TYPE as well...

I'll look into that.

For many operations, we currently call VirtualFileSystem#getattr(Inode),
which gets a full set of "stat" metadata for a given Inode.

In many cases however, we're only interested in the type of the Inode
(e.g., directory, regular file, symlink, etc.). Certain
VirtualFileSystem implementations may be able to retrieve that specific
information significantly faster than the full metadata set.

Replace calls to vfs.getattr(Inode).type() with vfs.getStatType() where
applicable, and provide default implementations for backwards
compatibility.

Also don't retrieve Stat information at all where not required:

1. In PseudoFS.checkAccess with ACE4_READ_ATTRIBUTES, and

2. For OperationREAD, allow VirtualFileSystem to skip the Stat check
(currently checking StatType but also file size), which is currently
done per every call to "read":

Clarify the requirement of signaling "eof reached" as per NFSv4 spec,
provide a new read() method to VirtualFileSystem with a corresponding
callback function, and provide a default implementation for backwards
compatibility.

Signed-off-by: Christian Kohlschütter <[email protected]>
Signed-off-by: Christian Kohlschütter <[email protected]>
As per request, let's handle getting the Stat type not as a special case
but via a generalizable getattr method that takes an EnumSet of
StatAttributes.

Signed-off-by: Christian Kohlschütter <[email protected]>
@kohlschuetter
Copy link
Contributor Author

kohlschuetter commented Jul 14, 2025

OK, I hope this works for you now. We don't need a new StatAttribute.TYPE after all. I'll just check for STAT_ATTRIBUTES_TYPE_ONLY in my code.

PS: I see that on Linux, statx has that TYPE-only option too, so STAT_ATTRIBUTES_TYPE_ONLY could eventually be used for that as well.

@kofemann kofemann merged commit ad8f569 into dCache:master Jul 14, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants