Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions lfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -3180,8 +3180,6 @@ static int lfs_file_opencfg_(lfs_t *lfs, lfs_file_t *file,
err = LFS_ERR_NOSPC;
goto cleanup;
}

file->flags |= LFS_F_DIRTY;
}
#endif
}
Expand Down Expand Up @@ -3441,7 +3439,9 @@ static int lfs_file_sync_(lfs_t *lfs, lfs_file_t *file) {
}


if ((file->flags & LFS_F_DIRTY) &&
if (((file->flags & LFS_F_DIRTY) ||
(/* User request attributes write */(file->cfg->attr_count > 0) && (file->flags & LFS_O_WRONLY)))
&&
!lfs_pair_isnull(file->m.pair)) {
// before we commit metadata, we need sync the disk to make sure
// data writes don't complete after metadata writes
Expand Down
6 changes: 3 additions & 3 deletions lfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -351,9 +351,9 @@ struct lfs_file_config {
// Optional list of custom attributes related to the file. If the file
// is opened with read access, these attributes will be read from disk
// during the open call. If the file is opened with write access, the
// attributes will be written to disk every file sync or close. This
// write occurs atomically with update to the file's contents.
//
// attributes will be written to disk every file sync or close according
// to the attr_count value and attrs content upon close. This write occurs
// atomically with update to the file's contents.
// Custom attributes are uniquely identified by an 8-bit type and limited
// to LFS_ATTR_MAX bytes. When read, if the stored attribute is smaller
// than the buffer, it will be padded with zeros. If the stored attribute
Expand Down
36 changes: 36 additions & 0 deletions tests/test_attrs.toml
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,42 @@ code = '''
memcmp(buffer, "hello", strlen("hello")) => 0;
lfs_file_close(&lfs, &file);
lfs_unmount(&lfs) => 0;

lfs_mount(&lfs, cfg) => 0;
struct lfs_attr attrs4[] = {
{'A', buffer, 4},
};
memset(buffer, 'a', sizeof(buffer));
struct lfs_file_config cfg4 = {.attrs=attrs4};
lfs_file_open(&lfs, &file, "hello/hello2", LFS_O_WRONLY | LFS_O_CREAT) => 0;
lfs_file_close(&lfs, &file);


cfg4.attr_count = 1;
lfs_file_opencfg(&lfs, &file, "hello/hello2", LFS_O_WRONLY | LFS_O_RDONLY, &cfg4) => 0;
lfs_off_t origin_file_metadata_offset = file.m.off;
cfg4.attr_count = 0;
lfs_file_sync(&lfs, &file); // No write expected, although that upon opening attr_count was 1
lfs_getattr(&lfs, "hello/hello2", 'A', buffer, 4) => LFS_ERR_NOATTR;
(file.m.off != origin_file_metadata_offset) => 0; // expecten no write to happen
cfg4.attr_count = 1;
lfs_file_sync(&lfs, &file); // attributes expected to be written because attr_count is 1, although no write happened
lfs_getattr(&lfs, "hello/hello2", 'A', buffer, 4) => 4;
lfs_file_close(&lfs, &file);

memset(buffer, 'b', sizeof(buffer));
cfg4.attr_count = 1;
lfs_file_opencfg(&lfs, &file, "hello/hello3", LFS_O_WRONLY | LFS_O_CREAT, &cfg4) => 0;
lfs_file_sync(&lfs, &file);
lfs_getattr(&lfs, "hello/hello3", 'A', buffer, 4) => 4;
memcmp(buffer, "bbbb", 4) => 0;
memset(buffer, 'c', sizeof(buffer));
lfs_file_sync(&lfs, &file); // attributes expected to be re-written because attr_count is still 1, although no write happened
lfs_getattr(&lfs, "hello/hello3", 'A', buffer, 4) => 4;
memcmp(buffer, "cccc", 4) => 0;
lfs_file_close(&lfs, &file);
lfs_unmount(&lfs) => 0;

'''

[cases.test_attrs_deferred_file]
Expand Down