fs/littlefs: Suppport the duplication function
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com> Change-Id: I64191bdeab3723b22476d27c44852493eed1b07e
This commit is contained in:
parent
db8e498e4f
commit
b2563b99ca
@ -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;
|
||||
}
|
||||
|
||||
if (--priv->refs <= 0)
|
||||
{
|
||||
lfs_file_close(&fs->lfs, &priv->file);
|
||||
}
|
||||
|
||||
lfs_file_close(&fs->lfs, priv);
|
||||
littlefs_semgive(fs);
|
||||
if (priv->refs <= 0)
|
||||
{
|
||||
kmm_free(priv);
|
||||
}
|
||||
|
||||
/* Now free the pointer */
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user