]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blobdiff - io/mmap.c
xfs: fix inverted return from xfs_btree_sblock_verify_crc
[thirdparty/xfsprogs-dev.git] / io / mmap.c
index 06f678f64b1bb949807fffcc2ce8388e647e2a0b..f9383e5e790de7b599671df21a981dd956306a43 100644 (file)
--- a/io/mmap.c
+++ b/io/mmap.c
@@ -1,24 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (c) 2004-2005 Silicon Graphics, Inc.
  * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write the Free Software Foundation,
- * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
-#include "xfs/xfs.h"
-#include "xfs/command.h"
-#include "xfs/input.h"
+#include "command.h"
+#include "input.h"
 #include <sys/mman.h>
 #include <signal.h>
 #include "init.h"
@@ -29,7 +16,9 @@ static cmdinfo_t mread_cmd;
 static cmdinfo_t msync_cmd;
 static cmdinfo_t munmap_cmd;
 static cmdinfo_t mwrite_cmd;
+#ifdef HAVE_MREMAP
 static cmdinfo_t mremap_cmd;
+#endif /* HAVE_MREMAP */
 
 mmap_region_t  *maptable;
 int            mapcount;
@@ -41,7 +30,7 @@ print_mapping(
        int             index,
        int             braces)
 {
-       unsigned char   buffer[8] = { 0 };
+       char            buffer[8] = { 0 };
        int             i;
 
        static struct {
@@ -56,6 +45,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,
@@ -145,6 +138,8 @@ 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"));
 }
@@ -155,17 +150,17 @@ mmap_f(
        char            **argv)
 {
        off64_t         offset;
-       ssize_t         length;
-       void            *address;
+       ssize_t         length = 0, length2 = 0;
+       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)
                        return maplist_f();
                fprintf(stderr, file ?
-                       _("no mapped regions, try 'help mmap'\n") : 
+                       _("no mapped regions, try 'help mmap'\n") :
                        _("no files are open, try 'help open'\n"));
                return 0;
        } else if (argc == 2) {
@@ -180,7 +175,9 @@ mmap_f(
                return 0;
        }
 
-       while ((c = getopt(argc, argv, "rwx")) != EOF) {
+       init_cvtnum(&blocksize, &sectsize);
+
+       while ((c = getopt(argc, argv, "rwxSs:")) != EOF) {
                switch (c) {
                case 'r':
                        prot |= PROT_READ;
@@ -191,6 +188,22 @@ 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;
                default:
                        return command_usage(&mmap_cmd);
                }
@@ -201,7 +214,6 @@ mmap_f(
        if (optind != argc - 2)
                return command_usage(&mmap_cmd);
 
-       init_cvtnum(&blocksize, &sectsize);
        offset = cvtnum(blocksize, sectsize, argv[optind]);
        if (offset < 0) {
                printf(_("non-numeric offset argument -- %s\n"), argv[optind]);
@@ -220,7 +232,19 @@ mmap_f(
                return 0;
        }
 
-       address = mmap(NULL, length, prot, MAP_SHARED, file->fd, offset);
+       /*
+        * mmap and munmap memory area of length2 region is helpful to
+        * make a region of extendible free memory. It's generally used
+        * for later mremap operation(no MREMAP_MAYMOVE flag). But there
+        * isn't guarantee that the memory after length (up to length2)
+        * will stay free.
+        */
+       if (length2 > length) {
+               address = mmap(NULL, length2, prot,
+                              MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+               munmap(address, length2);
+       }
+       address = mmap(address, length, prot, flags, file->fd, offset);
        if (address == MAP_FAILED) {
                perror("mmap");
                free(filename);
@@ -245,6 +269,7 @@ mmap_f(
        mapping->offset = offset;
        mapping->name = filename;
        mapping->prot = prot;
+       mapping->map_sync = (flags == (MAP_SYNC | MAP_SHARED_VALIDATE));
        return 0;
 }
 
@@ -265,7 +290,7 @@ msync_help(void)
 "\n"));
 }
 
-int
+static int
 msync_f(
        int             argc,
        char            **argv)
@@ -349,7 +374,7 @@ mread_help(void)
 "\n"));
 }
 
-int
+static int
 mread_f(
        int             argc,
        char            **argv)
@@ -411,7 +436,7 @@ mread_f(
 
        if (alloc_buffer(pagesize, 0, 0) < 0)
                return 0;
-       bp = (char *)buffer;
+       bp = (char *)io_buffer;
 
        dumplen = length % pagesize;
        if (!dumplen)
@@ -426,7 +451,7 @@ mread_f(
                                        dump_buffer(printoffset, dumplen);
                                        printoffset += dumplen;
                                }
-                               bp = (char *)buffer;
+                               bp = (char *)io_buffer;
                                dumplen = pagesize;
                                cnt = 0;
                        } else {
@@ -441,7 +466,7 @@ mread_f(
                                if (dump)
                                        dump_buffer(printoffset + tmp -
                                                (dumplen - 1), dumplen);
-                               bp = (char *)buffer;
+                               bp = (char *)io_buffer;
                                dumplen = pagesize;
                                cnt = 0;
                        } else {
@@ -452,7 +477,7 @@ mread_f(
        return 0;
 }
 
-int
+static int
 munmap_f(
        int             argc,
        char            **argv)
@@ -506,7 +531,7 @@ mwrite_help(void)
 "\n"));
 }
 
