Added statfs()

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@261 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2007-05-29 00:31:17 +00:00
parent 9dd25d7965
commit cf935803a0
9 changed files with 182 additions and 8 deletions

View File

@ -150,9 +150,9 @@
0.2.7 2007-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
* Added stat() to fs layer
* Added stat() supported to FAT
* Added stat() to fs layer and to FAT
* Fixed reference counting errors associated with mounted filesystems
* Added fat_getattrib() and fat_setattrib()
* Added statfs() to fs layer and to FAT
* Started m68322

View File

@ -584,10 +584,10 @@ Other memory:
0.2.7 2007-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
* Added stat() to fs layer
* Added stat() supported to FAT
* Added stat() to fs layer and to FAT
* Fixed reference counting errors associated with mounted filesystems
* Added fat_getattrib() and fat_setattrib()
* Added statfs() to fs layer and to FAT
* Started m68322
</pre></ul>

View File

@ -43,7 +43,7 @@ AOBJS = $(ASRCS:.S=$(OBJEXT))
CSRCS = fs_open.c fs_close.c fs_read.c fs_write.c fs_ioctl.c fs_dup.c \
fs_opendir.c fs_closedir.c fs_stat.c fs_readdir.c fs_readdirr.c \
fs_seekdir.c fs_telldir.c fs_rewinddir.c fs_fsync.c fs_files.c \
fs_inode.c fs_inodefind.c fs_inodereserve.c \
fs_inode.c fs_inodefind.c fs_inodereserve.c fs_statfs.c \
fs_inoderemove.c fs_registerdriver.c fs_unregisterdriver.c \
fs_inodeaddref.c fs_inoderelease.c
ifneq ($(CONFIG_DISABLE_MOUNTPOINT),y)

View File

@ -45,6 +45,7 @@
#include <nuttx/config.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/statfs.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
@ -93,6 +94,8 @@ static int fat_rewinddir(struct inode *mountpt, struct internal_dir_s *dir);
static int fat_bind(FAR struct inode *blkdriver, const void *data,
void **handle);
static int fat_unbind(void *handle, FAR struct inode **blkdriver);
static int fat_statfs(struct inode *mountpt, struct statfs *buf);
static int fat_unlink(struct inode *mountpt, const char *relpath);
static int fat_mkdir(struct inode *mountpt, const char *relpath,
mode_t mode);
@ -131,6 +134,8 @@ const struct mountpt_operations fat_operations =
fat_bind,
fat_unbind,
fat_statfs,
fat_unlink,
fat_mkdir,
fat_rmdir,
@ -1578,6 +1583,59 @@ static int fat_unbind(void *handle, FAR struct inode **blkdriver)
return ret;
}
/****************************************************************************
* Name: fat_statfs
*
* Description: Return filesystem statistics
*
****************************************************************************/
static int fat_statfs(struct inode *mountpt, struct statfs *buf)
{
struct fat_mountpt_s *fs;
int ret;
/* Sanity checks */
DEBUGASSERT(mountpt && mountpt->i_private);
/* Get the mountpoint private data from the inode structure */
fs = mountpt->i_private;
/* Check if the mount is still healthy */
fat_semtake(fs);
ret = fat_checkmount(fs);
if (ret < 0)
{
goto errout_with_semaphore;
}
/* Fill in the statfs info */
memset(buf, 0, sizeof(struct statfs));
buf->f_type = MSDOS_SUPER_MAGIC;
/* We will claim that the optimal transfer size is the size of a cluster in bytes */
buf->f_bsize = fs->fs_fatsecperclus * fs->fs_hwsectorsize;
/* Everything else follows in units of clusters */
buf->f_blocks = fs->fs_nclusters; /* Total data blocks in the file system */
ret = fat_nfreeclusters(fs, &buf->f_bfree); /* Free blocks in the file system */
buf->f_bavail = buf->f_bfree; /* Free blocks avail to non-superuser */
buf->f_namelen = (8+1+3); /* Maximum length of filenames */
fat_semgive(fs);
return OK;
errout_with_semaphore:
fat_semgive(fs);
return ret;
}
/****************************************************************************
* Name: fat_unlink
*

View File

@ -567,6 +567,7 @@ EXTERN int fat_ffcacheinvalidate(struct fat_mountpt_s *fs, struct fat_file_s
/* FSINFO sector support */
EXTERN int fat_updatefsinfo(struct fat_mountpt_s *fs);
EXTERN int fat_nfreeclusters(struct fat_mountpt_s *fs, size_t *pfreeclusters);
#undef EXTERN
#if defined(__cplusplus)

View File

