Declaring File System Capabilities - macfuse/macfuse GitHub Wiki

File systems can declare capabilities depending on the API they are built with.

libfuse.dylib

Capabilities

  • FUSE_CAP_ATOMIC_O_TRUNC
    The file system supports the open(2) flag O_TRUNC.

  • FUSE_CAP_XTIMES
    The file system implements the getxtimes() callback and supports returning crtime (creation time) and bkptime (backup time) for files.

  • FUSE_CAP_CASE_INSENSITIVE
    The file system is case insensitive. By default, macFUSE file systems are case sensitive.

  • FUSE_CAP_NODE_RWLOCK
    The file system supports read/write node locking. Declare this capability, if the file system is thread safe with respect to file system operations involving the same node. Otherwise, file system operations involving the same node are processed serially.

  • FUSE_CAP_ALLOCATE
    The file system implements the fallocate() callback and supports preallocating file space. See fcntl(2) (F_PREALLOCATE) for details.

  • FUSE_CAP_EXCHANGE_DATA
    The file system supports exchangedata(2) natively. exchangedata(2) was deprecated in macOS 10.13, support in macFUSE was dropped in macOS 11. Implement support for renamex_np(2) instead and declare FUSE_CAP_RENAME_SWAP.

  • FUSE_CAP_RENAME_SWAP
    The file system implements the renamex() callback and supports the flag FUSE_RENAME_SWAP. See renamex_np(2) for details.

  • FUSE_CAP_RENAME_EXCL
    The file system implements the renamex() callback and supports the flag FUSE_RENAME_EXCL. See renamex_np(2) for details.

  • FUSE_CAP_VOL_RENAME
    The file system supports renaming the mounted volume. Note, this requires specifying a device path when mounting the volume using the fsname option.

  • FUSE_CAP_ACCESS_EXTENDED
    The file system supports the following extended access modes in the access() callback.

    _READ_OK        read file data / read directory
    _WRITE_OK       write file data / add file to directory
    _EXECUTE_OK     execute file / search in directory
    _DELETE_OK      delete file / delete directory
    _APPEND_OK      append to file / add subdirectory to directory
    _RMFILE_OK      remove file from directory
    _RATTR_OK       read basic attributes
    _WATTR_OK       write basic attributes
    _REXT_OK        read extended attributes
    _WEXT_OK        write extended attributes
    _RPERM_OK       read permissions
    _WPERM_OK       write permissions
    _CHOWN_OK       change ownership
    

Example

See loopback_init() in the LoopbackFS-C demo file system.

void *
loopback_init(struct fuse_conn_info *conn)
{
    conn->want |= FUSE_CAP_VOL_RENAME | FUSE_CAP_XTIMES | FUSE_CAP_NODE_RWLOCK;

#ifdef FUSE_ENABLE_CASE_INSENSITIVE
    if (loopback.case_insensitive) {
        conn->want |= FUSE_CAP_CASE_INSENSITIVE;
    }
#endif

    return NULL;
}

macFUSE.framework

Capabilities

  • kGMUserFileSystemVolumeSupportsExtendedDatesKey
    The file system supports the attributes NSFileCreationDate and kGMUserFileSystemFileBackupDateKey.

  • kGMUserFileSystemVolumeSupportsCaseSensitiveNamesKey
    The file system is case sensitive. By default macFUSE file systems are case sensitive.

  • kGMUserFileSystemVolumeSupportsReadWriteNodeLockingKey
    The file system supports read/write node locking. Declare this capability, if the file system is thread safe with respect to file system operations involving the same node. Otherwise, file system operations involving the same node are processed serially.

  • kGMUserFileSystemVolumeSupportsAllocateKey
    The file system implements the [GMUserFileSystemOperations preallocateFileAtPath:userData:options:offset:length:error:] delegate method and supports supports preallocating file space. See fcntl(2) (F_PREALLOCATE) for details.

  • kGMUserFileSystemVolumeSupportsExchangeDataKey
    The file system implements the [GMUserFileSystemOperations exchangeDataOfItemAtPath:withItemAtPath:error:] delegate method and supports exchangedata(2) natively. exchangedata(2) was deprecated in macOS 10.13, support in macFUSE was dropped in macOS 11. Implement support for renamex_np(2) instead and declare kGMUserFileSystemVolumeSupportsSwapRenamingKey.

  • kGMUserFileSystemVolumeSupportsSwapRenamingKey
    The file system supports the rename option GMUserFileSystemMoveOptionSwap. See renamex_np(2) for details.

  • kGMUserFileSystemVolumeSupportsExclusiveRenamingKey
    The file system supports the rename option GMUserFileSystemMoveOptionExclusive. See renamex_np(2) for details.

  • kGMUserFileSystemVolumeSupportsSetVolumeNameKey
    The file system implements the [GMUserFileSystemOperations setAttributes:ofFileSystemAtPath:error:] delegate method and supports the attribute kGMUserFileSystemVolumeNameKey. Note, this requires specifying a device path when mounting the volume using the fsname option.

