1 /* 2 * Test filesystem listing concurrency limitations. 3 * 4 * Copyright (C) 2019, 2021, 2022 Paul Boddie <paul@boddie.org.uk> 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation; either version 2 of 9 * the License, or (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 * Boston, MA 02110-1301, USA 20 */ 21 22 #include <stdio.h> 23 #include <stdlib.h> 24 #include <string.h> 25 26 #include <sys/types.h> 27 #include <sys/stat.h> 28 29 #include <ext2fs/ext2fs.h> 30 31 #include "file.h" 32 #include "format.h" 33 #include "image.h" 34 #include "path.h" 35 #include "utils.h" 36 37 38 39 /* Show directory entries when iterating. */ 40 41 static int image_list_dir_proc(struct ext2_dir_entry *dirent, int offset, 42 int blocksize, char *buf, void *priv_data) 43 { 44 struct utils_list_dir_data *data = (struct utils_list_dir_data *) priv_data; 45 ext2_filsys fs = (ext2_filsys) data->fs; 46 struct ext2_inode inode; 47 ext2_file_t file; 48 __u64 size; 49 char *to_remove[] = {"file0061", "file0062", "file0063", "file0125", "file0126", "file0127", 0}; 50 char **f; 51 52 /* Call the formatting utility function. */ 53 54 utils_list_dir_proc(dirent, offset, blocksize, buf, priv_data); 55 56 /* Remove files at an awkward point in time. */ 57 58 if (!strncmp(dirent->name, "file0060", ext2fs_dirent_name_len(dirent))) 59 { 60 for (f = to_remove; *f; f++) 61 if (ext2fs_unlink(fs, EXT2_ROOT_INO, *f, 0, 0)) 62 printf("%s not removed!\n", *f); 63 } 64 65 return 0; 66 } 67 68 69 70 int main(int argc, char *argv[]) 71 { 72 int flags = EXT2_FLAG_RW; 73 char *fsname; 74 ext2_filsys fs = NULL; 75 errcode_t retval; 76 int exitcode = 0; 77 char basename[32]; 78 ext2_ino_t ino; 79 ext2_file_t file; 80 int i; 81 struct utils_list_dir_data list_dir_data; 82 83 if (argc < 2) 84 { 85 printf("Usage: %s <device or image file>\n", argv[0]); 86 return 1; 87 } 88 89 fsname = argv[1]; 90 91 /* Open the filesystem image using the POSIX file access mechanism. */ 92 93 retval = ext2fs_open(fsname, flags, 0, 0, unix_io_manager, &fs); 94 if (retval) 95 { 96 printf("Could not open filesystem using %s\n", fsname); 97 return 1; 98 } 99 100 retval = ext2fs_read_bitmaps(fs); 101 if (retval) 102 { 103 printf("Could not read bitmaps from %s\n", fsname); 104 return 1; 105 } 106 107 printf("Filesystem with blocksize %d\n", fs->blocksize); 108 109 /* Create some files. */ 110 111 for (i = 1; i <= 200; i++) 112 { 113 sprintf(basename, "file%04d", i); 114 115 retval = image_create_file(fs, EXT2_ROOT_INO, basename, 0644, 116 1000, 1000, &ino); 117 118 if (retval) 119 { 120 printf("Could not create file %s\n", basename); 121 return 1; 122 } 123 124 if (ext2fs_file_open(fs, ino, EXT2_FILE_WRITE | EXT2_FILE_CREATE, &file)) 125 { 126 printf("Could not write file %s\n", basename); 127 return 1; 128 } 129 130 ext2fs_file_flush(file); 131 ext2fs_file_close(file); 132 } 133 134 list_dir_data.fs = fs; 135 list_dir_data.filename = NULL; 136 list_dir_data.link_count = 0; 137 138 image_list_dir(fs, "", image_list_dir_proc, &list_dir_data); 139 image_list_dir(fs, "", image_list_dir_proc, &list_dir_data); 140 141 /* Close the filesystem image. */ 142 143 retval = ext2fs_flush(fs); 144 if (retval) 145 { 146 printf("Error flushing filesystem in %s\n", fsname); 147 exitcode = 1; 148 } 149 150 retval = ext2fs_close(fs); 151 if (retval) 152 { 153 printf("Error closing filesystem in %s\n", fsname); 154 exitcode = 1; 155 } 156 157 ext2fs_free(fs); 158 return exitcode; 159 }