mirror of
https://github.com/apache/nuttx.git
synced 2026-06-01 07:45:16 +08:00
fs/littlefs: revert fstat and use lfs_file_attr function
Signed-off-by: zhouliang3 <zhouliang3@xiaomi.com>
This commit is contained in:
@@ -31,8 +31,10 @@ if(CONFIG_FS_LITTLEFS)
|
|||||||
${CMAKE_BINARY_DIR}/fs/littlefs/littlefs
|
${CMAKE_BINARY_DIR}/fs/littlefs/littlefs
|
||||||
PATCH_COMMAND
|
PATCH_COMMAND
|
||||||
patch -p2 -d ${CMAKE_CURRENT_LIST_DIR} <
|
patch -p2 -d ${CMAKE_CURRENT_LIST_DIR} <
|
||||||
${CMAKE_CURRENT_LIST_DIR}/lfs_util.patch COMMAND patch -p2 -d
|
${CMAKE_CURRENT_LIST_DIR}/lfs_util.patch && patch -p2 -d
|
||||||
${CMAKE_CURRENT_LIST_DIR} < ${CMAKE_CURRENT_LIST_DIR}/lfs_getpath.patch)
|
${CMAKE_CURRENT_LIST_DIR} < ${CMAKE_CURRENT_LIST_DIR}/lfs_getpath.patch
|
||||||
|
&& patch -p2 -d ${CMAKE_CURRENT_LIST_DIR} <
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/lfs_getsetattr.patch)
|
||||||
FetchContent_MakeAvailable(littlefs)
|
FetchContent_MakeAvailable(littlefs)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ $(LITTLEFS_TARBALL):
|
|||||||
$(Q) mv littlefs/littlefs-$(LITTLEFS_VERSION) littlefs/littlefs
|
$(Q) mv littlefs/littlefs-$(LITTLEFS_VERSION) littlefs/littlefs
|
||||||
$(Q) git apply littlefs/lfs_util.patch
|
$(Q) git apply littlefs/lfs_util.patch
|
||||||
$(Q) git apply littlefs/lfs_getpath.patch
|
$(Q) git apply littlefs/lfs_getpath.patch
|
||||||
|
$(Q) git apply littlefs/lfs_getsetattr.patch
|
||||||
$(Q) touch littlefs/.littlefsunpack
|
$(Q) touch littlefs/.littlefsunpack
|
||||||
|
|
||||||
# Download and unpack tarball if no git repo found
|
# Download and unpack tarball if no git repo found
|
||||||
|
|||||||
@@ -0,0 +1,80 @@
|
|||||||
|
--- ./littlefs/littlefs/lfs.c
|
||||||
|
+++ ./littlefs/littlefs/lfs.c
|
||||||
|
@@ -5717,6 +5717,41 @@ int lfs_file_path(lfs_t *lfs, lfs_file_t *file, char *path, lfs_size_t size) {
|
||||||
|
return err < 0 ? err : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+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));
|
||||||
|
+
|
||||||
|
+ return 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);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#ifndef LFS_READONLY
|
||||||
|
+int lfs_file_setattr(lfs_t *lfs, lfs_file_t *file,
|
||||||
|
+ uint8_t type, const void *buffer, lfs_size_t size)
|
||||||
|
+{
|
||||||
|
+ int err = LFS_LOCK(lfs->cfg);
|
||||||
|
+ if (err) {
|
||||||
|
+ return err;
|
||||||
|
+ }
|
||||||
|
+ LFS_TRACE("lfs_file_getattr(%p, %p)", (void*)lfs, (void*)file);
|
||||||
|
+ LFS_TRACE("lfs_file_getattr(%"PRIu8", %p, %"PRIu32")",
|
||||||
|
+ type, buffer, size);
|
||||||
|
+ LFS_ASSERT(lfs_mlist_isopen(lfs->mlist, (struct lfs_mlist*)file));
|
||||||
|
+
|
||||||
|
+ return lfs_dir_commit(lfs, &file->m, LFS_MKATTRS(
|
||||||
|
+ {LFS_MKTAG(LFS_TYPE_USERATTR + type, file->id, size), buffer}));
|
||||||
|
+}
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
#ifndef LFS_READONLY
|
||||||
|
int lfs_mkdir(lfs_t *lfs, const char *path) {
|
||||||
|
int err = LFS_LOCK(lfs->cfg);
|
||||||
|
--- ./littlefs/littlefs/lfs.h
|
||||||
|
+++ ./littlefs/littlefs/lfs.h
|
||||||
|
@@ -611,6 +611,33 @@ lfs_soff_t lfs_file_size(lfs_t *lfs, lfs_file_t *file);
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfs_file_path(lfs_t *lfs, lfs_file_t *file, char *path, lfs_size_t size);
|
||||||
|
|
||||||
|
+// Get a custom attribute of file
|
||||||
|
+//
|
||||||
|
+// 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 no attribute is found, the error
|
||||||
|
+// LFS_ERR_NOATTR is returned and the buffer is filled with zeros.
|
||||||
|
+//
|
||||||
|
+// 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_file_getattr(lfs_t *lfs, lfs_file_t *file,
|
||||||
|
+ uint8_t type, void *buffer, lfs_size_t size);
|
||||||
|
+
|
||||||
|
+// Set custom attributes of file
|
||||||
|
+//
|
||||||
|
+// 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.
|
||||||
|
+//
|
||||||
|
+// Returns a negative error code on failure.
|
||||||
|
+#ifndef LFS_READONLY
|
||||||
|
+int lfs_file_setattr(lfs_t *lfs, lfs_file_t *file,
|
||||||
|
+ uint8_t type, const void *buffer, lfs_size_t size);
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
/// Directory operations ///
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
+92
-27
@@ -726,6 +726,7 @@ static int littlefs_fstat(FAR const struct file *filep, FAR struct stat *buf)
|
|||||||
FAR struct littlefs_mountpt_s *fs;
|
FAR struct littlefs_mountpt_s *fs;
|
||||||
FAR struct littlefs_file_s *priv;
|
FAR struct littlefs_file_s *priv;
|
||||||
FAR struct inode *inode;
|
FAR struct inode *inode;
|
||||||
|
struct littlefs_attr_s attr;
|
||||||
char path[LFS_NAME_MAX];
|
char path[LFS_NAME_MAX];
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@@ -745,20 +746,43 @@ static int littlefs_fstat(FAR const struct file *filep, FAR struct stat *buf)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = lfs_file_path(&fs->lfs, &priv->file, path, sizeof(path));
|
buf->st_size = lfs_file_size(&fs->lfs, &priv->file);
|
||||||
|
if (buf->st_size < 0)
|
||||||
|
{
|
||||||
|
ret = littlefs_convert_result(buf->st_size);
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = littlefs_convert_result(lfs_file_getattr(&fs->lfs, &priv->file, 0,
|
||||||
|
&attr, sizeof(attr)));
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
if (ret != -ENODATA)
|
||||||
|
{
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&attr, 0, sizeof(attr));
|
||||||
|
attr.at_mode = S_IRWXG | S_IRWXU | S_IRWXO;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
buf->st_mode = attr.at_mode | S_IFREG;
|
||||||
|
buf->st_uid = attr.at_uid;
|
||||||
|
buf->st_gid = attr.at_gid;
|
||||||
|
buf->st_atim.tv_sec = attr.at_atim / 1000000000ull;
|
||||||
|
buf->st_atim.tv_nsec = attr.at_atim % 1000000000ull;
|
||||||
|
buf->st_mtim.tv_sec = attr.at_mtim / 1000000000ull;
|
||||||
|
buf->st_mtim.tv_nsec = attr.at_mtim % 1000000000ull;
|
||||||
|
buf->st_ctim.tv_sec = attr.at_ctim / 1000000000ull;
|
||||||
|
buf->st_ctim.tv_nsec = attr.at_ctim % 1000000000ull;
|
||||||
|
buf->st_blksize = fs->cfg.block_size;
|
||||||
|
buf->st_blocks = (buf->st_size + buf->st_blksize - 1) /
|
||||||
|
buf->st_blksize;
|
||||||
|
|
||||||
|
errout:
|
||||||
nxmutex_unlock(&fs->lock);
|
nxmutex_unlock(&fs->lock);
|
||||||
if (ret < 0)
|
return ret;
|
||||||
{
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = littlefs_stat(inode, path, buf);
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
return OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int littlefs_fchstat(FAR const struct file *filep,
|
static int littlefs_fchstat(FAR const struct file *filep,
|
||||||
@@ -767,6 +791,7 @@ static int littlefs_fchstat(FAR const struct file *filep,
|
|||||||
FAR struct littlefs_mountpt_s *fs;
|
FAR struct littlefs_mountpt_s *fs;
|
||||||
FAR struct littlefs_file_s *priv;
|
FAR struct littlefs_file_s *priv;
|
||||||
FAR struct inode *inode;
|
FAR struct inode *inode;
|
||||||
|
struct littlefs_attr_s attr;
|
||||||
char path[LFS_NAME_MAX];
|
char path[LFS_NAME_MAX];
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@@ -784,20 +809,59 @@ static int littlefs_fchstat(FAR const struct file *filep,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = lfs_file_path(&fs->lfs, &priv->file, path, sizeof(path));
|
ret = littlefs_convert_result(lfs_file_getattr(&fs->lfs, &priv->file,
|
||||||
|
0, &attr, sizeof(attr)));
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
if (ret != -ENODATA)
|
||||||
|
{
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&attr, 0, sizeof(attr));
|
||||||
|
attr.at_mode = S_IRWXG | S_IRWXU | S_IRWXO;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((CH_STAT_MODE & flags) == CH_STAT_MODE)
|
||||||
|
{
|
||||||
|
attr.at_mode = buf->st_mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((CH_STAT_UID & flags) == CH_STAT_UID)
|
||||||
|
{
|
||||||
|
attr.at_uid = buf->st_uid;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((CH_STAT_GID & flags) == CH_STAT_GID)
|
||||||
|
{
|
||||||
|
attr.at_gid = buf->st_gid;
|
||||||
|
}
|
||||||
|
|
||||||
|
attr.at_ctim = 1000000000ull * buf->st_ctim.tv_sec +
|
||||||
|
buf->st_ctim.tv_nsec;
|
||||||
|
|
||||||
|
if ((CH_STAT_ATIME & flags) == CH_STAT_ATIME)
|
||||||
|
{
|
||||||
|
attr.at_atim = 1000000000ull * buf->st_atim.tv_sec +
|
||||||
|
buf->st_atim.tv_nsec;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((CH_STAT_MTIME & flags) == CH_STAT_MTIME)
|
||||||
|
{
|
||||||
|
attr.at_mtim = 1000000000ull * buf->st_mtim.tv_sec +
|
||||||
|
buf->st_mtim.tv_nsec;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = littlefs_convert_result(lfs_file_setattr(&fs->lfs, &priv->file, 0,
|
||||||
|
&attr, sizeof(attr)));
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
|
||||||
|
errout:
|
||||||
nxmutex_unlock(&fs->lock);
|
nxmutex_unlock(&fs->lock);
|
||||||
if (ret < 0)
|
return ret;
|
||||||
{
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = littlefs_chstat(inode, path, buf, flags);
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
return OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -1587,7 +1651,6 @@ static int littlefs_stat(FAR struct inode *mountpt, FAR const char *relpath,
|
|||||||
buf->st_mtim.tv_nsec = attr.at_mtim % 1000000000ull;
|
buf->st_mtim.tv_nsec = attr.at_mtim % 1000000000ull;
|
||||||
buf->st_ctim.tv_sec = attr.at_ctim / 1000000000ull;
|
buf->st_ctim.tv_sec = attr.at_ctim / 1000000000ull;
|
||||||
buf->st_ctim.tv_nsec = attr.at_ctim % 1000000000ull;
|
buf->st_ctim.tv_nsec = attr.at_ctim % 1000000000ull;
|
||||||
buf->st_size = info.size;
|
|
||||||
buf->st_blksize = fs->cfg.block_size;
|
buf->st_blksize = fs->cfg.block_size;
|
||||||
buf->st_blocks = (buf->st_size + buf->st_blksize - 1) /
|
buf->st_blocks = (buf->st_size + buf->st_blksize - 1) /
|
||||||
buf->st_blksize;
|
buf->st_blksize;
|
||||||
@@ -1595,10 +1658,12 @@ static int littlefs_stat(FAR struct inode *mountpt, FAR const char *relpath,
|
|||||||
if (info.type == LFS_TYPE_REG)
|
if (info.type == LFS_TYPE_REG)
|
||||||
{
|
{
|
||||||
buf->st_mode |= S_IFREG;
|
buf->st_mode |= S_IFREG;
|
||||||
|
buf->st_size = info.size;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
buf->st_mode |= S_IFDIR;
|
buf->st_mode |= S_IFDIR;
|
||||||
|
buf->st_size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
errout:
|
errout:
|
||||||
|
|||||||
Reference in New Issue
Block a user