瀏覽代碼

Updated custom attribute documentation and tweaked nonexistant attributes

Because of limitations in how littlefs manages attributes on disk,
littlefs views zero-length attributes and missing attributes as the same
thing. The simpliest implementation of attributes mirrors this behaviour
transparently for the user.
Christopher Haster 7 年之前
父節點
當前提交
a88230ae6a
共有 3 個文件被更改,包括 59 次插入50 次删除
  1. 3 9
      lfs.c
  2. 55 40
      lfs.h
  3. 1 1
      tests/test_attrs.sh

+ 3 - 9
lfs.c

@@ -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,

+ 55 - 40
lfs.h

@@ -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

+ 1 - 1
tests/test_attrs.sh

@@ -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;