WIP Documented custom attribute API and changed behaviour around

nonexisting attributes
This commit is contained in:
Christopher Haster
2018-08-04 19:23:49 -05:00
parent c3480c8c92
commit 2f73652937
3 changed files with 59 additions and 50 deletions

12
lfs.c
View File

@@ -2651,14 +2651,11 @@ lfs_ssize_t lfs_getattr(lfs_t *lfs, const char *path,
res = lfs_dir_get(lfs, &cwd, 0x7ffff000,
LFS_MKTAG(0x100 | type, lfs_tagid(res),
lfs_min(size, lfs->attr_size)), buffer);
if (res < 0) {
if (res == LFS_ERR_NOENT) {
return LFS_ERR_NOATTR;
}
if (res < 0 && res != LFS_ERR_NOENT) {
return res;
}
return lfs_tagsize(res);
return (res == LFS_ERR_NOENT) ? 0 : lfs_tagsize(res);
}
int lfs_setattr(lfs_t *lfs, const char *path,
@@ -3270,13 +3267,10 @@ lfs_ssize_t lfs_fs_getattr(lfs_t *lfs,
LFS_MKTAG(0x100 | type, 0,
lfs_min(size, lfs->attr_size)), buffer);
if (res < 0) {
if (res == LFS_ERR_NOENT) {
return LFS_ERR_NOATTR;
}
return res;
}
return lfs_tagsize(res);
return (res == LFS_ERR_NOENT) ? 0 : lfs_tagsize(res);
}
int lfs_fs_setattr(lfs_t *lfs,

95
lfs.h
View File

@@ -89,7 +89,6 @@ enum lfs_error {
LFS_ERR_NOSPC = -28, // No space left on device
LFS_ERR_NOMEM = -12, // No more memory available
LFS_ERR_NAMETOOLONG = -36, // File name too long
LFS_ERR_NOATTR = -61, // No data/attr available
};
// File types
@@ -248,7 +247,7 @@ struct lfs_info {
// Custom attribute structure
struct lfs_attr {
// 8-bit Type of attribute, provided by user and used to
// 8-bit type of attribute, provided by user and used to
// identify the attribute
uint8_t type;
@@ -268,8 +267,17 @@ struct lfs_file_config {
// If NULL, malloc will be used by default.
void *buffer;
// Optional, linked list of custom attributes.
// TODO document more
// Optional, linked list of custom attributes related to the file. If the
// file is opened with read access, the attributes will be read from
// 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.
//
// 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
// is larger, then it will be silently truncated. If the attribute is not
// found, it will be created implicitly.
struct lfs_attr *attrs;
};
@@ -436,24 +444,27 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath);
// Returns a negative error code on failure.
int lfs_stat(lfs_t *lfs, const char *path, struct lfs_info *info);
// Get custom attributes
// Get a custom attribute
//
// Attributes are looked up based on the type id. If the stored attribute is
// smaller than the buffer, it is padded with zeros. It the stored attribute
// is larger than the buffer, LFS_ERR_RANGE is returned.
// 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 is larger,
// then it will be silently truncated.
//
// TODO doc
// Returns a negative error code on failure.
// Returns the size of the attribute, or a negative error code on failure.
// Note, the returned size is the size of the attribute on disk, irrespective
// of the size of the buffer. This can be used to dynamically allocate a buffer
// or check for existance.
lfs_ssize_t lfs_getattr(lfs_t *lfs, const char *path,
uint8_t type, void *buffer, lfs_size_t size);
// Set custom attributes
//
// The array of attributes will be used to update the attributes stored on
// disk based on their type id. Unspecified attributes are left unmodified.
// Specifying an attribute with zero size deletes the attribute.
// Custom attributes are uniquely identified by an 8-bit type and limited
// to LFS_ATTR_MAX bytes. If an attribute is not found, it will be
// implicitly created, and setting the size of an attribute to zero deletes
// the attribute.
//
// TODO doc
// Returns a negative error code on failure.
int lfs_setattr(lfs_t *lfs, const char *path,
uint8_t type, const void *buffer, lfs_size_t size);
@@ -593,32 +604,7 @@ lfs_soff_t lfs_dir_tell(lfs_t *lfs, lfs_dir_t *dir);
int lfs_dir_rewind(lfs_t *lfs, lfs_dir_t *dir);
/// Filesystem filesystem operations /// TODO choose one
/// Miscellaneous littlefs specific operations /// TODO choose one
// Get custom attributes on the filesystem
//
// Attributes are looked up based on the type id. If the stored attribute is
// smaller than the buffer, it is padded with zeros. It the stored attribute
// is larger than the buffer, LFS_ERR_RANGE is returned.
//
// TODO doc
// Returns a negative error code on failure.
lfs_ssize_t lfs_fs_getattr(lfs_t *lfs,
uint8_t type, void *buffer, lfs_size_t size);
// Set custom attributes on the filesystem
//
// The array of attributes will be used to update the attributes stored on
// disk based on their type id. Unspecified attributes are left unmodified.
// Specifying an attribute with zero size deletes the attribute.
//
// Note: Filesystem level attributes are not available for wear-leveling
//
// TODO doc
// Returns a negative error code on failure.
int lfs_fs_setattr(lfs_t *lfs,
uint8_t type, const void *buffer, lfs_size_t size);
/// Filesystem-level filesystem operations
// Finds the current size of the filesystem
//
@@ -637,5 +623,34 @@ lfs_ssize_t lfs_fs_size(lfs_t *lfs);
// Returns a negative error code on failure.
int lfs_fs_traverse(lfs_t *lfs, int (*cb)(void*, lfs_block_t), void *data);
// Get custom attributes on the filesystem
//
// 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 is larger,
// then it will be silently truncated.
//
// Note, filesystem-level attributes are not available for wear-leveling
//
// Returns the size of the attribute, or a negative error code on failure.
// Note, the returned size is the size of the attribute on disk, irrespective
// of the size of the buffer. This can be used to dynamically allocate a buffer
// or check for existance.
lfs_ssize_t lfs_fs_getattr(lfs_t *lfs,
uint8_t type, void *buffer, lfs_size_t size);
// Set custom attributes on the filesystem
//
// Custom attributes are uniquely identified by an 8-bit type and limited
// to LFS_ATTR_MAX bytes. If an attribute is not found, it will be
// implicitly created, and setting the size of an attribute to zero deletes
// the attribute.
//
// Note, filesystem-level attributes are not available for wear-leveling
//
// Returns a negative error code on failure.
int lfs_fs_setattr(lfs_t *lfs,
uint8_t type, const void *buffer, lfs_size_t size);
#endif

View File

@@ -241,7 +241,7 @@ tests/test.py << TEST
lfs_getattr(&lfs, "hello/hello", 'B', buffer, 9) => 9;
lfs_getattr(&lfs, "hello/hello", 'C', buffer+9, 9) => 5;
lfs_getattr(&lfs, "hello/hello", 'D', buffer+18, 9) => LFS_ERR_NOATTR;
lfs_getattr(&lfs, "hello/hello", 'D', buffer+18, 9) => 0;
memcmp(buffer, "fffffffff", 9) => 0;
memcmp(buffer+9, "ccccc\0\0\0\0", 9) => 0;
memcmp(buffer+18, "\0\0\0\0\0\0\0\0\0", 9) => 0;