-int
+static int
 mwrite_f(
        int             argc,
        char            **argv)
@@ -575,6 +600,7 @@ mwrite_f(
        return 0;
 }
 
+#ifdef HAVE_MREMAP
 static void
 mremap_help(void)
 {
@@ -585,28 +611,32 @@ mremap_help(void)
 " Examples:\n"
 " 'mremap 8192' - resizes the current mapping to 8192 bytes.\n"
 "\n"
-" Resizes the mappping, growing or shrinking from the current size.\n"
+" Resizes the mapping, growing or shrinking from the current size.\n"
 " The default stored value is 'X', repeated to fill the range specified.\n"
-" -f -- use the MREMAP_FIXED flag\n"
+" -f <new_address> -- use MREMAP_FIXED flag to mremap on new_address\n"
 " -m -- use the MREMAP_MAYMOVE flag\n"
 "\n"));
 }
 
-int
+static int
 mremap_f(
        int             argc,
        char            **argv)
 {
        ssize_t         new_length;
-       void            *new_addr;
+       void            *new_addr = NULL;
        int             flags = 0;
        int             c;
        size_t          blocksize, sectsize;
 
-       while ((c = getopt(argc, argv, "fm")) != EOF) {
+       init_cvtnum(&blocksize, &sectsize);
+
+       while ((c = getopt(argc, argv, "f:m")) != EOF) {
                switch (c) {
                case 'f':
                        flags = MREMAP_FIXED|MREMAP_MAYMOVE;
+                       new_addr = (void *)(unsigned long)cvtnum(blocksize,
+                                                 sectsize, optarg);
                        break;
                case 'm':
                        flags = MREMAP_MAYMOVE;
@@ -616,7 +646,9 @@ mremap_f(
                }
        }
 
-       init_cvtnum(&blocksize, &sectsize);
+       if (optind != argc - 1)
+               return command_usage(&mremap_cmd);
+
        new_length = cvtnum(blocksize, sectsize, argv[optind]);
        if (new_length < 0) {
                printf(_("non-numeric offset argument -- %s\n"),
@@ -624,7 +656,12 @@ mremap_f(
                return 0;
        }
 
-       new_addr = mremap(mapping->addr, mapping->length, new_length, flags);
+       if (!new_addr)
+               new_addr = mremap(mapping->addr, mapping->length,
+                                 new_length, flags);
+       else
+               new_addr = mremap(mapping->addr, mapping->length,
+                                 new_length, flags, new_addr);
        if (new_addr == MAP_FAILED)
                perror("mremap");
        else {
@@ -634,6 +671,7 @@ mremap_f(
 
        return 0;
 }
+#endif /* HAVE_MREMAP */
 
 void
 mmap_init(void)
@@ -643,8 +681,9 @@ mmap_init(void)
        mmap_cmd.cfunc = mmap_f;
        mmap_cmd.argmin = 0;
        mmap_cmd.argmax = -1;
-       mmap_cmd.flags = CMD_NOMAP_OK | CMD_NOFILE_OK | CMD_FOREIGN_OK;
-       mmap_cmd.args = _("[N] | [-rwx] [off len]");
+       mmap_cmd.flags = CMD_NOMAP_OK | CMD_NOFILE_OK |
+                        CMD_FOREIGN_OK | CMD_FLAG_ONESHOT;
+       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;
@@ -689,21 +728,25 @@ mmap_init(void)
                _("writes data into a region in the current memory mapping");
        mwrite_cmd.help = mwrite_help;
 
+#ifdef HAVE_MREMAP
        mremap_cmd.name = "mremap";
        mremap_cmd.altname = "mrm";
        mremap_cmd.cfunc = mremap_f;
        mremap_cmd.argmin = 1;
-       mremap_cmd.argmax = 2;
+       mremap_cmd.argmax = 3;
        mremap_cmd.flags = CMD_NOFILE_OK | CMD_FOREIGN_OK;
-       mremap_cmd.args = _("[-m|-f] newsize");
+       mremap_cmd.args = _("[-m|-f <new_address>] newsize");
        mremap_cmd.oneline =
                _("alters the size of the current memory mapping");
        mremap_cmd.help = mremap_help;
+#endif /* HAVE_MREMAP */
 
        add_command(&mmap_cmd);
        add_command(&mread_cmd);
        add_command(&msync_cmd);
        add_command(&munmap_cmd);
        add_command(&mwrite_cmd);
+#ifdef HAVE_MREMAP
        add_command(&mremap_cmd);
+#endif /* HAVE_MREMAP */
 }