Skip to content

Commit 7a90be0

Browse files
author
Deepika
committed
Added statvfs API to get storage statistics
The API is as per posix standard, but does not provide stats for file/directory. Stats buffer (block size, total block count, free block count) is filled for entire mounted filesystem.
1 parent 9cce4d2 commit 7a90be0

File tree

10 files changed

+114
-9
lines changed

10 files changed

+114
-9
lines changed

features/filesystem/FileSystem.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ int FileSystem::mkdir(const char *path, mode_t mode)
5151
return -ENOSYS;
5252
}
5353

54+
int FileSystem::statvfs(const char *path, struct statvfs *buf)
55+
{
56+
return -ENOSYS;
57+
}
58+
5459
int FileSystem::file_sync(fs_file_t file)
5560
{
5661
return 0;

features/filesystem/FileSystem.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,14 @@ class FileSystem : public FileSystemLike {
109109
*/
110110
virtual int mkdir(const char *path, mode_t mode);
111111

112+
/** Store information about the mounted filesystem in a statvfs structure
113+
*
114+
* @param path The name of the file to find information about
115+
* @param buf The stat buffer to write to
116+
* @return 0 on success, negative error code on failure
117+
*/
118+
virtual int statvfs(const char *path, struct statvfs *buf);
119+
112120
protected:
113121
friend class File;
114122
friend class Dir;
@@ -143,7 +151,7 @@ class FileSystem : public FileSystemLike {
143151
*
144152
* @param file File handle
145153
* @param buffer The buffer to write from
146-
* @param size The number of bytes to write
154+
* @param size The number of bytes to write
147155
* @return The number of bytes written, negative error on failure
148156
*/
149157
virtual ssize_t file_write(fs_file_t file, const void *buffer, size_t size) = 0;
@@ -240,7 +248,7 @@ class FileSystem : public FileSystemLike {
240248
*/
241249
virtual void dir_rewind(fs_dir_t dir);
242250

243-
/** Get the sizeof the directory
251+
/** Get the sizeof the directory
244252
*
245253
* @param dir Dir handle
246254
* @return Number of files in the directory

features/filesystem/fat/FATFileSystem.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,34 @@ int FATFileSystem::stat(const char *path, struct stat *st) {
442442
return 0;
443443
}
444444

445+
int FATFileSystem::statvfs(const char *path, struct statvfs *buf) {
446+
447+
memset(buf, 0, sizeof(struct statvfs));
448+
FATFS *fs;
449+
DWORD fre_clust;
450+
451+
lock();
452+
FRESULT res = f_getfree(_fsid, &fre_clust, &fs);
453+
if (res != FR_OK) {
454+
unlock();
455+
return fat_error_remap(res);
456+
}
457+
458+
buf->f_bsize = fs->ssize;
459+
buf->f_frsize = fs->ssize;
460+
buf->f_blocks = (fs->n_fatent - 2) * fs->csize;
461+
buf->f_bfree = fre_clust * fs->csize;
462+
buf->f_bavail = buf->f_bfree;
463+
#if FF_USE_LFN
464+
buf->f_namemax = FF_LFN_BUF;
465+
#else
466+
buf->f_namemax = FF_SFN_BUF;
467+
#endif
468+
469+
unlock();
470+
return 0;
471+
}
472+
445473
void FATFileSystem::lock() {
446474
_ffs_mutex->lock();
447475
}

features/filesystem/fat/FATFileSystem.h

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class FATFileSystem : public FileSystem {
4343
*/
4444
FATFileSystem(const char *name = NULL, BlockDevice *bd = NULL);
4545
virtual ~FATFileSystem();
46-
46+
4747
/** Formats a logical drive, FDISK partitioning rule.
4848
*
4949
* The block device to format should be mounted when this function is called.
@@ -57,7 +57,7 @@ class FATFileSystem : public FileSystem {
5757
* cluster_size must be a multiple of the underlying device's allocation unit
5858
* and is currently limited to a max of 32,768 bytes. If zero, a cluster size
5959
* will be determined from the device's allocation unit. Defaults to zero.
60-
*
60+
*
6161
* @return 0 on success, negative error code on failure
6262
*/
6363
static int format(BlockDevice *bd, bd_size_t cluster_size = 0);
@@ -139,6 +139,14 @@ class FATFileSystem : public FileSystem {
139139
*/
140140
virtual int mkdir(const char *path, mode_t mode);
141141

142+
/** Store information about the mounted filesystem in a statvfs structure
143+
*
144+
* @param path The name of the file to find information about
145+
* @param buf The stat buffer to write to
146+
* @return 0 on success, negative error code on failure
147+
*/
148+
virtual int statvfs(const char *path, struct statvfs *buf);
149+
142150
protected:
143151
/** Open a file on the filesystem
144152
*
@@ -170,7 +178,7 @@ class FATFileSystem : public FileSystem {
170178
*
171179
* @param file File handle
172180
* @param buffer The buffer to write from
173-
* @param len The number of bytes to write
181+
* @param len The number of bytes to write
174182
* @return The number of bytes written, negative error on failure
175183
*/
176184
virtual ssize_t file_write(fs_file_t file, const void *buffer, size_t len);
@@ -251,7 +259,7 @@ class FATFileSystem : public FileSystem {
251259
* @param dir Dir handle
252260
*/
253261
virtual void dir_rewind(fs_dir_t dir);
254-
262+
255263
private:
256264
FATFS _fs; // Work area (file system object) for logical drive
257265
char _fsid[sizeof("0:")];

features/filesystem/littlefs/LittleFileSystem.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,9 @@ int LittleFileSystem::stat(const char *name, struct stat *st)
336336
return lfs_toerror(err);
337337
}
338338

339+
int LittleFileSystem::statvfs(const char *path, struct statvfs *buf)
340+
{
341+
}
339342

340343
////// File operations //////
341344
int LittleFileSystem::file_open(fs_file_t *file, const char *path, int flags)

features/filesystem/littlefs/LittleFileSystem.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,14 @@ class LittleFileSystem : public mbed::FileSystem {
143143
*/
144144
virtual int mkdir(const char *path, mode_t mode);
145145

146+
/** Store information about the mounted filesystem in a statvfs structure
147+
*
148+
* @param path The name of the file to find information about
149+
* @param buf The stat buffer to write to
150+
* @return 0 on success, negative error code on failure
151+
*/
152+
virtual int statvfs(const char *path, struct statvfs *buf);
153+
146154
protected:
147155
/** Open a file on the filesystem
148156
*

platform/FileSystemHandle.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,8 @@ int FileSystemHandle::mkdir(const char *path, mode_t mode)
4242
{
4343
return -ENOSYS;
4444
}
45+
46+
int FileSystemHandle::statvfs(const char *path, struct statvfs *buf)
47+
{
48+
return -ENOSYS;
49+
}

platform/FileSystemHandle.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,14 @@ class FileSystemHandle : private NonCopyable<FileSystemHandle> {
9494
* @return 0 on success, negative error code on failure
9595
*/
9696
virtual int mkdir(const char *path, mode_t mode);
97+
98+
/** Store information about the mounted filesystem in a statvfs structure
99+
*
100+
* @param path The name of the file to find information about
101+
* @param buf The stat buffer to write to
102+
* @return 0 on success, negative error code on failure
103+
*/
104+
virtual int statvfs(const char *path, struct statvfs *buf);
97105
};
98106
/**@}*/
99107

platform/mbed_retarget.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -709,6 +709,23 @@ extern "C" int stat(const char *path, struct stat *st) {
709709
}
710710
}
711711

712+
extern "C" int statvfs(const char *path, struct statvfs *buf) {
713+
FilePath fp(path);
714+
FileSystemHandle *fs = fp.fileSystem();
715+
if (fs == NULL) {
716+
errno = ENODEV;
717+
return -1;
718+
}
719+
720+
int err = fs->statvfs(fp.fileName(), buf);
721+
if (err < 0) {
722+
errno = -err;
723+
return -1;
724+
} else {
725+
return 0;
726+
}
727+
}
728+
712729
#if defined(TOOLCHAIN_GCC)
713730
/* prevents the exception handling name demangling code getting pulled in */
714731
#include "mbed_error.h"

platform/mbed_retarget.h

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,16 @@
2828
/* We can get the following standard types from sys/types for gcc, but we
2929
* need to define the types ourselves for the other compilers that normally
3030
* target embedded systems */
31-
typedef signed int ssize_t; ///< Signed size type, usually encodes negative errors
32-
typedef signed long off_t; ///< Offset in a data stream
31+
typedef signed int ssize_t; ///< Signed size type, usually encodes negative errors
32+
typedef signed long off_t; ///< Offset in a data stream
3333
#if defined(__ARMCC_VERSION) || !defined(__GNUC__)
3434
typedef unsigned int mode_t; ///< Mode for opening files
3535
typedef unsigned int dev_t; ///< Device ID type
3636
typedef unsigned long ino_t; ///< File serial number
3737
typedef unsigned int nlink_t; ///< Number of links to a file
3838
typedef unsigned int uid_t; ///< User ID
3939
typedef unsigned int gid_t; ///< Group ID
40+
typedef unsigned long long fsblkcnt_t; ///< Count of file system blocks
4041
#endif
4142

4243
#define O_RDONLY 0 ///< Open for reading
@@ -62,7 +63,7 @@ typedef unsigned int gid_t; ///< Group ID
6263
/* DIR declarations must also be here */
6364
#if __cplusplus
6465
namespace mbed {
65-
66+
6667
class FileHandle;
6768
class DirHandle;
6869
std::FILE *mbed_fdopen(FileHandle *fh, const char *mode);
@@ -415,10 +416,24 @@ struct stat {
415416
time_t st_ctime; ///< Time of last status change
416417
};
417418

419+
struct statvfs {
420+
unsigned long f_bsize; ///< Filesystem block size
421+
unsigned long f_frsize; ///< Fragment size (block size)
422+
423+
fsblkcnt_t f_blocks; ///< Number of blocks
424+
fsblkcnt_t f_bfree; ///< Number of free blocks
425+
fsblkcnt_t f_bavail; ///< Number of free blocks for unprivileged users
426+
427+
unsigned long f_fsid; ///< Filesystem ID
428+
429+
unsigned long f_namemax; ///< Maximum filename length
430+
};
431+
418432
#if __cplusplus
419433
extern "C" {
420434
#endif
421435
int stat(const char *path, struct stat *st);
436+
int statvfs(const char *path, struct statvfs *buf);
422437
#if __cplusplus
423438
};
424439
#endif

0 commit comments

Comments
 (0)