Page MenuHomeFreeBSD

Re-implement fix for PR 272127 by dedicated mount option
ClosedPublic

Authored by kib on Jul 11 2023, 5:14 AM.
Tags
None
Referenced Files
Unknown Object (File)
Mon, Sep 23, 1:17 PM
Unknown Object (File)
Mon, Sep 23, 7:11 AM
Unknown Object (File)
Sun, Sep 22, 4:27 PM
Unknown Object (File)
Wed, Sep 18, 7:35 PM
Unknown Object (File)
Wed, Sep 18, 5:56 AM
Unknown Object (File)
Sun, Sep 8, 7:52 AM
Unknown Object (File)
Aug 22 2024, 6:36 AM
Unknown Object (File)
Aug 6 2024, 11:11 AM

Details

Summary
Revert "VFS: Remove VV_READLINK flag" and "fdescfs: improve linrdlnk mount option"

This reverts commits 4a402dfe0bc44770c9eac6e58a501e4805e29413 and
3bffa2262328e4ff1737516f176107f607e7bc76.

The fix will be implemented in somewhat different manner.  The semantic
adjustment is incompatible with linuxolator expectations.

Reported by:    dchagin
fdescfs: add a mount option rdlnk

which changes /dev/fd/N files types to symbolic link with the behavior
of symbolic links.

PR:     272127
Reported by:    Peter Eriksson <pen@lysator.liu.se>
Document fdescfs mount option "rdlnk"

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

kib requested review of this revision.Jul 11 2023, 5:14 AM

tested linrdlink, fine to me

