Repository: dotnet/runtime
File: src/native/libs/System.Native/pal_io.c (C)

Code before:
    }
    return 1;
}
#endif
#endif /* TARGET_WASI */

uint32_t SystemNative_FileSystemSupportsLocking(intptr_t fd)
{
    // This method returns false when we identify the file system to be nfs (#44546), samba/cifs (#53182).
#if defined(TARGET_WASI)
    return 0; // WASI doesn't support locking.
#elif HAVE_STATFS_FSTYPENAME || defined(TARGET_LINUX)
    int statfsRes;
    struct statfs statfsArgs;
    // for our needs (get file system type) statfs is always enough and there is no need to use statfs64
    // which got deprecated in macOS 10.6, in favor of statfs
    while ((statfsRes = fstatfs(ToFileDescriptor(fd), &statfsArgs)) == -1 && errno == EINTR) ;
    if (statfsRes == -1) return 0;

#if HAVE_STATFS_FSTYPENAME
    return FileSystemNameSupportsLocking(statfsArgs.f_fstypename);
#elif defined(TARGET_LINUX)
    if (statfsArgs.f_type == 0x6969 ||     // NFS_SUPER_MAGIC
        statfsArgs.f_type == 0xFF534D42 || // CIFS_SUPER_MAGIC
        statfsArgs.f_type == 0x517B ||     // SMB_SUPER_MAGIC
        statfsArgs.f_type == 0xFE534D42)   // SMB2_SUPER_MAGIC
    {
        return 0;
    }
    return 1;
#endif
#elif HAVE_STATVFS_BASETYPE
    int statfsRes;
    struct statvfs statfsArgs;
    while ((statfsRes = fstatvfs(ToFileDescriptor(fd), &statfsArgs)) == -1 && errno == EINTR) ;
    if (statfsRes == -1) return 0;

    return FileSystemNameSupportsLocking(statfsArgs.f_basetype);
#else
    #error "Platform doesn't support fstatfs or fstatvfs"
#endif
}

int32_t SystemNative_LockFileRegion(intptr_t fd, int64_t offset, int64_t length, int16_t lockType)
{
#if !defined(TARGET_WASI)
    int16_t unixLockType = ConvertLockType(lockType);
    if (offset < 0 || length < 0)
    {
        errno = EINVAL;
        return -1;

Review comment (suggestion):
```suggestion
    if (statfsArgs.f_type == (__fsword_t)0x6969 ||     // NFS_SUPER_MAGIC
        statfsArgs.f_type == (__fsword_t)0xFF534D42 || // CIFS_SUPER_MAGIC
        statfsArgs.f_type == (__fsword_t)0x517B ||     // SMB_SUPER_MAGIC
        statfsArgs.f_type == (__fsword_t)0xFE534D42)   // SMB2_SUPER_MAGIC
```

Code after:
        default:
            assert_msg(managedLockType == 2, "Unknown Lock Type", (int)managedLockType);
            return F_UNLCK;
    }
}

#if HAVE_STATFS_FSTYPENAME || HAVE_STATVFS_BASETYPE || defined(TARGET_HAIKU)
static uint32_t FileSystemNameSupportsLocking(const char* fileSystemName)
{
    if (strcmp(fileSystemName, "nfs") == 0 ||
        strcmp(fileSystemName, "cifs") == 0 ||
        strcmp(fileSystemName, "smb") == 0 ||
        strcmp(fileSystemName, "smb2") == 0)
    {
        return 0;
    }
    return 1;
}
#endif
#endif /* TARGET_WASI */

// LOCK_SH does not work well for write access on nfs/cifs/samba. For example, writes are dropped silently.
// See https://github.com/dotnet/runtime/issues/44546 and https://github.com/dotnet/runtime/issues/53182.
uint32_t SystemNative_FileSystemSupportsLocking(intptr_t fd, int32_t lockOperation, int32_t accessWrite)
{
    assert(lockOperation == PAL_LOCK_SH || lockOperation == PAL_LOCK_EX);
#if defined(TARGET_WASI) || defined(TARGET_WASM)
    return 0; // WASI/WASM doesn't support locking.
#else
    if (lockOperation == PAL_LOCK_EX || accessWrite == 0)
    {
        return 1;
    }
#if defined(TARGET_HAIKU)
    struct stat st;
    int fstatRes;
    while ((fstatRes = fstat(ToFileDescriptor(fd), &st)) == -1 && errno == EINTR);
    if (fstatRes == -1) return 0;

    struct fs_info info;
    int fsStatDevRes;
    while ((fsStatDevRes = fs_stat_dev(st.st_dev, &info)) == -1 && errno == EINTR);
    if (fsStatDevRes == -1) return 0;

    return FileSystemNameSupportsLocking(info.fsh_name);
#elif HAVE_STATFS_FSTYPENAME || defined(TARGET_LINUX) || defined(TARGET_ANDROID)
    int statfsRes;
    struct statfs statfsArgs;
    // for our needs (get file system type) statfs is always enough and there is no need to use statfs64
    // which got deprecated in macOS 10.6, in favor of statfs
    while ((statfsRes = fstatfs(ToFileDescriptor(fd), &statfsArgs)) == -1 && errno == EINTR) ;