diff --git a/gdbserver/hostio.c b/gdbserver/hostio.c
index a3b32cd0fdc..6223b24a887 100644
--- a/gdbserver/hostio.c
+++ b/gdbserver/hostio.c
@@ -272,9 +272,7 @@ handle_setfs (char *own_buf)
      then there's no point in GDB sending "vFile:setfs:" packets.  We
      reply with an empty packet (i.e. we pretend we don't understand
      "vFile:setfs:") and that should stop GDB sending any more.  */
-  if (the_target->multifs_open == NULL
-      && the_target->multifs_unlink == NULL
-      && the_target->multifs_readlink == NULL)
+  if (!the_target->pt->supports_multifs ())
     {
       own_buf[0] = '\0';
       return;
@@ -321,9 +319,9 @@ handle_open (char *own_buf)
 
   /* We do not need to convert MODE, since the fileio protocol
      uses the standard values.  */
-  if (hostio_fs_pid != 0 && the_target->multifs_open != NULL)
-    fd = the_target->multifs_open (hostio_fs_pid, filename,
-				   flags, mode);
+  if (hostio_fs_pid != 0)
+    fd = the_target->pt->multifs_open (hostio_fs_pid, filename,
+				       flags, mode);
   else
     fd = open (filename, flags, mode);
 
@@ -541,8 +539,8 @@ handle_unlink (char *own_buf)
       return;
     }
 
-  if (hostio_fs_pid != 0 && the_target->multifs_unlink != NULL)
-    ret = the_target->multifs_unlink (hostio_fs_pid, filename);
+  if (hostio_fs_pid != 0)
+    ret = the_target->pt->multifs_unlink (hostio_fs_pid, filename);
   else
     ret = unlink (filename);
 
@@ -571,10 +569,10 @@ handle_readlink (char *own_buf, int *new_packet_len)
       return;
     }
 
-  if (hostio_fs_pid != 0 && the_target->multifs_readlink != NULL)
-    ret = the_target->multifs_readlink (hostio_fs_pid, filename,
-					linkname,
-					sizeof (linkname) - 1);
+  if (hostio_fs_pid != 0)
+    ret = the_target->pt->multifs_readlink (hostio_fs_pid, filename,
+					    linkname,
+					    sizeof (linkname) - 1);
   else
     ret = readlink (filename, linkname, sizeof (linkname) - 1);
 
diff --git a/gdbserver/linux-low.c b/gdbserver/linux-low.c
index 476ad1c5eaa..b19c3458bc5 100644
--- a/gdbserver/linux-low.c
+++ b/gdbserver/linux-low.c
@@ -6442,6 +6442,32 @@ linux_process_target::pid_to_exec_file (int pid)
   return linux_proc_pid_to_exec_file (pid);
 }
 
