mirror of
https://github.com/eledio-devices/thirdparty-littlefs.git
synced 2025-11-01 00:38:29 +01:00
WIP Added allocation randomization for dynamic wear-leveling
This commit is contained in:
@@ -19,6 +19,40 @@
|
|||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
|
||||||
|
// Emulated block device utils
|
||||||
|
static inline void lfs_emubd_tole32(lfs_emubd_t *emu) {
|
||||||
|
emu->cfg.read_size = lfs_tole32(emu->cfg.read_size);
|
||||||
|
emu->cfg.prog_size = lfs_tole32(emu->cfg.prog_size);
|
||||||
|
emu->cfg.block_size = lfs_tole32(emu->cfg.block_size);
|
||||||
|
emu->cfg.block_count = lfs_tole32(emu->cfg.block_count);
|
||||||
|
|
||||||
|
emu->stats.read_count = lfs_tole32(emu->stats.read_count);
|
||||||
|
emu->stats.prog_count = lfs_tole32(emu->stats.prog_count);
|
||||||
|
emu->stats.erase_count = lfs_tole32(emu->stats.erase_count);
|
||||||
|
|
||||||
|
for (int i = 0; i < sizeof(emu->history.blocks) /
|
||||||
|
sizeof(emu->history.blocks[0]); i++) {
|
||||||
|
emu->history.blocks[i] = lfs_tole32(emu->history.blocks[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void lfs_emubd_fromle32(lfs_emubd_t *emu) {
|
||||||
|
emu->cfg.read_size = lfs_fromle32(emu->cfg.read_size);
|
||||||
|
emu->cfg.prog_size = lfs_fromle32(emu->cfg.prog_size);
|
||||||
|
emu->cfg.block_size = lfs_fromle32(emu->cfg.block_size);
|
||||||
|
emu->cfg.block_count = lfs_fromle32(emu->cfg.block_count);
|
||||||
|
|
||||||
|
emu->stats.read_count = lfs_fromle32(emu->stats.read_count);
|
||||||
|
emu->stats.prog_count = lfs_fromle32(emu->stats.prog_count);
|
||||||
|
emu->stats.erase_count = lfs_fromle32(emu->stats.erase_count);
|
||||||
|
|
||||||
|
for (int i = 0; i < sizeof(emu->history.blocks) /
|
||||||
|
sizeof(emu->history.blocks[0]); i++) {
|
||||||
|
emu->history.blocks[i] = lfs_fromle32(emu->history.blocks[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Block device emulated on existing filesystem
|
// Block device emulated on existing filesystem
|
||||||
int lfs_emubd_create(const struct lfs_config *cfg, const char *path) {
|
int lfs_emubd_create(const struct lfs_config *cfg, const char *path) {
|
||||||
lfs_emubd_t *emu = cfg->context;
|
lfs_emubd_t *emu = cfg->context;
|
||||||
@@ -46,20 +80,39 @@ int lfs_emubd_create(const struct lfs_config *cfg, const char *path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Load stats to continue incrementing
|
// Load stats to continue incrementing
|
||||||
snprintf(emu->child, LFS_NAME_MAX, "stats");
|
snprintf(emu->child, LFS_NAME_MAX, ".stats");
|
||||||
FILE *f = fopen(emu->path, "r");
|
FILE *f = fopen(emu->path, "r");
|
||||||
if (!f) {
|
if (!f) {
|
||||||
return -errno;
|
memset(&emu->stats, 0, sizeof(emu->stats));
|
||||||
|
} else {
|
||||||
|
size_t res = fread(&emu->stats, sizeof(emu->stats), 1, f);
|
||||||
|
lfs_emubd_fromle32(emu);
|
||||||
|
if (res < 1) {
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = fclose(f);
|
||||||
|
if (err) {
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t res = fread(&emu->stats, sizeof(emu->stats), 1, f);
|
// Load history
|
||||||
if (res < 1) {
|
snprintf(emu->child, LFS_NAME_MAX, ".history");
|
||||||
return -errno;
|
f = fopen(emu->path, "r");
|
||||||
}
|
if (!f) {
|
||||||
|
memset(&emu->history, 0, sizeof(emu->history));
|
||||||
|
} else {
|
||||||
|
size_t res = fread(&emu->history, sizeof(emu->history), 1, f);
|
||||||
|
lfs_emubd_fromle32(emu);
|
||||||
|
if (res < 1) {
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
|
||||||
err = fclose(f);
|
err = fclose(f);
|
||||||
if (err) {
|
if (err) {
|
||||||
return -errno;
|
return -errno;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -161,6 +214,13 @@ int lfs_emubd_prog(const struct lfs_config *cfg, lfs_block_t block,
|
|||||||
return -errno;
|
return -errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update history and stats
|
||||||
|
if (block != emu->history.blocks[0]) {
|
||||||
|
memcpy(&emu->history.blocks[1], &emu->history.blocks[0],
|
||||||
|
sizeof(emu->history) - sizeof(emu->history.blocks[0]));
|
||||||
|
emu->history.blocks[0] = block;
|
||||||
|
}
|
||||||
|
|
||||||
emu->stats.prog_count += 1;
|
emu->stats.prog_count += 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -206,13 +266,15 @@ int lfs_emubd_sync(const struct lfs_config *cfg) {
|
|||||||
lfs_emubd_t *emu = cfg->context;
|
lfs_emubd_t *emu = cfg->context;
|
||||||
|
|
||||||
// Just write out info/stats for later lookup
|
// Just write out info/stats for later lookup
|
||||||
snprintf(emu->child, LFS_NAME_MAX, "config");
|
snprintf(emu->child, LFS_NAME_MAX, ".config");
|
||||||
FILE *f = fopen(emu->path, "w");
|
FILE *f = fopen(emu->path, "w");
|
||||||
if (!f) {
|
if (!f) {
|
||||||
return -errno;
|
return -errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lfs_emubd_tole32(emu);
|
||||||
size_t res = fwrite(&emu->cfg, sizeof(emu->cfg), 1, f);
|
size_t res = fwrite(&emu->cfg, sizeof(emu->cfg), 1, f);
|
||||||
|
lfs_emubd_fromle32(emu);
|
||||||
if (res < 1) {
|
if (res < 1) {
|
||||||
return -errno;
|
return -errno;
|
||||||
}
|
}
|
||||||
@@ -222,13 +284,33 @@ int lfs_emubd_sync(const struct lfs_config *cfg) {
|
|||||||
return -errno;
|
return -errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(emu->child, LFS_NAME_MAX, "stats");
|
snprintf(emu->child, LFS_NAME_MAX, ".stats");
|
||||||
f = fopen(emu->path, "w");
|
f = fopen(emu->path, "w");
|
||||||
if (!f) {
|
if (!f) {
|
||||||
return -errno;
|
return -errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lfs_emubd_tole32(emu);
|
||||||
res = fwrite(&emu->stats, sizeof(emu->stats), 1, f);
|
res = fwrite(&emu->stats, sizeof(emu->stats), 1, f);
|
||||||
|
lfs_emubd_fromle32(emu);
|
||||||
|
if (res < 1) {
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = fclose(f);
|
||||||
|
if (err) {
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(emu->child, LFS_NAME_MAX, ".history");
|
||||||
|
f = fopen(emu->path, "w");
|
||||||
|
if (!f) {
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
lfs_emubd_tole32(emu);
|
||||||
|
res = fwrite(&emu->history, sizeof(emu->history), 1, f);
|
||||||
|
lfs_emubd_fromle32(emu);
|
||||||
if (res < 1) {
|
if (res < 1) {
|
||||||
return -errno;
|
return -errno;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,6 +45,10 @@ typedef struct lfs_emubd {
|
|||||||
uint64_t erase_count;
|
uint64_t erase_count;
|
||||||
} stats;
|
} stats;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
lfs_block_t blocks[4];
|
||||||
|
} history;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
uint32_t read_size;
|
uint32_t read_size;
|
||||||
uint32_t prog_size;
|
uint32_t prog_size;
|
||||||
|
|||||||
15
lfs.c
15
lfs.c
@@ -879,6 +879,8 @@ static int32_t lfs_dir_fetchmatch(lfs_t *lfs,
|
|||||||
dir->tail[1] = temptail[1];
|
dir->tail[1] = temptail[1];
|
||||||
dir->split = tempsplit;
|
dir->split = tempsplit;
|
||||||
dir->locals = templocals;
|
dir->locals = templocals;
|
||||||
|
|
||||||
|
lfs->seed ^= crc;
|
||||||
crc = 0xffffffff;
|
crc = 0xffffffff;
|
||||||
} else {
|
} else {
|
||||||
err = lfs_bd_crc32(lfs, dir->pair[0],
|
err = lfs_bd_crc32(lfs, dir->pair[0],
|
||||||
@@ -2874,6 +2876,7 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) {
|
|||||||
lfs->root[0] = 0xffffffff;
|
lfs->root[0] = 0xffffffff;
|
||||||
lfs->root[1] = 0xffffffff;
|
lfs->root[1] = 0xffffffff;
|
||||||
lfs->mlist = NULL;
|
lfs->mlist = NULL;
|
||||||
|
lfs->seed = 0;
|
||||||
lfs->globals.s.movepair[0] = 0xffffffff;
|
lfs->globals.s.movepair[0] = 0xffffffff;
|
||||||
lfs->globals.s.movepair[1] = 0xffffffff;
|
lfs->globals.s.movepair[1] = 0xffffffff;
|
||||||
lfs->globals.s.moveid = 0x3ff;
|
lfs->globals.s.moveid = 0x3ff;
|
||||||
@@ -2962,12 +2965,6 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
// setup free lookahead
|
|
||||||
lfs->free.off = 0;
|
|
||||||
lfs->free.size = 0;
|
|
||||||
lfs->free.i = 0;
|
|
||||||
lfs_alloc_ack(lfs);
|
|
||||||
|
|
||||||
// load superblock
|
// load superblock
|
||||||
lfs_mdir_t root;
|
lfs_mdir_t root;
|
||||||
err = lfs_dir_fetch(lfs, &root, (const lfs_block_t[2]){0, 1});
|
err = lfs_dir_fetch(lfs, &root, (const lfs_block_t[2]){0, 1});
|
||||||
@@ -3065,6 +3062,12 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
|
|||||||
lfs->globals.s.moveid);
|
lfs->globals.s.moveid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// setup free lookahead
|
||||||
|
lfs->free.off = lfs->seed % lfs->cfg->block_size;
|
||||||
|
lfs->free.size = 0;
|
||||||
|
lfs->free.i = 0;
|
||||||
|
lfs_alloc_ack(lfs);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
|||||||
1
lfs.h
1
lfs.h
@@ -382,6 +382,7 @@ typedef struct lfs {
|
|||||||
|
|
||||||
lfs_block_t root[2];
|
lfs_block_t root[2];
|
||||||
lfs_mlist_t *mlist;
|
lfs_mlist_t *mlist;
|
||||||
|
uint32_t seed;
|
||||||
|
|
||||||
lfs_global_t globals;
|
lfs_global_t globals;
|
||||||
lfs_global_t locals;
|
lfs_global_t locals;
|
||||||
|
|||||||
@@ -3,37 +3,41 @@
|
|||||||
import struct
|
import struct
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
import argparse
|
||||||
|
|
||||||
def main(*paths):
|
def corrupt(block):
|
||||||
# find most recent block
|
with open(block, 'r+b') as file:
|
||||||
file = None
|
# skip rev
|
||||||
rev = None
|
file.read(4)
|
||||||
for path in paths:
|
|
||||||
try:
|
|
||||||
nfile = open(path, 'r+b')
|
|
||||||
nrev, = struct.unpack('<I', nfile.read(4))
|
|
||||||
|
|
||||||
assert rev != nrev
|
# go to last commit
|
||||||
if not file or ((rev - nrev) & 0x80000000):
|
tag = 0
|
||||||
file = nfile
|
while True:
|
||||||
rev = nrev
|
try:
|
||||||
except IOError:
|
ntag, = struct.unpack('<I', file.read(4))
|
||||||
pass
|
except struct.error:
|
||||||
|
break
|
||||||
|
|
||||||
# go to last commit
|
tag ^= ntag
|
||||||
tag = 0
|
file.seek(tag & 0xfff, os.SEEK_CUR)
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
ntag, = struct.unpack('<I', file.read(4))
|
|
||||||
except struct.error:
|
|
||||||
break
|
|
||||||
|
|
||||||
tag ^= ntag
|
# lob off last 3 bytes
|
||||||
file.seek(tag & 0xfff, os.SEEK_CUR)
|
file.seek(-((tag & 0xfff) + 3), os.SEEK_CUR)
|
||||||
|
file.truncate()
|
||||||
|
|
||||||
# lob off last 3 bytes
|
def main(args):
|
||||||
file.seek(-((tag & 0xfff) + 3), os.SEEK_CUR)
|
if args.n or not args.blocks:
|
||||||
file.truncate()
|
with open('blocks/.history', 'rb') as file:
|
||||||
|
for i in range(int(args.n or 1)):
|
||||||
|
last, = struct.unpack('<I', file.read(4))
|
||||||
|
args.blocks.append('blocks/%x' % last)
|
||||||
|
|
||||||
|
for block in args.blocks:
|
||||||
|
print 'corrupting %s' % block
|
||||||
|
corrupt(block)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main(*sys.argv[1:])
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument('-n')
|
||||||
|
parser.add_argument('blocks', nargs='*')
|
||||||
|
main(parser.parse_args())
|
||||||
|
|||||||
98
tests/debug.py
Executable file
98
tests/debug.py
Executable file
@@ -0,0 +1,98 @@
|
|||||||
|
#!/usr/bin/env python2
|
||||||
|
|
||||||
|
import struct
|
||||||
|
import binascii
|
||||||
|
|
||||||
|
TYPES = {
|
||||||
|
(0x1ff, 0x001): 'reg',
|
||||||
|
(0x1ff, 0x002): 'dir',
|
||||||
|
(0x1ff, 0x011): 'superblock',
|
||||||
|
(0x1ff, 0x012): 'root',
|
||||||
|
(0x1ff, 0x030): 'delete',
|
||||||
|
(0x1f0, 0x080): 'globals',
|
||||||
|
(0x1ff, 0x0c0): 'tail soft',
|
||||||
|
(0x1ff, 0x0c1): 'tail hard',
|
||||||
|
(0x1ff, 0x0f0): 'crc',
|
||||||
|
(0x1ff, 0x040): 'struct dir',
|
||||||
|
(0x1ff, 0x041): 'struct inline',
|
||||||
|
(0x1ff, 0x042): 'struct ctz',
|
||||||
|
(0x100, 0x100): 'attr',
|
||||||
|
}
|
||||||
|
|
||||||
|
def typeof(type):
|
||||||
|
for prefix in range(9):
|
||||||
|
mask = 0x1ff & ~((1 << prefix)-1)
|
||||||
|
if (mask, type & mask) in TYPES:
|
||||||
|
return TYPES[mask, type & mask] + (
|
||||||
|
' [%0*x]' % (prefix/4, type & ((1 << prefix)-1))
|
||||||
|
if prefix else '')
|
||||||
|
else:
|
||||||
|
return '[%02x]' % type
|
||||||
|
|
||||||
|
def main(*blocks):
|
||||||
|
# find most recent block
|
||||||
|
file = None
|
||||||
|
rev = None
|
||||||
|
crc = None
|
||||||
|
versions = []
|
||||||
|
|
||||||
|
for block in blocks:
|
||||||
|
try:
|
||||||
|
nfile = open(block, 'rb')
|
||||||
|
ndata = nfile.read(4)
|
||||||
|
ncrc = binascii.crc32(ndata)
|
||||||
|
nrev, = struct.unpack('<I', ndata)
|
||||||
|
|
||||||
|
assert rev != nrev
|
||||||
|
if not file or ((rev - nrev) & 0x80000000):
|
||||||
|
file = nfile
|
||||||
|
rev = nrev
|
||||||
|
crc = ncrc
|
||||||
|
|
||||||
|
versions.append((nrev, '%s (rev %d)' % (block, nrev)))
|
||||||
|
except IOError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
print "--- %s ---" % ', '.join(v for _,v in sorted(versions, reverse=True))
|
||||||
|
|
||||||
|
# go through each tag, print useful information
|
||||||
|
print "%-4s %-8s %-14s %3s %3s %s" % (
|
||||||
|
'off', 'tag', 'type', 'id', 'len', 'dump')
|
||||||
|
|
||||||
|
tag = 0
|
||||||
|
off = 4
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
data = file.read(4)
|
||||||
|
crc = binascii.crc32(data, crc)
|
||||||
|
ntag, = struct.unpack('<I', data)
|
||||||
|
except struct.error:
|
||||||
|
break
|
||||||
|
|
||||||
|
tag ^= ntag
|
||||||
|
off += 4
|
||||||
|
|
||||||
|
type = (tag & 0x7fc00000) >> 22
|
||||||
|
id = (tag & 0x003ff000) >> 12
|
||||||
|
size = (tag & 0x00000fff) >> 0
|
||||||
|
|
||||||
|
data = file.read(size)
|
||||||
|
if type == 0x0f0:
|
||||||
|
crc = binascii.crc32(data[:4], crc)
|
||||||
|
else:
|
||||||
|
crc = binascii.crc32(data, crc)
|
||||||
|
|
||||||
|
print '%04x: %08x %-14s %3s %3d %-23s %-8s' % (
|
||||||
|
off, tag,
|
||||||
|
typeof(type) + (' bad!' if type == 0x0f0 and ~crc else ''),
|
||||||
|
id if id != 0x3ff else '.', size,
|
||||||
|
' '.join('%02x' % ord(c) for c in data[:8]),
|
||||||
|
''.join(c if c >= ' ' and c <= '~' else '.' for c in data[:8]))
|
||||||
|
|
||||||
|
off += tag & 0xfff
|
||||||
|
if type == 0x0f0:
|
||||||
|
crc = 0
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import sys
|
||||||
|
main(*sys.argv[1:])
|
||||||
@@ -7,7 +7,7 @@ import os
|
|||||||
import re
|
import re
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
with open('blocks/config') as file:
|
with open('blocks/.config') as file:
|
||||||
s = struct.unpack('<LLLL', file.read())
|
s = struct.unpack('<LLLL', file.read())
|
||||||
print 'read_size: %d' % s[0]
|
print 'read_size: %d' % s[0]
|
||||||
print 'prog_size: %d' % s[1]
|
print 'prog_size: %d' % s[1]
|
||||||
@@ -18,7 +18,7 @@ def main():
|
|||||||
os.path.getsize(os.path.join('blocks', f))
|
os.path.getsize(os.path.join('blocks', f))
|
||||||
for f in os.listdir('blocks') if re.match('\d+', f))
|
for f in os.listdir('blocks') if re.match('\d+', f))
|
||||||
|
|
||||||
with open('blocks/stats') as file:
|
with open('blocks/.stats') as file:
|
||||||
s = struct.unpack('<QQQ', file.read())
|
s = struct.unpack('<QQQ', file.read())
|
||||||
print 'read_count: %d' % s[0]
|
print 'read_count: %d' % s[0]
|
||||||
print 'prog_count: %d' % s[1]
|
print 'prog_count: %d' % s[1]
|
||||||
|
|||||||
@@ -71,24 +71,25 @@ echo "--- Sanity check ---"
|
|||||||
rm -rf blocks
|
rm -rf blocks
|
||||||
lfs_mktree
|
lfs_mktree
|
||||||
lfs_chktree
|
lfs_chktree
|
||||||
|
BLOCKS="$(ls blocks | grep -vw '[01]')"
|
||||||
|
|
||||||
echo "--- Block corruption ---"
|
echo "--- Block corruption ---"
|
||||||
for i in {2..33}
|
for b in $BLOCKS
|
||||||
do
|
do
|
||||||
rm -rf blocks
|
rm -rf blocks
|
||||||
mkdir blocks
|
mkdir blocks
|
||||||
ln -s /dev/zero blocks/$(printf '%x' $i)
|
ln -s /dev/zero blocks/$b
|
||||||
lfs_mktree
|
lfs_mktree
|
||||||
lfs_chktree
|
lfs_chktree
|
||||||
done
|
done
|
||||||
|
|
||||||
echo "--- Block persistance ---"
|
echo "--- Block persistance ---"
|
||||||
for i in {2..33}
|
for b in $BLOCKS
|
||||||
do
|
do
|
||||||
rm -rf blocks
|
rm -rf blocks
|
||||||
mkdir blocks
|
mkdir blocks
|
||||||
lfs_mktree
|
lfs_mktree
|
||||||
chmod a-w blocks/$(printf '%x' $i) || true
|
chmod a-w blocks/$b
|
||||||
lfs_mktree
|
lfs_mktree
|
||||||
lfs_chktree
|
lfs_chktree
|
||||||
done
|
done
|
||||||
@@ -96,7 +97,7 @@ done
|
|||||||
echo "--- Big region corruption ---"
|
echo "--- Big region corruption ---"
|
||||||
rm -rf blocks
|
rm -rf blocks
|
||||||
mkdir blocks
|
mkdir blocks
|
||||||
for i in {2..255}
|
for i in {2..512}
|
||||||
do
|
do
|
||||||
ln -s /dev/zero blocks/$(printf '%x' $i)
|
ln -s /dev/zero blocks/$(printf '%x' $i)
|
||||||
done
|
done
|
||||||
@@ -106,7 +107,7 @@ lfs_chktree
|
|||||||
echo "--- Alternating corruption ---"
|
echo "--- Alternating corruption ---"
|
||||||
rm -rf blocks
|
rm -rf blocks
|
||||||
mkdir blocks
|
mkdir blocks
|
||||||
for i in {2..511..2}
|
for i in {2..1024..2}
|
||||||
do
|
do
|
||||||
ln -s /dev/zero blocks/$(printf '%x' $i)
|
ln -s /dev/zero blocks/$(printf '%x' $i)
|
||||||
done
|
done
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ tests/test.py << TEST
|
|||||||
lfs_rename(&lfs, "b/hello", "c/hello") => 0;
|
lfs_rename(&lfs, "b/hello", "c/hello") => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
TEST
|
TEST
|
||||||
tests/corrupt.py blocks/{4,5}
|
tests/corrupt.py -n 1
|
||||||
tests/test.py << TEST
|
tests/test.py << TEST
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, &cfg) => 0;
|
||||||
lfs_dir_open(&lfs, &dir[0], "b") => 0;
|
lfs_dir_open(&lfs, &dir[0], "b") => 0;
|
||||||
@@ -86,8 +86,7 @@ tests/test.py << TEST
|
|||||||
lfs_rename(&lfs, "c/hello", "d/hello") => 0;
|
lfs_rename(&lfs, "c/hello", "d/hello") => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
TEST
|
TEST
|
||||||
tests/corrupt.py blocks/{6,7}
|
tests/corrupt.py -n 2
|
||||||
tests/corrupt.py blocks/{8,9}
|
|
||||||
tests/test.py << TEST
|
tests/test.py << TEST
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, &cfg) => 0;
|
||||||
lfs_dir_open(&lfs, &dir[0], "c") => 0;
|
lfs_dir_open(&lfs, &dir[0], "c") => 0;
|
||||||
@@ -166,7 +165,7 @@ tests/test.py << TEST
|
|||||||
lfs_rename(&lfs, "b/hi", "c/hi") => 0;
|
lfs_rename(&lfs, "b/hi", "c/hi") => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
TEST
|
TEST
|
||||||
tests/corrupt.py blocks/{4,5}
|
tests/corrupt.py -n 1
|
||||||
tests/test.py << TEST
|
tests/test.py << TEST
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, &cfg) => 0;
|
||||||
lfs_dir_open(&lfs, &dir[0], "b") => 0;
|
lfs_dir_open(&lfs, &dir[0], "b") => 0;
|
||||||
@@ -193,8 +192,7 @@ tests/test.py << TEST
|
|||||||
lfs_rename(&lfs, "c/hi", "d/hi") => 0;
|
lfs_rename(&lfs, "c/hi", "d/hi") => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
TEST
|
TEST
|
||||||
tests/corrupt.py blocks/{6,7}
|
tests/corrupt.py -n 2
|
||||||
tests/corrupt.py blocks/{8,9}
|
|
||||||
tests/test.py << TEST
|
tests/test.py << TEST
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, &cfg) => 0;
|
||||||
lfs_dir_open(&lfs, &dir[0], "c") => 0;
|
lfs_dir_open(&lfs, &dir[0], "c") => 0;
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ tests/test.py << TEST
|
|||||||
TEST
|
TEST
|
||||||
# corrupt most recent commit, this should be the update to the previous
|
# corrupt most recent commit, this should be the update to the previous
|
||||||
# linked-list entry and should orphan the child
|
# linked-list entry and should orphan the child
|
||||||
tests/corrupt.py blocks/{6,7}
|
tests/corrupt.py
|
||||||
tests/test.py << TEST
|
tests/test.py << TEST
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, &cfg) => 0;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user