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