Examples

See [GMUserFileSystemOperations attributesOfFileSystemForPath:error:] in the LoopbackFS-ObjC demo file system.

- (NSDictionary *)attributesOfFileSystemForPath:(NSString *)path
                                          error:(NSError **)error {
    NSString *p = [rootPath_ stringByAppendingString:path];
    NSDictionary *d = [[NSFileManager defaultManager] attributesOfFileSystemForPath:p error:error];
    if (d) {
        NSMutableDictionary *attribs = [NSMutableDictionary dictionaryWithDictionary:d];
        [attribs setObject:[NSNumber numberWithBool:YES]
                    forKey:kGMUserFileSystemVolumeSupportsExtendedDatesKey];

        NSURL *URL = [NSURL fileURLWithPath:p isDirectory:YES];
        NSNumber *supportsCaseSensitiveNames = nil;
        [URL getResourceValue:&supportsCaseSensitiveNames
                       forKey:NSURLVolumeSupportsCaseSensitiveNamesKey
                        error:NULL];
        if (supportsCaseSensitiveNames == nil) {
            supportsCaseSensitiveNames = [NSNumber numberWithBool:YES];
        }
        [attribs setObject:supportsCaseSensitiveNames
                    forKey:kGMUserFileSystemVolumeSupportsCaseSensitiveNamesKey];

        [attribs setObject:[NSNumber numberWithBool:YES]
                    forKey:kGMUserFileSystemVolumeSupportsSwapRenamingKey];
        [attribs setObject:[NSNumber numberWithBool:YES]
                    forKey:kGMUserFileSystemVolumeSupportsExclusiveRenamingKey];

        [attribs setObject:[NSNumber numberWithBool:YES]
                    forKey:kGMUserFileSystemVolumeSupportsSetVolumeNameKey];

        [attribs setObject:[NSNumber numberWithBool:YES]
                    forKey:kGMUserFileSystemVolumeSupportsReadWriteNodeLockingKey];

        return attribs;
    }
    return nil;
}

See attributesOfFileSystem(forPath:) in the LoopbackFS-Swift demo file system.

override func attributesOfFileSystem(forPath path: String!) throws -> [AnyHashable : Any] {
    let originalPath = rootPath.appending(path)

    var attributes = try FileManager.default.attributesOfFileSystem(forPath: originalPath)
    attributes[FileAttributeKey(rawValue: kGMUserFileSystemVolumeSupportsExtendedDatesKey)] = true

    let originalUrl = URL(fileURLWithPath: originalPath, isDirectory: true)

    let volumeSupportsCaseSensitiveNames = try originalUrl.resourceValues(forKeys: [.volumeSupportsCaseSensitiveNamesKey]).volumeSupportsCaseSensitiveNames ?? true
    attributes[FileAttributeKey(rawValue: kGMUserFileSystemVolumeSupportsCaseSensitiveNamesKey)] = volumeSupportsCaseSensitiveNames

    attributes[FileAttributeKey(rawValue: kGMUserFileSystemVolumeSupportsSwapRenamingKey)] = true
    attributes[FileAttributeKey(rawValue: kGMUserFileSystemVolumeSupportsExclusiveRenamingKey)] = true

    attributes[FileAttributeKey(rawValue: kGMUserFileSystemVolumeSupportsSetVolumeNameKey)] = true

    attributes[FileAttributeKey(rawValue: kGMUserFileSystemVolumeSupportsReadWriteNodeLockingKey)] = true

    return attributes
}