[PATCH] D58801: [Support] Implement is_local_impl with AIX mntctl

Hubert Tong via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 28 16:20:17 PST 2019


hubert.reinterpretcast created this revision.
hubert.reinterpretcast added reviewers: jasonliu, xingxue.
Herald added subscribers: kristina, krytarowski.
Herald added a project: LLVM.

On AIX, we can determine whether a filesystem is remote using `mntctl`.

If the information is not found, then claim that the file is remote (since that is the more restrictive case).


Repository:
  rL LLVM

https://reviews.llvm.org/D58801

Files:
  lib/Support/Unix/Path.inc


Index: lib/Support/Unix/Path.inc
===================================================================
--- lib/Support/Unix/Path.inc
+++ lib/Support/Unix/Path.inc
@@ -55,7 +55,7 @@
 
 #include <sys/types.h>
 #if !defined(__APPLE__) && !defined(__OpenBSD__) && !defined(__FreeBSD__) &&   \
-    !defined(__linux__) && !defined(__FreeBSD_kernel__)
+    !defined(__linux__) && !defined(__FreeBSD_kernel__) && !defined(_AIX)
 #include <sys/statvfs.h>
 #define STATVFS statvfs
 #define FSTATVFS fstatvfs
@@ -76,6 +76,10 @@
 #endif
 #endif
 #include <sys/vfs.h>
+#elif defined(_AIX)
+#include <sys/statfs.h>
+typedef uint_t uint;
+#include <sys/vmount.h>
 #else
 #include <sys/mount.h>
 #endif
@@ -245,7 +249,7 @@
 
 ErrorOr<space_info> disk_space(const Twine &Path) {
   struct STATVFS Vfs;
-  if (::STATVFS(Path.str().c_str(), &Vfs))
+  if (::STATVFS(const_cast<char *>(Path.str().c_str()), &Vfs))
     return std::error_code(errno, std::generic_category());
   auto FrSize = STATVFS_F_FRSIZE(Vfs);
   space_info SpaceInfo;
@@ -405,6 +409,35 @@
   StringRef fstype(Vfs.f_basetype);
   // NFS is the only non-local fstype??
   return !fstype.equals("nfs");
+#elif defined(_AIX)
+  // Call mntctl; try more than twice in case of timing issues with a concurrent
+  // mount.
+  int ret;
+  size_t bufsize = 2048u;
+  std::unique_ptr<char[]> buf;
+  int tries = 3;
+  while (tries--) {
+    buf = llvm::make_unique<char[]>(bufsize);
+    ret = mntctl(MCTL_QUERY, bufsize, buf.get());
+    if (ret != 0)
+      break;
+    bufsize = *reinterpret_cast<unsigned int *>(buf.get());
+    buf.reset();
+  }
+  if (ret == -1)
+    return false;
+  // Look for the correct vmount entry.
+  char *curobjptr = buf.get();
+  while (ret--) {
+    struct vmount *vp = reinterpret_cast<struct vmount *>(curobjptr);
+    static_assert(sizeof(Vfs.f_fsid) == sizeof(vp->vmt_fsid),
+                  "fsid length mismatch");
+    if (memcmp(&Vfs.f_fsid, &vp->vmt_fsid, sizeof Vfs.f_fsid) == 0)
+      return (vp->vmt_flags & MNT_REMOTE) == 0;
+
+    curobjptr += vp->vmt_length;
+  }
+  return false;
 #else
   return !!(STATVFS_F_FLAG(Vfs) & MNT_LOCAL);
 #endif
@@ -412,7 +445,7 @@
 
 std::error_code is_local(const Twine &Path, bool &Result) {
   struct STATVFS Vfs;
-  if (::STATVFS(Path.str().c_str(), &Vfs))
+  if (::STATVFS(const_cast<char *>(Path.str().c_str()), &Vfs))
     return std::error_code(errno, std::generic_category());
 
   Result = is_local_impl(Vfs);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D58801.188810.patch
Type: text/x-patch
Size: 2445 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190301/6d29306e/attachment.bin>


More information about the llvm-commits mailing list