Skip to content

Commit 44992c8

Browse files
DS-LKGUIDINGLI
authored andcommitted
fs/littlefs: Implement fchstat and chstat of littlefs
Signed-off-by: zhouliang3 <[email protected]>
1 parent 140ce28 commit 44992c8

File tree

1 file changed

+184
-22
lines changed

1 file changed

+184
-22
lines changed

fs/littlefs/lfs_vfs.c

Lines changed: 184 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,17 @@ struct littlefs_mountpt_s
8080
struct lfs lfs;
8181
};
8282

83+
struct littlefs_attr_s
84+
{
85+
uint32_t at_ver; /* For the later extension */
86+
uint32_t at_mode; /* File type, attributes, and access mode bits */
87+
uint32_t at_uid; /* User ID of file */
88+
uint32_t at_gid; /* Group ID of file */
89+
uint64_t at_atim; /* Time of last access */
90+
uint64_t at_mtim; /* Time of last modification */
91+
uint64_t at_ctim; /* Time of last status change */
92+
};
93+
8394
/****************************************************************************
8495
* Private Function Prototypes
8596
****************************************************************************/
@@ -101,6 +112,8 @@ static int littlefs_dup(FAR const struct file *oldp,
101112
FAR struct file *newp);
102113
static int littlefs_fstat(FAR const struct file *filep,
103114
FAR struct stat *buf);
115+
static int littlefs_fchstat(FAR const struct file *filep,
116+
FAR const struct stat *buf, int flags);
104117
static int littlefs_truncate(FAR struct file *filep,
105118
off_t length);
106119

@@ -133,6 +146,9 @@ static int littlefs_rename(FAR struct inode *mountpt,
133146
FAR const char *newrelpath);
134147
static int littlefs_stat(FAR struct inode *mountpt,
135148
FAR const char *relpath, FAR struct stat *buf);
149+
static int littlefs_chstat(FAR struct inode *mountpt,
150+
FAR const char *relpath,
151+
FAR const struct stat *buf, int flags);
136152

137153
/****************************************************************************
138154
* Public Data
@@ -158,7 +174,7 @@ const struct mountpt_operations g_littlefs_operations =
158174
littlefs_sync, /* sync */
159175
littlefs_dup, /* dup */
160176
littlefs_fstat, /* fstat */
161-
NULL, /* fchstat */
177+
littlefs_fchstat, /* fchstat */
162178

163179
littlefs_opendir, /* opendir */
164180
littlefs_closedir, /* closedir */
@@ -174,7 +190,7 @@ const struct mountpt_operations g_littlefs_operations =
174190
littlefs_rmdir, /* rmdir */
175191
littlefs_rename, /* rename */
176192
littlefs_stat, /* stat */
177-
NULL /* chstat */
193+
littlefs_chstat /* chstat */
178194
};
179195

180196
/****************************************************************************
@@ -327,6 +343,26 @@ static int littlefs_open(FAR struct file *filep, FAR const char *relpath,
327343
goto errout;
328344
}
329345

346+
if (oflags & LFS_O_CREAT)
347+
{
348+
struct littlefs_attr_s attr;
349+
struct timespec time;
350+
351+
clock_gettime(CLOCK_REALTIME, &time);
352+
memset(&attr, 0, sizeof(attr));
353+
attr.at_mode = mode;
354+
attr.at_ctim = 1000000000ull * time.tv_sec + time.tv_nsec;
355+
attr.at_atim = attr.at_ctim;
356+
attr.at_mtim = attr.at_ctim;
357+
ret = littlefs_convert_result(lfs_setattr(&fs->lfs, relpath, 0,
358+
&attr, sizeof(attr)));
359+
if (ret < 0)
360+
{
361+
lfs_remove(&fs->lfs, relpath);
362+
goto errout_with_file;
363+
}
364+
}
365+
330366
/* In append mode, we need to set the file pointer to the end of the
331367
* file.
332368
*/
@@ -690,6 +726,7 @@ static int littlefs_fstat(FAR const struct file *filep, FAR struct stat *buf)
690726
FAR struct littlefs_mountpt_s *fs;
691727
FAR struct littlefs_file_s *priv;
692728
FAR struct inode *inode;
729+
char path[LFS_NAME_MAX];
693730
int ret;
694731

