You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ag...@apache.org on 2021/03/23 07:34:19 UTC
[incubator-nuttx] branch master updated: fs/littlefs: Suppport the
duplication function
This is an automated email from the ASF dual-hosted git repository.
aguettouche pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new b2563b9 fs/littlefs: Suppport the duplication function
b2563b9 is described below
commit b2563b99caad661a47b66f62b0128e94d3599610
Author: Xiang Xiao <xi...@xiaomi.com>
AuthorDate: Mon Mar 22 17:39:44 2021 +0800
fs/littlefs: Suppport the duplication function
Signed-off-by: Xiang Xiao <xi...@xiaomi.com>
Change-Id: I64191bdeab3723b22476d27c44852493eed1b07e
---
fs/littlefs/lfs_vfs.c | 113 +++++++++++++++++++++++++++++++++++---------------
1 file changed, 79 insertions(+), 34 deletions(-)
diff --git a/fs/littlefs/lfs_vfs.c b/fs/littlefs/lfs_vfs.c
index 19e5792..b8f8363 100644
--- a/fs/littlefs/lfs_vfs.c
+++ b/fs/littlefs/lfs_vfs.c
@@ -44,6 +44,12 @@
* Private Types
****************************************************************************/
+struct littlefs_file_s
+{
+ struct lfs_file file;
+ int refs;
+};
+
/* This structure represents the overall mountpoint state. An instance of
* this structure is retained as inode private data on each mountpoint that
* is mounted with a littlefs filesystem.
@@ -224,7 +230,7 @@ static int littlefs_open(FAR struct file *filep, FAR const char *relpath,
int oflags, mode_t mode)
{
FAR struct littlefs_mountpt_s *fs;
- FAR struct lfs_file *priv;
+ FAR struct littlefs_file_s *priv;
FAR struct inode *inode;
int ret;
@@ -243,6 +249,8 @@ static int littlefs_open(FAR struct file *filep, FAR const char *relpath,
return -ENOMEM;
}
+ priv->refs = 1;
+
/* Take the semaphore */
ret = littlefs_semtake(fs);
@@ -254,7 +262,7 @@ static int littlefs_open(FAR struct file *filep, FAR const char *relpath,
/* Try to open the file */
oflags = littlefs_convert_oflags(oflags);
- ret = lfs_file_open(&fs->lfs, priv, relpath, oflags);
+ ret = lfs_file_open(&fs->lfs, &priv->file, relpath, oflags);
if (ret < 0)
{
/* Error opening file */
@@ -268,7 +276,7 @@ static int littlefs_open(FAR struct file *filep, FAR const char *relpath,
if (oflags & LFS_O_APPEND)
{
- ret = lfs_file_seek(&fs->lfs, priv, 0, LFS_SEEK_END);
+ ret = lfs_file_seek(&fs->lfs, &priv->file, 0, LFS_SEEK_END);
if (ret >= 0)
{
filep->f_pos = ret;
@@ -283,8 +291,7 @@ static int littlefs_open(FAR struct file *filep, FAR const char *relpath,
* e.g. total 8M, fileA 6M, O_TRUNC re-wrting fileA 6M, meet error.
*/
- lfs_file_sync(&fs->lfs, priv);
-
+ lfs_file_sync(&fs->lfs, &priv->file);
littlefs_semgive(fs);
/* Attach the private date to the struct file instance */
@@ -293,7 +300,7 @@ static int littlefs_open(FAR struct file *filep, FAR const char *relpath,
return OK;
errout_with_file:
- lfs_file_close(&fs->lfs, priv);
+ lfs_file_close(&fs->lfs, &priv->file);
errout:
littlefs_semgive(fs);
errsem:
@@ -308,7 +315,7 @@ errsem:
static int littlefs_close(FAR struct file *filep)
{
FAR struct littlefs_mountpt_s *fs;
- FAR struct lfs_file *priv;
+ FAR struct littlefs_file_s *priv;
FAR struct inode *inode;
int ret;
@@ -323,16 +330,20 @@ static int littlefs_close(FAR struct file *filep)
ret = littlefs_semtake(fs);
if (ret < 0)
{
- goto errsem;
+ return ret;
}
- lfs_file_close(&fs->lfs, priv);
- littlefs_semgive(fs);
+ if (--priv->refs <= 0)
+ {
+ lfs_file_close(&fs->lfs, &priv->file);
+ }
- /* Now free the pointer */
+ littlefs_semgive(fs);
+ if (priv->refs <= 0)
+ {
+ kmm_free(priv);
+ }
-errsem:
- kmm_free(priv);
return OK;
}
@@ -344,7 +355,7 @@ static ssize_t littlefs_read(FAR struct file *filep, FAR char *buffer,
size_t buflen)
{
FAR struct littlefs_mountpt_s *fs;
- FAR struct lfs_file *priv;
+ FAR struct littlefs_file_s *priv;
FAR struct inode *inode;
ssize_t ret;
@@ -362,14 +373,23 @@ static ssize_t littlefs_read(FAR struct file *filep, FAR char *buffer,
return ret;
}
- ret = lfs_file_read(&fs->lfs, priv, buffer, buflen);
+ if (filep->f_pos != priv->file.pos)
+ {
+ ret = lfs_file_seek(&fs->lfs, &priv->file, filep->f_pos, LFS_SEEK_SET);
+ if (ret < 0)
+ {
+ goto out;
+ }
+ }
+
+ ret = lfs_file_read(&fs->lfs, &priv->file, buffer, buflen);
if (ret > 0)
{
filep->f_pos += ret;
}
+out:
littlefs_semgive(fs);
-
return ret;
}
@@ -381,7 +401,7 @@ static ssize_t littlefs_write(FAR struct file *filep, const char *buffer,
size_t buflen)
{
FAR struct littlefs_mountpt_s *fs;
- FAR struct lfs_file *priv;
+ FAR struct littlefs_file_s *priv;
FAR struct inode *inode;
ssize_t ret;
@@ -399,14 +419,23 @@ static ssize_t littlefs_write(FAR struct file *filep, const char *buffer,
return ret;
}
- ret = lfs_file_write(&fs->lfs, priv, buffer, buflen);
+ if (filep->f_pos != priv->file.pos)
+ {
+ ret = lfs_file_seek(&fs->lfs, &priv->file, filep->f_pos, LFS_SEEK_SET);
+ if (ret < 0)
+ {
+ goto out;
+ }
+ }
+
+ ret = lfs_file_write(&fs->lfs, &priv->file, buffer, buflen);
if (ret > 0)
{
filep->f_pos += ret;
}
+out:
littlefs_semgive(fs);
-
return ret;
}
@@ -417,7 +446,7 @@ static ssize_t littlefs_write(FAR struct file *filep, const char *buffer,
static off_t littlefs_seek(FAR struct file *filep, off_t offset, int whence)
{
FAR struct littlefs_mountpt_s *fs;
- FAR struct lfs_file *priv;
+ FAR struct littlefs_file_s *priv;
FAR struct inode *inode;
off_t ret;
@@ -435,14 +464,13 @@ static off_t littlefs_seek(FAR struct file *filep, off_t offset, int whence)
return ret;
}
- ret = lfs_file_seek(&fs->lfs, priv, offset, whence);
+ ret = lfs_file_seek(&fs->lfs, &priv->file, offset, whence);
if (ret >= 0)
{
filep->f_pos = ret;
}
littlefs_semgive(fs);
-
return ret;
}
@@ -483,7 +511,7 @@ static int littlefs_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
static int littlefs_sync(FAR struct file *filep)
{
FAR struct littlefs_mountpt_s *fs;
- FAR struct lfs_file *priv;
+ FAR struct littlefs_file_s *priv;
FAR struct inode *inode;
int ret;
@@ -499,7 +527,7 @@ static int littlefs_sync(FAR struct file *filep)
return ret;
}
- ret = lfs_file_sync(&fs->lfs, priv);
+ ret = lfs_file_sync(&fs->lfs, &priv->file);
littlefs_semgive(fs);
return ret;
@@ -514,7 +542,28 @@ static int littlefs_sync(FAR struct file *filep)
static int littlefs_dup(FAR const struct file *oldp, FAR struct file *newp)
{
- return -ENOSYS;
+ FAR struct littlefs_mountpt_s *fs;
+ FAR struct littlefs_file_s *priv;
+ FAR struct inode *inode;
+ int ret;
+
+ /* Recover our private data from the struct file instance */
+
+ priv = oldp->f_priv;
+ inode = oldp->f_inode;
+ fs = inode->i_private;
+
+ ret = littlefs_semtake(fs);
+ if (ret < 0)
+ {
+ return ret;
+ }
+
+ priv->refs++;
+ newp->f_priv = priv;
+ littlefs_semgive(fs);
+
+ return ret;
}
/****************************************************************************
@@ -529,7 +578,7 @@ static int littlefs_dup(FAR const struct file *oldp, FAR struct file *newp)
static int littlefs_fstat(FAR const struct file *filep, FAR struct stat *buf)
{
FAR struct littlefs_mountpt_s *fs;
- FAR struct lfs_file *priv;
+ FAR struct littlefs_file_s *priv;
FAR struct inode *inode;
int ret;
@@ -549,7 +598,7 @@ static int littlefs_fstat(FAR const struct file *filep, FAR struct stat *buf)
return ret;
}
- buf->st_size = lfs_file_size(&fs->lfs, priv);
+ buf->st_size = lfs_file_size(&fs->lfs, &priv->file);
littlefs_semgive(fs);
if (buf->st_size < 0)
@@ -576,7 +625,7 @@ static int littlefs_fstat(FAR const struct file *filep, FAR struct stat *buf)
static int littlefs_truncate(FAR struct file *filep, off_t length)
{
FAR struct littlefs_mountpt_s *fs;
- FAR struct lfs_file *priv;
+ FAR struct littlefs_file_s *priv;
FAR struct inode *inode;
int ret;
@@ -594,7 +643,7 @@ static int littlefs_truncate(FAR struct file *filep, off_t length)
return ret;
}
- ret = lfs_file_truncate(&fs->lfs, priv, length);
+ ret = lfs_file_truncate(&fs->lfs, &priv->file, length);
littlefs_semgive(fs);
return ret;
@@ -680,13 +729,12 @@ static int littlefs_closedir(FAR struct inode *mountpt,
ret = littlefs_semtake(fs);
if (ret < 0)
{
- goto errsem;
+ return ret;
}
lfs_dir_close(&fs->lfs, priv);
littlefs_semgive(fs);
-errsem:
kmm_free(priv);
return OK;
}
@@ -740,7 +788,6 @@ static int littlefs_readdir(FAR struct inode *mountpt,
}
littlefs_semgive(fs);
-
return ret;
}
@@ -778,7 +825,6 @@ static int littlefs_rewinddir(FAR struct inode *mountpt,
}
littlefs_semgive(fs);
-
return ret;
}
@@ -1135,7 +1181,6 @@ static int littlefs_statfs(FAR struct inode *mountpt, FAR struct statfs *buf)
}
littlefs_semgive(fs);
-
return ret;
}