Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FUSE: add flags (Windows file attributes) support #114

Closed
PhilLehmann opened this issue Oct 22, 2017 · 12 comments
Closed

FUSE: add flags (Windows file attributes) support #114

PhilLehmann opened this issue Oct 22, 2017 · 12 comments
Milestone

Comments

@PhilLehmann
Copy link

PhilLehmann commented Oct 22, 2017

Is it possible with winfsp (fuse) to set a file as hidden and system?

The reason I am asking is that I would like to add a desktop.ini to the virtual drive, but that file is only being evaluated by windows, if it is a system file. In addition to that, hiding it from the user would be great.

https://superuser.com/questions/882442/self-created-desktop-ini-does-not-work

I searched your and libfuse API docs and although they are great, maybe I lack the experience to search for the right needle in the haystack.

@PhilLehmann
Copy link
Author

I typically don't crosspost, but I just felt like the jnr-fuse issue board might be a better place for asking this, since I use jnr-fuse on top of winfsp (from my Java app).

Yet, if winfsp might not support this, there is probably nothing jnr-fuse can do.

I'll post any insights gained over there here.

@billziss-gh
Copy link
Collaborator

billziss-gh commented Oct 22, 2017

WinFsp supports the hidden and system file attributes. However the FUSE API originated in Linux, which does not in general support those attributes (some BSD's and Apple's OSX do). So you cannot use FUSE and at the same time support those attributes.

The only thing that we could do is to consider adding an extension to FUSE to support those attributes. I believe OSXFUSE does have such extensions, which we could potentially adopt (e.g. chflags).

@PhilLehmann
Copy link
Author

PhilLehmann commented Oct 23, 2017

Here is some info I found about chflags - it looks like your feeling was right:

Would you consider adding a comparable extension to the fuse layer of WinFSP - mapping to windows file flags?

@PhilLehmann
Copy link
Author

PhilLehmann commented Oct 23, 2017

