readlink not working on Windows
diamondq opened this issue · comments
winfsp issues a call to readlink during startup to see if it's supported. The order of the fields in the fuse_operations struct in winfsp is
struct fuse_operations
{
/* S - supported by WinFsp */
/* S */ int (*getattr)(const char *path, struct fuse_stat *stbuf);
/* S */ int (*getdir)(const char *path, fuse_dirh_t h, fuse_dirfil_t filler);
/* S */ int (*readlink)(const char *path, char *buf, size_t size);
However, in jnr-fuse, FuseOperations, it's
public class FuseOperations extends BaseStruct {
public final Func<GetAttrCallback> getattr = func(GetAttrCallback.class);
public final Func<ReadlinkCallback> readlink = func(ReadlinkCallback.class);
@Deprecated
public final Func<GetAttrCallback> getdir = func(GetAttrCallback.class);
Since getdir is deprecated, and usually null, winfsp believes that readlink isn't implemented.
I found that by flipping the order of getdir/readlink in FuseOperations, winfsp started issuing readlink calls correctly.
I do not know if that'll have any impact in Linux or OSX.
Hey, @diamondq! Thank you for the report, do you have a test case by any chance? I'd help to understand the issue.
If you mount an file system on Windows, you should immediately see an init, statfs, getattr and then a readlink call. These all happen before any other calls.
This is the winfsp code within fsp_fuse_loop_start (in fuse_loop.c).
However, if readlink is not set (ie. the reported bug), you won't see the readlink call during startup. fsp_fuse_loop_start is using these calls to probe the features that are available in your FUSE-based filesystem. If it can't execute a readlink, then it will not properly handle any files that return a mode of S_IFLNK from a stat call (aka getattr).
I don't have a Java code sample at the moment using symbolic links. I ran into the bug while tracing winfsp's feature probing (a separate issue where I was trying to see if I could get winfsp to enable ADS support over FUSE).