1[[case]] # move file 2code = ''' 3 lfs_format(&lfs, &cfg) => 0; 4 lfs_mount(&lfs, &cfg) => 0; 5 lfs_mkdir(&lfs, "a") => 0; 6 lfs_mkdir(&lfs, "b") => 0; 7 lfs_mkdir(&lfs, "c") => 0; 8 lfs_mkdir(&lfs, "d") => 0; 9 lfs_file_open(&lfs, &file, "a/hello", LFS_O_CREAT | LFS_O_WRONLY) => 0; 10 lfs_file_write(&lfs, &file, "hola\n", 5) => 5; 11 lfs_file_write(&lfs, &file, "bonjour\n", 8) => 8; 12 lfs_file_write(&lfs, &file, "ohayo\n", 6) => 6; 13 lfs_file_close(&lfs, &file) => 0; 14 lfs_unmount(&lfs) => 0; 15 16 lfs_mount(&lfs, &cfg) => 0; 17 lfs_rename(&lfs, "a/hello", "c/hello") => 0; 18 lfs_unmount(&lfs) => 0; 19 20 lfs_mount(&lfs, &cfg) => 0; 21 lfs_dir_open(&lfs, &dir, "a") => 0; 22 lfs_dir_read(&lfs, &dir, &info) => 1; 23 assert(strcmp(info.name, ".") == 0); 24 assert(info.type == LFS_TYPE_DIR); 25 lfs_dir_read(&lfs, &dir, &info) => 1; 26 assert(strcmp(info.name, "..") == 0); 27 assert(info.type == LFS_TYPE_DIR); 28 lfs_dir_read(&lfs, &dir, &info) => 0; 29 lfs_dir_close(&lfs, &dir) => 0; 30 lfs_dir_open(&lfs, &dir, "c") => 0; 31 lfs_dir_read(&lfs, &dir, &info) => 1; 32 assert(strcmp(info.name, ".") == 0); 33 assert(info.type == LFS_TYPE_DIR); 34 lfs_dir_read(&lfs, &dir, &info) => 1; 35 assert(strcmp(info.name, "..") == 0); 36 assert(info.type == LFS_TYPE_DIR); 37 lfs_dir_read(&lfs, &dir, &info) => 1; 38 assert(strcmp(info.name, "hello") == 0); 39 assert(info.type == LFS_TYPE_REG); 40 assert(info.size == 5+8+6); 41 lfs_dir_read(&lfs, &dir, &info) => 0; 42 lfs_dir_close(&lfs, &dir) => 0; 43 44 lfs_file_open(&lfs, &file, "a/hello", LFS_O_RDONLY) => LFS_ERR_NOENT; 45 lfs_file_open(&lfs, &file, "b/hello", LFS_O_RDONLY) => LFS_ERR_NOENT; 46 lfs_file_open(&lfs, &file, "c/hello", LFS_O_RDONLY) => 0; 47 lfs_file_read(&lfs, &file, buffer, 5) => 5; 48 memcmp(buffer, "hola\n", 5) => 0; 49 lfs_file_read(&lfs, &file, buffer, 8) => 8; 50 memcmp(buffer, "bonjour\n", 8) => 0; 51 lfs_file_read(&lfs, &file, buffer, 6) => 6; 52 memcmp(buffer, "ohayo\n", 6) => 0; 53 lfs_file_close(&lfs, &file) => 0; 54 lfs_file_open(&lfs, &file, "d/hello", LFS_O_RDONLY) => LFS_ERR_NOENT; 55 lfs_unmount(&lfs) => 0; 56''' 57 58[[case]] # noop move, yes this is legal 59code = ''' 60 lfs_format(&lfs, &cfg) => 0; 61 lfs_mount(&lfs, &cfg) => 0; 62 lfs_mkdir(&lfs, "hi") => 0; 63 lfs_rename(&lfs, "hi", "hi") => 0; 64 lfs_mkdir(&lfs, "hi/hi") => 0; 65 lfs_rename(&lfs, "hi/hi", "hi/hi") => 0; 66 lfs_mkdir(&lfs, "hi/hi/hi") => 0; 67 lfs_rename(&lfs, "hi/hi/hi", "hi/hi/hi") => 0; 68 lfs_stat(&lfs, "hi/hi/hi", &info) => 0; 69 assert(strcmp(info.name, "hi") == 0); 70 assert(info.type == LFS_TYPE_DIR); 71 lfs_unmount(&lfs) => 0; 72''' 73 74[[case]] # move file corrupt source 75in = "lfs.c" 76code = ''' 77 lfs_format(&lfs, &cfg) => 0; 78 lfs_mount(&lfs, &cfg) => 0; 79 lfs_mkdir(&lfs, "a") => 0; 80 lfs_mkdir(&lfs, "b") => 0; 81 lfs_mkdir(&lfs, "c") => 0; 82 lfs_mkdir(&lfs, "d") => 0; 83 lfs_file_open(&lfs, &file, "a/hello", LFS_O_CREAT | LFS_O_WRONLY) => 0; 84 lfs_file_write(&lfs, &file, "hola\n", 5) => 5; 85 lfs_file_write(&lfs, &file, "bonjour\n", 8) => 8; 86 lfs_file_write(&lfs, &file, "ohayo\n", 6) => 6; 87 lfs_file_close(&lfs, &file) => 0; 88 lfs_unmount(&lfs) => 0; 89 90 lfs_mount(&lfs, &cfg) => 0; 91 lfs_rename(&lfs, "a/hello", "c/hello") => 0; 92 lfs_unmount(&lfs) => 0; 93 94 // corrupt the source 95 lfs_mount(&lfs, &cfg) => 0; 96 lfs_dir_open(&lfs, &dir, "a") => 0; 97 lfs_block_t block = dir.m.pair[0]; 98 lfs_dir_close(&lfs, &dir) => 0; 99 lfs_unmount(&lfs) => 0; 100 uint8_t bbuffer[LFS_BLOCK_SIZE]; 101 cfg.read(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; 102 int off = LFS_BLOCK_SIZE-1; 103 while (off >= 0 && bbuffer[off] == LFS_ERASE_VALUE) { 104 off -= 1; 105 } 106 memset(&bbuffer[off-3], LFS_BLOCK_SIZE, 3); 107 cfg.erase(&cfg, block) => 0; 108 cfg.prog(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; 109 cfg.sync(&cfg) => 0; 110 111 lfs_mount(&lfs, &cfg) => 0; 112 lfs_dir_open(&lfs, &dir, "a") => 0; 113 lfs_dir_read(&lfs, &dir, &info) => 1; 114 assert(strcmp(info.name, ".") == 0); 115 assert(info.type == LFS_TYPE_DIR); 116 lfs_dir_read(&lfs, &dir, &info) => 1; 117 assert(strcmp(info.name, "..") == 0); 118 assert(info.type == LFS_TYPE_DIR); 119 lfs_dir_read(&lfs, &dir, &info) => 0; 120 lfs_dir_close(&lfs, &dir) => 0; 121 lfs_dir_open(&lfs, &dir, "c") => 0; 122 lfs_dir_read(&lfs, &dir, &info) => 1; 123 assert(strcmp(info.name, ".") == 0); 124 assert(info.type == LFS_TYPE_DIR); 125 lfs_dir_read(&lfs, &dir, &info) => 1; 126 assert(strcmp(info.name, "..") == 0); 127 assert(info.type == LFS_TYPE_DIR); 128 lfs_dir_read(&lfs, &dir, &info) => 1; 129 assert(strcmp(info.name, "hello") == 0); 130 assert(info.type == LFS_TYPE_REG); 131 assert(info.size == 5+8+6); 132 lfs_dir_read(&lfs, &dir, &info) => 0; 133 lfs_dir_close(&lfs, &dir) => 0; 134 135 lfs_file_open(&lfs, &file, "a/hello", LFS_O_RDONLY) => LFS_ERR_NOENT; 136 lfs_file_open(&lfs, &file, "b/hello", LFS_O_RDONLY) => LFS_ERR_NOENT; 137 lfs_file_open(&lfs, &file, "c/hello", LFS_O_RDONLY) => 0; 138 lfs_file_read(&lfs, &file, buffer, 5) => 5; 139 memcmp(buffer, "hola\n", 5) => 0; 140 lfs_file_read(&lfs, &file, buffer, 8) => 8; 141 memcmp(buffer, "bonjour\n", 8) => 0; 142 lfs_file_read(&lfs, &file, buffer, 6) => 6; 143 memcmp(buffer, "ohayo\n", 6) => 0; 144 lfs_file_close(&lfs, &file) => 0; 145 lfs_file_open(&lfs, &file, "d/hello", LFS_O_RDONLY) => LFS_ERR_NOENT; 146 lfs_unmount(&lfs) => 0; 147''' 148 149[[case]] # move file corrupt source and dest 150in = "lfs.c" 151if = 'LFS_PROG_SIZE <= 0x3fe' # only works with one crc per commit 152code = ''' 153 lfs_format(&lfs, &cfg) => 0; 154 lfs_mount(&lfs, &cfg) => 0; 155 lfs_mkdir(&lfs, "a") => 0; 156 lfs_mkdir(&lfs, "b") => 0; 157 lfs_mkdir(&lfs, "c") => 0; 158 lfs_mkdir(&lfs, "d") => 0; 159 lfs_file_open(&lfs, &file, "a/hello", LFS_O_CREAT | LFS_O_WRONLY) => 0; 160 lfs_file_write(&lfs, &file, "hola\n", 5) => 5; 161 lfs_file_write(&lfs, &file, "bonjour\n", 8) => 8; 162 lfs_file_write(&lfs, &file, "ohayo\n", 6) => 6; 163 lfs_file_close(&lfs, &file) => 0; 164 lfs_unmount(&lfs) => 0; 165 166 lfs_mount(&lfs, &cfg) => 0; 167 lfs_rename(&lfs, "a/hello", "c/hello") => 0; 168 lfs_unmount(&lfs) => 0; 169 170 // corrupt the source 171 lfs_mount(&lfs, &cfg) => 0; 172 lfs_dir_open(&lfs, &dir, "a") => 0; 173 lfs_block_t block = dir.m.pair[0]; 174 lfs_dir_close(&lfs, &dir) => 0; 175 lfs_unmount(&lfs) => 0; 176 uint8_t bbuffer[LFS_BLOCK_SIZE]; 177 cfg.read(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; 178 int off = LFS_BLOCK_SIZE-1; 179 while (off >= 0 && bbuffer[off] == LFS_ERASE_VALUE) { 180 off -= 1; 181 } 182 memset(&bbuffer[off-3], LFS_BLOCK_SIZE, 3); 183 cfg.erase(&cfg, block) => 0; 184 cfg.prog(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; 185 cfg.sync(&cfg) => 0; 186 187 // corrupt the destination 188 lfs_mount(&lfs, &cfg) => 0; 189 lfs_dir_open(&lfs, &dir, "c") => 0; 190 block = dir.m.pair[0]; 191 lfs_dir_close(&lfs, &dir) => 0; 192 lfs_unmount(&lfs) => 0; 193 cfg.read(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; 194 off = LFS_BLOCK_SIZE-1; 195 while (off >= 0 && bbuffer[off] == LFS_ERASE_VALUE) { 196 off -= 1; 197 } 198 memset(&bbuffer[off-3], LFS_BLOCK_SIZE, 3); 199 cfg.erase(&cfg, block) => 0; 200 cfg.prog(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; 201 cfg.sync(&cfg) => 0; 202 203 lfs_mount(&lfs, &cfg) => 0; 204 lfs_dir_open(&lfs, &dir, "a") => 0; 205 lfs_dir_read(&lfs, &dir, &info) => 1; 206 assert(strcmp(info.name, ".") == 0); 207 assert(info.type == LFS_TYPE_DIR); 208 lfs_dir_read(&lfs, &dir, &info) => 1; 209 assert(strcmp(info.name, "..") == 0); 210 assert(info.type == LFS_TYPE_DIR); 211 lfs_dir_read(&lfs, &dir, &info) => 1; 212 assert(strcmp(info.name, "hello") == 0); 213 assert(info.type == LFS_TYPE_REG); 214 assert(info.size == 5+8+6); 215 lfs_dir_read(&lfs, &dir, &info) => 0; 216 lfs_dir_close(&lfs, &dir) => 0; 217 lfs_dir_open(&lfs, &dir, "c") => 0; 218 lfs_dir_read(&lfs, &dir, &info) => 1; 219 assert(strcmp(info.name, ".") == 0); 220 assert(info.type == LFS_TYPE_DIR); 221 lfs_dir_read(&lfs, &dir, &info) => 1; 222 assert(strcmp(info.name, "..") == 0); 223 assert(info.type == LFS_TYPE_DIR); 224 lfs_dir_read(&lfs, &dir, &info) => 0; 225 lfs_dir_close(&lfs, &dir) => 0; 226 227 lfs_file_open(&lfs, &file, "a/hello", LFS_O_RDONLY) => 0; 228 lfs_file_read(&lfs, &file, buffer, 5) => 5; 229 memcmp(buffer, "hola\n", 5) => 0; 230 lfs_file_read(&lfs, &file, buffer, 8) => 8; 231 memcmp(buffer, "bonjour\n", 8) => 0; 232 lfs_file_read(&lfs, &file, buffer, 6) => 6; 233 memcmp(buffer, "ohayo\n", 6) => 0; 234 lfs_file_close(&lfs, &file) => 0; 235 lfs_file_open(&lfs, &file, "b/hello", LFS_O_RDONLY) => LFS_ERR_NOENT; 236 lfs_file_open(&lfs, &file, "c/hello", LFS_O_RDONLY) => LFS_ERR_NOENT; 237 lfs_file_open(&lfs, &file, "d/hello", LFS_O_RDONLY) => LFS_ERR_NOENT; 238 lfs_unmount(&lfs) => 0; 239''' 240 241[[case]] # move file after corrupt 242in = "lfs.c" 243if = 'LFS_PROG_SIZE <= 0x3fe' # only works with one crc per commit 244code = ''' 245 lfs_format(&lfs, &cfg) => 0; 246 lfs_mount(&lfs, &cfg) => 0; 247 lfs_mkdir(&lfs, "a") => 0; 248 lfs_mkdir(&lfs, "b") => 0; 249 lfs_mkdir(&lfs, "c") => 0; 250 lfs_mkdir(&lfs, "d") => 0; 251 lfs_file_open(&lfs, &file, "a/hello", LFS_O_CREAT | LFS_O_WRONLY) => 0; 252 lfs_file_write(&lfs, &file, "hola\n", 5) => 5; 253 lfs_file_write(&lfs, &file, "bonjour\n", 8) => 8; 254 lfs_file_write(&lfs, &file, "ohayo\n", 6) => 6; 255 lfs_file_close(&lfs, &file) => 0; 256 lfs_unmount(&lfs) => 0; 257 258 lfs_mount(&lfs, &cfg) => 0; 259 lfs_rename(&lfs, "a/hello", "c/hello") => 0; 260 lfs_unmount(&lfs) => 0; 261 262 // corrupt the source 263 lfs_mount(&lfs, &cfg) => 0; 264 lfs_dir_open(&lfs, &dir, "a") => 0; 265 lfs_block_t block = dir.m.pair[0]; 266 lfs_dir_close(&lfs, &dir) => 0; 267 lfs_unmount(&lfs) => 0; 268 uint8_t bbuffer[LFS_BLOCK_SIZE]; 269 cfg.read(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; 270 int off = LFS_BLOCK_SIZE-1; 271 while (off >= 0 && bbuffer[off] == LFS_ERASE_VALUE) { 272 off -= 1; 273 } 274 memset(&bbuffer[off-3], LFS_BLOCK_SIZE, 3); 275 cfg.erase(&cfg, block) => 0; 276 cfg.prog(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; 277 cfg.sync(&cfg) => 0; 278 279 // corrupt the destination 280 lfs_mount(&lfs, &cfg) => 0; 281 lfs_dir_open(&lfs, &dir, "c") => 0; 282 block = dir.m.pair[0]; 283 lfs_dir_close(&lfs, &dir) => 0; 284 lfs_unmount(&lfs) => 0; 285 cfg.read(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; 286 off = LFS_BLOCK_SIZE-1; 287 while (off >= 0 && bbuffer[off] == LFS_ERASE_VALUE) { 288 off -= 1; 289 } 290 memset(&bbuffer[off-3], LFS_BLOCK_SIZE, 3); 291 cfg.erase(&cfg, block) => 0; 292 cfg.prog(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; 293 cfg.sync(&cfg) => 0; 294 295 // continue move 296 lfs_mount(&lfs, &cfg) => 0; 297 lfs_rename(&lfs, "a/hello", "c/hello") => 0; 298 lfs_unmount(&lfs) => 0; 299 300 lfs_mount(&lfs, &cfg) => 0; 301 lfs_dir_open(&lfs, &dir, "a") => 0; 302 lfs_dir_read(&lfs, &dir, &info) => 1; 303 assert(strcmp(info.name, ".") == 0); 304 assert(info.type == LFS_TYPE_DIR); 305 lfs_dir_read(&lfs, &dir, &info) => 1; 306 assert(strcmp(info.name, "..") == 0); 307 assert(info.type == LFS_TYPE_DIR); 308 lfs_dir_read(&lfs, &dir, &info) => 0; 309 lfs_dir_close(&lfs, &dir) => 0; 310 lfs_dir_open(&lfs, &dir, "c") => 0; 311 lfs_dir_read(&lfs, &dir, &info) => 1; 312 assert(strcmp(info.name, ".") == 0); 313 assert(info.type == LFS_TYPE_DIR); 314 lfs_dir_read(&lfs, &dir, &info) => 1; 315 assert(strcmp(info.name, "..") == 0); 316 assert(info.type == LFS_TYPE_DIR); 317 lfs_dir_read(&lfs, &dir, &info) => 1; 318 assert(strcmp(info.name, "hello") == 0); 319 assert(info.type == LFS_TYPE_REG); 320 assert(info.size == 5+8+6); 321 lfs_dir_read(&lfs, &dir, &info) => 0; 322 lfs_dir_close(&lfs, &dir) => 0; 323 324 lfs_file_open(&lfs, &file, "a/hello", LFS_O_RDONLY) => LFS_ERR_NOENT; 325 lfs_file_open(&lfs, &file, "b/hello", LFS_O_RDONLY) => LFS_ERR_NOENT; 326 lfs_file_open(&lfs, &file, "c/hello", LFS_O_RDONLY) => 0; 327 lfs_file_read(&lfs, &file, buffer, 5) => 5; 328 memcmp(buffer, "hola\n", 5) => 0; 329 lfs_file_read(&lfs, &file, buffer, 8) => 8; 330 memcmp(buffer, "bonjour\n", 8) => 0; 331 lfs_file_read(&lfs, &file, buffer, 6) => 6; 332 memcmp(buffer, "ohayo\n", 6) => 0; 333 lfs_file_close(&lfs, &file) => 0; 334 lfs_file_open(&lfs, &file, "d/hello", LFS_O_RDONLY) => LFS_ERR_NOENT; 335 lfs_unmount(&lfs) => 0; 336''' 337 338[[case]] # simple reentrant move file 339reentrant = true 340code = ''' 341 err = lfs_mount(&lfs, &cfg); 342 if (err) { 343 lfs_format(&lfs, &cfg) => 0; 344 lfs_mount(&lfs, &cfg) => 0; 345 } 346 err = lfs_mkdir(&lfs, "a"); 347 assert(!err || err == LFS_ERR_EXIST); 348 err = lfs_mkdir(&lfs, "b"); 349 assert(!err || err == LFS_ERR_EXIST); 350 err = lfs_mkdir(&lfs, "c"); 351 assert(!err || err == LFS_ERR_EXIST); 352 err = lfs_mkdir(&lfs, "d"); 353 assert(!err || err == LFS_ERR_EXIST); 354 lfs_unmount(&lfs) => 0; 355 356 while (true) { 357 lfs_mount(&lfs, &cfg) => 0; 358 // there should never exist _2_ hello files 359 int count = 0; 360 if (lfs_stat(&lfs, "a/hello", &info) == 0) { 361 assert(strcmp(info.name, "hello") == 0); 362 assert(info.type == LFS_TYPE_REG); 363 assert(info.size == 5+8+6 || info.size == 0); 364 count += 1; 365 } 366 if (lfs_stat(&lfs, "b/hello", &info) == 0) { 367 assert(strcmp(info.name, "hello") == 0); 368 assert(info.type == LFS_TYPE_REG); 369 assert(info.size == 5+8+6); 370 count += 1; 371 } 372 if (lfs_stat(&lfs, "c/hello", &info) == 0) { 373 assert(strcmp(info.name, "hello") == 0); 374 assert(info.type == LFS_TYPE_REG); 375 assert(info.size == 5+8+6); 376 count += 1; 377 } 378 if (lfs_stat(&lfs, "d/hello", &info) == 0) { 379 assert(strcmp(info.name, "hello") == 0); 380 assert(info.type == LFS_TYPE_REG); 381 assert(info.size == 5+8+6); 382 count += 1; 383 } 384 assert(count <= 1); 385 lfs_unmount(&lfs) => 0; 386 387 lfs_mount(&lfs, &cfg) => 0; 388 if (lfs_stat(&lfs, "a/hello", &info) == 0 && info.size > 0) { 389 lfs_rename(&lfs, "a/hello", "b/hello") => 0; 390 } else if (lfs_stat(&lfs, "b/hello", &info) == 0) { 391 lfs_rename(&lfs, "b/hello", "c/hello") => 0; 392 } else if (lfs_stat(&lfs, "c/hello", &info) == 0) { 393 lfs_rename(&lfs, "c/hello", "d/hello") => 0; 394 } else if (lfs_stat(&lfs, "d/hello", &info) == 0) { 395 // success 396 lfs_unmount(&lfs) => 0; 397 break; 398 } else { 399 // create file 400 lfs_file_open(&lfs, &file, "a/hello", 401 LFS_O_WRONLY | LFS_O_CREAT) => 0; 402 lfs_file_write(&lfs, &file, "hola\n", 5) => 5; 403 lfs_file_write(&lfs, &file, "bonjour\n", 8) => 8; 404 lfs_file_write(&lfs, &file, "ohayo\n", 6) => 6; 405 lfs_file_close(&lfs, &file) => 0; 406 } 407 lfs_unmount(&lfs) => 0; 408 } 409 410 lfs_mount(&lfs, &cfg) => 0; 411 lfs_dir_open(&lfs, &dir, "a") => 0; 412 lfs_dir_read(&lfs, &dir, &info) => 1; 413 assert(strcmp(info.name, ".") == 0); 414 assert(info.type == LFS_TYPE_DIR); 415 lfs_dir_read(&lfs, &dir, &info) => 1; 416 assert(strcmp(info.name, "..") == 0); 417 assert(info.type == LFS_TYPE_DIR); 418 lfs_dir_read(&lfs, &dir, &info) => 0; 419 lfs_dir_close(&lfs, &dir) => 0; 420 lfs_dir_open(&lfs, &dir, "d") => 0; 421 lfs_dir_read(&lfs, &dir, &info) => 1; 422 assert(strcmp(info.name, ".") == 0); 423 assert(info.type == LFS_TYPE_DIR); 424 lfs_dir_read(&lfs, &dir, &info) => 1; 425 assert(strcmp(info.name, "..") == 0); 426 assert(info.type == LFS_TYPE_DIR); 427 lfs_dir_read(&lfs, &dir, &info) => 1; 428 assert(strcmp(info.name, "hello") == 0); 429 assert(info.type == LFS_TYPE_REG); 430 assert(info.size == 5+8+6); 431 lfs_dir_read(&lfs, &dir, &info) => 0; 432 lfs_dir_close(&lfs, &dir) => 0; 433 434 lfs_file_open(&lfs, &file, "a/hello", LFS_O_RDONLY) => LFS_ERR_NOENT; 435 lfs_file_open(&lfs, &file, "b/hello", LFS_O_RDONLY) => LFS_ERR_NOENT; 436 lfs_file_open(&lfs, &file, "c/hello", LFS_O_RDONLY) => LFS_ERR_NOENT; 437 lfs_file_open(&lfs, &file, "d/hello", LFS_O_RDONLY) => 0; 438 lfs_file_read(&lfs, &file, buffer, 5) => 5; 439 memcmp(buffer, "hola\n", 5) => 0; 440 lfs_file_read(&lfs, &file, buffer, 8) => 8; 441 memcmp(buffer, "bonjour\n", 8) => 0; 442 lfs_file_read(&lfs, &file, buffer, 6) => 6; 443 memcmp(buffer, "ohayo\n", 6) => 0; 444 lfs_file_close(&lfs, &file) => 0; 445 lfs_unmount(&lfs) => 0; 446''' 447 448[[case]] # move dir 449code = ''' 450 lfs_format(&lfs, &cfg) => 0; 451 lfs_mount(&lfs, &cfg) => 0; 452 lfs_mkdir(&lfs, "a") => 0; 453 lfs_mkdir(&lfs, "b") => 0; 454 lfs_mkdir(&lfs, "c") => 0; 455 lfs_mkdir(&lfs, "d") => 0; 456 lfs_mkdir(&lfs, "a/hi") => 0; 457 lfs_mkdir(&lfs, "a/hi/hola") => 0; 458 lfs_mkdir(&lfs, "a/hi/bonjour") => 0; 459 lfs_mkdir(&lfs, "a/hi/ohayo") => 0; 460 lfs_unmount(&lfs) => 0; 461 462 lfs_mount(&lfs, &cfg) => 0; 463 lfs_rename(&lfs, "a/hi", "c/hi") => 0; 464 lfs_unmount(&lfs) => 0; 465 466 lfs_mount(&lfs, &cfg) => 0; 467 lfs_dir_open(&lfs, &dir, "a") => 0; 468 lfs_dir_read(&lfs, &dir, &info) => 1; 469 assert(strcmp(info.name, ".") == 0); 470 assert(info.type == LFS_TYPE_DIR); 471 lfs_dir_read(&lfs, &dir, &info) => 1; 472 assert(strcmp(info.name, "..") == 0); 473 assert(info.type == LFS_TYPE_DIR); 474 lfs_dir_read(&lfs, &dir, &info) => 0; 475 lfs_dir_close(&lfs, &dir) => 0; 476 lfs_dir_open(&lfs, &dir, "c") => 0; 477 lfs_dir_read(&lfs, &dir, &info) => 1; 478 assert(strcmp(info.name, ".") == 0); 479 assert(info.type == LFS_TYPE_DIR); 480 lfs_dir_read(&lfs, &dir, &info) => 1; 481 assert(strcmp(info.name, "..") == 0); 482 assert(info.type == LFS_TYPE_DIR); 483 lfs_dir_read(&lfs, &dir, &info) => 1; 484 assert(strcmp(info.name, "hi") == 0); 485 assert(info.type == LFS_TYPE_DIR); 486 lfs_dir_read(&lfs, &dir, &info) => 0; 487 lfs_dir_close(&lfs, &dir) => 0; 488 489 lfs_dir_open(&lfs, &dir, "a/hi") => LFS_ERR_NOENT; 490 lfs_dir_open(&lfs, &dir, "b/hi") => LFS_ERR_NOENT; 491 lfs_dir_open(&lfs, &dir, "c/hi") => 0; 492 lfs_dir_read(&lfs, &dir, &info) => 1; 493 assert(strcmp(info.name, ".") == 0); 494 assert(info.type == LFS_TYPE_DIR); 495 lfs_dir_read(&lfs, &dir, &info) => 1; 496 assert(strcmp(info.name, "..") == 0); 497 assert(info.type == LFS_TYPE_DIR); 498 lfs_dir_read(&lfs, &dir, &info) => 1; 499 assert(strcmp(info.name, "bonjour") == 0); 500 assert(info.type == LFS_TYPE_DIR); 501 lfs_dir_read(&lfs, &dir, &info) => 1; 502 assert(strcmp(info.name, "hola") == 0); 503 assert(info.type == LFS_TYPE_DIR); 504 lfs_dir_read(&lfs, &dir, &info) => 1; 505 assert(strcmp(info.name, "ohayo") == 0); 506 assert(info.type == LFS_TYPE_DIR); 507 lfs_dir_read(&lfs, &dir, &info) => 0; 508 lfs_dir_close(&lfs, &dir) => 0; 509 lfs_dir_open(&lfs, &dir, "d/hi") => LFS_ERR_NOENT; 510 lfs_unmount(&lfs) => 0; 511''' 512 513[[case]] # move dir corrupt source 514in = "lfs.c" 515code = ''' 516 lfs_format(&lfs, &cfg) => 0; 517 lfs_mount(&lfs, &cfg) => 0; 518 lfs_mkdir(&lfs, "a") => 0; 519 lfs_mkdir(&lfs, "b") => 0; 520 lfs_mkdir(&lfs, "c") => 0; 521 lfs_mkdir(&lfs, "d") => 0; 522 lfs_mkdir(&lfs, "a/hi") => 0; 523 lfs_mkdir(&lfs, "a/hi/hola") => 0; 524 lfs_mkdir(&lfs, "a/hi/bonjour") => 0; 525 lfs_mkdir(&lfs, "a/hi/ohayo") => 0; 526 lfs_unmount(&lfs) => 0; 527 528 lfs_mount(&lfs, &cfg) => 0; 529 lfs_rename(&lfs, "a/hi", "c/hi") => 0; 530 lfs_unmount(&lfs) => 0; 531 532 // corrupt the source 533 lfs_mount(&lfs, &cfg) => 0; 534 lfs_dir_open(&lfs, &dir, "a") => 0; 535 lfs_block_t block = dir.m.pair[0]; 536 lfs_dir_close(&lfs, &dir) => 0; 537 lfs_unmount(&lfs) => 0; 538 uint8_t bbuffer[LFS_BLOCK_SIZE]; 539 cfg.read(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; 540 int off = LFS_BLOCK_SIZE-1; 541 while (off >= 0 && bbuffer[off] == LFS_ERASE_VALUE) { 542 off -= 1; 543 } 544 memset(&bbuffer[off-3], LFS_BLOCK_SIZE, 3); 545 cfg.erase(&cfg, block) => 0; 546 cfg.prog(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; 547 cfg.sync(&cfg) => 0; 548 549 lfs_mount(&lfs, &cfg) => 0; 550 lfs_dir_open(&lfs, &dir, "a") => 0; 551 lfs_dir_read(&lfs, &dir, &info) => 1; 552 assert(strcmp(info.name, ".") == 0); 553 assert(info.type == LFS_TYPE_DIR); 554 lfs_dir_read(&lfs, &dir, &info) => 1; 555 assert(strcmp(info.name, "..") == 0); 556 assert(info.type == LFS_TYPE_DIR); 557 lfs_dir_read(&lfs, &dir, &info) => 0; 558 lfs_dir_close(&lfs, &dir) => 0; 559 lfs_dir_open(&lfs, &dir, "c") => 0; 560 lfs_dir_read(&lfs, &dir, &info) => 1; 561 assert(strcmp(info.name, ".") == 0); 562 assert(info.type == LFS_TYPE_DIR); 563 lfs_dir_read(&lfs, &dir, &info) => 1; 564 assert(strcmp(info.name, "..") == 0); 565 assert(info.type == LFS_TYPE_DIR); 566 lfs_dir_read(&lfs, &dir, &info) => 1; 567 assert(strcmp(info.name, "hi") == 0); 568 assert(info.type == LFS_TYPE_DIR); 569 lfs_dir_read(&lfs, &dir, &info) => 0; 570 lfs_dir_close(&lfs, &dir) => 0; 571 572 lfs_dir_open(&lfs, &dir, "a/hi") => LFS_ERR_NOENT; 573 lfs_dir_open(&lfs, &dir, "b/hi") => LFS_ERR_NOENT; 574 lfs_dir_open(&lfs, &dir, "c/hi") => 0; 575 lfs_dir_read(&lfs, &dir, &info) => 1; 576 assert(strcmp(info.name, ".") == 0); 577 assert(info.type == LFS_TYPE_DIR); 578 lfs_dir_read(&lfs, &dir, &info) => 1; 579 assert(strcmp(info.name, "..") == 0); 580 assert(info.type == LFS_TYPE_DIR); 581 lfs_dir_read(&lfs, &dir, &info) => 1; 582 assert(strcmp(info.name, "bonjour") == 0); 583 assert(info.type == LFS_TYPE_DIR); 584 lfs_dir_read(&lfs, &dir, &info) => 1; 585 assert(strcmp(info.name, "hola") == 0); 586 assert(info.type == LFS_TYPE_DIR); 587 lfs_dir_read(&lfs, &dir, &info) => 1; 588 assert(strcmp(info.name, "ohayo") == 0); 589 assert(info.type == LFS_TYPE_DIR); 590 lfs_dir_read(&lfs, &dir, &info) => 0; 591 lfs_dir_close(&lfs, &dir) => 0; 592 lfs_dir_open(&lfs, &dir, "d/hi") => LFS_ERR_NOENT; 593 lfs_unmount(&lfs) => 0; 594''' 595 596[[case]] # move dir corrupt source and dest 597in = "lfs.c" 598if = 'LFS_PROG_SIZE <= 0x3fe' # only works with one crc per commit 599code = ''' 600 lfs_format(&lfs, &cfg) => 0; 601 lfs_mount(&lfs, &cfg) => 0; 602 lfs_mkdir(&lfs, "a") => 0; 603 lfs_mkdir(&lfs, "b") => 0; 604 lfs_mkdir(&lfs, "c") => 0; 605 lfs_mkdir(&lfs, "d") => 0; 606 lfs_mkdir(&lfs, "a/hi") => 0; 607 lfs_mkdir(&lfs, "a/hi/hola") => 0; 608 lfs_mkdir(&lfs, "a/hi/bonjour") => 0; 609 lfs_mkdir(&lfs, "a/hi/ohayo") => 0; 610 lfs_unmount(&lfs) => 0; 611 612 lfs_mount(&lfs, &cfg) => 0; 613 lfs_rename(&lfs, "a/hi", "c/hi") => 0; 614 lfs_unmount(&lfs) => 0; 615 616 // corrupt the source 617 lfs_mount(&lfs, &cfg) => 0; 618 lfs_dir_open(&lfs, &dir, "a") => 0; 619 lfs_block_t block = dir.m.pair[0]; 620 lfs_dir_close(&lfs, &dir) => 0; 621 lfs_unmount(&lfs) => 0; 622 uint8_t bbuffer[LFS_BLOCK_SIZE]; 623 cfg.read(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; 624 int off = LFS_BLOCK_SIZE-1; 625 while (off >= 0 && bbuffer[off] == LFS_ERASE_VALUE) { 626 off -= 1; 627 } 628 memset(&bbuffer[off-3], LFS_BLOCK_SIZE, 3); 629 cfg.erase(&cfg, block) => 0; 630 cfg.prog(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; 631 cfg.sync(&cfg) => 0; 632 633 // corrupt the destination 634 lfs_mount(&lfs, &cfg) => 0; 635 lfs_dir_open(&lfs, &dir, "c") => 0; 636 block = dir.m.pair[0]; 637 lfs_dir_close(&lfs, &dir) => 0; 638 lfs_unmount(&lfs) => 0; 639 cfg.read(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; 640 off = LFS_BLOCK_SIZE-1; 641 while (off >= 0 && bbuffer[off] == LFS_ERASE_VALUE) { 642 off -= 1; 643 } 644 memset(&bbuffer[off-3], LFS_BLOCK_SIZE, 3); 645 cfg.erase(&cfg, block) => 0; 646 cfg.prog(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; 647 cfg.sync(&cfg) => 0; 648 649 lfs_mount(&lfs, &cfg) => 0; 650 lfs_dir_open(&lfs, &dir, "a") => 0; 651 lfs_dir_read(&lfs, &dir, &info) => 1; 652 assert(strcmp(info.name, ".") == 0); 653 assert(info.type == LFS_TYPE_DIR); 654 lfs_dir_read(&lfs, &dir, &info) => 1; 655 assert(strcmp(info.name, "..") == 0); 656 assert(info.type == LFS_TYPE_DIR); 657 lfs_dir_read(&lfs, &dir, &info) => 1; 658 assert(strcmp(info.name, "hi") == 0); 659 assert(info.type == LFS_TYPE_DIR); 660 lfs_dir_read(&lfs, &dir, &info) => 0; 661 lfs_dir_close(&lfs, &dir) => 0; 662 lfs_dir_open(&lfs, &dir, "c") => 0; 663 lfs_dir_read(&lfs, &dir, &info) => 1; 664 assert(strcmp(info.name, ".") == 0); 665 assert(info.type == LFS_TYPE_DIR); 666 lfs_dir_read(&lfs, &dir, &info) => 1; 667 assert(strcmp(info.name, "..") == 0); 668 assert(info.type == LFS_TYPE_DIR); 669 lfs_dir_read(&lfs, &dir, &info) => 0; 670 lfs_dir_close(&lfs, &dir) => 0; 671 672 lfs_dir_open(&lfs, &dir, "a/hi") => 0; 673 lfs_dir_read(&lfs, &dir, &info) => 1; 674 assert(strcmp(info.name, ".") == 0); 675 assert(info.type == LFS_TYPE_DIR); 676 lfs_dir_read(&lfs, &dir, &info) => 1; 677 assert(strcmp(info.name, "..") == 0); 678 assert(info.type == LFS_TYPE_DIR); 679 lfs_dir_read(&lfs, &dir, &info) => 1; 680 assert(strcmp(info.name, "bonjour") == 0); 681 assert(info.type == LFS_TYPE_DIR); 682 lfs_dir_read(&lfs, &dir, &info) => 1; 683 assert(strcmp(info.name, "hola") == 0); 684 assert(info.type == LFS_TYPE_DIR); 685 lfs_dir_read(&lfs, &dir, &info) => 1; 686 assert(strcmp(info.name, "ohayo") == 0); 687 assert(info.type == LFS_TYPE_DIR); 688 lfs_dir_read(&lfs, &dir, &info) => 0; 689 lfs_dir_close(&lfs, &dir) => 0; 690 lfs_dir_open(&lfs, &dir, "b/hi") => LFS_ERR_NOENT; 691 lfs_dir_open(&lfs, &dir, "c/hi") => LFS_ERR_NOENT; 692 lfs_dir_open(&lfs, &dir, "d/hi") => LFS_ERR_NOENT; 693 lfs_unmount(&lfs) => 0; 694''' 695 696[[case]] # move dir after corrupt 697in = "lfs.c" 698if = 'LFS_PROG_SIZE <= 0x3fe' # only works with one crc per commit 699code = ''' 700 lfs_format(&lfs, &cfg) => 0; 701 lfs_mount(&lfs, &cfg) => 0; 702 lfs_mkdir(&lfs, "a") => 0; 703 lfs_mkdir(&lfs, "b") => 0; 704 lfs_mkdir(&lfs, "c") => 0; 705 lfs_mkdir(&lfs, "d") => 0; 706 lfs_mkdir(&lfs, "a/hi") => 0; 707 lfs_mkdir(&lfs, "a/hi/hola") => 0; 708 lfs_mkdir(&lfs, "a/hi/bonjour") => 0; 709 lfs_mkdir(&lfs, "a/hi/ohayo") => 0; 710 lfs_unmount(&lfs) => 0; 711 712 lfs_mount(&lfs, &cfg) => 0; 713 lfs_rename(&lfs, "a/hi", "c/hi") => 0; 714 lfs_unmount(&lfs) => 0; 715 716 // corrupt the source 717 lfs_mount(&lfs, &cfg) => 0; 718 lfs_dir_open(&lfs, &dir, "a") => 0; 719 lfs_block_t block = dir.m.pair[0]; 720 lfs_dir_close(&lfs, &dir) => 0; 721 lfs_unmount(&lfs) => 0; 722 uint8_t bbuffer[LFS_BLOCK_SIZE]; 723 cfg.read(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; 724 int off = LFS_BLOCK_SIZE-1; 725 while (off >= 0 && bbuffer[off] == LFS_ERASE_VALUE) { 726 off -= 1; 727 } 728 memset(&bbuffer[off-3], LFS_BLOCK_SIZE, 3); 729 cfg.erase(&cfg, block) => 0; 730 cfg.prog(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; 731 cfg.sync(&cfg) => 0; 732 733 // corrupt the destination 734 lfs_mount(&lfs, &cfg) => 0; 735 lfs_dir_open(&lfs, &dir, "c") => 0; 736 block = dir.m.pair[0]; 737 lfs_dir_close(&lfs, &dir) => 0; 738 lfs_unmount(&lfs) => 0; 739 cfg.read(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; 740 off = LFS_BLOCK_SIZE-1; 741 while (off >= 0 && bbuffer[off] == LFS_ERASE_VALUE) { 742 off -= 1; 743 } 744 memset(&bbuffer[off-3], LFS_BLOCK_SIZE, 3); 745 cfg.erase(&cfg, block) => 0; 746 cfg.prog(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; 747 cfg.sync(&cfg) => 0; 748 749 // continue move 750 lfs_mount(&lfs, &cfg) => 0; 751 lfs_rename(&lfs, "a/hi", "c/hi") => 0; 752 lfs_unmount(&lfs) => 0; 753 754 lfs_mount(&lfs, &cfg) => 0; 755 lfs_dir_open(&lfs, &dir, "a") => 0; 756 lfs_dir_read(&lfs, &dir, &info) => 1; 757 assert(strcmp(info.name, ".") == 0); 758 assert(info.type == LFS_TYPE_DIR); 759 lfs_dir_read(&lfs, &dir, &info) => 1; 760 assert(strcmp(info.name, "..") == 0); 761 assert(info.type == LFS_TYPE_DIR); 762 lfs_dir_read(&lfs, &dir, &info) => 0; 763 lfs_dir_close(&lfs, &dir) => 0; 764 lfs_dir_open(&lfs, &dir, "c") => 0; 765 lfs_dir_read(&lfs, &dir, &info) => 1; 766 assert(strcmp(info.name, ".") == 0); 767 assert(info.type == LFS_TYPE_DIR); 768 lfs_dir_read(&lfs, &dir, &info) => 1; 769 assert(strcmp(info.name, "..") == 0); 770 assert(info.type == LFS_TYPE_DIR); 771 lfs_dir_read(&lfs, &dir, &info) => 1; 772 assert(strcmp(info.name, "hi") == 0); 773 assert(info.type == LFS_TYPE_DIR); 774 lfs_dir_read(&lfs, &dir, &info) => 0; 775 lfs_dir_close(&lfs, &dir) => 0; 776 777 lfs_dir_open(&lfs, &dir, "a/hi") => LFS_ERR_NOENT; 778 lfs_dir_open(&lfs, &dir, "b/hi") => LFS_ERR_NOENT; 779 lfs_dir_open(&lfs, &dir, "c/hi") => 0; 780 lfs_dir_read(&lfs, &dir, &info) => 1; 781 assert(strcmp(info.name, ".") == 0); 782 assert(info.type == LFS_TYPE_DIR); 783 lfs_dir_read(&lfs, &dir, &info) => 1; 784 assert(strcmp(info.name, "..") == 0); 785 assert(info.type == LFS_TYPE_DIR); 786 lfs_dir_read(&lfs, &dir, &info) => 1; 787 assert(strcmp(info.name, "bonjour") == 0); 788 assert(info.type == LFS_TYPE_DIR); 789 lfs_dir_read(&lfs, &dir, &info) => 1; 790 assert(strcmp(info.name, "hola") == 0); 791 assert(info.type == LFS_TYPE_DIR); 792 lfs_dir_read(&lfs, &dir, &info) => 1; 793 assert(strcmp(info.name, "ohayo") == 0); 794 assert(info.type == LFS_TYPE_DIR); 795 lfs_dir_read(&lfs, &dir, &info) => 0; 796 lfs_dir_close(&lfs, &dir) => 0; 797 lfs_dir_open(&lfs, &dir, "d/hi") => LFS_ERR_NOENT; 798 lfs_unmount(&lfs) => 0; 799''' 800 801[[case]] # simple reentrant move dir 802reentrant = true 803code = ''' 804 err = lfs_mount(&lfs, &cfg); 805 if (err) { 806 lfs_format(&lfs, &cfg) => 0; 807 lfs_mount(&lfs, &cfg) => 0; 808 } 809 err = lfs_mkdir(&lfs, "a"); 810 assert(!err || err == LFS_ERR_EXIST); 811 err = lfs_mkdir(&lfs, "b"); 812 assert(!err || err == LFS_ERR_EXIST); 813 err = lfs_mkdir(&lfs, "c"); 814 assert(!err || err == LFS_ERR_EXIST); 815 err = lfs_mkdir(&lfs, "d"); 816 assert(!err || err == LFS_ERR_EXIST); 817 lfs_unmount(&lfs) => 0; 818 819 while (true) { 820 lfs_mount(&lfs, &cfg) => 0; 821 // there should never exist _2_ hi directories 822 int count = 0; 823 if (lfs_stat(&lfs, "a/hi", &info) == 0) { 824 assert(strcmp(info.name, "hi") == 0); 825 assert(info.type == LFS_TYPE_DIR); 826 count += 1; 827 } 828 if (lfs_stat(&lfs, "b/hi", &info) == 0) { 829 assert(strcmp(info.name, "hi") == 0); 830 assert(info.type == LFS_TYPE_DIR); 831 count += 1; 832 } 833 if (lfs_stat(&lfs, "c/hi", &info) == 0) { 834 assert(strcmp(info.name, "hi") == 0); 835 assert(info.type == LFS_TYPE_DIR); 836 count += 1; 837 } 838 if (lfs_stat(&lfs, "d/hi", &info) == 0) { 839 assert(strcmp(info.name, "hi") == 0); 840 assert(info.type == LFS_TYPE_DIR); 841 count += 1; 842 } 843 assert(count <= 1); 844 lfs_unmount(&lfs) => 0; 845 846 lfs_mount(&lfs, &cfg) => 0; 847 if (lfs_stat(&lfs, "a/hi", &info) == 0) { 848 lfs_rename(&lfs, "a/hi", "b/hi") => 0; 849 } else if (lfs_stat(&lfs, "b/hi", &info) == 0) { 850 lfs_rename(&lfs, "b/hi", "c/hi") => 0; 851 } else if (lfs_stat(&lfs, "c/hi", &info) == 0) { 852 lfs_rename(&lfs, "c/hi", "d/hi") => 0; 853 } else if (lfs_stat(&lfs, "d/hi", &info) == 0) { 854 lfs_unmount(&lfs) => 0; 855 break; // success 856 } else { 857 // create dir and rename for atomicity 858 err = lfs_mkdir(&lfs, "temp"); 859 assert(!err || err == LFS_ERR_EXIST); 860 err = lfs_mkdir(&lfs, "temp/hola"); 861 assert(!err || err == LFS_ERR_EXIST); 862 err = lfs_mkdir(&lfs, "temp/bonjour"); 863 assert(!err || err == LFS_ERR_EXIST); 864 err = lfs_mkdir(&lfs, "temp/ohayo"); 865 assert(!err || err == LFS_ERR_EXIST); 866 lfs_rename(&lfs, "temp", "a/hi") => 0; 867 } 868 lfs_unmount(&lfs) => 0; 869 } 870 871 lfs_mount(&lfs, &cfg) => 0; 872 lfs_dir_open(&lfs, &dir, "a") => 0; 873 lfs_dir_read(&lfs, &dir, &info) => 1; 874 assert(strcmp(info.name, ".") == 0); 875 assert(info.type == LFS_TYPE_DIR); 876 lfs_dir_read(&lfs, &dir, &info) => 1; 877 assert(strcmp(info.name, "..") == 0); 878 assert(info.type == LFS_TYPE_DIR); 879 lfs_dir_read(&lfs, &dir, &info) => 0; 880 lfs_dir_close(&lfs, &dir) => 0; 881 lfs_dir_open(&lfs, &dir, "d") => 0; 882 lfs_dir_read(&lfs, &dir, &info) => 1; 883 assert(strcmp(info.name, ".") == 0); 884 assert(info.type == LFS_TYPE_DIR); 885 lfs_dir_read(&lfs, &dir, &info) => 1; 886 assert(strcmp(info.name, "..") == 0); 887 assert(info.type == LFS_TYPE_DIR); 888 lfs_dir_read(&lfs, &dir, &info) => 1; 889 assert(strcmp(info.name, "hi") == 0); 890 assert(info.type == LFS_TYPE_DIR); 891 lfs_dir_read(&lfs, &dir, &info) => 0; 892 lfs_dir_close(&lfs, &dir) => 0; 893 894 lfs_dir_open(&lfs, &dir, "a/hi") => LFS_ERR_NOENT; 895 lfs_dir_open(&lfs, &dir, "b/hi") => LFS_ERR_NOENT; 896 lfs_dir_open(&lfs, &dir, "c/hi") => LFS_ERR_NOENT; 897 lfs_dir_open(&lfs, &dir, "d/hi") => 0; 898 lfs_dir_read(&lfs, &dir, &info) => 1; 899 assert(strcmp(info.name, ".") == 0); 900 assert(info.type == LFS_TYPE_DIR); 901 lfs_dir_read(&lfs, &dir, &info) => 1; 902 assert(strcmp(info.name, "..") == 0); 903 assert(info.type == LFS_TYPE_DIR); 904 lfs_dir_read(&lfs, &dir, &info) => 1; 905 assert(strcmp(info.name, "bonjour") == 0); 906 assert(info.type == LFS_TYPE_DIR); 907 lfs_dir_read(&lfs, &dir, &info) => 1; 908 assert(strcmp(info.name, "hola") == 0); 909 assert(info.type == LFS_TYPE_DIR); 910 lfs_dir_read(&lfs, &dir, &info) => 1; 911 assert(strcmp(info.name, "ohayo") == 0); 912 assert(info.type == LFS_TYPE_DIR); 913 lfs_dir_read(&lfs, &dir, &info) => 0; 914 lfs_dir_close(&lfs, &dir) => 0; 915 lfs_unmount(&lfs) => 0; 916''' 917 918[[case]] # move state stealing 919code = ''' 920 lfs_format(&lfs, &cfg) => 0; 921 lfs_mount(&lfs, &cfg) => 0; 922 lfs_mkdir(&lfs, "a") => 0; 923 lfs_mkdir(&lfs, "b") => 0; 924 lfs_mkdir(&lfs, "c") => 0; 925 lfs_mkdir(&lfs, "d") => 0; 926 lfs_file_open(&lfs, &file, "a/hello", LFS_O_CREAT | LFS_O_WRONLY) => 0; 927 lfs_file_write(&lfs, &file, "hola\n", 5) => 5; 928 lfs_file_write(&lfs, &file, "bonjour\n", 8) => 8; 929 lfs_file_write(&lfs, &file, "ohayo\n", 6) => 6; 930 lfs_file_close(&lfs, &file) => 0; 931 lfs_unmount(&lfs) => 0; 932 933 lfs_mount(&lfs, &cfg) => 0; 934 lfs_rename(&lfs, "a/hello", "b/hello") => 0; 935 lfs_unmount(&lfs) => 0; 936 lfs_mount(&lfs, &cfg) => 0; 937 lfs_rename(&lfs, "b/hello", "c/hello") => 0; 938 lfs_unmount(&lfs) => 0; 939 lfs_mount(&lfs, &cfg) => 0; 940 lfs_rename(&lfs, "c/hello", "d/hello") => 0; 941 lfs_unmount(&lfs) => 0; 942 943 lfs_mount(&lfs, &cfg) => 0; 944 lfs_file_open(&lfs, &file, "a/hello", LFS_O_RDONLY) => LFS_ERR_NOENT; 945 lfs_file_open(&lfs, &file, "b/hello", LFS_O_RDONLY) => LFS_ERR_NOENT; 946 lfs_file_open(&lfs, &file, "c/hello", LFS_O_RDONLY) => LFS_ERR_NOENT; 947 lfs_file_open(&lfs, &file, "d/hello", LFS_O_RDONLY) => 0; 948 lfs_file_read(&lfs, &file, buffer, 5) => 5; 949 memcmp(buffer, "hola\n", 5) => 0; 950 lfs_file_read(&lfs, &file, buffer, 8) => 8; 951 memcmp(buffer, "bonjour\n", 8) => 0; 952 lfs_file_read(&lfs, &file, buffer, 6) => 6; 953 memcmp(buffer, "ohayo\n", 6) => 0; 954 lfs_file_close(&lfs, &file) => 0; 955 lfs_unmount(&lfs) => 0; 956 957 lfs_mount(&lfs, &cfg) => 0; 958 lfs_remove(&lfs, "b") => 0; 959 lfs_remove(&lfs, "c") => 0; 960 lfs_unmount(&lfs) => 0; 961 962 lfs_mount(&lfs, &cfg) => 0; 963 lfs_stat(&lfs, "a", &info) => 0; 964 lfs_stat(&lfs, "b", &info) => LFS_ERR_NOENT; 965 lfs_stat(&lfs, "c", &info) => LFS_ERR_NOENT; 966 lfs_stat(&lfs, "d", &info) => 0; 967 lfs_file_open(&lfs, &file, "a/hello", LFS_O_RDONLY) => LFS_ERR_NOENT; 968 lfs_file_open(&lfs, &file, "b/hello", LFS_O_RDONLY) => LFS_ERR_NOENT; 969 lfs_file_open(&lfs, &file, "c/hello", LFS_O_RDONLY) => LFS_ERR_NOENT; 970 lfs_file_open(&lfs, &file, "d/hello", LFS_O_RDONLY) => 0; 971 lfs_file_read(&lfs, &file, buffer, 5) => 5; 972 memcmp(buffer, "hola\n", 5) => 0; 973 lfs_file_read(&lfs, &file, buffer, 8) => 8; 974 memcmp(buffer, "bonjour\n", 8) => 0; 975 lfs_file_read(&lfs, &file, buffer, 6) => 6; 976 memcmp(buffer, "ohayo\n", 6) => 0; 977 lfs_file_close(&lfs, &file) => 0; 978 lfs_unmount(&lfs) => 0; 979''' 980 981# Other specific corner cases 982[[case]] # create + delete in same commit with neighbors 983code = ''' 984 lfs_format(&lfs, &cfg) => 0; 985 lfs_mount(&lfs, &cfg) => 0; 986 987 // littlefs keeps files sorted, so we know the order these will be in 988 lfs_file_open(&lfs, &file, "/1.move_me", 989 LFS_O_WRONLY | LFS_O_CREAT) => 0; 990 lfs_file_close(&lfs, &file) => 0; 991 992 lfs_file_open(&lfs, &file, "/0.before", 993 LFS_O_WRONLY | LFS_O_CREAT) => 0; 994 lfs_file_write(&lfs, &file, "test.1", 7) => 7; 995 lfs_file_close(&lfs, &file) => 0; 996 997 lfs_file_open(&lfs, &file, "/2.in_between", 998 LFS_O_WRONLY | LFS_O_CREAT) => 0; 999 lfs_file_write(&lfs, &file, "test.2", 7) => 7; 1000 lfs_file_close(&lfs, &file) => 0; 1001 1002 lfs_file_open(&lfs, &file, "/4.after", 1003 LFS_O_WRONLY | LFS_O_CREAT) => 0; 1004 lfs_file_write(&lfs, &file, "test.3", 7) => 7; 1005 lfs_file_close(&lfs, &file) => 0; 1006 1007 lfs_file_t files[3]; 1008 lfs_file_open(&lfs, &files[0], "0.before", 1009 LFS_O_WRONLY | LFS_O_TRUNC) => 0; 1010 lfs_file_open(&lfs, &files[1], "2.in_between", 1011 LFS_O_WRONLY | LFS_O_TRUNC) => 0; 1012 lfs_file_open(&lfs, &files[2], "4.after", 1013 LFS_O_WRONLY | LFS_O_TRUNC) => 0; 1014 lfs_file_write(&lfs, &files[0], "test.4", 7) => 7; 1015 lfs_file_write(&lfs, &files[1], "test.5", 7) => 7; 1016 lfs_file_write(&lfs, &files[2], "test.6", 7) => 7; 1017 1018 // rename file while everything is open, this triggers both 1019 // a create and delete simultaneously 1020 lfs_rename(&lfs, "/1.move_me", "/3.move_me") => 0; 1021 1022 lfs_file_close(&lfs, &files[0]) => 0; 1023 lfs_file_close(&lfs, &files[1]) => 0; 1024 lfs_file_close(&lfs, &files[2]) => 0; 1025 1026 // check that nothing was corrupted 1027 lfs_dir_open(&lfs, &dir, "/") => 0; 1028 lfs_dir_read(&lfs, &dir, &info) => 1; 1029 assert(strcmp(info.name, ".") == 0); 1030 assert(info.type == LFS_TYPE_DIR); 1031 lfs_dir_read(&lfs, &dir, &info) => 1; 1032 assert(strcmp(info.name, "..") == 0); 1033 assert(info.type == LFS_TYPE_DIR); 1034 lfs_dir_read(&lfs, &dir, &info) => 1; 1035 assert(strcmp(info.name, "0.before") == 0); 1036 assert(info.type == LFS_TYPE_REG); 1037 assert(info.size == 7); 1038 lfs_dir_read(&lfs, &dir, &info) => 1; 1039 assert(strcmp(info.name, "2.in_between") == 0); 1040 assert(info.type == LFS_TYPE_REG); 1041 assert(info.size == 7); 1042 lfs_dir_read(&lfs, &dir, &info) => 1; 1043 assert(strcmp(info.name, "3.move_me") == 0); 1044 assert(info.type == LFS_TYPE_REG); 1045 assert(info.size == 0); 1046 lfs_dir_read(&lfs, &dir, &info) => 1; 1047 assert(strcmp(info.name, "4.after") == 0); 1048 assert(info.type == LFS_TYPE_REG); 1049 assert(info.size == 7); 1050 lfs_dir_read(&lfs, &dir, &info) => 0; 1051 lfs_dir_close(&lfs, &dir) => 0; 1052 1053 lfs_file_open(&lfs, &file, "/0.before", LFS_O_RDONLY) => 0; 1054 lfs_file_read(&lfs, &file, buffer, 7) => 7; 1055 assert(strcmp((char*)buffer, "test.4") == 0); 1056 lfs_file_close(&lfs, &file) => 0; 1057 lfs_file_open(&lfs, &file, "/2.in_between", LFS_O_RDONLY) => 0; 1058 lfs_file_read(&lfs, &file, buffer, 7) => 7; 1059 assert(strcmp((char*)buffer, "test.5") == 0); 1060 lfs_file_close(&lfs, &file) => 0; 1061 lfs_file_open(&lfs, &file, "/4.after", LFS_O_RDONLY) => 0; 1062 lfs_file_read(&lfs, &file, buffer, 7) => 7; 1063 assert(strcmp((char*)buffer, "test.6") == 0); 1064 lfs_file_close(&lfs, &file) => 0; 1065 1066 // now move back 1067 lfs_file_open(&lfs, &files[0], "0.before", 1068 LFS_O_WRONLY | LFS_O_TRUNC) => 0; 1069 lfs_file_open(&lfs, &files[1], "2.in_between", 1070 LFS_O_WRONLY | LFS_O_TRUNC) => 0; 1071 lfs_file_open(&lfs, &files[2], "4.after", 1072 LFS_O_WRONLY | LFS_O_TRUNC) => 0; 1073 lfs_file_write(&lfs, &files[0], "test.7", 7) => 7; 1074 lfs_file_write(&lfs, &files[1], "test.8", 7) => 7; 1075 lfs_file_write(&lfs, &files[2], "test.9", 7) => 7; 1076 1077 // rename file while everything is open, this triggers both 1078 // a create and delete simultaneously 1079 lfs_rename(&lfs, "/3.move_me", "/1.move_me") => 0; 1080 1081 lfs_file_close(&lfs, &files[0]) => 0; 1082 lfs_file_close(&lfs, &files[1]) => 0; 1083 lfs_file_close(&lfs, &files[2]) => 0; 1084 1085 // and check that nothing was corrupted again 1086 lfs_dir_open(&lfs, &dir, "/") => 0; 1087 lfs_dir_read(&lfs, &dir, &info) => 1; 1088 assert(strcmp(info.name, ".") == 0); 1089 assert(info.type == LFS_TYPE_DIR); 1090 lfs_dir_read(&lfs, &dir, &info) => 1; 1091 assert(strcmp(info.name, "..") == 0); 1092 assert(info.type == LFS_TYPE_DIR); 1093 lfs_dir_read(&lfs, &dir, &info) => 1; 1094 assert(strcmp(info.name, "0.before") == 0); 1095 assert(info.type == LFS_TYPE_REG); 1096 assert(info.size == 7); 1097 lfs_dir_read(&lfs, &dir, &info) => 1; 1098 assert(strcmp(info.name, "1.move_me") == 0); 1099 assert(info.type == LFS_TYPE_REG); 1100 assert(info.size == 0); 1101 lfs_dir_read(&lfs, &dir, &info) => 1; 1102 assert(strcmp(info.name, "2.in_between") == 0); 1103 assert(info.type == LFS_TYPE_REG); 1104 assert(info.size == 7); 1105 lfs_dir_read(&lfs, &dir, &info) => 1; 1106 assert(strcmp(info.name, "4.after") == 0); 1107 assert(info.type == LFS_TYPE_REG); 1108 assert(info.size == 7); 1109 lfs_dir_read(&lfs, &dir, &info) => 0; 1110 lfs_dir_close(&lfs, &dir) => 0; 1111 1112 lfs_file_open(&lfs, &file, "/0.before", LFS_O_RDONLY) => 0; 1113 lfs_file_read(&lfs, &file, buffer, 7) => 7; 1114 assert(strcmp((char*)buffer, "test.7") == 0); 1115 lfs_file_close(&lfs, &file) => 0; 1116 lfs_file_open(&lfs, &file, "/2.in_between", LFS_O_RDONLY) => 0; 1117 lfs_file_read(&lfs, &file, buffer, 7) => 7; 1118 assert(strcmp((char*)buffer, "test.8") == 0); 1119 lfs_file_close(&lfs, &file) => 0; 1120 lfs_file_open(&lfs, &file, "/4.after", LFS_O_RDONLY) => 0; 1121 lfs_file_read(&lfs, &file, buffer, 7) => 7; 1122 assert(strcmp((char*)buffer, "test.9") == 0); 1123 lfs_file_close(&lfs, &file) => 0; 1124 lfs_unmount(&lfs) => 0; 1125''' 1126 1127# Other specific corner cases 1128[[case]] # create + delete + delete in same commit with neighbors 1129code = ''' 1130 lfs_format(&lfs, &cfg) => 0; 1131 lfs_mount(&lfs, &cfg) => 0; 1132 1133 // littlefs keeps files sorted, so we know the order these will be in 1134 lfs_file_open(&lfs, &file, "/1.move_me", 1135 LFS_O_WRONLY | LFS_O_CREAT) => 0; 1136 lfs_file_close(&lfs, &file) => 0; 1137 lfs_file_open(&lfs, &file, "/3.move_me", 1138 LFS_O_WRONLY | LFS_O_CREAT) => 0; 1139 lfs_file_write(&lfs, &file, "remove me", 1140 sizeof("remove me")) => sizeof("remove me"); 1141 lfs_file_close(&lfs, &file) => 0; 1142 1143 lfs_file_open(&lfs, &file, "/0.before", 1144 LFS_O_WRONLY | LFS_O_CREAT) => 0; 1145 lfs_file_write(&lfs, &file, "test.1", 7) => 7; 1146 lfs_file_close(&lfs, &file) => 0; 1147 1148 lfs_file_open(&lfs, &file, "/2.in_between", 1149 LFS_O_WRONLY | LFS_O_CREAT) => 0; 1150 lfs_file_write(&lfs, &file, "test.2", 7) => 7; 1151 lfs_file_close(&lfs, &file) => 0; 1152 1153 lfs_file_open(&lfs, &file, "/4.after", 1154 LFS_O_WRONLY | LFS_O_CREAT) => 0; 1155 lfs_file_write(&lfs, &file, "test.3", 7) => 7; 1156 lfs_file_close(&lfs, &file) => 0; 1157 1158 lfs_file_t files[3]; 1159 lfs_file_open(&lfs, &files[0], "0.before", 1160 LFS_O_WRONLY | LFS_O_TRUNC) => 0; 1161 lfs_file_open(&lfs, &files[1], "2.in_between", 1162 LFS_O_WRONLY | LFS_O_TRUNC) => 0; 1163 lfs_file_open(&lfs, &files[2], "4.after", 1164 LFS_O_WRONLY | LFS_O_TRUNC) => 0; 1165 lfs_file_write(&lfs, &files[0], "test.4", 7) => 7; 1166 lfs_file_write(&lfs, &files[1], "test.5", 7) => 7; 1167 lfs_file_write(&lfs, &files[2], "test.6", 7) => 7; 1168 1169 // rename file while everything is open, this triggers both 1170 // a create and delete simultaneously 1171 lfs_rename(&lfs, "/1.move_me", "/3.move_me") => 0; 1172 1173 lfs_file_close(&lfs, &files[0]) => 0; 1174 lfs_file_close(&lfs, &files[1]) => 0; 1175 lfs_file_close(&lfs, &files[2]) => 0; 1176 1177 // check that nothing was corrupted 1178 lfs_dir_open(&lfs, &dir, "/") => 0; 1179 lfs_dir_read(&lfs, &dir, &info) => 1; 1180 assert(strcmp(info.name, ".") == 0); 1181 assert(info.type == LFS_TYPE_DIR); 1182 lfs_dir_read(&lfs, &dir, &info) => 1; 1183 assert(strcmp(info.name, "..") == 0); 1184 assert(info.type == LFS_TYPE_DIR); 1185 lfs_dir_read(&lfs, &dir, &info) => 1; 1186 assert(strcmp(info.name, "0.before") == 0); 1187 assert(info.type == LFS_TYPE_REG); 1188 assert(info.size == 7); 1189 lfs_dir_read(&lfs, &dir, &info) => 1; 1190 assert(strcmp(info.name, "2.in_between") == 0); 1191 assert(info.type == LFS_TYPE_REG); 1192 assert(info.size == 7); 1193 lfs_dir_read(&lfs, &dir, &info) => 1; 1194 assert(strcmp(info.name, "3.move_me") == 0); 1195 assert(info.type == LFS_TYPE_REG); 1196 assert(info.size == 0); 1197 lfs_dir_read(&lfs, &dir, &info) => 1; 1198 assert(strcmp(info.name, "4.after") == 0); 1199 assert(info.type == LFS_TYPE_REG); 1200 assert(info.size == 7); 1201 lfs_dir_read(&lfs, &dir, &info) => 0; 1202 lfs_dir_close(&lfs, &dir) => 0; 1203 1204 lfs_file_open(&lfs, &file, "/0.before", LFS_O_RDONLY) => 0; 1205 lfs_file_read(&lfs, &file, buffer, 7) => 7; 1206 assert(strcmp((char*)buffer, "test.4") == 0); 1207 lfs_file_close(&lfs, &file) => 0; 1208 lfs_file_open(&lfs, &file, "/2.in_between", LFS_O_RDONLY) => 0; 1209 lfs_file_read(&lfs, &file, buffer, 7) => 7; 1210 assert(strcmp((char*)buffer, "test.5") == 0); 1211 lfs_file_close(&lfs, &file) => 0; 1212 lfs_file_open(&lfs, &file, "/4.after", LFS_O_RDONLY) => 0; 1213 lfs_file_read(&lfs, &file, buffer, 7) => 7; 1214 assert(strcmp((char*)buffer, "test.6") == 0); 1215 lfs_file_close(&lfs, &file) => 0; 1216 1217 // now move back 1218 lfs_file_open(&lfs, &file, "/1.move_me", 1219 LFS_O_WRONLY | LFS_O_CREAT) => 0; 1220 lfs_file_write(&lfs, &file, "remove me", 1221 sizeof("remove me")) => sizeof("remove me"); 1222 lfs_file_close(&lfs, &file) => 0; 1223 1224 lfs_file_open(&lfs, &files[0], "0.before", 1225 LFS_O_WRONLY | LFS_O_TRUNC) => 0; 1226 lfs_file_open(&lfs, &files[1], "2.in_between", 1227 LFS_O_WRONLY | LFS_O_TRUNC) => 0; 1228 lfs_file_open(&lfs, &files[2], "4.after", 1229 LFS_O_WRONLY | LFS_O_TRUNC) => 0; 1230 lfs_file_write(&lfs, &files[0], "test.7", 7) => 7; 1231 lfs_file_write(&lfs, &files[1], "test.8", 7) => 7; 1232 lfs_file_write(&lfs, &files[2], "test.9", 7) => 7; 1233 1234 // rename file while everything is open, this triggers both 1235 // a create and delete simultaneously 1236 lfs_rename(&lfs, "/3.move_me", "/1.move_me") => 0; 1237 1238 lfs_file_close(&lfs, &files[0]) => 0; 1239 lfs_file_close(&lfs, &files[1]) => 0; 1240 lfs_file_close(&lfs, &files[2]) => 0; 1241 1242 // and check that nothing was corrupted again 1243 lfs_dir_open(&lfs, &dir, "/") => 0; 1244 lfs_dir_read(&lfs, &dir, &info) => 1; 1245 assert(strcmp(info.name, ".") == 0); 1246 assert(info.type == LFS_TYPE_DIR); 1247 lfs_dir_read(&lfs, &dir, &info) => 1; 1248 assert(strcmp(info.name, "..") == 0); 1249 assert(info.type == LFS_TYPE_DIR); 1250 lfs_dir_read(&lfs, &dir, &info) => 1; 1251 assert(strcmp(info.name, "0.before") == 0); 1252 assert(info.type == LFS_TYPE_REG); 1253 assert(info.size == 7); 1254 lfs_dir_read(&lfs, &dir, &info) => 1; 1255 assert(strcmp(info.name, "1.move_me") == 0); 1256 assert(info.type == LFS_TYPE_REG); 1257 assert(info.size == 0); 1258 lfs_dir_read(&lfs, &dir, &info) => 1; 1259 assert(strcmp(info.name, "2.in_between") == 0); 1260 assert(info.type == LFS_TYPE_REG); 1261 assert(info.size == 7); 1262 lfs_dir_read(&lfs, &dir, &info) => 1; 1263 assert(strcmp(info.name, "4.after") == 0); 1264 assert(info.type == LFS_TYPE_REG); 1265 assert(info.size == 7); 1266 lfs_dir_read(&lfs, &dir, &info) => 0; 1267 lfs_dir_close(&lfs, &dir) => 0; 1268 1269 lfs_file_open(&lfs, &file, "/0.before", LFS_O_RDONLY) => 0; 1270 lfs_file_read(&lfs, &file, buffer, 7) => 7; 1271 assert(strcmp((char*)buffer, "test.7") == 0); 1272 lfs_file_close(&lfs, &file) => 0; 1273 lfs_file_open(&lfs, &file, "/2.in_between", LFS_O_RDONLY) => 0; 1274 lfs_file_read(&lfs, &file, buffer, 7) => 7; 1275 assert(strcmp((char*)buffer, "test.8") == 0); 1276 lfs_file_close(&lfs, &file) => 0; 1277 lfs_file_open(&lfs, &file, "/4.after", LFS_O_RDONLY) => 0; 1278 lfs_file_read(&lfs, &file, buffer, 7) => 7; 1279 assert(strcmp((char*)buffer, "test.9") == 0); 1280 lfs_file_close(&lfs, &file) => 0; 1281 lfs_unmount(&lfs) => 0; 1282''' 1283 1284[[case]] # create + delete in different dirs with neighbors 1285code = ''' 1286 lfs_format(&lfs, &cfg) => 0; 1287 lfs_mount(&lfs, &cfg) => 0; 1288 1289 // littlefs keeps files sorted, so we know the order these will be in 1290 lfs_mkdir(&lfs, "/dir.1") => 0; 1291 lfs_mkdir(&lfs, "/dir.2") => 0; 1292 lfs_file_open(&lfs, &file, "/dir.1/1.move_me", 1293 LFS_O_WRONLY | LFS_O_CREAT) => 0; 1294 lfs_file_close(&lfs, &file) => 0; 1295 lfs_file_open(&lfs, &file, "/dir.2/1.move_me", 1296 LFS_O_WRONLY | LFS_O_CREAT) => 0; 1297 lfs_file_write(&lfs, &file, "remove me", 1298 sizeof("remove me")) => sizeof("remove me"); 1299 lfs_file_close(&lfs, &file) => 0; 1300 1301 lfs_file_open(&lfs, &file, "/dir.1/0.before", 1302 LFS_O_WRONLY | LFS_O_CREAT) => 0; 1303 lfs_file_write(&lfs, &file, "test.1", 7) => 7; 1304 lfs_file_close(&lfs, &file) => 0; 1305 lfs_file_open(&lfs, &file, "/dir.1/2.after", 1306 LFS_O_WRONLY | LFS_O_CREAT) => 0; 1307 lfs_file_write(&lfs, &file, "test.2", 7) => 7; 1308 lfs_file_close(&lfs, &file) => 0; 1309 1310 lfs_file_open(&lfs, &file, "/dir.2/0.before", 1311 LFS_O_WRONLY | LFS_O_CREAT) => 0; 1312 lfs_file_write(&lfs, &file, "test.3", 7) => 7; 1313 lfs_file_close(&lfs, &file) => 0; 1314 lfs_file_open(&lfs, &file, "/dir.2/2.after", 1315 LFS_O_WRONLY | LFS_O_CREAT) => 0; 1316 lfs_file_write(&lfs, &file, "test.4", 7) => 7; 1317 lfs_file_close(&lfs, &file) => 0; 1318 1319 lfs_file_t files[4]; 1320 lfs_file_open(&lfs, &files[0], "/dir.1/0.before", 1321 LFS_O_WRONLY | LFS_O_TRUNC) => 0; 1322 lfs_file_open(&lfs, &files[1], "/dir.1/2.after", 1323 LFS_O_WRONLY | LFS_O_TRUNC) => 0; 1324 lfs_file_open(&lfs, &files[2], "/dir.2/0.before", 1325 LFS_O_WRONLY | LFS_O_TRUNC) => 0; 1326 lfs_file_open(&lfs, &files[3], "/dir.2/2.after", 1327 LFS_O_WRONLY | LFS_O_TRUNC) => 0; 1328 lfs_file_write(&lfs, &files[0], "test.5", 7) => 7; 1329 lfs_file_write(&lfs, &files[1], "test.6", 7) => 7; 1330 lfs_file_write(&lfs, &files[2], "test.7", 7) => 7; 1331 lfs_file_write(&lfs, &files[3], "test.8", 7) => 7; 1332 1333 // rename file while everything is open, this triggers both 1334 // a create and delete as it overwrites the destination file 1335 lfs_rename(&lfs, "/dir.1/1.move_me", "/dir.2/1.move_me") => 0; 1336 1337 lfs_file_close(&lfs, &files[0]) => 0; 1338 lfs_file_close(&lfs, &files[1]) => 0; 1339 lfs_file_close(&lfs, &files[2]) => 0; 1340 lfs_file_close(&lfs, &files[3]) => 0; 1341 1342 // check that nothing was corrupted 1343 lfs_dir_open(&lfs, &dir, "/") => 0; 1344 lfs_dir_read(&lfs, &dir, &info) => 1; 1345 assert(strcmp(info.name, ".") == 0); 1346 assert(info.type == LFS_TYPE_DIR); 1347 lfs_dir_read(&lfs, &dir, &info) => 1; 1348 assert(strcmp(info.name, "..") == 0); 1349 assert(info.type == LFS_TYPE_DIR); 1350 lfs_dir_read(&lfs, &dir, &info) => 1; 1351 assert(strcmp(info.name, "dir.1") == 0); 1352 assert(info.type == LFS_TYPE_DIR); 1353 lfs_dir_read(&lfs, &dir, &info) => 1; 1354 assert(strcmp(info.name, "dir.2") == 0); 1355 assert(info.type == LFS_TYPE_DIR); 1356 lfs_dir_read(&lfs, &dir, &info) => 0; 1357 lfs_dir_close(&lfs, &dir) => 0; 1358 1359 lfs_dir_open(&lfs, &dir, "/dir.1") => 0; 1360 lfs_dir_read(&lfs, &dir, &info) => 1; 1361 assert(strcmp(info.name, ".") == 0); 1362 assert(info.type == LFS_TYPE_DIR); 1363 lfs_dir_read(&lfs, &dir, &info) => 1; 1364 assert(strcmp(info.name, "..") == 0); 1365 assert(info.type == LFS_TYPE_DIR); 1366 lfs_dir_read(&lfs, &dir, &info) => 1; 1367 assert(strcmp(info.name, "0.before") == 0); 1368 assert(info.type == LFS_TYPE_REG); 1369 assert(info.size == 7); 1370 lfs_dir_read(&lfs, &dir, &info) => 1; 1371 assert(strcmp(info.name, "2.after") == 0); 1372 assert(info.type == LFS_TYPE_REG); 1373 assert(info.size == 7); 1374 lfs_dir_read(&lfs, &dir, &info) => 0; 1375 lfs_dir_close(&lfs, &dir) => 0; 1376 1377 lfs_dir_open(&lfs, &dir, "/dir.2") => 0; 1378 lfs_dir_read(&lfs, &dir, &info) => 1; 1379 assert(strcmp(info.name, ".") == 0); 1380 assert(info.type == LFS_TYPE_DIR); 1381 lfs_dir_read(&lfs, &dir, &info) => 1; 1382 assert(strcmp(info.name, "..") == 0); 1383 assert(info.type == LFS_TYPE_DIR); 1384 lfs_dir_read(&lfs, &dir, &info) => 1; 1385 assert(strcmp(info.name, "0.before") == 0); 1386 assert(info.type == LFS_TYPE_REG); 1387 assert(info.size == 7); 1388 lfs_dir_read(&lfs, &dir, &info) => 1; 1389 assert(strcmp(info.name, "1.move_me") == 0); 1390 assert(info.type == LFS_TYPE_REG); 1391 assert(info.size == 0); 1392 lfs_dir_read(&lfs, &dir, &info) => 1; 1393 assert(strcmp(info.name, "2.after") == 0); 1394 assert(info.type == LFS_TYPE_REG); 1395 assert(info.size == 7); 1396 lfs_dir_read(&lfs, &dir, &info) => 0; 1397 lfs_dir_close(&lfs, &dir) => 0; 1398 1399 lfs_file_open(&lfs, &file, "/dir.1/0.before", LFS_O_RDONLY) => 0; 1400 lfs_file_read(&lfs, &file, buffer, 7) => 7; 1401 assert(strcmp((char*)buffer, "test.5") == 0); 1402 lfs_file_close(&lfs, &file) => 0; 1403 lfs_file_open(&lfs, &file, "/dir.1/2.after", LFS_O_RDONLY) => 0; 1404 lfs_file_read(&lfs, &file, buffer, 7) => 7; 1405 assert(strcmp((char*)buffer, "test.6") == 0); 1406 lfs_file_close(&lfs, &file) => 0; 1407 lfs_file_open(&lfs, &file, "/dir.2/0.before", LFS_O_RDONLY) => 0; 1408 lfs_file_read(&lfs, &file, buffer, 7) => 7; 1409 assert(strcmp((char*)buffer, "test.7") == 0); 1410 lfs_file_close(&lfs, &file) => 0; 1411 lfs_file_open(&lfs, &file, "/dir.2/2.after", LFS_O_RDONLY) => 0; 1412 lfs_file_read(&lfs, &file, buffer, 7) => 7; 1413 assert(strcmp((char*)buffer, "test.8") == 0); 1414 lfs_file_close(&lfs, &file) => 0; 1415 1416 // now move back 1417 lfs_file_open(&lfs, &file, "/dir.1/1.move_me", 1418 LFS_O_WRONLY | LFS_O_CREAT) => 0; 1419 lfs_file_write(&lfs, &file, "remove me", 1420 sizeof("remove me")) => sizeof("remove me"); 1421 lfs_file_close(&lfs, &file) => 0; 1422 1423 lfs_file_open(&lfs, &files[0], "/dir.1/0.before", 1424 LFS_O_WRONLY | LFS_O_TRUNC) => 0; 1425 lfs_file_open(&lfs, &files[1], "/dir.1/2.after", 1426 LFS_O_WRONLY | LFS_O_TRUNC) => 0; 1427 lfs_file_open(&lfs, &files[2], "/dir.2/0.before", 1428 LFS_O_WRONLY | LFS_O_TRUNC) => 0; 1429 lfs_file_open(&lfs, &files[3], "/dir.2/2.after", 1430 LFS_O_WRONLY | LFS_O_TRUNC) => 0; 1431 lfs_file_write(&lfs, &files[0], "test.9", 7) => 7; 1432 lfs_file_write(&lfs, &files[1], "test.a", 7) => 7; 1433 lfs_file_write(&lfs, &files[2], "test.b", 7) => 7; 1434 lfs_file_write(&lfs, &files[3], "test.c", 7) => 7; 1435 1436 // rename file while everything is open, this triggers both 1437 // a create and delete simultaneously 1438 lfs_rename(&lfs, "/dir.2/1.move_me", "/dir.1/1.move_me") => 0; 1439 1440 lfs_file_close(&lfs, &files[0]) => 0; 1441 lfs_file_close(&lfs, &files[1]) => 0; 1442 lfs_file_close(&lfs, &files[2]) => 0; 1443 lfs_file_close(&lfs, &files[3]) => 0; 1444 1445 // and check that nothing was corrupted again 1446 lfs_dir_open(&lfs, &dir, "/") => 0; 1447 lfs_dir_read(&lfs, &dir, &info) => 1; 1448 assert(strcmp(info.name, ".") == 0); 1449 assert(info.type == LFS_TYPE_DIR); 1450 lfs_dir_read(&lfs, &dir, &info) => 1; 1451 assert(strcmp(info.name, "..") == 0); 1452 assert(info.type == LFS_TYPE_DIR); 1453 lfs_dir_read(&lfs, &dir, &info) => 1; 1454 assert(strcmp(info.name, "dir.1") == 0); 1455 assert(info.type == LFS_TYPE_DIR); 1456 lfs_dir_read(&lfs, &dir, &info) => 1; 1457 assert(strcmp(info.name, "dir.2") == 0); 1458 assert(info.type == LFS_TYPE_DIR); 1459 lfs_dir_read(&lfs, &dir, &info) => 0; 1460 lfs_dir_close(&lfs, &dir) => 0; 1461 1462 lfs_dir_open(&lfs, &dir, "/dir.1") => 0; 1463 lfs_dir_read(&lfs, &dir, &info) => 1; 1464 assert(strcmp(info.name, ".") == 0); 1465 assert(info.type == LFS_TYPE_DIR); 1466 lfs_dir_read(&lfs, &dir, &info) => 1; 1467 assert(strcmp(info.name, "..") == 0); 1468 assert(info.type == LFS_TYPE_DIR); 1469 lfs_dir_read(&lfs, &dir, &info) => 1; 1470 assert(strcmp(info.name, "0.before") == 0); 1471 assert(info.type == LFS_TYPE_REG); 1472 assert(info.size == 7); 1473 lfs_dir_read(&lfs, &dir, &info) => 1; 1474 assert(strcmp(info.name, "1.move_me") == 0); 1475 assert(info.type == LFS_TYPE_REG); 1476 assert(info.size == 0); 1477 lfs_dir_read(&lfs, &dir, &info) => 1; 1478 assert(strcmp(info.name, "2.after") == 0); 1479 assert(info.type == LFS_TYPE_REG); 1480 assert(info.size == 7); 1481 lfs_dir_read(&lfs, &dir, &info) => 0; 1482 lfs_dir_close(&lfs, &dir) => 0; 1483 1484 lfs_dir_open(&lfs, &dir, "/dir.2") => 0; 1485 lfs_dir_read(&lfs, &dir, &info) => 1; 1486 assert(strcmp(info.name, ".") == 0); 1487 assert(info.type == LFS_TYPE_DIR); 1488 lfs_dir_read(&lfs, &dir, &info) => 1; 1489 assert(strcmp(info.name, "..") == 0); 1490 assert(info.type == LFS_TYPE_DIR); 1491 lfs_dir_read(&lfs, &dir, &info) => 1; 1492 assert(strcmp(info.name, "0.before") == 0); 1493 assert(info.type == LFS_TYPE_REG); 1494 assert(info.size == 7); 1495 lfs_dir_read(&lfs, &dir, &info) => 1; 1496 assert(strcmp(info.name, "2.after") == 0); 1497 assert(info.type == LFS_TYPE_REG); 1498 assert(info.size == 7); 1499 lfs_dir_read(&lfs, &dir, &info) => 0; 1500 lfs_dir_close(&lfs, &dir) => 0; 1501 1502 lfs_file_open(&lfs, &file, "/dir.1/0.before", LFS_O_RDONLY) => 0; 1503 lfs_file_read(&lfs, &file, buffer, 7) => 7; 1504 assert(strcmp((char*)buffer, "test.9") == 0); 1505 lfs_file_close(&lfs, &file) => 0; 1506 lfs_file_open(&lfs, &file, "/dir.1/2.after", LFS_O_RDONLY) => 0; 1507 lfs_file_read(&lfs, &file, buffer, 7) => 7; 1508 assert(strcmp((char*)buffer, "test.a") == 0); 1509 lfs_file_close(&lfs, &file) => 0; 1510 lfs_file_open(&lfs, &file, "/dir.2/0.before", LFS_O_RDONLY) => 0; 1511 lfs_file_read(&lfs, &file, buffer, 7) => 7; 1512 assert(strcmp((char*)buffer, "test.b") == 0); 1513 lfs_file_close(&lfs, &file) => 0; 1514 lfs_file_open(&lfs, &file, "/dir.2/2.after", LFS_O_RDONLY) => 0; 1515 lfs_file_read(&lfs, &file, buffer, 7) => 7; 1516 assert(strcmp((char*)buffer, "test.c") == 0); 1517 lfs_file_close(&lfs, &file) => 0; 1518 lfs_unmount(&lfs) => 0; 1519''' 1520 1521[[case]] # move fix in relocation 1522in = "lfs.c" 1523define.RELOCATIONS = 'range(0x3+1)' 1524define.LFS_ERASE_CYCLES = 0xffffffff 1525code = ''' 1526 lfs_format(&lfs, &cfg) => 0; 1527 lfs_mount(&lfs, &cfg) => 0; 1528 1529 lfs_mkdir(&lfs, "/parent") => 0; 1530 lfs_mkdir(&lfs, "/parent/child") => 0; 1531 1532 lfs_file_open(&lfs, &file, "/parent/1.move_me", 1533 LFS_O_WRONLY | LFS_O_CREAT) => 0; 1534 lfs_file_write(&lfs, &file, "move me", 1535 sizeof("move me")) => sizeof("move me"); 1536 lfs_file_close(&lfs, &file) => 0; 1537 1538 lfs_file_open(&lfs, &file, "/parent/0.before", 1539 LFS_O_WRONLY | LFS_O_CREAT) => 0; 1540 lfs_file_write(&lfs, &file, "test.1", 7) => 7; 1541 lfs_file_close(&lfs, &file) => 0; 1542 lfs_file_open(&lfs, &file, "/parent/2.after", 1543 LFS_O_WRONLY | LFS_O_CREAT) => 0; 1544 lfs_file_write(&lfs, &file, "test.2", 7) => 7; 1545 lfs_file_close(&lfs, &file) => 0; 1546 lfs_file_open(&lfs, &file, "/parent/child/0.before", 1547 LFS_O_WRONLY | LFS_O_CREAT) => 0; 1548 lfs_file_write(&lfs, &file, "test.3", 7) => 7; 1549 lfs_file_close(&lfs, &file) => 0; 1550 lfs_file_open(&lfs, &file, "/parent/child/2.after", 1551 LFS_O_WRONLY | LFS_O_CREAT) => 0; 1552 lfs_file_write(&lfs, &file, "test.4", 7) => 7; 1553 lfs_file_close(&lfs, &file) => 0; 1554 1555 lfs_file_t files[4]; 1556 lfs_file_open(&lfs, &files[0], "/parent/0.before", 1557 LFS_O_WRONLY | LFS_O_TRUNC) => 0; 1558 lfs_file_open(&lfs, &files[1], "/parent/2.after", 1559 LFS_O_WRONLY | LFS_O_TRUNC) => 0; 1560 lfs_file_open(&lfs, &files[2], "/parent/child/0.before", 1561 LFS_O_WRONLY | LFS_O_TRUNC) => 0; 1562 lfs_file_open(&lfs, &files[3], "/parent/child/2.after", 1563 LFS_O_WRONLY | LFS_O_TRUNC) => 0; 1564 lfs_file_write(&lfs, &files[0], "test.5", 7) => 7; 1565 lfs_file_write(&lfs, &files[1], "test.6", 7) => 7; 1566 lfs_file_write(&lfs, &files[2], "test.7", 7) => 7; 1567 lfs_file_write(&lfs, &files[3], "test.8", 7) => 7; 1568 1569 // force specific directories to relocate 1570 if (RELOCATIONS & 0x1) { 1571 lfs_dir_open(&lfs, &dir, "/parent"); 1572 lfs_testbd_setwear(&cfg, dir.m.pair[0], 0xffffffff) => 0; 1573 lfs_testbd_setwear(&cfg, dir.m.pair[1], 0xffffffff) => 0; 1574 lfs_dir_close(&lfs, &dir) => 0; 1575 } 1576 if (RELOCATIONS & 0x2) { 1577 lfs_dir_open(&lfs, &dir, "/parent/child"); 1578 lfs_testbd_setwear(&cfg, dir.m.pair[0], 0xffffffff) => 0; 1579 lfs_testbd_setwear(&cfg, dir.m.pair[1], 0xffffffff) => 0; 1580 lfs_dir_close(&lfs, &dir) => 0; 1581 } 1582 1583 // ok, now we move the file, this creates a move that needs to be 1584 // fixed, possibly in a metadata-pair that needs to be relocated 1585 // 1586 // the worst case is if we need to relocate and we need to implicit 1587 // fix the move in our parent before it falls out of date 1588 lfs_rename(&lfs, "/parent/1.move_me", "/parent/child/1.move_me") => 0; 1589 1590 lfs_file_close(&lfs, &files[0]) => 0; 1591 lfs_file_close(&lfs, &files[1]) => 0; 1592 lfs_file_close(&lfs, &files[2]) => 0; 1593 lfs_file_close(&lfs, &files[3]) => 0; 1594 1595 // check that nothing was corrupted 1596 lfs_dir_open(&lfs, &dir, "/parent") => 0; 1597 lfs_dir_read(&lfs, &dir, &info) => 1; 1598 assert(strcmp(info.name, ".") == 0); 1599 assert(info.type == LFS_TYPE_DIR); 1600 lfs_dir_read(&lfs, &dir, &info) => 1; 1601 assert(strcmp(info.name, "..") == 0); 1602 assert(info.type == LFS_TYPE_DIR); 1603 lfs_dir_read(&lfs, &dir, &info) => 1; 1604 assert(strcmp(info.name, "0.before") == 0); 1605 assert(info.type == LFS_TYPE_REG); 1606 assert(info.size == 7); 1607 lfs_dir_read(&lfs, &dir, &info) => 1; 1608 assert(strcmp(info.name, "2.after") == 0); 1609 assert(info.type == LFS_TYPE_REG); 1610 assert(info.size == 7); 1611 lfs_dir_read(&lfs, &dir, &info) => 1; 1612 assert(strcmp(info.name, "child") == 0); 1613 assert(info.type == LFS_TYPE_DIR); 1614 lfs_dir_read(&lfs, &dir, &info) => 0; 1615 lfs_dir_close(&lfs, &dir) => 0; 1616 1617 lfs_dir_open(&lfs, &dir, "/parent/child") => 0; 1618 lfs_dir_read(&lfs, &dir, &info) => 1; 1619 assert(strcmp(info.name, ".") == 0); 1620 assert(info.type == LFS_TYPE_DIR); 1621 lfs_dir_read(&lfs, &dir, &info) => 1; 1622 assert(strcmp(info.name, "..") == 0); 1623 assert(info.type == LFS_TYPE_DIR); 1624 lfs_dir_read(&lfs, &dir, &info) => 1; 1625 assert(strcmp(info.name, "0.before") == 0); 1626 assert(info.type == LFS_TYPE_REG); 1627 assert(info.size == 7); 1628 lfs_dir_read(&lfs, &dir, &info) => 1; 1629 assert(strcmp(info.name, "1.move_me") == 0); 1630 assert(info.type == LFS_TYPE_REG); 1631 assert(info.size == sizeof("move me")); 1632 lfs_dir_read(&lfs, &dir, &info) => 1; 1633 assert(strcmp(info.name, "2.after") == 0); 1634 assert(info.type == LFS_TYPE_REG); 1635 assert(info.size == 7); 1636 lfs_dir_read(&lfs, &dir, &info) => 0; 1637 lfs_dir_close(&lfs, &dir) => 0; 1638 1639 lfs_file_open(&lfs, &file, "/parent/0.before", LFS_O_RDONLY) => 0; 1640 lfs_file_read(&lfs, &file, buffer, 7) => 7; 1641 assert(strcmp((char*)buffer, "test.5") == 0); 1642 lfs_file_close(&lfs, &file) => 0; 1643 lfs_file_open(&lfs, &file, "/parent/2.after", LFS_O_RDONLY) => 0; 1644 lfs_file_read(&lfs, &file, buffer, 7) => 7; 1645 assert(strcmp((char*)buffer, "test.6") == 0); 1646 lfs_file_close(&lfs, &file) => 0; 1647 lfs_file_open(&lfs, &file, "/parent/child/0.before", LFS_O_RDONLY) => 0; 1648 lfs_file_read(&lfs, &file, buffer, 7) => 7; 1649 assert(strcmp((char*)buffer, "test.7") == 0); 1650 lfs_file_close(&lfs, &file) => 0; 1651 lfs_file_open(&lfs, &file, "/parent/child/2.after", LFS_O_RDONLY) => 0; 1652 lfs_file_read(&lfs, &file, buffer, 7) => 7; 1653 assert(strcmp((char*)buffer, "test.8") == 0); 1654 lfs_file_close(&lfs, &file) => 0; 1655 lfs_unmount(&lfs) => 0; 1656''' 1657 1658[[case]] # move fix in relocation with predecessor 1659in = "lfs.c" 1660define.RELOCATIONS = 'range(0x7+1)' 1661define.LFS_ERASE_CYCLES = 0xffffffff 1662code = ''' 1663 lfs_format(&lfs, &cfg) => 0; 1664 lfs_mount(&lfs, &cfg) => 0; 1665 1666 lfs_mkdir(&lfs, "/parent") => 0; 1667 lfs_mkdir(&lfs, "/parent/child") => 0; 1668 lfs_mkdir(&lfs, "/parent/sibling") => 0; 1669 1670 lfs_file_open(&lfs, &file, "/parent/sibling/1.move_me", 1671 LFS_O_WRONLY | LFS_O_CREAT) => 0; 1672 lfs_file_write(&lfs, &file, "move me", 1673 sizeof("move me")) => sizeof("move me"); 1674 lfs_file_close(&lfs, &file) => 0; 1675 1676 lfs_file_open(&lfs, &file, "/parent/sibling/0.before", 1677 LFS_O_WRONLY | LFS_O_CREAT) => 0; 1678 lfs_file_write(&lfs, &file, "test.1", 7) => 7; 1679 lfs_file_close(&lfs, &file) => 0; 1680 lfs_file_open(&lfs, &file, "/parent/sibling/2.after", 1681 LFS_O_WRONLY | LFS_O_CREAT) => 0; 1682 lfs_file_write(&lfs, &file, "test.2", 7) => 7; 1683 lfs_file_close(&lfs, &file) => 0; 1684 lfs_file_open(&lfs, &file, "/parent/child/0.before", 1685 LFS_O_WRONLY | LFS_O_CREAT) => 0; 1686 lfs_file_write(&lfs, &file, "test.3", 7) => 7; 1687 lfs_file_close(&lfs, &file) => 0; 1688 lfs_file_open(&lfs, &file, "/parent/child/2.after", 1689 LFS_O_WRONLY | LFS_O_CREAT) => 0; 1690 lfs_file_write(&lfs, &file, "test.4", 7) => 7; 1691 lfs_file_close(&lfs, &file) => 0; 1692 1693 lfs_file_t files[4]; 1694 lfs_file_open(&lfs, &files[0], "/parent/sibling/0.before", 1695 LFS_O_WRONLY | LFS_O_TRUNC) => 0; 1696 lfs_file_open(&lfs, &files[1], "/parent/sibling/2.after", 1697 LFS_O_WRONLY | LFS_O_TRUNC) => 0; 1698 lfs_file_open(&lfs, &files[2], "/parent/child/0.before", 1699 LFS_O_WRONLY | LFS_O_TRUNC) => 0; 1700 lfs_file_open(&lfs, &files[3], "/parent/child/2.after", 1701 LFS_O_WRONLY | LFS_O_TRUNC) => 0; 1702 lfs_file_write(&lfs, &files[0], "test.5", 7) => 7; 1703 lfs_file_write(&lfs, &files[1], "test.6", 7) => 7; 1704 lfs_file_write(&lfs, &files[2], "test.7", 7) => 7; 1705 lfs_file_write(&lfs, &files[3], "test.8", 7) => 7; 1706 1707 // force specific directories to relocate 1708 if (RELOCATIONS & 0x1) { 1709 lfs_dir_open(&lfs, &dir, "/parent"); 1710 lfs_testbd_setwear(&cfg, dir.m.pair[0], 0xffffffff) => 0; 1711 lfs_testbd_setwear(&cfg, dir.m.pair[1], 0xffffffff) => 0; 1712 lfs_dir_close(&lfs, &dir) => 0; 1713 } 1714 if (RELOCATIONS & 0x2) { 1715 lfs_dir_open(&lfs, &dir, "/parent/sibling"); 1716 lfs_testbd_setwear(&cfg, dir.m.pair[0], 0xffffffff) => 0; 1717 lfs_testbd_setwear(&cfg, dir.m.pair[1], 0xffffffff) => 0; 1718 lfs_dir_close(&lfs, &dir) => 0; 1719 } 1720 if (RELOCATIONS & 0x4) { 1721 lfs_dir_open(&lfs, &dir, "/parent/child"); 1722 lfs_testbd_setwear(&cfg, dir.m.pair[0], 0xffffffff) => 0; 1723 lfs_testbd_setwear(&cfg, dir.m.pair[1], 0xffffffff) => 0; 1724 lfs_dir_close(&lfs, &dir) => 0; 1725 } 1726 1727 // ok, now we move the file, this creates a move that needs to be 1728 // fixed, possibly in a metadata-pair that needs to be relocated 1729 // 1730 // and now relocations can force us to need to fix our move in either 1731 // the parent or child before things break 1732 lfs_rename(&lfs, 1733 "/parent/sibling/1.move_me", 1734 "/parent/child/1.move_me") => 0; 1735 1736 lfs_file_close(&lfs, &files[0]) => 0; 1737 lfs_file_close(&lfs, &files[1]) => 0; 1738 lfs_file_close(&lfs, &files[2]) => 0; 1739 lfs_file_close(&lfs, &files[3]) => 0; 1740 1741 // check that nothing was corrupted 1742 lfs_dir_open(&lfs, &dir, "/parent") => 0; 1743 lfs_dir_read(&lfs, &dir, &info) => 1; 1744 assert(strcmp(info.name, ".") == 0); 1745 assert(info.type == LFS_TYPE_DIR); 1746 lfs_dir_read(&lfs, &dir, &info) => 1; 1747 assert(strcmp(info.name, "..") == 0); 1748 assert(info.type == LFS_TYPE_DIR); 1749 lfs_dir_read(&lfs, &dir, &info) => 1; 1750 assert(strcmp(info.name, "child") == 0); 1751 assert(info.type == LFS_TYPE_DIR); 1752 lfs_dir_read(&lfs, &dir, &info) => 1; 1753 assert(strcmp(info.name, "sibling") == 0); 1754 assert(info.type == LFS_TYPE_DIR); 1755 lfs_dir_read(&lfs, &dir, &info) => 0; 1756 lfs_dir_close(&lfs, &dir) => 0; 1757 1758 lfs_dir_open(&lfs, &dir, "/parent/sibling") => 0; 1759 lfs_dir_read(&lfs, &dir, &info) => 1; 1760 assert(strcmp(info.name, ".") == 0); 1761 assert(info.type == LFS_TYPE_DIR); 1762 lfs_dir_read(&lfs, &dir, &info) => 1; 1763 assert(strcmp(info.name, "..") == 0); 1764 assert(info.type == LFS_TYPE_DIR); 1765 lfs_dir_read(&lfs, &dir, &info) => 1; 1766 assert(strcmp(info.name, "0.before") == 0); 1767 assert(info.type == LFS_TYPE_REG); 1768 assert(info.size == 7); 1769 lfs_dir_read(&lfs, &dir, &info) => 1; 1770 assert(strcmp(info.name, "2.after") == 0); 1771 assert(info.type == LFS_TYPE_REG); 1772 assert(info.size == 7); 1773 lfs_dir_read(&lfs, &dir, &info) => 0; 1774 lfs_dir_close(&lfs, &dir) => 0; 1775 1776 lfs_dir_open(&lfs, &dir, "/parent/child") => 0; 1777 lfs_dir_read(&lfs, &dir, &info) => 1; 1778 assert(strcmp(info.name, ".") == 0); 1779 assert(info.type == LFS_TYPE_DIR); 1780 lfs_dir_read(&lfs, &dir, &info) => 1; 1781 assert(strcmp(info.name, "..") == 0); 1782 assert(info.type == LFS_TYPE_DIR); 1783 lfs_dir_read(&lfs, &dir, &info) => 1; 1784 assert(strcmp(info.name, "0.before") == 0); 1785 assert(info.type == LFS_TYPE_REG); 1786 assert(info.size == 7); 1787 lfs_dir_read(&lfs, &dir, &info) => 1; 1788 assert(strcmp(info.name, "1.move_me") == 0); 1789 assert(info.type == LFS_TYPE_REG); 1790 assert(info.size == sizeof("move me")); 1791 lfs_dir_read(&lfs, &dir, &info) => 1; 1792 assert(strcmp(info.name, "2.after") == 0); 1793 assert(info.type == LFS_TYPE_REG); 1794 assert(info.size == 7); 1795 lfs_dir_read(&lfs, &dir, &info) => 0; 1796 lfs_dir_close(&lfs, &dir) => 0; 1797 1798 lfs_file_open(&lfs, &file, "/parent/sibling/0.before", LFS_O_RDONLY) => 0; 1799 lfs_file_read(&lfs, &file, buffer, 7) => 7; 1800 assert(strcmp((char*)buffer, "test.5") == 0); 1801 lfs_file_close(&lfs, &file) => 0; 1802 lfs_file_open(&lfs, &file, "/parent/sibling/2.after", LFS_O_RDONLY) => 0; 1803 lfs_file_read(&lfs, &file, buffer, 7) => 7; 1804 assert(strcmp((char*)buffer, "test.6") == 0); 1805 lfs_file_close(&lfs, &file) => 0; 1806 lfs_file_open(&lfs, &file, "/parent/child/0.before", LFS_O_RDONLY) => 0; 1807 lfs_file_read(&lfs, &file, buffer, 7) => 7; 1808 assert(strcmp((char*)buffer, "test.7") == 0); 1809 lfs_file_close(&lfs, &file) => 0; 1810 lfs_file_open(&lfs, &file, "/parent/child/2.after", LFS_O_RDONLY) => 0; 1811 lfs_file_read(&lfs, &file, buffer, 7) => 7; 1812 assert(strcmp((char*)buffer, "test.8") == 0); 1813 lfs_file_close(&lfs, &file) => 0; 1814 lfs_unmount(&lfs) => 0; 1815''' 1816