]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs_io: add MAP_SYNC support to mmap()
authorRoss Zwisler <ross.zwisler@linux.intel.com>
Thu, 4 Jan 2018 19:58:29 +0000 (13:58 -0600)
committerEric Sandeen <sandeen@redhat.com>
Thu, 4 Jan 2018 19:58:29 +0000 (13:58 -0600)
Add support for a new -S flag to xfs_io's mmap command.  This opens the
mapping with the (MAP_SYNC | MAP_SHARED_VALIDATE) flags instead of the
standard MAP_SHARED flag.

Signed-off-by: Ross Zwisler <ross.zwisler@linux.intel.com>
Suggested-by: Dave Chinner <david@fromorbit.com>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
configure.ac
include/builddefs.in
include/linux.h
io/Makefile
io/io.h
io/mmap.c
m4/package_libcdev.m4
man/man8/xfs_io.8

index e5d0309f806e15af7b01af603b75ee4070454111..f3325aa044089089138e1699c774e90a67bd3cc6 100644 (file)
@@ -163,6 +163,7 @@ AC_HAVE_MREMAP
 AC_NEED_INTERNAL_FSXATTR
 AC_HAVE_GETFSMAP
 AC_HAVE_STATFS_FLAGS
+AC_HAVE_MAP_SYNC
 
 if test "$enable_blkid" = yes; then
 AC_HAVE_BLKID_TOPO
index f4448c62df414ef31795613d7e8a45664d7ea1fe..1f3302232170b322b12ddc10ca06432e9ed60609 100644 (file)
@@ -116,6 +116,7 @@ HAVE_MREMAP = @have_mremap@
 NEED_INTERNAL_FSXATTR = @need_internal_fsxattr@
 HAVE_GETFSMAP = @have_getfsmap@
 HAVE_STATFS_FLAGS = @have_statfs_flags@
+HAVE_MAP_SYNC = @have_map_sync@
 
 GCCFLAGS = -funsigned-char -fno-strict-aliasing -Wall
 #         -Wbitwise -Wno-transparent-union -Wno-old-initializer -Wno-decl
