Skip to content

Commit

Permalink
Support opening handle to directory
Browse files Browse the repository at this point in the history
Allows attributes to be accessed more efficiently, and enumerated
  • Loading branch information
mikee47 committed Jan 29, 2022
1 parent 3db7846 commit 0e41b8a
Show file tree
Hide file tree
Showing 4 changed files with 224 additions and 160 deletions.
65 changes: 56 additions & 9 deletions lfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -2494,15 +2494,26 @@ static int lfs_file_rawopencfg(lfs_t *lfs, lfs_file_t *file,
file->off = 0;
file->cache.buffer = NULL;

// allocate entry for file if it doesn't exist
lfs_stag_t tag = lfs_dir_find(lfs, &file->m, &path, &file->id);
if (tag < 0 && !(tag == LFS_ERR_NOENT && file->id != 0x3ff)) {
err = tag;
goto cleanup;
lfs_stag_t tag;
// special case for root
if (path == NULL || *path == '\0' || strcmp(path, "/") == 0) {
err = lfs_dir_fetch(lfs, &file->m, lfs->root);
if (err) {
goto cleanup;
}
tag = 0x3ff;
file->type = LFS_TYPE_DIR;
} else {
// allocate entry for file if it doesn't exist
tag = lfs_dir_find(lfs, &file->m, &path, &file->id);
if (tag < 0 && !(tag == LFS_ERR_NOENT && file->id != 0x3ff)) {
err = tag;
goto cleanup;
}
file->type = (tag == LFS_ERR_NOENT) ? LFS_TYPE_REG : lfs_tag_type3(tag);
}

// get id, add to list of mdirs to catch update changes
file->type = LFS_TYPE_REG;
lfs_mlist_append(lfs, (struct lfs_mlist *)file);

#ifdef LFS_READONLY
Expand Down Expand Up @@ -2538,16 +2549,20 @@ static int lfs_file_rawopencfg(lfs_t *lfs, lfs_file_t *file,
err = LFS_ERR_EXIST;
goto cleanup;
#endif
} else if (lfs_tag_type3(tag) != LFS_TYPE_REG) {
err = LFS_ERR_ISDIR;
} else if (file->type != LFS_TYPE_REG && file->type != LFS_TYPE_DIR) {
err = LFS_ERR_NOENT;
goto cleanup;
#ifndef LFS_READONLY
} else if (flags & LFS_O_TRUNC) {
if(file->type != LFS_TYPE_REG) {
err = LFS_ERR_ISDIR;
goto cleanup;
}
// truncate if requested
tag = LFS_MKTAG(LFS_TYPE_INLINESTRUCT, file->id, 0);
file->flags |= LFS_F_DIRTY;
#endif
} else {
} else if (file->type == LFS_TYPE_REG) {
// try to load what's on disk, if it's inlined we'll fix it later
tag = lfs_dir_get(lfs, &file->m, LFS_MKTAG(0x700, 0x3ff, 0),
LFS_MKTAG(LFS_TYPE_STRUCT, file->id, 8), &file->ctz);
Expand Down Expand Up @@ -2747,6 +2762,10 @@ static int lfs_file_outline(lfs_t *lfs, lfs_file_t *file) {

#ifndef LFS_READONLY
static int lfs_file_flush(lfs_t *lfs, lfs_file_t *file) {
if (file->type != LFS_TYPE_REG) {
return LFS_ERR_ISDIR;
}

if (file->flags & LFS_F_READING) {
if (!(file->flags & LFS_F_INLINE)) {
lfs_cache_drop(lfs, &file->cache);
Expand All @@ -2760,6 +2779,7 @@ static int lfs_file_flush(lfs_t *lfs, lfs_file_t *file) {
if (!(file->flags & LFS_F_INLINE)) {
// copy over anything after current branch
lfs_file_t orig = {
.type = file->type,
.ctz.head = file->ctz.head,
.ctz.size = file->ctz.size,
.flags = LFS_O_RDONLY,
Expand Down Expand Up @@ -2827,6 +2847,10 @@ static int lfs_file_flush(lfs_t *lfs, lfs_file_t *file) {

#ifndef LFS_READONLY
static int lfs_file_rawsync(lfs_t *lfs, lfs_file_t *file) {
if (file->type != LFS_TYPE_REG) {
return 0;
}

if (file->flags & LFS_F_ERRED) {
// it's not safe to do anything if our file errored
return 0;
Expand Down Expand Up @@ -2880,6 +2904,10 @@ static int lfs_file_rawsync(lfs_t *lfs, lfs_file_t *file) {

static lfs_ssize_t lfs_file_rawread(lfs_t *lfs, lfs_file_t *file,
void *buffer, lfs_size_t size) {
if (file->type != LFS_TYPE_REG) {
return 0;
}

LFS_ASSERT((file->flags & LFS_O_RDONLY) == LFS_O_RDONLY);

uint8_t *data = buffer;
Expand Down Expand Up @@ -2956,6 +2984,10 @@ static lfs_ssize_t lfs_file_rawwrite(lfs_t *lfs, lfs_file_t *file,
const void *buffer, lfs_size_t size) {
LFS_ASSERT((file->flags & LFS_O_WRONLY) == LFS_O_WRONLY);

if (file->type != LFS_TYPE_REG) {
return (size == 0) ? 0 : LFS_ERR_ISDIR;
}

const uint8_t *data = buffer;
lfs_size_t nsize = size;

Expand Down Expand Up @@ -3076,6 +3108,10 @@ static lfs_ssize_t lfs_file_rawwrite(lfs_t *lfs, lfs_file_t *file,

static lfs_soff_t lfs_file_rawseek(lfs_t *lfs, lfs_file_t *file,
lfs_soff_t off, int whence) {
if (file->type != LFS_TYPE_REG) {
return LFS_ERR_ISDIR;
}

// find new pos
lfs_off_t npos = file->pos;
if (whence == LFS_SEEK_SET) {
Expand Down Expand Up @@ -3113,6 +3149,10 @@ static lfs_soff_t lfs_file_rawseek(lfs_t *lfs, lfs_file_t *file,
static int lfs_file_rawtruncate(lfs_t *lfs, lfs_file_t *file, lfs_off_t size) {
LFS_ASSERT((file->flags & LFS_O_WRONLY) == LFS_O_WRONLY);

if (file->type != LFS_TYPE_REG) {
return LFS_ERR_ISDIR;
}

if (size > LFS_FILE_MAX) {
return LFS_ERR_INVAL;
}
Expand Down Expand Up @@ -3168,6 +3208,9 @@ static int lfs_file_rawtruncate(lfs_t *lfs, lfs_file_t *file, lfs_off_t size) {

static lfs_soff_t lfs_file_rawtell(lfs_t *lfs, lfs_file_t *file) {
(void)lfs;
if (file->type != LFS_TYPE_REG) {
return LFS_ERR_ISDIR;
}
return file->pos;
}

Expand All @@ -3183,6 +3226,10 @@ static int lfs_file_rawrewind(lfs_t *lfs, lfs_file_t *file) {
static lfs_soff_t lfs_file_rawsize(lfs_t *lfs, lfs_file_t *file) {
(void)lfs;

if (file->type != LFS_TYPE_REG) {
return 0;
}

#ifndef LFS_READONLY
if (file->flags & LFS_F_WRITING) {
return lfs_max(file->pos, file->ctz.size);
Expand Down
Loading

0 comments on commit 0e41b8a

Please sign in to comment.