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

Is MacFUSE support fcntl(fd, F_GLOBAL_NOCACHE, 1) #1010

Closed
E6ren opened this issue Apr 7, 2024 · 7 comments
Closed

Is MacFUSE support fcntl(fd, F_GLOBAL_NOCACHE, 1) #1010

E6ren opened this issue Apr 7, 2024 · 7 comments
Assignees
Labels

Comments

@E6ren
Copy link

E6ren commented Apr 7, 2024

I'm trying to find a way to disable the kernal Unified Buffer Cache for some special files. I found that fcntl(fd, F_GLOBAL_NOCACHE, 1) is designed to turn data caching off/on (globally) for a file descriptor. But after I set F_GLOBAL_NOCACHE with flag 1, the file cache seems still there.

So I wonder to know whether macFuse already supports fcntl(fd, F_GLOBAL_NOCACHE, 1)? Or is there anyway to disable the UBC?

@bfleischer
Copy link
Member

You can specifying the mount option noubc to disable caching for a FUSE volume.

F_GLOBAL_NOCACHE is handled by the kernel, not macFUSE. When it's set, the kernel is supposed to write-through to disk and always read from disk.

But after I set F_GLOBAL_NOCACHE with flag 1, the file cache seems still there.

How did you come to this conclusion? What did not behave as expected?

@bfleischer bfleischer self-assigned this Apr 8, 2024
@E6ren
Copy link
Author

E6ren commented Apr 9, 2024

But after I set F_GLOBAL_NOCACHE with flag 1, the file cache seems still there.

How did you come to this conclusion? What did not behave as expected?

I set this flag to the file descriptor when the open callback from macFUSE comes, after I use other APP opend this file once, then I tried to copy the file out of macFUSE mounted folder, found that macFUSE read callback did not come, so I suspect the cache still works.
I expected the read callback will be called everytime after I set F_GLOBAL_NOCACHE flag to a file.

@bfleischer
Copy link
Member

Just to avoid misunderstandings, did you set F_GLOBAL_NOCACHE on the file descriptor you opened in your file system daemon and then returned in the FUSE open callback?

You would need to set F_GLOBAL_NOCACHE on the file descriptor that macOS returns when opening a file on the virtual volume, not the file descriptor you pass to the FUSE callback.

@E6ren
Copy link
Author

E6ren commented Apr 9, 2024

Here is the code snippet, in my file system daemon:

// open callback from FUSE
- (BOOL)openFileAtPath:(NSString *)path
                  mode:(int)mode
              userData:(id *)userData
                 error:(NSError **)error {
  NSString* p = [rootPath_ stringByAppendingString:path];
  int fd = open([p UTF8String], mode);
  if ( fd < 0 ) {
    if ( error ) {
      *error = [NSError errorWithPOSIXCode:errno];
    }
    return NO;
  }
  *userData = [NSNumber numberWithLong:fd];
  fcntl(fd, F_GLOBAL_NOCACHE, 1);
  return YES;
}

I'm not sure the file descriptor I got here is from FUSE or the macOS.

@bfleischer
Copy link
Member

You are setting F_GLOBAL_NOCACHE for the file descriptor on your backing storage, not on the file descriptor for the virtual file on the your FUSE volume. This is not having the effect you are looking for. To test if F_GLOBAL_NOCACHE works as expected, you would need to open a file on your virtual volume and set F_GLOBAL_NOCACHE for that file descriptor.

For file systems using the libfuse (high level or low level) API there is the option of setting the direct_io flag (struct fuse_file_info) in the open callback. This disables caching for the opened file, but this flag is not available in macFUSE.framework.

I think the cleanest option (when the macFUSE.framework) would be disabling caching for the whole volume by specifying the noubc mount option.

@E6ren
Copy link
Author

E6ren commented Apr 10, 2024

To test if F_GLOBAL_NOCACHE works as expected, you would need to open a file on your virtual volume and set F_GLOBAL_NOCACHE for that file descriptor.

Yes, I setted noubc mount option, everything goes fine. But I still curious about the meaning of 'open a file on your virtual volume'. Do you mean call open API on Apple file system volume, not macFUSE mounted volume?

@bfleischer
Copy link
Member

Yes, I setted noubc mount option, everything goes fine. But I still curious about the meaning of 'open a file on your virtual volume'. Do you mean call open API on Apple file system volume, not macFUSE mounted volume?

Let's assume there is a file called test.txt on your virtual volume and your virtual volume is mounted unter /Volumes/TestVolume. Then you would need to open /Volumes/TestVolume/test.txt and set F_GLOBAL_NOCACHE on the resulting file descriptor. Reads and Writes should then always trigger a callback in your file system code for this particular file.

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

No branches or pull requests

2 participants