695732
memset(buf, 0, sizeof(*buf));
@@ -708,17 +745,57 @@ static int littlefs_fstat(FAR const struct file *filep, FAR struct stat *buf)
708745
return ret;
709746
}
710747

711-
buf->st_size = lfs_file_size(&fs->lfs, &priv->file);
748+
ret = lfs_file_path(&fs->lfs, &priv->file, path, sizeof(path));
712749
nxmutex_unlock(&fs->lock);
750+
if (ret < 0)
751+
{
752+
return ret;
753+
}
713754

714-
if (buf->st_size < 0)
755+
ret = littlefs_stat(inode, path, buf);
756+
if (ret < 0)
715757
{
716-
return littlefs_convert_result(buf->st_size);
758+
return ret;
717759
}
718760

719-
buf->st_mode = S_IRWXO | S_IRWXG | S_IRWXU | S_IFREG;
720-
buf->st_blksize = fs->cfg.block_size;
721-
buf->st_blocks = (buf->st_size + buf->st_blksize - 1) / buf->st_blksize;
761+
return OK;
762+
}
763+
764+
static int littlefs_fchstat(FAR const struct file *filep,
765+
FAR const struct stat *buf, int flags)
766+
{
767+
FAR struct littlefs_mountpt_s *fs;
768+
FAR struct littlefs_file_s *priv;
769+
FAR struct inode *inode;
770+
char path[LFS_NAME_MAX];
771+
int ret;
772+
773+
/* Recover our private data from the struct file instance */
774+
775+
priv = filep->f_priv;
776+
inode = filep->f_inode;
777+
fs = inode->i_private;
778+
779+
/* Call LFS to get file size */
780+
781+
ret = nxmutex_lock(&fs->lock);
782+
if (ret < 0)
783+
{
784+
return ret;
785+
}
786+
787+
ret = lfs_file_path(&fs->lfs, &priv->file, path, sizeof(path));
788+
nxmutex_unlock(&fs->lock);
789+
if (ret < 0)
790+
{
791+
return ret;
792+
}
793+
794+
ret = littlefs_chstat(inode, path, buf, flags);
795+
if (ret < 0)
796+
{
797+
return ret;
798+
}
722799

723800
return OK;
724801
}
@@ -1445,6 +1522,7 @@ static int littlefs_stat(FAR struct inode *mountpt, FAR const char *relpath,
14451522
{
14461523
FAR struct littlefs_mountpt_s *fs;
14471524
struct lfs_info info;
1525+
struct littlefs_attr_s attr;
14481526
int ret;
14491527

14501528
memset(buf, 0, sizeof(*buf));
@@ -1462,28 +1540,112 @@ static int littlefs_stat(FAR struct inode *mountpt, FAR const char *relpath,
14621540
}
14631541

14641542
ret = lfs_stat(&fs->lfs, relpath, &info);
1465-
nxmutex_unlock(&fs->lock);
1466-
1467-
if (ret >= 0)
1543+
if (ret < 0)
14681544
{
1469-
/* Convert info to stat */
1545+
goto errout;
1546+
}
14701547

1471-
buf->st_mode = S_IRWXO | S_IRWXG | S_IRWXU;
1472-
if (info.type == LFS_TYPE_REG)
1548+
ret = littlefs_convert_result(lfs_getattr(&fs->lfs, relpath, 0,
1549+
&attr, sizeof(attr)));
1550+
if (ret < 0)
1551+
{
1552+
if (ret != -ENODATA)
14731553
{
1474-
buf->st_mode |= S_IFREG;
1475-
buf->st_size = info.size;
1554+
goto errout;
14761555
}
1477-
else
1556+
1557+
memset(&attr, 0, sizeof(attr));
1558+
}
1559+
1560+
buf->st_mode = attr.at_mode;
1561+
buf->st_uid = attr.at_uid;
1562+
buf->st_gid = attr.at_gid;
1563+
buf->st_atim.tv_sec = attr.at_atim / 1000000000ull;
1564+
buf->st_atim.tv_nsec = attr.at_atim % 1000000000ull;
1565+
buf->st_mtim.tv_sec = attr.at_mtim / 1000000000ull;
1566+
buf->st_mtim.tv_nsec = attr.at_mtim % 1000000000ull;
1567+
buf->st_ctim.tv_sec = attr.at_ctim / 1000000000ull;
1568+
buf->st_ctim.tv_nsec = attr.at_ctim % 1000000000ull;
1569+
buf->st_size = info.size;
1570+
buf->st_blksize = fs->cfg.block_size;
1571+
buf->st_blocks = (buf->st_size + buf->st_blksize - 1) /
1572+
buf->st_blksize;
1573+
1574+
errout:
1575+
nxmutex_unlock(&fs->lock);
1576+
return ret;
1577+
}
1578+
1579+
static int littlefs_chstat(FAR struct inode *mountpt,
1580+
FAR const char *relpath,
1581+
FAR const struct stat *buf, int flags)
1582+
{
1583+
FAR struct littlefs_mountpt_s *fs;
1584+
struct littlefs_attr_s attr;
1585+
int ret;
1586+
1587+
/* Get the mountpoint private data from the inode structure */
1588+
1589+
fs = mountpt->i_private;
1590+
1591+
/* Call LFS to get file size */
1592+
1593+
ret = nxmutex_lock(&fs->lock);
1594+
if (ret < 0)
1595+
{
1596+
return ret;
1597+
}
1598+
1599+
ret = littlefs_convert_result(lfs_getattr(&fs->lfs, relpath, 0,
1600+
&attr, sizeof(attr)));
1601+
if (ret < 0)
1602+
{
1603+
if (ret != -ENODATA)
14781604
{
1479-
buf->st_mode |= S_IFDIR;
1480-
buf->st_size = 0;
1605+
goto errout;
14811606
}
14821607

1483-
buf->st_blksize = fs->cfg.block_size;
1484-
buf->st_blocks = (buf->st_size + buf->st_blksize - 1) /
1485-
buf->st_blksize;
1608+
memset(&attr, 0, sizeof(attr));
1609+
}
1610+
1611+
if ((CH_STAT_MODE & flags) == CH_STAT_MODE)
1612+
{
1613+
attr.at_mode = buf->st_mode;
1614+
}
1615+
1616+
if ((CH_STAT_UID & flags) == CH_STAT_UID)
1617+
{
1618+
attr.at_uid = buf->st_uid;
14861619
}
14871620

1621+
if ((CH_STAT_GID & flags) == CH_STAT_GID)
1622+
{
1623+
attr.at_gid = buf->st_gid;
1624+
}
1625+
1626+
attr.at_ctim = 1000000000ull * buf->st_ctim.tv_sec +
1627+
buf->st_ctim.tv_nsec;
1628+
1629+
if ((CH_STAT_ATIME & flags) == CH_STAT_ATIME)
1630+
{
1631+
attr.at_atim = 1000000000ull * buf->st_atim.tv_sec +
1632+
buf->st_atim.tv_nsec;
1633+
}
1634+
1635+
if ((CH_STAT_MTIME & flags) == CH_STAT_MTIME)
1636+
{
1637+
attr.at_mtim = 1000000000ull * buf->st_mtim.tv_sec +
1638+
buf->st_mtim.tv_nsec;
1639+
}
1640+
1641+
ret = littlefs_convert_result(lfs_setattr(&fs->lfs, relpath, 0,
1642+
&attr, sizeof(attr)));
1643+
if (ret < 0)
1644+
{
1645+
goto errout;
1646+
}
1647+
1648+
errout:
1649+
nxmutex_unlock(&fs->lock);
14881650
return ret;
14891651
}

0 commit comments

Comments
 (0)