summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2007-05-29 00:31:17 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2007-05-29 00:31:17 +0000
commit642245aa3c464b76fce9807ca63229770b313027 (patch)
tree39b1938584d32944b1032c47d8003cdf99664769
parenta72bee0b87f055095a1f9e84208dd2c4a363dde2 (diff)
downloadnuttx-642245aa3c464b76fce9807ca63229770b313027.tar.gz
nuttx-642245aa3c464b76fce9807ca63229770b313027.tar.bz2
nuttx-642245aa3c464b76fce9807ca63229770b313027.zip
Added statfs()
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@261 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r--nuttx/ChangeLog4
-rw-r--r--nuttx/Documentation/NuttX.html4
-rw-r--r--nuttx/fs/Makefile2
-rw-r--r--nuttx/fs/fs_fat32.c58
-rw-r--r--nuttx/fs/fs_fat32.h1
-rw-r--r--nuttx/fs/fs_fat32util.c107
-rw-r--r--nuttx/fs/fs_statfs.c6
-rw-r--r--nuttx/include/nuttx/fs.h6
-rw-r--r--nuttx/include/sys/statfs.h2
9 files changed, 182 insertions, 8 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index e7dba2db7..6efc3b98d 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/ChangeLog
@@ -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
diff --git a/nuttx/Documentation/NuttX.html b/nuttx/Documentation/NuttX.html
index 0706b2f4c..b9367abbe 100644
--- a/nuttx/Documentation/NuttX.html
+++ b/nuttx/Documentation/NuttX.html
@@ -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>
diff --git a/nuttx/fs/Makefile b/nuttx/fs/Makefile
index 49fdce3a5..0bae52215 100644
--- a/nuttx/fs/Makefile
+++ b/nuttx/fs/Makefile
@@ -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)
diff --git a/nuttx/fs/fs_fat32.c b/nuttx/fs/fs_fat32.c
index 6aa58710f..93ea721a9 100644
--- a/nuttx/fs/fs_fat32.c
+++ b/nuttx/fs/fs_fat32.c
@@ -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,
@@ -1579,6 +1584,59 @@ static int fat_unbind(void *handle, FAR struct inode **blkdriver)
}
/****************************************************************************
+ * 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
*
* Description: Remove a file
diff --git a/nuttx/fs/fs_fat32.h b/nuttx/fs/fs_fat32.h
index ff516be00..0ea0eca36 100644
--- a/nuttx/fs/fs_fat32.h
+++ b/nuttx/fs/fs_fat32.h
@@ -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)
diff --git a/nuttx/fs/fs_fat32util.c b/nuttx/fs/fs_fat32util.c
index f68d4cf1b..a21783e01 100644
--- a/nuttx/fs/fs_fat32util.c
+++ b/nuttx/fs/fs_fat32util.c
@@ -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 */
diff --git a/nuttx/fs/fs_statfs.c b/nuttx/fs/fs_statfs.c
index 24b9113ef..515723ed6 100644
--- a/nuttx/fs/fs_statfs.c
+++ b/nuttx/fs/fs_statfs.c
@@ -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
diff --git a/nuttx/include/nuttx/fs.h b/nuttx/include/nuttx/fs.h
index 69d093716..73c509629 100644
--- a/nuttx/include/nuttx/fs.h
+++ b/nuttx/include/nuttx/fs.h
@@ -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);
diff --git a/nuttx/include/sys/statfs.h b/nuttx/include/sys/statfs.h
index 7baf4be6f..c677e7f1a 100644
--- a/nuttx/include/sys/statfs.h
+++ b/nuttx/include/sys/statfs.h
@@ -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 */