Skip to content

Commit 4dd4054

Browse files
committed
Add lfs_enumattr() function
Allows file attributes to be efficiently enumerated, required for filesystem backup, etc.
1 parent b78c243 commit 4dd4054

2 files changed

Lines changed: 32 additions & 23 deletions

File tree

lfs.c

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3873,38 +3873,40 @@ static lfs_soff_t lfs_file_size_(lfs_t *lfs, lfs_file_t *file) {
38733873
return file->ctz.size;
38743874
}
38753875

3876-
3877-
static int lfs_file_enumattr_(lfs_t* lfs, lfs_file_t* file,
3876+
static int lfs_enumattr_(lfs_t* lfs, const char* path,
38783877
lfs_attr_callback_t callback, struct lfs_attr_enum_t* e)
38793878
{
3879+
lfs_mdir_t cwd;
3880+
lfs_stag_t tag = lfs_dir_find(lfs, &cwd, &path, NULL);
3881+
if (tag < 0) {
3882+
return tag;
3883+
}
3884+
3885+
uint16_t id = lfs_tag_id(tag);
3886+
if (id == 0x3ff) {
3887+
// special case for root
3888+
id = 0;
3889+
int err = lfs_dir_fetch(lfs, &cwd, lfs->root);
3890+
if (err) {
3891+
return err;
3892+
}
3893+
}
3894+
38803895
size_t count = 0;
38813896

38823897
// Set of flags to avoid returning old versions of an attribute
38833898
uint8_t found_attrs[256 / 8] = {0};
38843899

3885-
// Enumerate registered attributes first as they may have been updated
3886-
for(unsigned i = 0; i < file->cfg->attr_count; i++) {
3887-
struct lfs_attr* const attr = &file->cfg->attrs[i];
3888-
memcpy(e->buffer, attr->buffer, lfs_min(attr->size, e->bufsize));
3889-
++count;
3890-
if(!callback(e, attr->type, attr->size)) {
3891-
return count;
3892-
}
3893-
uint8_t offset = attr->type / 8;
3894-
uint8_t mask = 1 << (attr->type % 8);
3895-
found_attrs[offset] |= mask;
3896-
}
3897-
38983900
// Enumerate on-disk attributes
38993901

3900-
lfs_mdir_t* dir = &file->m;
3902+
lfs_mdir_t* dir = &cwd;
39013903
lfs_off_t off = dir->off;
39023904
lfs_tag_t ntag = dir->etag;
39033905
lfs_stag_t gdiff = 0;
39043906

39053907
lfs_tag_t gmask = LFS_MKTAG(LFS_TYPE_USERATTR, 0x3ff, 0);
39063908
lfs_size_t gsize = lfs_min(e->bufsize, lfs->attr_max);
3907-
lfs_tag_t gtag = LFS_MKTAG(LFS_TYPE_USERATTR + 0, file->id, gsize);
3909+
lfs_tag_t gtag = LFS_MKTAG(LFS_TYPE_USERATTR + 0, id, gsize);
39083910

39093911
if (lfs_gstate_hasmovehere(&lfs->gdisk, dir->pair) &&
39103912
lfs_tag_id(gmask) != 0 &&
@@ -6434,19 +6436,19 @@ lfs_soff_t lfs_file_size(lfs_t *lfs, lfs_file_t *file) {
64346436
return res;
64356437
}
64366438

6437-
int lfs_file_enumattr(lfs_t* lfs, lfs_file_t* file,
6439+
int lfs_enumattr(lfs_t* lfs, const char* path,
64386440
lfs_attr_callback_t callback, struct lfs_attr_enum_t* e)
64396441
{
64406442
int err = LFS_LOCK(lfs->cfg);
64416443
if(err) {
64426444
return err;
64436445
}
6444-
LFS_TRACE("lfs_file_enumattr(%p, %p, %p)", (void*)lfs, (void*)file, (void*)e);
6445-
LFS_ASSERT(lfs_mlist_isopen(lfs->mlist, (struct lfs_mlist*)file));
6446+
LFS_TRACE("lfs_enumattr(%p, \"%s\", %p, %p)",
6447+
(void*)lfs, path, (void*)e);
64466448

6447-
err = lfs_file_enumattr_(lfs, file, callback, e);
6449+
err = lfs_enumattr_(lfs, path, callback, e);
64486450

6449-
LFS_TRACE("lfs_file_enumattr -> %d", err);
6451+
LFS_TRACE("lfs_enumattr -> %"PRId32, err);
64506452
LFS_UNLOCK(lfs->cfg);
64516453
return err;
64526454
}

lfs.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -661,6 +661,13 @@ int lfs_file_rewind(lfs_t *lfs, lfs_file_t *file);
661661
// Returns the size of the file, or a negative error code on failure.
662662
lfs_soff_t lfs_file_size(lfs_t *lfs, lfs_file_t *file);
663663

664+
// Parameters used during attribute enumeration
665+
struct lfs_attr_enum_t {
666+
void* param;
667+
void* buffer;
668+
size_t bufsize;
669+
};
670+
664671
// Callback to receive details for each file attribute
665672
//
666673
// Return true to continue enumeration, false to stop
@@ -670,7 +677,7 @@ typedef bool (*lfs_attr_callback_t)
670677
// Enumerate file attributes
671678
//
672679
// Invokes a callback for each attribute found
673-
int lfs_file_enumattr(lfs_t *lfs, lfs_file_t* file,
680+
int lfs_enumattr(lfs_t *lfs, const char* path,
674681
lfs_attr_callback_t callback, struct lfs_attr_enum_t* e);
675682

676683
/// Directory operations ///

0 commit comments

Comments
 (0)