Skip to content

Commit 3d89cd5

Browse files
committed
lfs:Added lfs_file_getattr interface
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]>
1 parent d01280e commit 3d89cd5

File tree

3 files changed

+87
-0
lines changed

3 files changed

+87
-0
lines changed

lfs.c

+32
Original file line numberDiff line numberDiff line change
@@ -6235,6 +6235,38 @@ lfs_soff_t lfs_file_size(lfs_t *lfs, lfs_file_t *file) {
62356235
return res;
62366236
}
62376237

6238+
lfs_ssize_t lfs_file_getattr(lfs_t *lfs, lfs_file_t *file,
6239+
uint8_t type, void *buffer, lfs_size_t size)
6240+
{
6241+
int err = LFS_LOCK(lfs->cfg);
6242+
if (err) {
6243+
return err;
6244+
}
6245+
LFS_TRACE("lfs_file_setattr(%p, %p)", (void*)lfs, (void*)file);
6246+
LFS_TRACE("lfs_file_setattr(%"PRIu8", %p, %"PRIu32")",
6247+
type, buffer, size);
6248+
LFS_ASSERT(lfs_mlist_isopen(lfs->mlist, (struct lfs_mlist*)file));
6249+
6250+
if (file->cfg && file->cfg->attrs) {
6251+
for (unsigned i = 0; i < file->cfg->attr_count; i++) {
6252+
const struct lfs_attr *attr = &file->cfg->attrs[i];
6253+
if (attr->type == LFS_TYPE_USERATTR + type) {
6254+
lfs_size_t attr_size = lfs_min(size, attr->size);
6255+
memcpy(buffer, attr->buffer, attr_size);
6256+
LFS_UNLOCK(lfs->cfg);
6257+
return 0;
6258+
}
6259+
}
6260+
}
6261+
6262+
int res = lfs_dir_get(lfs, &file->m,
6263+
LFS_MKTAG(0x7ff, 0x3ff, 0),
6264+
LFS_MKTAG(LFS_TYPE_USERATTR + type,
6265+
file->id, lfs_min(size, lfs->attr_max)), buffer);
6266+
LFS_UNLOCK(lfs->cfg);
6267+
return (res < 0) ? LFS_ERR_NOATTR : 0;
6268+
}
6269+
62386270
#ifndef LFS_READONLY
62396271
int lfs_mkdir(lfs_t *lfs, const char *path) {
62406272
int err = LFS_LOCK(lfs->cfg);

lfs.h

+7
Original file line numberDiff line numberDiff line change
@@ -656,6 +656,13 @@ int lfs_file_rewind(lfs_t *lfs, lfs_file_t *file);
656656
// Returns the size of the file, or a negative error code on failure.
657657
lfs_soff_t lfs_file_size(lfs_t *lfs, lfs_file_t *file);
658658

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

660667
/// Directory operations ///
661668

tests/test_attrs.toml

+48
Original file line numberDiff line numberDiff line change
@@ -314,3 +314,51 @@ code = '''
314314
lfs_file_close(&lfs, &file) => 0;
315315
lfs_unmount(&lfs) => 0;
316316
'''
317+
318+
[cases.test_file_getattr]
319+
code = '''
320+
struct lfs_attr_s {
321+
uint32_t at_ver;
322+
uint32_t at_mode;
323+
uint32_t at_uid;
324+
uint32_t at_gid;
325+
uint64_t at_atim;
326+
uint64_t at_mtim;
327+
uint64_t at_ctim;
328+
};
329+
330+
lfs_t lfs;
331+
lfs_format(&lfs, cfg) => 0;
332+
lfs_mount(&lfs, cfg) => 0;
333+
334+
lfs_file_t file;
335+
struct lfs_attr_s attr_get[1024];
336+
memset(attr_get, 0, sizeof(attr_get));
337+
lfs_file_open(&lfs, &file, "hello", LFS_O_WRONLY | LFS_O_CREAT) => 0;
338+
lfs_file_write(&lfs, &file, "world", strlen("world")) => strlen("world");
339+
lfs_file_getattr(&lfs, &file, 0, attr_get, sizeof(struct lfs_attr_s)) => -61;
340+
341+
struct lfs_attr_s attr_set = {
342+
.at_ver = 1,
343+
.at_mode = 0644,
344+
.at_uid = 1000,
345+
.at_gid = 1000,
346+
.at_atim = 1693123456,
347+
.at_mtim = 1693123456,
348+
.at_ctim = 1693123456,
349+
};
350+
lfs_setattr(&lfs, "hello", 0, &attr_set, sizeof(attr_set)) => 0;
351+
memset(attr_get, 0, sizeof(attr_get));
352+
lfs_file_getattr(&lfs, &file, 0, attr_get, sizeof(struct lfs_attr_s)) => 0;
353+
attr_get->at_ver => attr_set.at_ver;
354+
attr_get->at_mode => attr_set.at_mode;
355+
attr_get->at_uid => attr_set.at_uid;
356+
attr_get->at_gid => attr_set.at_gid;
357+
attr_get->at_atim => attr_set.at_atim;
358+
attr_get->at_mtim => attr_set.at_mtim;
359+
attr_get->at_ctim => attr_set.at_ctim;
360+
361+
lfs_file_sync(&lfs, &file) => 0;
362+
lfs_file_close(&lfs, &file) => 0;
363+
lfs_unmount(&lfs) => 0;
364+
'''

0 commit comments

Comments
 (0)