share/man/man5/fdescfs.5
97 ↗(On Diff #124475)

Perhaps, it may be worth adding that this options are mutual-exclusive?

share/man/man5/fdescfs.5
97 ↗(On Diff #124475)

They are not mutually-exclusive. I stated below that linrdlnk semantic is the strict subset of the rdlnk case. Specifying them both should be same as rdlnk.

I must be confused, but are you telling me that the expected Linux-compatible "linrdlnk" behavior when stat(2):ing fdescfs objects is that the first time return information about the "symlink" and then the rest of the time return information about the target it points to? That sounds rather... strange.

  1. umount /compat/linrdlnk/dev/fd ; /usr/obj/usr/src/13.2/amd64.amd64/sbin/mount/mount -t fdescfs -o linrdlnk fdescfs /compat/linrdlnk/dev/fd
  2. ./t -ss -v -D/compat/linrdlnk/dev/fd /home/peter86 test.txt

open("/home/peter86", O_RDONLY) -> 3

openat(3, "test.txt", O_RDONLY) -> 4
  stat("/compat/linrdlnk/dev/fd/4") -> 0 [type=symlink, size=0, uid=0, gid=0]
    readlink("/compat/linrdlnk/dev/fd/4") -> 29 [path=/export/home/peter86/test.txt]
  stat("/compat/linrdlnk/dev/fd/4") -> 0 [type=file, size=13, uid=1003258, gid=100001000]
openat(3, "test.txt", O_RDONLY) -> 4
  stat("/compat/linrdlnk/dev/fd/4") -> 0 [type=file, size=13, uid=1003258, gid=100001000]
  stat("/compat/linrdlnk/dev/fd/4") -> 0 [type=file, size=13, uid=1003258, gid=100001000]
  open("/compat/linrdlnk/dev/fd/4", O_RDONLY) -> 5
  openat(4, "", O_EMPTY_PATH) -> 5

Also, when testing this new patch I don't get the expected behaviour with "rdlnk":

  1. /usr/src/13.2/amd64.amd64/sbin/mount/mount -t fdescfs -o rdlnk fdescfs /compat/rdlnk/dev/fd
  2. ls -l /compat/rdlnk/dev/fd/

total 0
cr-xr-xr-x 1 root wheel 0x3 Jul 11 12:58 0
cr-xr-xr-x 1 root wheel 0x4 Jul 11 12:58 1
cr-xr-xr-x 1 root wheel 0x5 Jul 11 12:58 2
cr-xr-xr-x 1 root wheel 0x6 Jul 11 12:58 3
cr-xr-xr-x 1 root wheel 0x7 Jul 11 12:58 4

These should show as symbolic links and not character devices...

./t -ss -v -D/compat/nodup/dev/fd /home/peter86 test.txt

open("/home/peter86", O_RDONLY) -> 3

openat(3, "test.txt", O_RDONLY) -> 4
  stat("/compat/nodup/dev/fd/4") -> 0 [type=file, size=13, uid=1003258, gid=100001000]
  stat("/compat/nodup/dev/fd/4") -> 0 [type=file, size=13, uid=1003258, gid=100001000]
openat(3, "test.txt", O_RDONLY) -> 4
  stat("/compat/nodup/dev/fd/4") -> 0 [type=file, size=13, uid=1003258, gid=100001000]
  stat("/compat/nodup/dev/fd/4") -> 0 [type=file, size=13, uid=1003258, gid=100001000]
  open("/compat/nodup/dev/fd/4", O_RDONLY) -> 5
  openat(4, "", O_EMPTY_PATH) -> 5

./t -ss -v -D/compat/rdlnk/dev/fd /home/peter86 test.txt

open("/home/peter86", O_RDONLY) -> 3

openat(3, "test.txt", O_RDONLY) -> 4
  stat("/compat/rdlnk/dev/fd/4") -> 0 [type=char, size=0, uid=0, gid=0]
  stat("/compat/rdlnk/dev/fd/4") -> 0 [type=char, size=0, uid=0, gid=0]
openat(3, "test.txt", O_RDONLY) -> 4
  stat("/compat/rdlnk/dev/fd/4") -> 0 [type=char, size=0, uid=0, gid=0]
  stat("/compat/rdlnk/dev/fd/4") -> 0 [type=char, size=0, uid=0, gid=0]
  open("/compat/rdlnk/dev/fd/4", O_RDONLY) -> 5
  openat(4, "", O_EMPTY_PATH) -> 5

For reference, using the test program on a Linux (Ubuntu 22.04):

$ ./t -ss -v . test.txt
open(".", O_RDONLY) -> 3

openat(3, "test.txt", O_RDONLY) -> 4
  stat("/dev/fd/4") -> 0 [type=file, size=13, uid=1000, gid=1000]
  stat("/dev/fd/4") -> 0 [type=file, size=13, uid=1000, gid=1000]
openat(3, "test.txt", O_RDONLY) -> 4
  stat("/dev/fd/4") -> 0 [type=file, size=13, uid=1000, gid=1000]
  stat("/dev/fd/4") -> 0 [type=file, size=13, uid=1000, gid=1000]
  open("/dev/fd/4", O_RDONLY) -> 5

Source for the test program can be downloaded from: https://www.grebo.net/~peter/fdescfs/t.c

Plug one more place where fdescfs vnode type was incorrectly reported for "rdlnk".

The bug you noted should be fixed.

Issue with the change to linrdlnk (and with rdlnk) is that readlink(2)/VOP_READLINK() relies on name cache to resolve the full vnode path, and this could fail if cache was invalidated or flushed for the vnode. Then, operations like open(2) on the /dev/fd/N fail because name lookup needs to read symbolic link,

From my understanding, this is the problem that Dmitry reported.

In D40969#932639, @kib wrote:

The bug you noted should be fixed.

Issue with the change to linrdlnk (and with rdlnk) is that readlink(2)/VOP_READLINK() relies on name cache to resolve the full vnode path, and this could fail if cache was invalidated or flushed for the vnode. Then, operations like open(2) on the /dev/fd/N fail because name lookup needs to read symbolic link,

From my understanding, this is the problem that Dmitry reported.

yes, its a big problem in Linux emulation, /dev/fd/x is often used to get filename by fd,
second, we have many requests from users about inotify implementation which is also depends on namecache <-> vnode consistency. it looks like it's time to solve this task

This revision is now accepted and ready to land.Jul 12 2023, 2:39 PM