+bool
+linux_process_target::supports_multifs ()
+{
+  return true;
+}
+
+int
+linux_process_target::multifs_open (int pid, const char *filename,
+				    int flags, mode_t mode)
+{
+  return linux_mntns_open_cloexec (pid, filename, flags, mode);
+}
+
+int
+linux_process_target::multifs_unlink (int pid, const char *filename)
+{
+  return linux_mntns_unlink (pid, filename);
+}
+
+ssize_t
+linux_process_target::multifs_readlink (int pid, const char *filename,
+					char *buf, size_t bufsiz)
+{
+  return linux_mntns_readlink (pid, filename, buf, bufsiz);
+}
+
 #if defined PT_GETDSBT || defined PTRACE_GETFDPIC
 struct target_loadseg
 {
@@ -7472,9 +7498,6 @@ linux_get_hwcap2 (int wordsize)
 static linux_process_target the_linux_target;
 
 static process_stratum_target linux_target_ops = {
-  linux_mntns_open_cloexec,
-  linux_mntns_unlink,
-  linux_mntns_readlink,
   linux_breakpoint_kind_from_pc,
   linux_sw_breakpoint_from_kind,
   linux_proc_tid_get_name,
diff --git a/gdbserver/linux-low.h b/gdbserver/linux-low.h
index cb11c199033..7ee9c0c03d0 100644
--- a/gdbserver/linux-low.h
+++ b/gdbserver/linux-low.h
@@ -455,6 +455,16 @@ public:
   bool supports_pid_to_exec_file () override;
 
   char *pid_to_exec_file (int pid) override;
+
+  bool supports_multifs () override;
+
+  int multifs_open (int pid, const char *filename, int flags,
+		    mode_t mode) override;
+
+  int multifs_unlink (int pid, const char *filename) override;
+
+  ssize_t multifs_readlink (int pid, const char *filename, char *buf,
+			    size_t bufsiz) override;
 };
 
 #define get_thread_lwp(thr) ((struct lwp_info *) (thread_target_data (thr)))
diff --git a/gdbserver/lynx-low.c b/gdbserver/lynx-low.c
index 132087ce7ea..11a7ab9e6a6 100644
--- a/gdbserver/lynx-low.c
+++ b/gdbserver/lynx-low.c
@@ -735,9 +735,6 @@ static lynx_process_target the_lynx_target;
 /* The LynxOS target_ops vector.  */
 
 static process_stratum_target lynx_target_ops = {
-  NULL,  /* multifs_open */
-  NULL,  /* multifs_unlink */
-  NULL,  /* multifs_readlink */
   NULL,  /* breakpoint_kind_from_pc */
   NULL,  /* sw_breakpoint_from_kind */
   NULL,  /* thread_name */
diff --git a/gdbserver/nto-low.c b/gdbserver/nto-low.c
index 8927293d75d..f5919baa5cb 100644
--- a/gdbserver/nto-low.c
+++ b/gdbserver/nto-low.c
@@ -947,9 +947,6 @@ nto_sw_breakpoint_from_kind (int kind, int *size)
 static nto_process_target the_nto_target;
 
 static process_stratum_target nto_target_ops = {
-  NULL, /* multifs_open */
-  NULL, /* multifs_unlink */
-  NULL, /* multifs_readlink */
   NULL, /* breakpoint_kind_from_pc */
   nto_sw_breakpoint_from_kind,
   NULL, /* thread_name */
diff --git a/gdbserver/target.c b/gdbserver/target.c
index b1c318f59b8..39e763dffc8 100644
--- a/gdbserver/target.c
+++ b/gdbserver/target.c
@@ -22,6 +22,10 @@
 #include "tracepoint.h"
 #include "gdbsupport/byte-vector.h"
 #include "hostio.h"
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
 
 process_stratum_target *the_target;
 
@@ -771,3 +775,29 @@ process_target::pid_to_exec_file (int pid)
 {
   gdb_assert_not_reached ("target op pid_to_exec_file not supported");
 }
+
+bool
+process_target::supports_multifs ()
+{
+  return false;
+}
+
+int
+process_target::multifs_open (int pid, const char *filename,
+			      int flags, mode_t mode)
+{
+  return open (filename, flags, mode);
+}
+
+int
+process_target::multifs_unlink (int pid, const char *filename)
+{
+  return unlink (filename);
+}
+
+ssize_t
+process_target::multifs_readlink (int pid, const char *filename,
+				  char *buf, size_t bufsiz)
+{
+  return readlink (filename, buf, bufsiz);
+}
diff --git a/gdbserver/target.h b/gdbserver/target.h
index 6de6c3cdaec..f7f0e6b779c 100644
--- a/gdbserver/target.h
+++ b/gdbserver/target.h
@@ -70,27 +70,6 @@ class process_target;
    shared code.  */
 struct process_stratum_target
 {
-  /* Multiple-filesystem-aware open.  Like open(2), but operating in
-     the filesystem as it appears to process PID.  Systems where all
-     processes share a common filesystem should set this to NULL.
-     If NULL, the caller should fall back to open(2).  */
-  int (*multifs_open) (int pid, const char *filename,
-		       int flags, mode_t mode);
-
-  /* Multiple-filesystem-aware unlink.  Like unlink(2), but operates
-     in the filesystem as it appears to process PID.  Systems where
-     all processes share a common filesystem should set this to NULL.
-     If NULL, the caller should fall back to unlink(2).  */
-  int (*multifs_unlink) (int pid, const char *filename);
-
-  /* Multiple-filesystem-aware readlink.  Like readlink(2), but
-     operating in the filesystem as it appears to process PID.
-     Systems where all processes share a common filesystem should
-     set this to NULL.  If NULL, the caller should fall back to
-     readlink(2).  */
-  ssize_t (*multifs_readlink) (int pid, const char *filename,
-			       char *buf, size_t bufsiz);
-
   /* Return the breakpoint kind for this target based on PC.  The PCPTR is
      adjusted to the real memory location in case a flag (e.g., the Thumb bit on
      ARM) was present in the PC.  */
@@ -501,6 +480,29 @@ public:
      string should be copied into a buffer by the client if the string
      will not be immediately used, or if it must persist.  */
   virtual char *pid_to_exec_file (int pid);
+
+  /* Return true if any of the multifs ops is supported.  */
+  virtual bool supports_multifs ();
+
+  /* Multiple-filesystem-aware open.  Like open(2), but operating in
+     the filesystem as it appears to process PID.  Systems where all
+     processes share a common filesystem should not override this.
+     The default behavior is to use open(2).  */
+  virtual int multifs_open (int pid, const char *filename,
+			    int flags, mode_t mode);
+
+  /* Multiple-filesystem-aware unlink.  Like unlink(2), but operates
+     in the filesystem as it appears to process PID.  Systems where
+     all processes share a common filesystem should not override this.
+     The default behavior is to use unlink(2).  */
+  virtual int multifs_unlink (int pid, const char *filename);
+
+  /* Multiple-filesystem-aware readlink.  Like readlink(2), but
+     operating in the filesystem as it appears to process PID.
+     Systems where all processes share a common filesystem should
+     not override this.  The default behavior is to use readlink(2).  */
+  virtual ssize_t multifs_readlink (int pid, const char *filename,
+				    char *buf, size_t bufsiz);
 };
 
 extern process_stratum_target *the_target;
diff --git a/gdbserver/win32-low.c b/gdbserver/win32-low.c
index d5e15202ae1..ecece2d579c 100644
--- a/gdbserver/win32-low.c
+++ b/gdbserver/win32-low.c
@@ -1848,9 +1848,6 @@ win32_sw_breakpoint_from_kind (int kind, int *size)
 static win32_process_target the_win32_target;
 
 static process_stratum_target win32_target_ops = {
-  NULL, /* multifs_open */
-  NULL, /* multifs_unlink */
-  NULL, /* multifs_readlink */
   NULL, /* breakpoint_kind_from_pc */
   win32_sw_breakpoint_from_kind,
   NULL, /* thread_name */
