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
|
* Private Types
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
struct littlefs_file_s
|
||||||
|
{
|
||||||
|
struct lfs_file file;
|
||||||
|
int refs;
|
||||||
|
};
|
||||||
|
|
||||||
/* This structure represents the overall mountpoint state. An instance of
|
/* This structure represents the overall mountpoint state. An instance of
|
||||||
* this structure is retained as inode private data on each mountpoint that
|
* this structure is retained as inode private data on each mountpoint that
|
||||||
* is mounted with a littlefs filesystem.
|
* 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)
|
int oflags, mode_t mode)
|
||||||
{
|
{
|
||||||
FAR struct littlefs_mountpt_s *fs;
|
FAR struct littlefs_mountpt_s *fs;
|
||||||
FAR struct lfs_file *priv;
|
FAR struct littlefs_file_s *priv;
|
||||||
FAR struct inode *inode;
|
FAR struct inode *inode;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -243,6 +249,8 @@ static int littlefs_open(FAR struct file *filep, FAR const char *relpath,
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
priv->refs = 1;
|
||||||
|
|
||||||
/* Take the semaphore */
|
/* Take the semaphore */
|
||||||
|
|
||||||
ret = littlefs_semtake(fs);
|
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 */
|
/* Try to open the file */
|
||||||
|
|
||||||
oflags = littlefs_convert_oflags(oflags);
|
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)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
/* Error opening file */
|
/* Error opening file */
|
||||||
@ -268,7 +276,7 @@ static int littlefs_open(FAR struct file *filep, FAR const char *relpath,
|
|||||||
|
|
||||||
if (oflags & LFS_O_APPEND)
|
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)
|
if (ret >= 0)
|
||||||
{
|
{
|
||||||
filep->f_pos = ret;
|
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.
|
* 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);
|
littlefs_semgive(fs);
|
||||||
|
|
||||||
/* Attach the private date to the struct file instance */
|
/* 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;
|
return OK;
|
||||||
|
|
||||||
errout_with_file:
|
errout_with_file:
|
||||||
lfs_file_close(&fs->lfs, priv);
|
lfs_file_close(&fs->lfs, &priv->file);
|
||||||
errout:
|
errout:
|
||||||
littlefs_semgive(fs);
|
littlefs_semgive(fs);
|
||||||
errsem:
|
errsem:
|
||||||
@ -308,7 +315,7 @@ errsem:
|
|||||||
static int littlefs_close(FAR struct file *filep)
|
static int littlefs_close(FAR struct file *filep)
|
||||||
{
|
{
|
||||||
FAR struct littlefs_mountpt_s *fs;
|
FAR struct littlefs_mountpt_s *fs;
|
||||||
FAR struct lfs_file *priv;
|
FAR struct littlefs_file_s *priv;
|
||||||
FAR struct inode *inode;
|
FAR struct inode *inode;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -323,16 +330,20 @@ static int littlefs_close(FAR struct file *filep)
|
|||||||
ret = littlefs_semtake(fs);
|
ret = littlefs_semtake(fs);
|
||||||
if (ret < 0)
|
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);
|
littlefs_semgive(fs);
|
||||||
|
if (priv->refs <= 0)
|
||||||
|
{
|
||||||
|
kmm_free(priv);
|
||||||
|
}
|
||||||
|
|
||||||
/* Now free the pointer */
|
|
||||||
|
|
||||||
errsem:
|
|
||||||
kmm_free(priv);
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -344,7 +355,7 @@ static ssize_t littlefs_read(FAR struct file *filep, FAR char *buffer,
|
|||||||
size_t buflen)
|
size_t buflen)
|
||||||
{
|
{
|
||||||
FAR struct littlefs_mountpt_s *fs;
|
FAR struct littlefs_mountpt_s *fs;
|
||||||
FAR struct lfs_file *priv;
|
FAR struct littlefs_file_s *priv;
|
||||||
FAR struct inode *inode;
|
FAR struct inode *inode;
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
|
||||||
@ -362,14 +373,23 @@ static ssize_t littlefs_read(FAR struct file *filep, FAR char *buffer,
|
|||||||
return ret;
|
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)
|
if (ret > 0)
|
||||||
{
|
{
|
||||||
filep->f_pos += ret;
|
filep->f_pos += ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
littlefs_semgive(fs);
|
littlefs_semgive(fs);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -381,7 +401,7 @@ static ssize_t littlefs_write(FAR struct file *filep, const char *buffer,
|
|||||||
size_t buflen)
|
size_t buflen)
|
||||||
{
|
{
|
||||||
FAR struct littlefs_mountpt_s *fs;
|
FAR struct littlefs_mountpt_s *fs;
|
||||||
FAR struct lfs_file *priv;
|
FAR struct littlefs_file_s *priv;
|
||||||
FAR struct inode *inode;
|
FAR struct inode *inode;
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
|
||||||
@ -399,14 +419,23 @@ static ssize_t littlefs_write(FAR struct file *filep, const char *buffer,
|
|||||||
return ret;
|
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)
|
if (ret > 0)
|
||||||
{
|
{
|
||||||
filep->f_pos += ret;
|
filep->f_pos += ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
littlefs_semgive(fs);
|
littlefs_semgive(fs);
|
||||||
|
|
||||||
return ret;
|
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)
|
static off_t littlefs_seek(FAR struct file *filep, off_t offset, int whence)
|
||||||
{
|
{
|
||||||
FAR struct littlefs_mountpt_s *fs;
|
FAR struct littlefs_mountpt_s *fs;
|
||||||
FAR struct lfs_file *priv;
|
FAR struct littlefs_file_s *priv;
|
||||||
FAR struct inode *inode;
|
FAR struct inode *inode;
|
||||||
off_t ret;
|
off_t ret;
|
||||||
|
|
||||||
@ -435,14 +464,13 @@ static off_t littlefs_seek(FAR struct file *filep, off_t offset, int whence)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = lfs_file_seek(&fs->lfs, priv, offset, whence);
|
ret = lfs_file_seek(&fs->lfs, &priv->file, offset, whence);
|
||||||
if (ret >= 0)
|
if (ret >= 0)
|
||||||
{
|
{
|
||||||
filep->f_pos = ret;
|
filep->f_pos = ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
littlefs_semgive(fs);
|
littlefs_semgive(fs);
|
||||||
|
|
||||||
return ret;
|
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)
|
static int littlefs_sync(FAR struct file *filep)
|
||||||
{
|
{
|
||||||
FAR struct littlefs_mountpt_s *fs;
|
FAR struct littlefs_mountpt_s *fs;
|
||||||
FAR struct lfs_file *priv;
|
FAR struct littlefs_file_s *priv;
|
||||||
FAR struct inode *inode;
|
FAR struct inode *inode;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -499,7 +527,7 @@ static int littlefs_sync(FAR struct file *filep)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = lfs_file_sync(&fs->lfs, priv);
|
ret = lfs_file_sync(&fs->lfs, &priv->file);
|
||||||
littlefs_semgive(fs);
|
littlefs_semgive(fs);
|
||||||
|
|
||||||
return ret;
|
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)
|
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)
|
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 lfs_file *priv;
|
FAR struct littlefs_file_s *priv;
|
||||||
FAR struct inode *inode;
|
FAR struct inode *inode;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -549,7 +598,7 @@ static int littlefs_fstat(FAR const struct file *filep, FAR struct stat *buf)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf->st_size = lfs_file_size(&fs->lfs, priv);
|
buf->st_size = lfs_file_size(&fs->lfs, &priv->file);
|
||||||
littlefs_semgive(fs);
|
littlefs_semgive(fs);
|
||||||
|
|
||||||
if (buf->st_size < 0)
|
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)
|
static int littlefs_truncate(FAR struct file *filep, off_t length)
|
||||||
{
|
{
|
||||||
FAR struct littlefs_mountpt_s *fs;
|
FAR struct littlefs_mountpt_s *fs;
|
||||||
FAR struct lfs_file *priv;
|
FAR struct littlefs_file_s *priv;
|
||||||
FAR struct inode *inode;
|
FAR struct inode *inode;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -594,7 +643,7 @@ static int littlefs_truncate(FAR struct file *filep, off_t length)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = lfs_file_truncate(&fs->lfs, priv, length);
|
ret = lfs_file_truncate(&fs->lfs, &priv->file, length);
|
||||||
littlefs_semgive(fs);
|
littlefs_semgive(fs);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -680,13 +729,12 @@ static int littlefs_closedir(FAR struct inode *mountpt,
|
|||||||
ret = littlefs_semtake(fs);
|
ret = littlefs_semtake(fs);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
goto errsem;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
lfs_dir_close(&fs->lfs, priv);
|
lfs_dir_close(&fs->lfs, priv);
|
||||||
littlefs_semgive(fs);
|
littlefs_semgive(fs);
|
||||||
|
|
||||||
errsem:
|
|
||||||
kmm_free(priv);
|
kmm_free(priv);
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
@ -740,7 +788,6 @@ static int littlefs_readdir(FAR struct inode *mountpt,
|
|||||||
}
|
}
|
||||||
|
|
||||||
littlefs_semgive(fs);
|
littlefs_semgive(fs);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -778,7 +825,6 @@ static int littlefs_rewinddir(FAR struct inode *mountpt,
|
|||||||
}
|
}
|
||||||
|
|
||||||
littlefs_semgive(fs);
|
littlefs_semgive(fs);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1135,7 +1181,6 @@ static int littlefs_statfs(FAR struct inode *mountpt, FAR struct statfs *buf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
littlefs_semgive(fs);
|
littlefs_semgive(fs);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user