Another possibility may be (again, not the expert speaking here) extended attributes (http://man7.org/linux/man-pages/man7/xattr.7.html)?

Looking again at the fusexmp_fh.c source, as the method is named xmp_setattr_x, chflags may just be a special kind of extended attributes, though...

@billziss-gh
Copy link
Collaborator

billziss-gh commented Oct 23, 2017

The flags is how FreeBSD and Darwin encode what Windows calls "file attributes". So we would have to add flags support to WinFsp-FUSE.

We would need to:

  • Get the flags. OSXFUSE uses getattr, because struct stat in OSX includes a st_flags field (see man 2 stat on OSX). Unfortunately WinFsp-FUSE uses a struct stat that is compatible with Cygwin, which does not include this field!
    • We could conceivably add an st_flags field to struct fuse_stat, which might work for getattr and fgetattr purposes, because it is the FUSE layer that provides the struct fuse_stat storage in these cases. However it would not work for fuse_fill_dir_t, because in this case the file system passes its own struct fuse_stat back to the FUSE layer (and therefore both the FUSE layer and the file system must agree on the size of struct fuse_stat).
  • Set the flags. OSXFUSE uses chflags for this purpose. It is conceivable that we could add this operation to fuse_operations in WinFsp-FUSE, but we would have to make sure that we do not break compatibility somehow.
  • Map the OSX flag definitions to the Windows file attribute ones. For example, in OSX UF_HIDDEN is defined as 0x00008000 on my Macbook, but FILE_ATTRIBUTE_HIDDEN is defined as 0x2 in Windows. [This is unlikely, but some OSXFUSE file system may have used 0x00008000 instead of UF_HIDDEN for a hidden file.]

So I am open to add this extension to WinFsp-FUSE with the following caveats:

  • We must make sure to do so in a backwards compatible manner. In particular our solution must not break Cygwin or any existing WinFsp-FUSE file systems, even if they are not recompiled!
  • I do not currently have time to do this. I do accept well-written PR's however :)

Another possibility may be (again, not the expert speaking here) extended attributes (http://man7.org/linux/man-pages/man7/xattr.7.html)?

The getattr_x and setattr_x are not the usual extended attributes, but a method for OSXFUSE to get/set additional stat fields that are outside POSIX (including flags). They are rather OSX specific and I would avoid duplicating these to WinFsp-FUSE.

@billziss-gh
Copy link
Collaborator

billziss-gh commented Oct 23, 2017

Here is a more fleshed out (potential) plan to add this feature to the FUSE interface:

  • Introduce struct fuse_stat_ex (or struct fuse_bigstat?) in winfsp_fuse.h with the definition:

    struct fuse_stat_ex
    {
        struct fuse_stat base;
        uint32_t st_flags;
        uint64_t st_reserved[3];
    };
  • Introduce new capability FSP_FUSE_CAP_FLAGS in fuse_common.h with the definition below. This capability instructs the FUSE layer to treat every struct fuse_stat as struct fuse_stat_ex:

    #define FSP_FUSE_CAP_FLAGS              (1 << 23)   /* file system supports BSD/OSX flags */
  • The operations getattr and fgetattr and the typedef fuse_fill_dir_t should not be changed. However if the FSP_FUSE_CAP_FLAGS is present (during init), then the struct fuse_stat can be treated as struct fuse_stat_ex and the following conversion will be valid within getattr, fgetattr and fuse_fill_dir_t:

    struct fuse_stat_ex *exbuf = (struct fuse_stat_ex *)stbuf;
  • Add chflags to fuse_operations. The FUSE layer receives the size of the fuse_operations struct in fuse_main_real and/or fuse_new, so it is possible to determine if this operation is included or not.

  • Implement the internal changes required (in fuse_intf.c) to support the new getattr, fgetattr, fuse_fill_dir_t and chflags.

This wraps up extending the FUSE interface in a (hopefully) backwards compatible manner. Somewhat hairy and incompatible with OSXFUSE, so I am not hugely fond of it. Better alternatives are welcome.

@billziss-gh billziss-gh changed the title Serve a file as hidden file / system file FUSE: add flags (Windows file attributes) support Nov 3, 2017
@billziss-gh
Copy link
Collaborator

Any opinions on this? I will be away next week, but I may look into implementing it for the upcoming 1.2 release.

Ping @SerCeMan. If this was added to WinFsp-FUSE would you be able to add support for it from jnr-fuse?

@PhilLehmann
Copy link
Author

PhilLehmann commented Nov 3, 2017

Your concept is sound and seems backward compatible. Sorry that I cannot help - i need a garbage collector /:

@SerCeMan
Copy link

SerCeMan commented Nov 7, 2017

@billziss-gh As far as I can see, from jnr-fuse point of view, the only required change is adding new win-only fields to struct which should not be a problem at all.

The solution itself sounds a bit brittle to me, but it solves the problem.

@billziss-gh
Copy link
Collaborator

@SerCeMan thanks for the feedback.

The solution itself sounds a bit brittle to me, but it solves the problem.

How would you suggest we make it more robust?

@billziss-gh billziss-gh added this to the v1.2B3 milestone Nov 14, 2017
@billziss-gh
Copy link
Collaborator

Work in progress.

@billziss-gh
Copy link
Collaborator

billziss-gh commented Nov 15, 2017

This functionality has now been added. It is currently in the pvt-flags branch but will be merged into master soon. Expect to see it in the next Beta release (v1.2B3).

From the recently updated Changelog:

WinFsp-FUSE now supports BSD flags (Windows file attributes) during getattr and fgetattr. It also adds the chflags operation. BSD flags support requires use of the FSP_FUSE_CAP_STAT_EX capability and the new struct fuse_stat_ex which includes an st_flags field. If the preprocessor macro FSP_FUSE_USE_STAT_EX is defined before inclusion of <fuse.h> then struct fuse_stat will also be defined to include the st_flags field.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

3 participants