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