Skip to content

Commit

Permalink
lfs:Added lfs_file_getattr interface
Browse files Browse the repository at this point in the history
1. Added a new interface lfs_file_getattr to get the corresponding
   file attributes through lfs_file. This interface is similar to lfs_getattr,
   but lfs_file_getattr replaces path with lfs_file.
2. Implemented the corresponding test case in test_attrs.toml.

Signed-off-by: chenrun1 <[email protected]>
  • Loading branch information
crafcat7 committed Nov 25, 2024
1 parent d01280e commit d8d4693
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 0 deletions.
32 changes: 32 additions & 0 deletions lfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -6235,6 +6235,38 @@ lfs_soff_t lfs_file_size(lfs_t *lfs, lfs_file_t *file) {
return res;
}

lfs_ssize_t lfs_file_getattr(lfs_t *lfs, lfs_file_t *file,
uint8_t type, void *buffer, lfs_size_t size)
{
int err = LFS_LOCK(lfs->cfg);
if (err) {
return err;
}
LFS_TRACE("lfs_file_setattr(%p, %p)", (void*)lfs, (void*)file);
LFS_TRACE("lfs_file_setattr(%"PRIu8", %p, %"PRIu32")",
type, buffer, size);
LFS_ASSERT(lfs_mlist_isopen(lfs->mlist, (struct lfs_mlist*)file));

if (file->cfg && file->cfg->attrs) {
for (unsigned i = 0; i < file->cfg->attr_count; i++) {
const struct lfs_attr *attr = &file->cfg->attrs[i];
if (attr->type == LFS_TYPE_USERATTR + type) {
lfs_size_t attr_size = lfs_min(size, attr->size);
memcpy(buffer, attr->buffer, attr_size);
LFS_UNLOCK(lfs->cfg);
return 0;
}
}
}

err = lfs_dir_get(lfs, &file->m,
LFS_MKTAG(0x7ff, 0x3ff, 0),
LFS_MKTAG(LFS_TYPE_USERATTR + type,
file->id, lfs_min(size, lfs->attr_max)), buffer);
LFS_UNLOCK(lfs->cfg);
return (err < 0) ? LFS_ERR_NOATTR : 0;
}

#ifndef LFS_READONLY
int lfs_mkdir(lfs_t *lfs, const char *path) {
int err = LFS_LOCK(lfs->cfg);
Expand Down
7 changes: 7 additions & 0 deletions lfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,13 @@ int lfs_file_rewind(lfs_t *lfs, lfs_file_t *file);
// Returns the size of the file, or a negative error code on failure.
lfs_soff_t lfs_file_size(lfs_t *lfs, lfs_file_t *file);

// Get the attribute of a file
//
// Retrieves the value of the attribute specified by `type` for the given `file`.
// Copies up to `size` bytes into `buffer`. Returns 0 on success, or a negative
// error code (e.g., LFS_ERR_NOATTR if not found).
lfs_ssize_t lfs_file_getattr(lfs_t *lfs, lfs_file_t *file,
uint8_t type, void *buffer, lfs_size_t size);

/// Directory operations ///

Expand Down
48 changes: 48 additions & 0 deletions tests/test_attrs.toml
Original file line number Diff line number Diff line change
Expand Up @@ -314,3 +314,51 @@ code = '''
lfs_file_close(&lfs, &file) => 0;
lfs_unmount(&lfs) => 0;
'''

[cases.test_file_getattr]
code = '''
struct lfs_attr_s {
uint32_t at_ver;
uint32_t at_mode;
uint32_t at_uid;
uint32_t at_gid;
uint64_t at_atim;
uint64_t at_mtim;
uint64_t at_ctim;
};

lfs_t lfs;
lfs_format(&lfs, cfg) => 0;
lfs_mount(&lfs, cfg) => 0;

lfs_file_t file;
struct lfs_attr_s attr_get[1024];
memset(attr_get, 0, sizeof(attr_get));
lfs_file_open(&lfs, &file, "hello", LFS_O_WRONLY | LFS_O_CREAT) => 0;
lfs_file_write(&lfs, &file, "world", strlen("world")) => strlen("world");
lfs_file_getattr(&lfs, &file, 0, attr_get, sizeof(struct lfs_attr_s)) => -61;

struct lfs_attr_s attr_set = {
.at_ver = 1,
.at_mode = 0644,
.at_uid = 1000,
.at_gid = 1000,
.at_atim = 1693123456,
.at_mtim = 1693123456,
.at_ctim = 1693123456,
};
lfs_setattr(&lfs, "hello", 0, &attr_set, sizeof(attr_set)) => 0;
memset(attr_get, 0, sizeof(attr_get));
lfs_file_getattr(&lfs, &file, 0, attr_get, sizeof(struct lfs_attr_s)) => 0;
attr_get->at_ver => attr_set.at_ver;
attr_get->at_mode => attr_set.at_mode;
attr_get->at_uid => attr_set.at_uid;
attr_get->at_gid => attr_set.at_gid;
attr_get->at_atim => attr_set.at_atim;
attr_get->at_mtim => attr_set.at_mtim;
attr_get->at_ctim => attr_set.at_ctim;

lfs_file_sync(&lfs, &file) => 0;
lfs_file_close(&lfs, &file) => 0;
lfs_unmount(&lfs) => 0;
'''

0 comments on commit d8d4693

Please sign in to comment.