diff options
| author | Enji Cooper <ngie@FreeBSD.org> | 2026-02-15 01:57:42 +0000 |
|---|---|---|
| committer | Enji Cooper <ngie@FreeBSD.org> | 2026-02-15 02:12:44 +0000 |
| commit | e8dbf2b6df199526a660f81de07d17925cfd8518 (patch) | |
| tree | cd0c09449bea5df56ef67059e797737d70587070 /fs | |
| parent | 56a7ce8416d181a2060d7a428aed9c3c6a431e6d (diff) | |
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/cd9660/h_hexdump_r.c | 100 | ||||
| -rw-r--r-- | fs/cd9660/pr_48787.image.hex | 278 | ||||
| -rw-r--r-- | fs/lfs/t_basic.c | 79 | ||||
| -rw-r--r-- | fs/lfs/t_fcntl.c | 407 | ||||
| -rw-r--r-- | fs/lfs/t_orphan.c | 203 | ||||
| -rw-r--r-- | fs/lfs/t_resize.c | 180 | ||||
| -rw-r--r-- | fs/lfs/util.c | 181 | ||||
| -rw-r--r-- | fs/lfs/util.h | 28 |
8 files changed, 1456 insertions, 0 deletions
diff --git a/fs/cd9660/h_hexdump_r.c b/fs/cd9660/h_hexdump_r.c new file mode 100644 index 000000000000..5436a71b5f8f --- /dev/null +++ b/fs/cd9660/h_hexdump_r.c @@ -0,0 +1,100 @@ +/* $NetBSD: h_hexdump_r.c,v 1.1 2024/04/28 14:39:22 rillig Exp $ */ + +/* + * Copyright (c) 2024 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code was contributed to The NetBSD Foundation by Roland Illig. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* Given the output from "hexdump -C", reconstruct the original file. */ + +#include <err.h> +#include <inttypes.h> +#include <regex.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define H "[0-9a-f]" +#define HH " (" H H ")" + +static off_t off, noff; +static unsigned char prev_bytes[16], bytes[16], zeroes[16]; + +int +main(void) +{ + char line[81]; + regex_t data_re, end_re; + regmatch_t m[18]; + + if (regcomp(&data_re, "^(" H "{8,9})" + " " HH HH HH HH HH HH HH HH " " HH HH HH HH HH HH HH HH + " \\|.{16}\\|$", REG_EXTENDED) != 0) + err(1, "regcomp"); + if (regcomp(&end_re, "^(" H "{8,9})$", REG_EXTENDED) != 0) + err(1, "regcomp"); + + while (fgets(line, sizeof(line), stdin) != NULL) { + line[strcspn(line, "\n")] = '\0'; + + if (strcmp(line, "*") == 0) + continue; + + if (regexec(&data_re, line, 18, m, 0) == 0) { + noff = (off_t)strtoimax(line + m[1].rm_so, NULL, 16); + for (size_t i = 0; i < 16; i++) + bytes[i] = (unsigned char)strtoumax( + line + m[2 + i].rm_so, NULL, 16); + + } else if (regexec(&end_re, line, 2, m, 0) == 0) { + noff = (off_t)strtoimax(line + m[1].rm_so, NULL, 16); + if (off < noff) { + if (fseeko(stdout, noff - 16, SEEK_SET) != 0) + err(1, "fseeko"); + if (fwrite(prev_bytes, 1, 16, stdout) != 16) + err(1, "fwrite"); + } + } else + err(1, "invalid line '%s'", line); + + if (memcmp(prev_bytes, zeroes, 16) != 0) { + while (off < noff) { + if (fwrite(prev_bytes, 1, 16, stdout) != 16) + err(1, "fwrite"); + off += 16; + } + if (off != noff) + err(1, "off"); + } else { + if (fseeko(stdout, noff, SEEK_SET) != 0) + err(1, "fseeko"); + off = noff; + } + + memcpy(prev_bytes, bytes, 16); + } + return 0; +} diff --git a/fs/cd9660/pr_48787.image.hex b/fs/cd9660/pr_48787.image.hex new file mode 100644 index 000000000000..706af997e830 --- /dev/null +++ b/fs/cd9660/pr_48787.image.hex @@ -0,0 +1,278 @@ +00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +00008000 01 43 44 30 30 31 01 00 20 20 20 20 20 20 20 20 |.CD001.. | +00008010 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 | | +00008020 20 20 20 20 20 20 20 20 49 53 4f 49 4d 41 47 45 | ISOIMAGE| +00008030 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 | | +00008040 20 20 20 20 20 20 20 20 00 00 00 00 00 00 00 00 | ........| +00008050 f9 41 20 00 00 20 41 f9 00 00 00 00 00 00 00 00 |.A .. A.........| +00008060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +00008070 00 00 00 00 00 00 00 00 01 00 00 01 01 00 00 01 |................| +00008080 00 08 08 00 14 00 00 00 00 00 00 14 f5 41 20 00 |.............A .| +00008090 00 00 00 00 00 20 41 f6 00 00 00 00 22 00 f2 41 |..... A....."..A| +000080a0 20 00 00 20 41 f2 00 08 00 00 00 00 08 00 72 05 | .. A.........r.| +000080b0 06 0f 1f 21 00 02 00 00 01 00 00 01 01 00 20 20 |...!.......... | +000080c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 | | +* +000081b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 58 4f | XO| +000081c0 52 52 49 53 4f 2d 31 2e 33 2e 37 20 32 30 31 34 |RRISO-1.3.7 2014| +000081d0 2e 30 35 2e 30 33 2e 31 31 35 30 31 31 2c 20 4c |.05.03.115011, L| +000081e0 49 42 49 53 4f 42 55 52 4e 2d 31 2e 33 2e 37 2c |IBISOBURN-1.3.7,| +000081f0 20 4c 49 42 49 53 4f 46 53 2d 31 2e 33 2e 37 2c | LIBISOFS-1.3.7,| +00008200 20 4c 49 42 42 55 52 4e 2d 31 2e 33 2e 37 20 20 | LIBBURN-1.3.7 | +00008210 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 | | +* +00008320 20 20 20 20 20 20 20 20 20 20 20 20 20 32 30 31 | 201| +00008330 34 30 35 30 36 31 35 33 34 32 38 30 30 00 32 30 |4050615342800.20| +00008340 31 34 30 35 30 36 31 35 33 34 32 38 30 30 00 30 |14050615342800.0| +00008350 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 00 |000000000000000.| +00008360 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 |0000000000000000| +00008370 00 01 00 20 20 20 20 20 20 20 20 20 20 20 20 20 |... | +00008380 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 | | +* +00008570 20 20 20 00 00 00 00 00 00 00 00 00 00 00 00 00 | .............| +00008580 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +00008800 ff 43 44 30 30 31 01 00 00 00 00 00 00 00 00 00 |.CD001..........| +00008810 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +00018000 01 43 44 30 30 31 01 00 20 20 20 20 20 20 20 20 |.CD001.. | +00018010 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 | | +00018020 20 20 20 20 20 20 20 20 49 53 4f 49 4d 41 47 45 | ISOIMAGE| +00018030 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 | | +00018040 20 20 20 20 20 20 20 20 00 00 00 00 00 00 00 00 | ........| +00018050 b9 41 20 00 00 20 41 b9 00 00 00 00 00 00 00 00 |.A .. A.........| +00018060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +00018070 00 00 00 00 00 00 00 00 01 00 00 01 01 00 00 01 |................| +00018080 00 08 08 00 14 00 00 00 00 00 00 14 35 00 00 00 |............5...| +00018090 00 00 00 00 00 00 00 36 00 00 00 00 22 00 32 00 |.......6....".2.| +000180a0 00 00 00 00 00 32 00 08 00 00 00 00 08 00 72 05 |.....2........r.| +000180b0 06 0f 1f 21 00 02 00 00 01 00 00 01 01 00 20 20 |...!.......... | +000180c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 | | +* +000181b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 58 4f | XO| +000181c0 52 52 49 53 4f 2d 31 2e 33 2e 37 20 32 30 31 34 |RRISO-1.3.7 2014| +000181d0 2e 30 35 2e 30 33 2e 31 31 35 30 31 31 2c 20 4c |.05.03.115011, L| +000181e0 49 42 49 53 4f 42 55 52 4e 2d 31 2e 33 2e 37 2c |IBISOBURN-1.3.7,| +000181f0 20 4c 49 42 49 53 4f 46 53 2d 31 2e 33 2e 37 2c | LIBISOFS-1.3.7,| +00018200 20 4c 49 42 42 55 52 4e 2d 31 2e 33 2e 37 20 20 | LIBBURN-1.3.7 | +00018210 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 | | +* +00018320 20 20 20 20 20 20 20 20 20 20 20 20 20 32 30 31 | 201| +00018330 34 30 35 30 36 31 35 33 31 33 33 30 30 00 32 30 |4050615313300.20| +00018340 31 34 30 35 30 36 31 35 33 31 33 33 30 30 00 30 |14050615313300.0| +00018350 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 00 |000000000000000.| +00018360 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 |0000000000000000| +00018370 00 01 00 20 20 20 20 20 20 20 20 20 20 20 20 20 |... | +00018380 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 | | +* +00018570 20 20 20 00 00 00 00 00 00 00 00 00 00 00 00 00 | .............| +00018580 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +00018800 ff 43 44 30 30 31 01 00 00 00 00 00 00 00 00 00 |.CD001..........| +00018810 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +00019000 84 00 32 00 00 00 00 00 00 32 00 08 00 00 00 00 |..2......2......| +00019010 08 00 72 05 06 0f 1f 21 00 02 00 00 01 00 00 01 |..r....!........| +00019020 01 00 53 50 07 01 be ef 00 50 58 24 01 ed 41 00 |..SP.....PX$..A.| +00019030 00 00 00 41 ed 01 00 00 00 00 00 00 01 00 00 00 |...A............| +00019040 00 00 00 00 00 00 00 00 00 00 00 00 00 54 46 1a |.............TF.| +00019050 01 0e 72 05 06 0f 1f 21 00 72 05 06 0f 1f 21 00 |..r....!.r....!.| +00019060 72 05 06 0f 1f 21 00 43 45 1c 01 33 00 00 00 00 |r....!.CE..3....| +00019070 00 00 33 00 00 00 00 00 00 00 00 ed 00 00 00 00 |..3.............| +00019080 00 00 ed 00 60 00 32 00 00 00 00 00 00 32 00 08 |....`.2......2..| +00019090 00 00 00 00 08 00 72 05 06 0f 1f 21 00 02 00 00 |......r....!....| +000190a0 01 00 00 01 01 01 50 58 24 01 ed 41 00 00 00 00 |......PX$..A....| +000190b0 41 ed 01 00 00 00 00 00 00 01 00 00 00 00 00 00 |A...............| +000190c0 00 00 00 00 00 00 00 00 00 00 54 46 1a 01 0e 72 |..........TF...r| +000190d0 05 06 0f 1f 21 00 72 05 06 0f 1f 21 00 72 05 06 |....!.r....!.r..| +000190e0 0f 1f 21 00 6a 00 34 00 00 00 00 00 00 34 00 08 |..!.j.4......4..| +000190f0 00 00 00 00 08 00 72 05 06 0f 1e 12 00 02 00 00 |......r.........| +00019100 01 00 00 01 02 4d 59 00 50 58 24 01 ed 41 00 00 |.....MY.PX$..A..| +00019110 00 00 41 ed 01 00 00 00 00 00 00 01 e8 03 00 00 |..A.............| +00019120 00 00 03 e8 e8 03 00 00 00 00 03 e8 54 46 1a 01 |............TF..| +00019130 0e 72 05 06 0f 1e 12 00 72 05 06 0f 1a 0e 00 72 |.r......r......r| +00019140 05 06 0f 1e 12 00 4e 4d 07 01 00 6d 79 00 00 00 |......NM...my...| +00019150 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +00019800 45 52 ed 01 0a 54 87 01 52 52 49 50 5f 31 39 39 |ER...T..RRIP_199| +00019810 31 41 54 48 45 20 52 4f 43 4b 20 52 49 44 47 45 |1ATHE ROCK RIDGE| +00019820 20 49 4e 54 45 52 43 48 41 4e 47 45 20 50 52 4f | INTERCHANGE PRO| +00019830 54 4f 43 4f 4c 20 50 52 4f 56 49 44 45 53 20 53 |TOCOL PROVIDES S| +00019840 55 50 50 4f 52 54 20 46 4f 52 20 50 4f 53 49 58 |UPPORT FOR POSIX| +00019850 20 46 49 4c 45 20 53 59 53 54 45 4d 20 53 45 4d | FILE SYSTEM SEM| +00019860 41 4e 54 49 43 53 50 4c 45 41 53 45 20 43 4f 4e |ANTICSPLEASE CON| +00019870 54 41 43 54 20 44 49 53 43 20 50 55 42 4c 49 53 |TACT DISC PUBLIS| +00019880 48 45 52 20 46 4f 52 20 53 50 45 43 49 46 49 43 |HER FOR SPECIFIC| +00019890 41 54 49 4f 4e 20 53 4f 55 52 43 45 2e 20 20 53 |ATION SOURCE. S| +000198a0 45 45 20 50 55 42 4c 49 53 48 45 52 20 49 44 45 |EE PUBLISHER IDE| +000198b0 4e 54 49 46 49 45 52 20 49 4e 20 50 52 49 4d 41 |NTIFIER IN PRIMA| +000198c0 52 59 20 56 4f 4c 55 4d 45 20 44 45 53 43 52 49 |RY VOLUME DESCRI| +000198d0 50 54 4f 52 20 46 4f 52 20 43 4f 4e 54 41 43 54 |PTOR FOR CONTACT| +000198e0 20 49 4e 46 4f 52 4d 41 54 49 4f 4e 2e 00 00 00 | INFORMATION....| +000198f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +0001a000 60 00 34 00 00 00 00 00 00 34 00 08 00 00 00 00 |`.4......4......| +0001a010 08 00 72 05 06 0f 1e 12 00 02 00 00 01 00 00 01 |..r.............| +0001a020 01 00 50 58 24 01 ed 41 00 00 00 00 41 ed 01 00 |..PX$..A....A...| +0001a030 00 00 00 00 00 01 e8 03 00 00 00 00 03 e8 e8 03 |................| +0001a040 00 00 00 00 03 e8 54 46 1a 01 0e 72 05 06 0f 1e |......TF...r....| +0001a050 12 00 72 05 06 0f 1a 0e 00 72 05 06 0f 1e 12 00 |..r......r......| +0001a060 60 00 32 00 00 00 00 00 00 32 00 08 00 00 00 00 |`.2......2......| +0001a070 08 00 72 05 06 0f 1f 21 00 02 00 00 01 00 00 01 |..r....!........| +0001a080 01 01 50 58 24 01 ed 41 00 00 00 00 41 ed 01 00 |..PX$..A....A...| +0001a090 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 |................| +0001a0a0 00 00 00 00 00 00 54 46 1a 01 0e 72 05 06 0f 1f |......TF...r....| +0001a0b0 21 00 72 05 06 0f 1f 21 00 72 05 06 0f 1f 21 00 |!.r....!.r....!.| +0001a0c0 7c 00 38 00 00 00 00 00 00 38 00 f8 ff ff ff ff ||.8......8......| +0001a0d0 f8 00 72 05 06 0f 1e 12 00 80 00 00 01 00 00 01 |..r.............| +0001a0e0 0d 4c 41 52 47 45 5f 46 49 4c 45 2e 3b 31 50 58 |.LARGE_FILE.;1PX| +0001a0f0 24 01 a4 81 00 00 00 00 81 a4 01 00 00 00 00 00 |$...............| +0001a100 00 01 e8 03 00 00 00 00 03 e8 e8 03 00 00 00 00 |................| +0001a110 03 e8 54 46 1a 01 0e 72 05 06 0f 1e 12 00 72 05 |..TF...r......r.| +0001a120 06 0f 1e 12 00 72 05 06 0f 1e 12 00 4e 4d 0f 01 |.....r......NM..| +0001a130 00 6c 61 72 67 65 5f 66 69 6c 65 00 7c 00 37 00 |.large_file.|.7.| +0001a140 20 00 00 20 00 37 00 10 0d 02 02 0d 10 00 72 05 | .. .7........r.| +0001a150 06 0f 1e 12 00 00 00 00 01 00 00 01 0d 4c 41 52 |.............LAR| +0001a160 47 45 5f 46 49 4c 45 2e 3b 31 50 58 24 01 a4 81 |GE_FILE.;1PX$...| +0001a170 00 00 00 00 81 a4 01 00 00 00 00 00 00 01 e8 03 |................| +0001a180 00 00 00 00 03 e8 e8 03 00 00 00 00 03 e8 54 46 |..............TF| +0001a190 1a 01 0e 72 05 06 0f 1e 12 00 72 05 06 0f 1e 12 |...r......r.....| +0001a1a0 00 72 05 06 0f 1e 12 00 4e 4d 0f 01 00 6c 61 72 |.r......NM...lar| +0001a1b0 67 65 5f 66 69 6c 65 00 00 00 00 00 00 00 00 00 |ge_file.........| +0001a1c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +0001a800 01 00 32 00 00 00 01 00 00 00 02 00 34 00 00 00 |..2.........4...| +0001a810 01 00 4d 59 00 00 00 00 00 00 00 00 00 00 00 00 |..MY............| +0001a820 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +0001b000 01 00 00 00 00 32 00 01 00 00 02 00 00 00 00 34 |.....2.........4| +0001b010 00 01 4d 59 00 00 00 00 00 00 00 00 00 00 00 00 |..MY............| +0001b020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +1020f8000 01 43 44 30 30 31 01 00 20 20 20 20 20 20 20 20 |.CD001.. | +1020f8010 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 | | +1020f8020 20 20 20 20 20 20 20 20 49 53 4f 49 4d 41 47 45 | ISOIMAGE| +1020f8030 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 | | +1020f8040 20 20 20 20 20 20 20 20 00 00 00 00 00 00 00 00 | ........| +1020f8050 19 00 00 00 00 00 00 19 00 00 00 00 00 00 00 00 |................| +1020f8060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +1020f8070 00 00 00 00 00 00 00 00 01 00 00 01 01 00 00 01 |................| +1020f8080 00 08 08 00 14 00 00 00 00 00 00 14 f5 41 20 00 |.............A .| +1020f8090 00 00 00 00 00 20 41 f6 00 00 00 00 22 00 f2 41 |..... A....."..A| +1020f80a0 20 00 00 20 41 f2 00 08 00 00 00 00 08 00 72 05 | .. A.........r.| +1020f80b0 06 0f 1f 21 00 02 00 00 01 00 00 01 01 00 20 20 |...!.......... | +1020f80c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 | | +* +1020f81b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 58 4f | XO| +1020f81c0 52 52 49 53 4f 2d 31 2e 33 2e 37 20 32 30 31 34 |RRISO-1.3.7 2014| +1020f81d0 2e 30 35 2e 30 33 2e 31 31 35 30 31 31 2c 20 4c |.05.03.115011, L| +1020f81e0 49 42 49 53 4f 42 55 52 4e 2d 31 2e 33 2e 37 2c |IBISOBURN-1.3.7,| +1020f81f0 20 4c 49 42 49 53 4f 46 53 2d 31 2e 33 2e 37 2c | LIBISOFS-1.3.7,| +1020f8200 20 4c 49 42 42 55 52 4e 2d 31 2e 33 2e 37 20 20 | LIBBURN-1.3.7 | +1020f8210 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 | | +* +1020f8320 20 20 20 20 20 20 20 20 20 20 20 20 20 32 30 31 | 201| +1020f8330 34 30 35 30 36 31 35 33 34 32 38 30 30 00 32 30 |4050615342800.20| +1020f8340 31 34 30 35 30 36 31 35 33 34 32 38 30 30 00 30 |14050615342800.0| +1020f8350 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 00 |000000000000000.| +1020f8360 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 |0000000000000000| +1020f8370 00 01 00 20 20 20 20 20 20 20 20 20 20 20 20 20 |... | +1020f8380 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 | | +* +1020f8570 20 20 20 00 00 00 00 00 00 00 00 00 00 00 00 00 | .............| +1020f8580 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +1020f8800 ff 43 44 30 30 31 01 00 00 00 00 00 00 00 00 00 |.CD001..........| +1020f8810 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +1020f9000 84 00 f2 41 20 00 00 20 41 f2 00 08 00 00 00 00 |...A .. A.......| +1020f9010 08 00 72 05 06 0f 1f 21 00 02 00 00 01 00 00 01 |..r....!........| +1020f9020 01 00 53 50 07 01 be ef 00 50 58 24 01 ed 41 00 |..SP.....PX$..A.| +1020f9030 00 00 00 41 ed 01 00 00 00 00 00 00 01 00 00 00 |...A............| +1020f9040 00 00 00 00 00 00 00 00 00 00 00 00 00 54 46 1a |.............TF.| +1020f9050 01 0e 72 05 06 0f 1f 21 00 72 05 06 0f 1f 21 00 |..r....!.r....!.| +1020f9060 72 05 06 0f 1f 21 00 43 45 1c 01 f3 41 20 00 00 |r....!.CE...A ..| +1020f9070 20 41 f3 00 00 00 00 00 00 00 00 ed 00 00 00 00 | A..............| +1020f9080 00 00 ed 00 60 00 f2 41 20 00 00 20 41 f2 00 08 |....`..A .. A...| +1020f9090 00 00 00 00 08 00 72 05 06 0f 1f 21 00 02 00 00 |......r....!....| +1020f90a0 01 00 00 01 01 01 50 58 24 01 ed 41 00 00 00 00 |......PX$..A....| +1020f90b0 41 ed 01 00 00 00 00 00 00 01 00 00 00 00 00 00 |A...............| +1020f90c0 00 00 00 00 00 00 00 00 00 00 54 46 1a 01 0e 72 |..........TF...r| +1020f90d0 05 06 0f 1f 21 00 72 05 06 0f 1f 21 00 72 05 06 |....!.r....!.r..| +1020f90e0 0f 1f 21 00 6a 00 f4 41 20 00 00 20 41 f4 00 08 |..!.j..A .. A...| +1020f90f0 00 00 00 00 08 00 72 05 06 0f 1e 12 00 02 00 00 |......r.........| +1020f9100 01 00 00 01 02 4d 59 00 50 58 24 01 ed 41 00 00 |.....MY.PX$..A..| +1020f9110 00 00 41 ed 01 00 00 00 00 00 00 01 e8 03 00 00 |..A.............| +1020f9120 00 00 03 e8 e8 03 00 00 00 00 03 e8 54 46 1a 01 |............TF..| +1020f9130 0e 72 05 06 0f 1e 12 00 72 05 06 0f 1a 0e 00 72 |.r......r......r| +1020f9140 05 06 0f 1e 12 00 4e 4d 07 01 00 6d 79 00 7c 00 |......NM...my.|.| +1020f9150 f8 41 20 00 00 20 41 f8 06 00 00 00 00 00 00 06 |.A .. A.........| +1020f9160 72 05 06 0f 22 00 00 00 00 00 01 00 00 01 0d 53 |r..."..........S| +1020f9170 4d 41 4c 4c 5f 46 49 4c 45 2e 3b 31 50 58 24 01 |MALL_FILE.;1PX$.| +1020f9180 a4 81 00 00 00 00 81 a4 01 00 00 00 00 00 00 01 |................| +1020f9190 e8 03 00 00 00 00 03 e8 e8 03 00 00 00 00 03 e8 |................| +1020f91a0 54 46 1a 01 0e 72 05 06 0f 22 00 00 72 05 06 0f |TF...r..."..r...| +1020f91b0 22 00 00 72 05 06 0f 22 00 00 4e 4d 0f 01 00 73 |"..r..."..NM...s| +1020f91c0 6d 61 6c 6c 5f 66 69 6c 65 00 00 00 00 00 00 00 |mall_file.......| +1020f91d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +1020f9800 45 52 ed 01 0a 54 87 01 52 52 49 50 5f 31 39 39 |ER...T..RRIP_199| +1020f9810 31 41 54 48 45 20 52 4f 43 4b 20 52 49 44 47 45 |1ATHE ROCK RIDGE| +1020f9820 20 49 4e 54 45 52 43 48 41 4e 47 45 20 50 52 4f | INTERCHANGE PRO| +1020f9830 54 4f 43 4f 4c 20 50 52 4f 56 49 44 45 53 20 53 |TOCOL PROVIDES S| +1020f9840 55 50 50 4f 52 54 20 46 4f 52 20 50 4f 53 49 58 |UPPORT FOR POSIX| +1020f9850 20 46 49 4c 45 20 53 59 53 54 45 4d 20 53 45 4d | FILE SYSTEM SEM| +1020f9860 41 4e 54 49 43 53 50 4c 45 41 53 45 20 43 4f 4e |ANTICSPLEASE CON| +1020f9870 54 41 43 54 20 44 49 53 43 20 50 55 42 4c 49 53 |TACT DISC PUBLIS| +1020f9880 48 45 52 20 46 4f 52 20 53 50 45 43 49 46 49 43 |HER FOR SPECIFIC| +1020f9890 41 54 49 4f 4e 20 53 4f 55 52 43 45 2e 20 20 53 |ATION SOURCE. S| +1020f98a0 45 45 20 50 55 42 4c 49 53 48 45 52 20 49 44 45 |EE PUBLISHER IDE| +1020f98b0 4e 54 49 46 49 45 52 20 49 4e 20 50 52 49 4d 41 |NTIFIER IN PRIMA| +1020f98c0 52 59 20 56 4f 4c 55 4d 45 20 44 45 53 43 52 49 |RY VOLUME DESCRI| +1020f98d0 50 54 4f 52 20 46 4f 52 20 43 4f 4e 54 41 43 54 |PTOR FOR CONTACT| +1020f98e0 20 49 4e 46 4f 52 4d 41 54 49 4f 4e 2e 00 00 00 | INFORMATION....| +1020f98f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +1020fa000 60 00 f4 41 20 00 00 20 41 f4 00 08 00 00 00 00 |`..A .. A.......| +1020fa010 08 00 72 05 06 0f 1e 12 00 02 00 00 01 00 00 01 |..r.............| +1020fa020 01 00 50 58 24 01 ed 41 00 00 00 00 41 ed 01 00 |..PX$..A....A...| +1020fa030 00 00 00 00 00 01 e8 03 00 00 00 00 03 e8 e8 03 |................| +1020fa040 00 00 00 00 03 e8 54 46 1a 01 0e 72 05 06 0f 1e |......TF...r....| +1020fa050 12 00 72 05 06 0f 1a 0e 00 72 05 06 0f 1e 12 00 |..r......r......| +1020fa060 60 00 f2 41 20 00 00 20 41 f2 00 08 00 00 00 00 |`..A .. A.......| +1020fa070 08 00 72 05 06 0f 1f 21 00 02 00 00 01 00 00 01 |..r....!........| +1020fa080 01 01 50 58 24 01 ed 41 00 00 00 00 41 ed 01 00 |..PX$..A....A...| +1020fa090 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 |................| +1020fa0a0 00 00 00 00 00 00 54 46 1a 01 0e 72 05 06 0f 1f |......TF...r....| +1020fa0b0 21 00 72 05 06 0f 1f 21 00 72 05 06 0f 1f 21 00 |!.r....!.r....!.| +1020fa0c0 7c 00 38 00 00 00 00 00 00 38 00 f8 ff ff ff ff ||.8......8......| +1020fa0d0 f8 00 72 05 06 0f 1e 12 00 80 00 00 01 00 00 01 |..r.............| +1020fa0e0 0d 4c 41 52 47 45 5f 46 49 4c 45 2e 3b 31 50 58 |.LARGE_FILE.;1PX| +1020fa0f0 24 01 a4 81 00 00 00 00 81 a4 01 00 00 00 00 00 |$...............| +1020fa100 00 01 e8 03 00 00 00 00 03 e8 e8 03 00 00 00 00 |................| +1020fa110 03 e8 54 46 1a 01 0e 72 05 06 0f 1e 12 00 72 05 |..TF...r......r.| +1020fa120 06 0f 1e 12 00 72 05 06 0f 1e 12 00 4e 4d 0f 01 |.....r......NM..| +1020fa130 00 6c 61 72 67 65 5f 66 69 6c 65 00 7c 00 37 00 |.large_file.|.7.| +1020fa140 20 00 00 20 00 37 00 10 0d 02 02 0d 10 00 72 05 | .. .7........r.| +1020fa150 06 0f 1e 12 00 00 00 00 01 00 00 01 0d 4c 41 52 |.............LAR| +1020fa160 47 45 5f 46 49 4c 45 2e 3b 31 50 58 24 01 a4 81 |GE_FILE.;1PX$...| +1020fa170 00 00 00 00 81 a4 01 00 00 00 00 00 00 01 e8 03 |................| +1020fa180 00 00 00 00 03 e8 e8 03 00 00 00 00 03 e8 54 46 |..............TF| +1020fa190 1a 01 0e 72 05 06 0f 1e 12 00 72 05 06 0f 1e 12 |...r......r.....| +1020fa1a0 00 72 05 06 0f 1e 12 00 4e 4d 0f 01 00 6c 61 72 |.r......NM...lar| +1020fa1b0 67 65 5f 66 69 6c 65 00 00 00 00 00 00 00 00 00 |ge_file.........| +1020fa1c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +1020fa800 01 00 f2 41 20 00 01 00 00 00 02 00 f4 41 20 00 |...A ........A .| +1020fa810 01 00 4d 59 00 00 00 00 00 00 00 00 00 00 00 00 |..MY............| +1020fa820 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +1020fb000 01 00 00 20 41 f2 00 01 00 00 02 00 00 20 41 f4 |... A........ A.| +1020fb010 00 01 4d 59 00 00 00 00 00 00 00 00 00 00 00 00 |..MY............| +1020fb020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +1020fc000 68 65 6c 6c 6f 0a 00 00 00 00 00 00 00 00 00 00 |hello...........| +1020fc010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +102150000 diff --git a/fs/lfs/t_basic.c b/fs/lfs/t_basic.c new file mode 100644 index 000000000000..3a01a5a43569 --- /dev/null +++ b/fs/lfs/t_basic.c @@ -0,0 +1,79 @@ +/* $NetBSD: t_basic.c,v 1.1 2025/10/13 00:44:35 perseant Exp $ */ + +#include <sys/types.h> +#include <sys/mount.h> +#include <sys/wait.h> + +#include <atf-c.h> +#include <ctype.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> + +#include <rump/rump.h> +#include <rump/rump_syscalls.h> + +#include <ufs/ufs/ufsmount.h> +#include <ufs/lfs/lfs.h> +#include <ufs/lfs/lfs_extern.h> + +#include "h_macros.h" +#include "util.h" + +#define FSSIZE 10000 + +/* Actually run the test */ +void test(int); + +ATF_TC(newfs_fsck32); +ATF_TC_HEAD(newfs_fsck32, tc) +{ + atf_tc_set_md_var(tc, "descr", + "LFS32 newfs_lfs produces a filesystem that passes fsck_lfs"); + atf_tc_set_md_var(tc, "timeout", "20"); +} + +ATF_TC(newfs_fsck64); +ATF_TC_HEAD(newfs_fsck64, tc) +{ + atf_tc_set_md_var(tc, "descr", + "LFS64 newfs_lfs produces a filesystem that passes fsck_lfs"); + atf_tc_set_md_var(tc, "timeout", "20"); +} + +ATF_TC_BODY(newfs_fsck32, tc) +{ + test(32); +} + +ATF_TC_BODY(newfs_fsck64, tc) +{ + test(64); +} + +void test(int width) +{ + setvbuf(stdout, NULL, _IONBF, 0); + + /* + * Initialize. + */ + + /* Create image file larger than filesystem */ + create_lfs(FSSIZE, FSSIZE, width, 1); + + if (fsck()) + atf_tc_fail_errno("fsck found errors after first unmount"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, newfs_fsck32); + ATF_TP_ADD_TC(tp, newfs_fsck64); + return atf_no_error(); +} diff --git a/fs/lfs/t_fcntl.c b/fs/lfs/t_fcntl.c new file mode 100644 index 000000000000..0d7c1f86d79f --- /dev/null +++ b/fs/lfs/t_fcntl.c @@ -0,0 +1,407 @@ +/* $NetBSD: t_fcntl.c,v 1.6 2025/12/10 03:08:52 perseant Exp $ */ + +#include <sys/types.h> +#include <sys/mount.h> +#include <sys/wait.h> + +#include <atf-c.h> +#include <ctype.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <string.h> + +#include <rump/rump.h> +#include <rump/rump_syscalls.h> + +#include <ufs/ufs/ufsmount.h> +#include <ufs/lfs/lfs.h> +#include <ufs/lfs/lfs_extern.h> + +#include "h_macros.h" +#include "util.h" + +/* Debugging conditions */ +/* #define FORCE_SUCCESS */ /* Don't actually revert, everything worked */ +/* #define USE_DUMPLFS */ /* Dump the filesystem at certain steps */ + +#define UNCHANGED_CONTROL MP "/3-a-random-file" +#define FSSIZE 10000 /* In sectors */ +#define A_FEW_BLOCKS 6500 /* In bytes; a few blocks worth */ +#define MORE_THAN_A_SEGMENT (4 * SEGSIZE) /* In bytes; > SEGSIZE */ + +/* Set up filesystem with a file in it */ +int setup(int, struct ufs_args *, off_t); + +/* Actually run the test */ +void coalesce(int); +void cleanseg(int); +void autoclean(int); + +/* Unmount and check fsck */ +void teardown(int, struct ufs_args *, off_t); + +ATF_TC(coalesce32); +ATF_TC_HEAD(coalesce32, tc) +{ + atf_tc_set_md_var(tc, "descr", + "LFS32 LFCNSCRAMBLE/LFCNREWRITEFILE"); + /* atf_tc_set_md_var(tc, "timeout", "20"); */ +} + +ATF_TC(coalesce64); +ATF_TC_HEAD(coalesce64, tc) +{ + atf_tc_set_md_var(tc, "descr", + "LFS64 LFCNSCRAMBLE/LFCNREWRITEFILE"); + /* atf_tc_set_md_var(tc, "timeout", "20"); */ +} + +ATF_TC(cleanseg32); +ATF_TC_HEAD(cleanseg32, tc) +{ + atf_tc_set_md_var(tc, "descr", + "LFS32 LFCNREWRITESEG"); + atf_tc_set_md_var(tc, "timeout", "20"); +} + +ATF_TC(cleanseg64); +ATF_TC_HEAD(cleanseg64, tc) +{ + atf_tc_set_md_var(tc, "descr", + "LFS64 LFCNREWRITESEG"); + atf_tc_set_md_var(tc, "timeout", "20"); +} + +ATF_TC(autoclean32); +ATF_TC_HEAD(autoclean32, tc) +{ + atf_tc_set_md_var(tc, "descr", + "LFS32 LFCNAUTOCLEAN"); + /* atf_tc_set_md_var(tc, "timeout", "20"); */ +} + +ATF_TC(autoclean64); +ATF_TC_HEAD(autoclean64, tc) +{ + atf_tc_set_md_var(tc, "descr", + "LFS64 LFCNAUTOCLEAN"); + /* atf_tc_set_md_var(tc, "timeout", "20"); */ +} + +ATF_TC_BODY(coalesce32, tc) +{ + coalesce(32); +} + +ATF_TC_BODY(coalesce64, tc) +{ + coalesce(64); +} + +ATF_TC_BODY(cleanseg32, tc) +{ + cleanseg(32); +} + +ATF_TC_BODY(cleanseg64, tc) +{ + cleanseg(64); +} + +ATF_TC_BODY(autoclean32, tc) +{ + autoclean(32); +} + +ATF_TC_BODY(autoclean64, tc) +{ + autoclean(64); +} + +int setup(int width, struct ufs_args *argsp, off_t filesize) +{ + int fd; + + setvbuf(stdout, NULL, _IONBF, 0); + + /* + * Initialize. + */ + + /* Create image file */ + create_lfs(FSSIZE, FSSIZE, width, 1); + + /* Mount filesystem */ + fprintf(stderr, "* Mount fs [1]\n"); + memset(argsp, 0, sizeof *argsp); + argsp->fspec = __UNCONST(FAKEBLK); + if (rump_sys_mount(MOUNT_LFS, MP, 0, argsp, sizeof *argsp) == -1) + atf_tc_fail_errno("rump_sys_mount failed"); + + /* Payload */ + fprintf(stderr, "* Initial payload\n"); + write_file(UNCHANGED_CONTROL, filesize, 1, 3); + + /* Make the data go to disk */ + fprintf(stderr, "* Double sync\n"); + rump_sys_sync(); + rump_sys_sync(); + + /* Get a handle to the root of the file system */ + fd = rump_sys_open(MP, O_RDONLY); + if (fd < 0) + atf_tc_fail_errno("rump_sys_open mount point root failed"); + + return fd; +} + +void teardown(int fd, struct ufs_args *argsp, off_t filesize) +{ + /* Close descriptor */ + rump_sys_close(fd); + + /* Unmount */ + if (rump_sys_unmount(MP, 0) < 0) + atf_tc_fail_errno("rump_sys_unmount failed[1]"); + + /* Fsck */ + fprintf(stderr, "* Fsck after final unmount\n"); + if (fsck()) + atf_tc_fail("fsck found errors after final unmount"); + + /* + * Check file system contents + */ + + /* Mount filesystem one last time */ + fprintf(stderr, "* Mount fs again to check contents\n"); + if (rump_sys_mount(MOUNT_LFS, MP, 0, argsp, sizeof *argsp) == -1) + atf_tc_fail_errno("rump_sys_mount failed [4]"); + + if (check_file(UNCHANGED_CONTROL, filesize, 3) != 0) + atf_tc_fail("Unchanged control file differs(!)"); + + /* Umount filesystem */ + if (rump_sys_unmount(MP, 0) < 0) + atf_tc_fail_errno("rump_sys_unmount failed[2]"); + + /* Final fsck to double check */ + fprintf(stderr, "* Fsck after final unmount\n"); + if (fsck()) + atf_tc_fail("fsck found errors after final unmount"); +} + +void coalesce(int width) +{ + struct ufs_args args; + struct stat statbuf; + struct lfs_filestat_req fsr; + struct lfs_filestats fss_before, fss_scrambled, fss_after; + struct lfs_inode_array inotbl; + int fd; + ino_t ino; + + fd = setup(width, &args, A_FEW_BLOCKS); + + /* Get our file's inode number */ + if (rump_sys_stat(UNCHANGED_CONTROL, &statbuf) != 0) + atf_tc_fail_errno("rump_sys_stat failed"); + ino = statbuf.st_ino; + + fprintf(stderr, "Treating inode %d\n", (int)ino); + + /* Retrieve fragmentation statistics */ + memset(&fss_before, 0, sizeof fss_before); + memset(&fss_scrambled, 0, sizeof fss_scrambled); + memset(&fss_after, 0, sizeof fss_after); + + fsr.ino = ino; + fsr.len = 1; + fsr.fss = &fss_before; + if (rump_sys_fcntl(fd, LFCNFILESTATS, &fsr) < 0) + atf_tc_fail_errno("LFCNFILESTATS[1] failed"); + + inotbl.len = 1; + inotbl.inodes = &ino; + + fprintf(stderr, "Start ino %d nblk %d count %d total %d\n", + (int)ino, (int)fss_before.nblk, (int)fss_before.dc_count, + (int)fss_before.dc_sum); + + /* Scramble */ + if (rump_sys_fcntl(fd, LFCNSCRAMBLE, &inotbl) < 0) + atf_tc_fail_errno("LFCNSCRAMBLE failed"); + fsr.fss = &fss_scrambled; + if (rump_sys_fcntl(fd, LFCNFILESTATS, &fsr) < 0) + atf_tc_fail_errno("LFCNFILESTATS[2] failed"); + if (fss_scrambled.dc_count <= fss_before.dc_count) + atf_tc_fail("Scramble did not worsen gap count"); + if (fss_scrambled.dc_sum <= fss_before.dc_sum) + atf_tc_fail("Scramble did not worsen total gap length"); + + fprintf(stderr, "Scrambled ino %d nblk %d count %d total %d\n", + (int)ino, (int)fss_scrambled.nblk, (int)fss_scrambled.dc_count, + (int)fss_scrambled.dc_sum); + + /* Coalesce */ + if (rump_sys_fcntl(fd, LFCNREWRITEFILE, &inotbl) < 0) + atf_tc_fail_errno("LFCNREWRITEFILE failed"); + fsr.fss = &fss_after; + if (rump_sys_fcntl(fd, LFCNFILESTATS, &fsr) < 0) + atf_tc_fail_errno("LFCNFILESTATS[3] failed"); + if (fss_scrambled.dc_count <= fss_after.dc_count) + atf_tc_fail("Rewrite did not improve gap count"); + if (fss_scrambled.dc_sum <= fss_after.dc_sum) + atf_tc_fail("Rewrite did not improve total gap length"); + + fprintf(stderr, "Coalesced ino %d nblk %d count %d total %d\n", + (int)ino, (int)fss_after.nblk, (int)fss_after.dc_count, + (int)fss_after.dc_sum); + + teardown(fd, &args, A_FEW_BLOCKS); +} + +void cleanseg(int width) +{ + struct ufs_args args; + struct lfs_segnum_array sna; + struct lfs_seguse_array sua; + int fd, sn; + + fd = setup(width, &args, MORE_THAN_A_SEGMENT); + + fprintf(stderr, "* Get seguse\n"); + sua.len = LFS_SEGUSE_MAXCNT; + sua.start = 0; + sua.seguse = malloc(LFS_SEGUSE_MAXCNT * sizeof(*sua.seguse)); + if (rump_sys_fcntl(fd, LFCNSEGUSE, &sua) < 0) + atf_tc_fail_errno("LFCNSEGUSE[1] failed"); + + for (sn = 0; sn < (int)sua.len; ++sn) { + if (sua.seguse[sn].su_nbytes == 0) + continue; + if ((sua.seguse[sn].su_flags & (SEGUSE_DIRTY | SEGUSE_ACTIVE)) + != SEGUSE_DIRTY) + continue; + break; + } + if (sn == (int)sua.len) + atf_tc_fail("No segments found to clean"); + + fprintf(stderr, "* Cleaning segment #%d\n", sn); + + memset(&sna, 0, sizeof sna); + sna.len = 1; + sna.segments = &sn; + if (rump_sys_fcntl(fd, LFCNREWRITESEGS, &sna) < 0) + atf_tc_fail_errno("LFCNREWRITESEGS failed"); + + fprintf(stderr, "* Double sync\n"); + rump_sys_sync(); + rump_sys_sync(); + + fprintf(stderr, "* Get seguse again\n"); + sua.len = 1; + sua.start = sn; + if (rump_sys_fcntl(fd, LFCNSEGUSE, &sua) < 0) + atf_tc_fail_errno("LFCNSEGUSE[2] failed"); + + if (sua.seguse[0].su_nbytes > 0) + atf_tc_fail("Empty bytes after clean"); + + fprintf(stderr, "* Teardown\n"); + teardown(fd, &args, MORE_THAN_A_SEGMENT); +} + +void autoclean(int width) +{ + struct ufs_args args; + struct lfs_autoclean_params autoclean; + int i, fd; + char filename[1024]; + struct statvfs statbuf; + CLEANERINFO64 ci_before, ci_after; + unsigned long target; + + fd = setup(width, &args, CHUNKSIZE); + + rump_sys_fstatvfs1(fd, &statbuf, ST_WAIT); + target = 7 * statbuf.f_blocks / 8; + + /* Write a number of files, deleting every other one. */ + fprintf(stderr, "* Write numbered files\n"); + for (i = 4; ; i++) { + fprintf(stderr, "* create %d\n", i); + sprintf(filename, "%s/%d", MP, i); + write_file(filename, SEGSIZE / 3, 1, 0); + rump_sys_fstatvfs1(fd, &statbuf, ST_WAIT); + if (statbuf.f_bfree < target) + break; + fprintf(stderr, " %ld blocks vs target %ld\n", + (long)statbuf.f_bfree, (long)target); + } + rump_sys_sync(); + rump_sys_sync(); + + /* Record cleanerinfo */ + fprintf(stderr, "* Get cleanerinfo\n"); + if (rump_sys_fcntl(fd, LFCNCLEANERINFO, &ci_before) < 0) + atf_tc_fail_errno("LFCNCLEANERINFO[1] failed"); + + /* Start autocleaner */ + autoclean.size = sizeof(autoclean); + autoclean.mode = LFS_CLEANMODE_GREEDY; + autoclean.thresh = -1; + autoclean.target = -1; + if (rump_sys_fcntl(fd, LFCNAUTOCLEAN, &autoclean) < 0) + atf_tc_fail_errno("LFCNAUTOCLEAN[1] failed"); + + /* Make many segments almost empty */ + fprintf(stderr, "* Delete most files\n"); + for (; i > 0; i--) { + if (i % 3 == 0) + continue; + fprintf(stderr, "* delete %d\n", i); + sprintf(filename, "%s/%d", MP, i); + rump_sys_unlink(filename); + } + rump_sys_sync(); + rump_sys_sync(); + + /* Give the cleaner a chance to run */ + fprintf(stderr, "* Sleep\n"); + sleep(5); + + /* Auto reclaim freed segments */ + fprintf(stderr, "* Sync\n"); + rump_sys_sync(); + rump_sys_sync(); + + /* Record cleanerinfo again */ + fprintf(stderr, "* Get cleanerinfo again\n"); + if (rump_sys_fcntl(fd, LFCNCLEANERINFO, &ci_after) < 0) + atf_tc_fail_errno("LFCNCLEANERINFO[2] failed"); + + /* Compare */ + if (ci_before.avail >= ci_after.avail) + atf_tc_fail("No improvement"); + + teardown(fd, &args, CHUNKSIZE); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, coalesce32); + ATF_TP_ADD_TC(tp, coalesce64); + ATF_TP_ADD_TC(tp, cleanseg32); + ATF_TP_ADD_TC(tp, cleanseg64); + ATF_TP_ADD_TC(tp, autoclean32); + ATF_TP_ADD_TC(tp, autoclean64); + return atf_no_error(); +} diff --git a/fs/lfs/t_orphan.c b/fs/lfs/t_orphan.c new file mode 100644 index 000000000000..c1cf7f1f71b8 --- /dev/null +++ b/fs/lfs/t_orphan.c @@ -0,0 +1,203 @@ +/* $NetBSD: t_orphan.c,v 1.4 2025/12/19 20:58:08 perseant Exp $ */ + +#include <sys/types.h> +#include <sys/mount.h> +#include <sys/wait.h> + +#include <atf-c.h> +#include <ctype.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <string.h> + +#include <rump/rump.h> +#include <rump/rump_syscalls.h> + +#include <ufs/ufs/ufsmount.h> +#include <ufs/lfs/lfs.h> +#include <ufs/lfs/lfs_extern.h> + +#include "h_macros.h" +#include "util.h" + +/* Debugging conditions */ +/* #define FORCE_SUCCESS */ /* Don't actually revert, everything worked */ +/* #define USE_DUMPLFS */ /* Dump the filesystem at certain steps */ + +#define UNCHANGED_CONTROL MP "/3-a-random-file" +#define FSSIZE 10000 /* In sectors */ +#define FILE_SIZE 65000 /* In bytes; a few blocks worth */ +#define TMPFILE "filehandle" + +/* Actually run the test */ +void orphan(int); + +ATF_TC(orphan32); +ATF_TC_HEAD(orphan32, tc) +{ + atf_tc_set_md_var(tc, "descr", + "LFS32 orphan removal"); + atf_tc_set_md_var(tc, "timeout", "20"); +} + +ATF_TC(orphan64); +ATF_TC_HEAD(orphan64, tc) +{ + atf_tc_set_md_var(tc, "descr", + "LFS64 orphan removal"); + atf_tc_set_md_var(tc, "timeout", "20"); +} + +ATF_TC_BODY(orphan32, tc) +{ + orphan(32); +} + +ATF_TC_BODY(orphan64, tc) +{ + orphan(64); +} + +void orphan(int width) +{ + char s[MAXLINE]; + struct ufs_args args; + struct stat statbuf; + int fd, status; + pid_t childpid; + FILE *fp; + int thisinum, version, found; + ino_t inum; + + setvbuf(stdout, NULL, _IONBF, 0); + + /* + * Initialize. + */ + + /* Create image file */ + create_lfs(FSSIZE, FSSIZE, width, 0); + + /* Prepare to mount */ + memset(&args, 0, sizeof args); + args.fspec = __UNCONST(FAKEBLK); + + if ((childpid = fork()) == 0) { + /* Set up rump */ + rump_init(); + if (rump_sys_mkdir(MP, 0777) == -1) + atf_tc_fail_errno("cannot create mountpoint"); + rump_pub_etfs_register(FAKEBLK, IMGNAME, RUMP_ETFS_BLK); + + /* Mount filesystem */ + fprintf(stderr, "* Mount fs [1]\n"); + if (rump_sys_mount(MOUNT_LFS, MP, 0, &args, sizeof args) == -1) + atf_tc_fail_errno("rump_sys_mount failed"); + + /* Payload */ + fprintf(stderr, "* Initial payload\n"); + fd = write_file(UNCHANGED_CONTROL, FILE_SIZE, 0, 0); + + /* Make the data go to disk */ + rump_sys_sync(); + rump_sys_sync(); + + /* Write the inode number into a temporary file */ + rump_sys_fstat(fd, &statbuf); + fprintf(stderr, "Inode is => %d <=\n", (int)statbuf.st_ino); + + fp = fopen(TMPFILE, "wb"); + fwrite(&statbuf.st_ino, sizeof(ino_t), 1, fp); + fclose(fp); + + /* Delete while still open */ + if (rump_sys_unlink(UNCHANGED_CONTROL) != 0) + atf_tc_fail_errno("rump_sys_unlink failed"); + + /* Sanity check values */ + if (statbuf.st_size != FILE_SIZE) + atf_tc_fail("wrong size in initial stat"); + if (statbuf.st_nlink <= 0) + atf_tc_fail("file already deleted"); + if (statbuf.st_blocks <= 0) + atf_tc_fail("no blocks"); + + /* Make the data go to disk */ + rump_sys_sync(); + rump_sys_sync(); + + /* Simulate a system crash */ + exit(0); + } + + /* Wait for child to terminate */ + waitpid(childpid, &status, 0); + + /* If it died, die ourselves */ + if (WEXITSTATUS(status)) + exit(WEXITSTATUS(status)); + + /* Fsck */ + fprintf(stderr, "* Fsck after crash\n"); + if (fsck()) + atf_tc_fail("fsck found errors after crash"); + + /* Read the inode number from temporary file */ + fp = fopen(TMPFILE, "rb"); + fread(&inum, sizeof(ino_t), 1, fp); + fclose(fp); + + fprintf(stderr, "Seeking inum => %d <=\n", (int)inum); + + /* Set up rump */ + rump_init(); + if (rump_sys_mkdir(MP, 0777) == -1) + atf_tc_fail_errno("cannot create mountpoint"); + rump_pub_etfs_register(FAKEBLK, IMGNAME, RUMP_ETFS_BLK); + + /* Remount */ + fprintf(stderr, "* Mount fs [2]\n"); + if (rump_sys_mount(MOUNT_LFS, MP, 0, &args, sizeof args) == -1) + atf_tc_fail_errno("rump_sys_mount failed[2]"); + + /* At this point the orphan should be deleted. */ + + /* Unmount */ + fprintf(stderr, "* Unmount\n"); + if (rump_sys_unmount(MP, 0) != 0) + atf_tc_fail_errno("rump_sys_unmount failed[1]"); + + /* Check that it was in fact deleted. */ + fprintf(stderr, "* Check for orphaned file\n"); + found = 0; + fp = popen("dumplfs -i -s9 ./" IMGNAME, "r"); + while (fgets(s, MAXLINE, fp) != NULL) { + if (sscanf(s, "%d FREE %d", &thisinum, &version) == 2 + && (ino_t)thisinum == inum) { + found = 1; + break; + } + } + fclose(fp); + if (!found) + atf_tc_fail("orphaned inode not freed on subsequent mount"); + + /* Fsck */ + fprintf(stderr, "* Fsck after final unmount\n"); + if (fsck()) + atf_tc_fail("fsck found errors after final unmount"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, orphan32); + ATF_TP_ADD_TC(tp, orphan64); + return atf_no_error(); +} + diff --git a/fs/lfs/t_resize.c b/fs/lfs/t_resize.c new file mode 100644 index 000000000000..0dae56429261 --- /dev/null +++ b/fs/lfs/t_resize.c @@ -0,0 +1,180 @@ +/* $NetBSD: t_resize.c,v 1.2 2025/10/30 15:30:17 perseant Exp $ */ + +#include <sys/types.h> +#include <sys/mount.h> +#include <sys/wait.h> + +#include <atf-c.h> +#include <ctype.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> + +#include <rump/rump.h> +#include <rump/rump_syscalls.h> + +#include <ufs/ufs/ufsmount.h> +#include <ufs/lfs/lfs.h> +#include <ufs/lfs/lfs_extern.h> + +#include "h_macros.h" +#include "util.h" + +/* Debugging conditions */ +/* #define FORCE_SUCCESS */ /* Don't actually revert, everything worked */ +/* #define USE_DUMPLFS */ /* Dump the filesystem at certain steps */ + +#define UNCHANGED_CONTROL MP "/3-a-random-file" +#define BIGSIZE 15000 +#define SMALLSIZE 10000 +__CTASSERT(BIGSIZE > SMALLSIZE); + +/* Resize filesystem */ +void resize(int, size_t); + +/* Actually run the test */ +void test(int); + +ATF_TC(resize32); +ATF_TC_HEAD(resize32, tc) +{ + atf_tc_set_md_var(tc, "descr", + "LFS32 resize_lfs creates an inconsistent filesystem"); + atf_tc_set_md_var(tc, "timeout", "20"); +} + +ATF_TC(resize64); +ATF_TC_HEAD(resize64, tc) +{ + atf_tc_set_md_var(tc, "descr", + "LFS64 resize_lfs creates an inconsistent filesystem"); + atf_tc_set_md_var(tc, "timeout", "20"); +} + +ATF_TC_BODY(resize32, tc) +{ + test(32); +} + +ATF_TC_BODY(resize64, tc) +{ + test(64); +} + +void test(int width) +{ + struct ufs_args args; + int fd; + + setvbuf(stdout, NULL, _IONBF, 0); + + /* + * Initialize. + */ + + /* Create image file larger than filesystem */ + create_lfs(BIGSIZE, SMALLSIZE, width, 1); + + /* Mount filesystem */ + fprintf(stderr, "* Mount fs [1]\n"); + memset(&args, 0, sizeof(args)); + args.fspec = __UNCONST(FAKEBLK); + if (rump_sys_mount(MOUNT_LFS, MP, 0, &args, sizeof(args)) == -1) + atf_tc_fail_errno("rump_sys_mount failed"); + + /* Payload */ + fprintf(stderr, "* Initial payload\n"); + write_file(UNCHANGED_CONTROL, CHUNKSIZE, 1, 0); + + /* Unmount */ + rump_sys_unmount(MP, 0); + if (fsck()) + atf_tc_fail_errno("fsck found errors after first unmount"); + + /* + * Remount and resize. + */ + + /* Reconfigure and mount filesystem again */ + fprintf(stderr, "* Remount fs [2, to enlarge]\n"); + if (rump_sys_mount(MOUNT_LFS, MP, 0, &args, sizeof(args)) == -1) + atf_tc_fail_errno("rump_sys_mount failed [2]"); + + /* Get a handle to the root of the file system */ + fd = rump_sys_open(MP, O_RDONLY); + if (fd < 0) + atf_tc_fail_errno("rump_sys_open mount point root failed"); + + /* Enlarge filesystem */ + fprintf(stderr, "* Resize (enlarge)\n"); + resize(fd, BIGSIZE); + + /* Unmount fs and check */ + rump_sys_close(fd); + rump_sys_unmount(MP, 0); + if (fsck()) + atf_tc_fail_errno("fsck found errors after enlarge"); + + /* Mount filesystem for shrink */ + fprintf(stderr, "* Mount fs [3, to shrink]\n"); + if (rump_sys_mount(MOUNT_LFS, MP, 0, &args, sizeof(args)) == -1) + atf_tc_fail_errno("rump_sys_mount failed [3]"); + + /* Get a handle to the root of the file system */ + fd = rump_sys_open(MP, O_RDONLY); + if (fd < 0) + atf_tc_fail_errno("rump_sys_open mount point root failed"); + + /* Shrink filesystem */ + fprintf(stderr, "* Resize (shrink)\n"); + resize(fd, SMALLSIZE); + + /* Unmount and check again */ + rump_sys_close(fd); + if (rump_sys_unmount(MP, 0) != 0) + atf_tc_fail_errno("rump_sys_umount failed after shrink"); + fprintf(stderr, "* Fsck after shrink\n"); + if (fsck()) + atf_tc_fail("fsck found errors after shrink"); + + /* + * Check file system contents + */ + + /* Mount filesystem one last time */ + fprintf(stderr, "* Mount fs [4, to check contents]\n"); + if (rump_sys_mount(MOUNT_LFS, MP, 0, &args, sizeof(args)) == -1) + atf_tc_fail_errno("rump_sys_mount failed [4]"); + + if (check_file(UNCHANGED_CONTROL, CHUNKSIZE, 0) != 0) + atf_tc_fail("Unchanged control file differs(!)"); + + /* Umount filesystem */ + rump_sys_unmount(MP, 0); + + /* Final fsck to double check */ + fprintf(stderr, "* Fsck after final unmount\n"); + if (fsck()) + atf_tc_fail("fsck found errors after final unmount"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, resize32); + ATF_TP_ADD_TC(tp, resize64); + return atf_no_error(); +} + +void +resize(int fd, size_t size) +{ + int newnseg = (size * DEV_BSIZE) / SEGSIZE; + + if (rump_sys_fcntl(fd, LFCNRESIZE, &newnseg) != 0) + atf_tc_fail_errno("LFCNRESIZE failed"); +} diff --git a/fs/lfs/util.c b/fs/lfs/util.c new file mode 100644 index 000000000000..75ca59983596 --- /dev/null +++ b/fs/lfs/util.c @@ -0,0 +1,181 @@ +/* $NetBSD: util.c,v 1.6 2025/12/19 20:58:08 perseant Exp $ */ + +#include <sys/mount.h> + +#include <ctype.h> +#include <fcntl.h> + +#include <rump/rump.h> +#include <rump/rump_syscalls.h> + +#include "h_macros.h" +#include "util.h" + +long long sbaddr[2] = { -1, -1 }; + +/* Create filesystem, note superblock locations */ +void create_lfs(size_t imgsize, size_t fssize, int width, int do_setup) +{ + FILE *pipe; + char cmd[MAXLINE]; + char buf[MAXLINE]; + + /* Create image file larger than filesystem */ + sprintf(cmd, "dd if=/dev/zero of=%s bs=512 count=%zd", + IMGNAME, imgsize); + if (system(cmd) == -1) + atf_tc_fail_errno("create image failed"); + + /* Create filesystem */ + fprintf(stderr, "* Create file system\n"); + sprintf(cmd, "newfs_lfs -D -F -B %d -s %zd -w%d ./%s > %s", + SEGSIZE, fssize, width, IMGNAME, LOGFILE); + if (system(cmd) == -1) + atf_tc_fail_errno("newfs failed"); + pipe = fopen(LOGFILE, "r"); + if (pipe == NULL) + atf_tc_fail_errno("newfs failed to execute"); + while (fgets(buf, MAXLINE, pipe) != NULL) { + if (sscanf(buf, "%lld,%lld", sbaddr, sbaddr + 1) == 2) + break; + } + while (fgets(buf, MAXLINE, pipe) != NULL) + ; + fclose(pipe); + if (sbaddr[0] < 0 || sbaddr[1] < 0) + atf_tc_fail("superblock not found"); + fprintf(stderr, "* Superblocks at %lld and %lld\n", + sbaddr[0], sbaddr[1]); + + if (do_setup) { + /* Set up rump */ + rump_init(); + if (rump_sys_mkdir(MP, 0777) == -1) + atf_tc_fail_errno("cannot create mountpoint"); + rump_pub_etfs_register(FAKEBLK, IMGNAME, RUMP_ETFS_BLK); + } +} + +/* Write some data into a file */ +int write_file(const char *filename, off_t len, int close, unsigned int seed) +{ + int fd; + unsigned i, j; + struct stat statbuf; + int flags = O_CREAT|O_WRONLY; + char buf[1024]; + off_t size; + + srandom(seed); + if (rump_sys_stat(filename, &statbuf) < 0) + size = 0; + else { + size = statbuf.st_size; + flags |= O_APPEND; + + /* Reset randomness */ + for (i = 0; i < size; i++) + random(); + } + + fd = rump_sys_open(filename, flags); + + for (i = 0; i < len; i+= sizeof(buf)) { + for (j = 0; j < sizeof(buf); j++) + buf[j] = ((unsigned)random()) & 0xff; + rump_sys_write(fd, buf, MIN(len - i, (off_t)sizeof(buf))); + } + + if (close) { + rump_sys_close(fd); + fd = -1; + } + + return fd; +} + +/* Check file's existence, size and contents */ +int check_file(const char *filename, int size, unsigned int seed) +{ + int fd, i, j, res; + struct stat statbuf; + unsigned char b, buf[1024]; + + if (rump_sys_stat(filename, &statbuf) < 0) { + fprintf(stderr, "%s: stat failed\n", filename); + return 1; + } + if (size != statbuf.st_size) { + fprintf(stderr, "%s: expected %d bytes, found %d\n", + filename, size, (int)statbuf.st_size); + return 2; + } + + fd = rump_sys_open(filename, O_RDONLY); + + srandom(seed); + for (i = 0; i < size; i += sizeof(buf)) { + res = MIN(size - i, (off_t)sizeof(buf)); + rump_sys_read(fd, buf, res); + for (j = 0; j < res; j++) { + b = (((unsigned)random()) & 0xff); + if (buf[j] != b) { + fprintf(stderr, "%s: byte %d:" + " expected %hhx found %hhx\n", + filename, i + j, + b, buf[j]); + rump_sys_close(fd); + return 3; + } + } + } + rump_sys_close(fd); + fprintf(stderr, "%s: no problem\n", filename); + return 0; +} + +/* Run a file system consistency check */ +int fsck(void) +{ + char s[MAXLINE]; + int i, errors = 0; + FILE *pipe; + char cmd[MAXLINE]; + + for (i = 0; i < 2; i++) { + sprintf(cmd, "fsck_lfs -n -a -b %jd -f " IMGNAME, + (intmax_t)sbaddr[i]); + pipe = popen(cmd, "r"); + while (fgets(s, MAXLINE, pipe) != NULL) { + if (isdigit((int)s[0])) /* "5 files ... " */ + continue; + if (isspace((int)s[0]) || s[0] == '*') + continue; + if (strncmp(s, "Alternate", 9) == 0) + continue; + if (strncmp(s, "ROLL ", 5) == 0) + continue; + fprintf(stderr, "FSCK[sb@%lld]: %s", sbaddr[i], s); + ++errors; + } + pclose(pipe); + if (errors) { + break; + } + } + + return errors; +} + +/* Run dumplfs */ +void dumplfs() +{ + char s[MAXLINE]; + FILE *pipe; + + pipe = popen("dumplfs -S -s 2 -s 1 -s 0 " IMGNAME, "r"); + while (fgets(s, MAXLINE, pipe) != NULL) + fprintf(stderr, "DUMPLFS: %s", s); + pclose(pipe); +} + diff --git a/fs/lfs/util.h b/fs/lfs/util.h new file mode 100644 index 000000000000..b33f89d084ab --- /dev/null +++ b/fs/lfs/util.h @@ -0,0 +1,28 @@ +/* $NetBSD: util.h,v 1.4 2025/10/30 15:30:17 perseant Exp $ */ + +/* Create test image and filesystem, record superblock locations */ +void create_lfs(size_t, size_t, int, int); + +/* Write a well-known byte pattern into a file, appending if it exists */ +int write_file(const char *, off_t, int, unsigned int); + +/* Check the byte pattern and size of the file */ +int check_file(const char *, int, unsigned int); + +/* Check the file system for consistency */ +int fsck(void); + +/* Run dumplfs; for debugging */ +void dumplfs(void); + +#define MAXLINE 132 +#define CHUNKSIZE 300 +#define SEGSIZE 32768 + +#define IMGNAME "disk.img" +#define FAKEBLK "/dev/blk" +#define LOGFILE "newfs.log" + +#define MP "/mp" + +extern long long sbaddr[2]; |
