Page MenuHomeFreeBSD

realpath: Avoid doing unnecessary work
AbandonedPublic

Authored by des on Fri, Oct 10, 2:05 PM.
Tags
None
Referenced Files
Unknown Object (File)
Tue, Oct 21, 8:08 PM
Unknown Object (File)
Sat, Oct 18, 1:45 AM
Unknown Object (File)
Sat, Oct 18, 12:38 AM
Unknown Object (File)
Sat, Oct 18, 12:37 AM
Unknown Object (File)
Sat, Oct 18, 12:37 AM
Unknown Object (File)
Fri, Oct 17, 2:50 PM
Unknown Object (File)
Sat, Oct 11, 10:58 PM
Unknown Object (File)
Sat, Oct 11, 9:34 PM
Subscribers

Details

Reviewers
markj
Group Reviewers
Klara
Summary

The only case in which the userland implementation would return a
different error than the system call is if we are racing against
someone modifying the hierarchy we are traversing, but that is not a
scenario that we are expected to handle gracefully. Therefore,
unless the caller passed in a buffer (which the system call does not
populate), do not call the userland implementation unless the system
call is unavailable.

Sponsored by: Klara, Inc.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped
Build Status
Buildable 67703
Build 64586: arc lint + arc unit

Event Timeline

des requested review of this revision.Fri, Oct 10, 2:05 PM
markj added inline comments.
lib/libc/stdlib/realpath.c
234

This res == NULL case only happens when we call realpath1().

The only case in which the userland implementation would return a different error than the system call is if we are racing against someone modifying the hierarchy we are traversing

How do you know this? It seems possible that there are some corner cases which __realpathat() simply doesn't handle.

lib/libc/stdlib/realpath.c
234

True, but I think the code is easier to reason about if I leave it as is.

The only case in which the userland implementation would return a different error than the system call is if we are racing against someone modifying the hierarchy we are traversing

How do you know this? It seems possible that there are some corner cases which __realpathat() simply doesn't handle.

Such as?

In D53026#1211680, @des wrote:

The only case in which the userland implementation would return a different error than the system call is if we are racing against someone modifying the hierarchy we are traversing

How do you know this? It seems possible that there are some corner cases which __realpathat() simply doesn't handle.

Such as?

I don't know. It's not obvious that the old behaviour wasn't intentional. Looking at the implementation of the syscall, I can't see any reason it would be, so ok.

This revision is now accepted and ready to land.Fri, Oct 10, 11:58 PM

@mjg @kib do you agree that there is no reason why the userland implementation of realpath() would succeed after the syscall failed, except in the case of a race?

In D53026#1211786, @des wrote:

@mjg @kib do you agree that there is no reason why the userland implementation of realpath() would succeed after the syscall failed, except in the case of a race?

sys__realpath() relies on specific filesystem' VOP_VPTOCNP(), which in principle is allowed to fail in a way that prevents regular (AKA directory dotdot lookup) fallback from happen.
It might be that we could fix it by carefully inspecting errors and standardizing the error returns from the VOP to distinguish a voluntarily refuse to work vs. real error. But right now it was not designed with this in mind.

I think some work can be saved if the errno is ENOENT or EACCESS, but someone(tm) has to make sure errors of the sort are not returned from the stage where the syscall does the reverse lookup.