in watchman/fs/FSDetect.cpp [124:218]
w_string w_fstype(const char* path) {
#ifdef __linux__
// If possible, we prefer to read the filesystem type names from
// `/proc/self/mounts`
std::string mounts;
if (folly::readFile("/proc/self/mounts", mounts)) {
auto fstype = find_fstype_in_linux_proc_mounts(path, mounts);
if (fstype) {
return fstype;
}
}
// Reading the mount table can fail for the simple reason that `/proc` isn't
// mounted, so fall back to some slightly manual code that looks at known
// filesystem type ids.
struct statfs sfs;
const char* name = "unknown";
// Unfortunately the FUSE magic number is not defined in linux/magic.h,
// and is only available in the Linux source code in fs/fuse/inode.c
constexpr __fsword_t FUSE_MAGIC_NUMBER = 0x65735546;
if (statfs(path, &sfs) == 0) {
switch (sfs.f_type) {
#ifdef CIFS_MAGIC_NUMBER
case CIFS_MAGIC_NUMBER:
name = "cifs";
break;
#endif
#ifdef NFS_SUPER_MAGIC
case NFS_SUPER_MAGIC:
name = "nfs";
break;
#endif
#ifdef SMB_SUPER_MAGIC
case SMB_SUPER_MAGIC:
name = "smb";
break;
#endif
case FUSE_MAGIC_NUMBER:
name = "fuse";
break;
default:
name = "unknown";
}
}
return w_string(name, W_STRING_UNICODE);
#elif STATVFS_HAS_FSTYPE_AS_STRING
// if this is going to be used on macos this needs
// to detect edenfs with w_fstype_detect_macos_nfs
struct statvfs sfs;
if (statvfs(path, &sfs) == 0) {
#ifdef HAVE_STRUCT_STATVFS_F_FSTYPENAME
return w_string(sfs.f_fstypename, W_STRING_UNICODE);
#endif
#ifdef HAVE_STRUCT_STATVFS_F_BASETYPE
return w_string(sfs.f_basetype, W_STRING_UNICODE);
#endif
}
#elif HAVE_STATFS
struct statfs sfs;
if (statfs(path, &sfs) == 0) {
auto fstype = w_string(sfs.f_fstypename, W_STRING_UNICODE);
auto edenfs_indicator = w_string(sfs.f_mntfromname, W_STRING_UNICODE);
return w_fstype_detect_macos_nfs(fstype, edenfs_indicator);
}
#endif
#ifdef _WIN32
auto wpath = w_string_piece(path).asWideUNC();
WCHAR fstype[MAX_PATH + 1];
FileDescriptor h(
intptr_t(CreateFileW(
wpath.c_str(),
GENERIC_READ,
FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
nullptr,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS,
nullptr)),
FileDescriptor::FDType::Generic);
if (h &&
GetVolumeInformationByHandleW(
(HANDLE)h.handle(), nullptr, 0, 0, 0, 0, fstype, MAX_PATH + 1)) {
return w_string(fstype, wcslen(fstype));
}
return w_string("unknown", W_STRING_UNICODE);
#else
unused_parameter(path);
return w_string("unknown", W_STRING_UNICODE);
#endif
}