@ -861,7 +861,7 @@ ssize_t fat_cluster2sector(struct fat_mountpt_s *fs, uint32 cluster )
*
* Desciption: Get the cluster start sector into the FAT.
*
* Return: <0: error, >=0: sector number
* Return: <0: error, 0:cluster unassigned, >=0: start sector of cluster
*
****************************************************************************/
@ -2340,5 +2340,110 @@ int fat_updatefsinfo(struct fat_mountpt_s *fs)
return ret;
}
/****************************************************************************
* Name: fat_nfreeclusters
*
* Desciption: Get the number of free clusters
*
****************************************************************************/
int fat_nfreeclusters(struct fat_mountpt_s *fs, size_t *pfreeclusters)
{
uint32 nfreeclusters;
/* If number of the first free cluster is valid, then just return that value. */
if (fs->fs_fsifreecount <= fs->fs_nclusters - 2)
{
*pfreeclusters = fs->fs_fsifreecount;
return OK;
}
/* Otherwise, we will have to count the number of free clusters */
nfreeclusters = 0;
if (fs->fs_type == FSTYPE_FAT12)
{
size_t sector;
/* Examine every cluster in the fat */
for (sector = 2; sector < fs->fs_nclusters; sector++)
{
/* If the cluster is unassigned, then increment the count of free clusters */
if ((uint16)fat_getcluster(fs, sector) == 0)
{
nfreeclusters++;
}
}
}
else
{
unsigned int cluster;
size_t fatsector;
unsigned int offset;
int ret;
fatsector = fs->fs_fatbase;
offset = fs->fs_hwsectorsize;
/* Examine each cluster in the fat */
for (cluster = fs->fs_nclusters; cluster > 0; cluster--)
{
/* If we are starting a new sector, then read the new sector in fs_buffer */
if (offset >= fs->fs_hwsectorsize)
{
ret = fat_fscacheread(fs, fatsector++);
if (ret < 0)
{
return ret;
}
/* Reset the offset to the next FAT entry.
* Increment the sector number to read next time around.
*/
offset = 0;
fatsector++;
}
/* FAT16 and FAT32 differ only on the size of each cluster start
* sector number in the FAT.
*/
if (fs->fs_type == FSTYPE_FAT16)
{
if (FAT_GETFAT16(fs->fs_buffer, offset) == 0)
{
nfreeclusters++;
}
offset += 2;
}
else
{
if (FAT_GETFAT32(fs->fs_buffer, offset) == 0)
{
nfreeclusters++;
}
offset += 4;
}
}
}
fs->fs_fsifreecount = nfreeclusters;
if (fs->fs_type == FSTYPE_FAT32)
{
fs->fs_fsidirty = TRUE;
}
*pfreeclusters = nfreeclusters;
return OK;
}
#endif /* CONFIG_DISABLE_MOUNTPOUNT */
#endif /* CONFIG_FS_FAT */

View File

@ -45,6 +45,7 @@
#include <sys/types.h>
#include <sys/statfs.h>
#include <string.h>
#include <limits.h>
#include <sched.h>
#include <errno.h>
#include "fs_internal.h"
@ -61,6 +62,9 @@
static inline int statpsuedofs(FAR struct inode *inode, FAR struct statfs *buf)
{
memset(buf, 0, sizeof(struct statfs));
buf->f_type = PROC_SUPER_MAGIC;
buf->f_namelen = NAME_MAX;
return OK;
}
@ -132,7 +136,7 @@ int statfs(const char *path, struct statfs *buf)
{
/* Perform the rewinddir() operation */
ret = inode->u.i_mops->statfs(inode, relpath, buf);
ret = inode->u.i_mops->statfs(inode, buf);
}
}
else

View File

@ -116,6 +116,8 @@ struct block_operations
struct inode;
struct internal_dir_s;
struct stat;
struct statfs;
struct mountpt_operations
{
/* The mountpoint open method differs from the driver open method
@ -159,6 +161,10 @@ struct mountpt_operations
int (*bind)(FAR struct inode *blkdriver, const void *data, void **handle);
int (*unbind)(void *handle, FAR struct inode **blkdriver);
int (*statfs)(struct inode *mountpt, struct statfs *buf);
/* Operations on pathes */
int (*unlink)(struct inode *mountpt, const char *relpath);
int (*mkdir)(struct inode *mountpt, const char *relpath, mode_t mode);
int (*rmdir)(struct inode *mountpt, const char *relpath);

View File

@ -102,7 +102,7 @@ struct statfs
{
uint32 f_type; /* Type of filesystem (see definitions above) */
size_t f_bsize; /* Optimal block size for transfers */
size_t f_blocks; /* Totat data blocks in the file system of this size */
size_t f_blocks; /* Total data blocks in the file system of this size */
size_t f_bfree; /* Free blocks in the file system */
size_t f_bavail; /* Free blocks avail to non-superuser */
size_t f_files; /* Total file nodes in the file system */