index 6ce344c5ec3f543139be5b451d3fd234fc1e0c9d..1998941a6df5935df8e033560b0026457f7cb40f 100644 (file)
@@ -327,4 +327,12 @@ fsmap_advance(
 #define HAVE_GETFSMAP
 #endif /* HAVE_GETFSMAP */
 
+#ifndef HAVE_MAP_SYNC
+#define MAP_SYNC 0
+#define MAP_SHARED_VALIDATE 0
+#else
+#include <asm-generic/mman.h>
+#include <asm-generic/mman-common.h>
+#endif /* HAVE_MAP_SYNC */
+
 #endif /* __XFS_LINUX_H__ */
index aa0ab7de7c0dcf2bb45a4014c3626e01f9c3dc99..979434a2a15852c070d87ceb6b7876a09c5a5240 100644 (file)
@@ -104,6 +104,10 @@ ifeq ($(HAVE_MREMAP),yes)
 LCFLAGS += -DHAVE_MREMAP
 endif
 
+ifeq ($(HAVE_MAP_SYNC),yes)
+LCFLAGS += -DHAVE_MAP_SYNC
+endif
+
 # On linux we get fsmap from the system or define it ourselves
 # so include this based on platform type.  If this reverts to only
 # the autoconf check w/o local definition, change to testing HAVE_GETFSMAP
diff --git a/io/io.h b/io/io.h
index 82e142f2836bd6a3602142ce054df5d2d463fbac..5255c08705d23d079599d8117bf234ff9a77b187 100644 (file)
--- a/io/io.h
+++ b/io/io.h
@@ -65,6 +65,7 @@ typedef struct mmap_region {
        size_t          length;         /* length of mapping */
        off64_t         offset;         /* start offset into backing file */
        int             prot;           /* protection mode of the mapping */
+       bool            map_sync;       /* is this a MAP_SYNC mapping? */
        char            *name;          /* name of backing file */
 } mmap_region_t;
 
index 7a8150e3d5175acc65cf930f8d1c3cc90558b01d..f905989bd011e83d05fcafdbc474623b24b0c6f6 100644 (file)
--- a/io/mmap.c
+++ b/io/mmap.c
@@ -42,7 +42,7 @@ print_mapping(
        int             index,
        int             braces)
 {
-       unsigned char   buffer[8] = { 0 };
+       char            buffer[8] = { 0 };
        int             i;
 
        static struct {
@@ -57,6 +57,10 @@ print_mapping(
 
        for (i = 0, p = pflags; p->prot != PROT_NONE; i++, p++)
                buffer[i] = (map->prot & p->prot) ? p->mode : '-';
+
+       if (map->map_sync)
+               sprintf(&buffer[i], " S");
+
        printf("%c%03d%c 0x%lx - 0x%lx %s  %14s (%lld : %ld)\n",
                braces? '[' : ' ', index, braces? ']' : ' ',
                (unsigned long)map->addr,
@@ -146,6 +150,7 @@ mmap_help(void)
 " -r -- map with PROT_READ protection\n"
 " -w -- map with PROT_WRITE protection\n"
 " -x -- map with PROT_EXEC protection\n"
+" -S -- map with MAP_SYNC and MAP_SHARED_VALIDATE flags\n"
 " -s <size> -- first do mmap(size)/munmap(size), try to reserve some free space\n"
 " If no protection mode is specified, all are used by default.\n"
 "\n"));
@@ -161,7 +166,7 @@ mmap_f(
        void            *address = NULL;
        char            *filename;
        size_t          blocksize, sectsize;
-       int             c, prot = 0;
+       int             c, prot = 0, flags = MAP_SHARED;
 
        if (argc == 1) {
                if (mapping)
@@ -184,7 +189,7 @@ mmap_f(
 
        init_cvtnum(&blocksize, &sectsize);
 
-       while ((c = getopt(argc, argv, "rwxs:")) != EOF) {
+       while ((c = getopt(argc, argv, "rwxSs:")) != EOF) {
                switch (c) {
                case 'r':
                        prot |= PROT_READ;
@@ -195,6 +200,19 @@ mmap_f(
                case 'x':
                        prot |= PROT_EXEC;
                        break;
+               case 'S':
+                       flags = MAP_SYNC | MAP_SHARED_VALIDATE;
+
+                       /*
+                        * If MAP_SYNC and MAP_SHARED_VALIDATE aren't defined
+                        * in the system headers we will have defined them
+                        * both as 0.
+                        */
+                       if (!flags) {
+                               printf("MAP_SYNC not supported\n");
+                               return 0;
+                       }
+                       break;
                case 's':
                        length2 = cvtnum(blocksize, sectsize, optarg);
                        break;
@@ -238,7 +256,7 @@ mmap_f(
                               MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
                munmap(address, length2);
        }
-       address = mmap(address, length, prot, MAP_SHARED, file->fd, offset);
+       address = mmap(address, length, prot, flags, file->fd, offset);
        if (address == MAP_FAILED) {
                perror("mmap");
                free(filename);
@@ -263,6 +281,7 @@ mmap_f(
        mapping->offset = offset;
        mapping->name = filename;
        mapping->prot = prot;
+       mapping->map_sync = (flags == (MAP_SYNC | MAP_SHARED_VALIDATE));
        return 0;
 }
 
@@ -676,7 +695,7 @@ mmap_init(void)
        mmap_cmd.argmax = -1;
        mmap_cmd.flags = CMD_NOMAP_OK | CMD_NOFILE_OK |
                         CMD_FOREIGN_OK | CMD_FLAG_ONESHOT;
-       mmap_cmd.args = _("[N] | [-rwx] [-s size] [off len]");
+       mmap_cmd.args = _("[N] | [-rwxS] [-s size] [off len]");
        mmap_cmd.oneline =
                _("mmap a range in the current file, show mappings");
        mmap_cmd.help = mmap_help;
index 7b4dfc85531d2cbca35a2f6a82919628f3b8989c..71cedc5cab4387ac44941f7dd042f4d554796112 100644 (file)
@@ -328,3 +328,19 @@ AC_DEFUN([AC_HAVE_STATFS_FLAGS],
     )
     AC_SUBST(have_statfs_flags)
   ])
+
+#
+# Check if we have MAP_SYNC defines (Linux)
+#
+AC_DEFUN([AC_HAVE_MAP_SYNC],
+  [ AC_MSG_CHECKING([for MAP_SYNC])
+    AC_TRY_COMPILE([
+#include <asm-generic/mman.h>
+#include <asm-generic/mman-common.h>
+    ], [
+        int flags = MAP_SYNC | MAP_SHARED_VALIDATE;
+    ], have_map_sync=yes
+       AC_MSG_RESULT(yes),
+       AC_MSG_RESULT(no))
+    AC_SUBST(have_map_sync)
+  ])
index a9bcc29dcd2c278f8cd58a048d7c1e4b26dbf0a1..3f77781f3384c7b2842101beabe3cf44b48a47cc 100644 (file)
@@ -776,7 +776,7 @@ Each (sec, nsec) pair constitutes a single timestamp value.
 
 .SH MEMORY MAPPED I/O COMMANDS
 .TP
-.BI "mmap [ " N " | [[ \-rwx ] [\-s " size " ] " "offset length " ]]
+.BI "mmap [ " N " | [[ \-rwxS ] [\-s " size " ] " "offset length " ]]
 With no arguments,
 .B mmap
 shows the current mappings. Specifying a single numeric argument
@@ -792,6 +792,10 @@ PROT_WRITE
 .RB ( \-w ),
 and PROT_EXEC
 .RB ( \-x ).
+The mapping will be created with the MAP_SHARED flag by default, or with the
+Linux specific (MAP_SYNC | MAP_SHARED_VALIDATE) flags if
+.B -S
+is given.
 .BI \-s " size"
 is used to do a mmap(size) && munmap(size) operation at first, try to reserve some
 extendible free memory space, if