diff --git a/OAT.xml b/OAT.xml index f409640..8c0fa1f 100644 --- a/OAT.xml +++ b/OAT.xml @@ -22,6 +22,7 @@ please copy it to your project root dir and modify it refer to OpenHarmony/tools LICENSE + @@ -32,6 +33,7 @@ please copy it to your project root dir and modify it refer to OpenHarmony/tools + @@ -68,8 +70,8 @@ please copy it to your project root dir and modify it refer to OpenHarmony/tools - + + diff --git a/drivers/bch/bchlib_write.c b/drivers/bch/bchlib_write.c index 30a4df2..9b1859d 100644 --- a/drivers/bch/bchlib_write.c +++ b/drivers/bch/bchlib_write.c @@ -127,6 +127,15 @@ ssize_t bchlib_write(void *handle, const char *buffer, loff_t offset, size_t len nsectors = bch->nsectors - sector; } + /* Flush the dirty sector to keep the sector sequence */ + + ret = bchlib_flushsector(bch); + if (ret < 0) + { + PRINTK("ERROR: Flush failed: %d\n", ret); + return ret; + } + /* Write the contiguous sectors */ ret = los_disk_write(bch->disk->disk_id, (const void *)buffer, @@ -179,14 +188,7 @@ ssize_t bchlib_write(void *handle, const char *buffer, loff_t offset, size_t len byteswritten += len; } - /* Finally, flush any cached writes to the device as well */ - - ret = bchlib_flushsector(bch); - if (ret < 0) - { - PRINTK("ERROR: Flush failed: %d\n", ret); - return byteswritten; - } + return byteswritten; } diff --git a/drivers/pipes/pipe_common.c b/drivers/pipes/pipe_common.c index a6e54ad..c5ec17f 100644 --- a/drivers/pipes/pipe_common.c +++ b/drivers/pipes/pipe_common.c @@ -144,7 +144,7 @@ struct pipe_dev_s *pipecommon_allocdev(size_t bufsize, const char *name) * should not have priority inheritance enabled. */ - dev->d_bufsize = bufsize; + dev->d_bufsize = bufsize + 1; /* +1 to compensate the full indicator */ } return dev; diff --git a/fs/nfs/nfs_proto.h b/fs/nfs/nfs_proto.h index d9e0f2c..6b8fe0c 100644 --- a/fs/nfs/nfs_proto.h +++ b/fs/nfs/nfs_proto.h @@ -65,107 +65,107 @@ extern "C" { * Specification" */ -#define NFS_PORT 2049 -#define NFS_PROG 100003 -#define NFS_VER2 2 -#define NFS_VER3 3 -#define NFS_VER4 4 -#define NFS_MAXDGRAMDATA 32768 -#define MAXBSIZE 64000 -#define NFS_MAXDATA MAXBSIZE -#define NFS_MAXPATHLEN 1024 -#define NFS_MAXNAMLEN 255 -#define NFS_MAXPKTHDR 404 -#define NFS_MAXPACKET (NFS_MAXPKTHDR + NFS_MAXDATA) -#define NFS_MINPACKET 20 -#define NFS_FABLKSIZE 512 /* Size in bytes of a block wrt fa_blocks */ +#define NFS_PORT 2049 +#define NFS_PROG 100003 +#define NFS_VER2 2 +#define NFS_VER3 3 +#define NFS_VER4 4 +#define NFS_MAXDGRAMDATA 32768 +#define MAXBSIZE 64000 +#define NFS_MAXDATA MAXBSIZE +#define NFS_MAXPATHLEN 1024 +#define NFS_MAXNAMLEN 255 +#define NFS_MAXPKTHDR 404 +#define NFS_MAXPACKET (NFS_MAXPKTHDR + NFS_MAXDATA) +#define NFS_MINPACKET 20 +#define NFS_FABLKSIZE 512 /* Size in bytes of a block wrt fa_blocks */ #define NFS_MOUNT_PATH_MAX_SIZE PATH_MAX /* Stat numbers for rpc returns (version 2 and 3) */ -#define NFS_OK 0 -#define NFSERR_PERM 1 -#define NFSERR_NOENT 2 -#define NFSERR_IO 5 -#define NFSERR_NXIO 6 -#define NFSERR_ACCES 13 -#define NFSERR_EXIST 17 -#define NFSERR_XDEV 18 /* Version 3 only */ -#define NFSERR_NODEV 19 -#define NFSERR_NOTDIR 20 -#define NFSERR_ISDIR 21 -#define NFSERR_INVAL 22 /* Version 3 only */ -#define NFSERR_FBIG 27 -#define NFSERR_NOSPC 28 -#define NFSERR_ROFS 30 -#define NFSERR_MLINK 31 /* Version 3 only */ -#define NFSERR_NAMETOL 63 -#define NFSERR_NOTEMPTY 66 -#define NFSERR_DQUOT 69 -#define NFSERR_STALE 70 -#define NFSERR_REMOTE 71 /* Version 3 only */ -#define NFSERR_WFLUSH 99 /* Version 2 only */ -#define NFSERR_BADHANDLE 10001 /* The rest Version 3 only */ -#define NFSERR_NOT_SYNC 10002 -#define NFSERR_BAD_COOKIE 10003 -#define NFSERR_NOTSUPP 10004 -#define NFSERR_TOOSMALL 10005 -#define NFSERR_SERVERFAULT 10006 -#define NFSERR_BADTYPE 10007 -#define NFSERR_JUKEBOX 10008 -#define NFSERR_TRYLATER NFSERR_JUKEBOX -#define NFSERR_STALEWRITEVERF 30001 /* Fake return for nfs_commit() */ +#define NFS_OK 0 +#define NFSERR_PERM 1 +#define NFSERR_NOENT 2 +#define NFSERR_IO 5 +#define NFSERR_NXIO 6 +#define NFSERR_ACCES 13 +#define NFSERR_EXIST 17 +#define NFSERR_XDEV 18 /* Version 3 only */ +#define NFSERR_NODEV 19 +#define NFSERR_NOTDIR 20 +#define NFSERR_ISDIR 21 +#define NFSERR_INVAL 22 /* Version 3 only */ +#define NFSERR_FBIG 27 +#define NFSERR_NOSPC 28 +#define NFSERR_ROFS 30 +#define NFSERR_MLINK 31 /* Version 3 only */ +#define NFSERR_NAMETOL 63 +#define NFSERR_NOTEMPTY 66 +#define NFSERR_DQUOT 69 +#define NFSERR_STALE 70 +#define NFSERR_REMOTE 71 /* Version 3 only */ +#define NFSERR_WFLUSH 99 /* Version 2 only */ +#define NFSERR_BADHANDLE 10001 /* The rest Version 3 only */ +#define NFSERR_NOT_SYNC 10002 +#define NFSERR_BAD_COOKIE 10003 +#define NFSERR_NOTSUPP 10004 +#define NFSERR_TOOSMALL 10005 +#define NFSERR_SERVERFAULT 10006 +#define NFSERR_BADTYPE 10007 +#define NFSERR_JUKEBOX 10008 +#define NFSERR_TRYLATER NFSERR_JUKEBOX +#define NFSERR_STALEWRITEVERF 30001 /* Fake return for nfs_commit() */ -#define NFSERR_RETVOID 0x20000000 /* Return void, not error */ -#define NFSERR_AUTHERR 0x40000000 /* Mark an authentication error */ -#define NFSERR_RETERR 0x80000000 /* Mark an error return for V3 */ +#define NFSERR_RETVOID 0x20000000 /* Return void, not error */ +#define NFSERR_AUTHERR 0x40000000 /* Mark an authentication error */ +#define NFSERR_RETERR 0x80000000 /* Mark an error return for V3 */ /* Sizes in bytes of various NFS RPC components */ -#define NFSX_UNSIGNED 4 +#define NFSX_UNSIGNED 4 /* Specific to NFS Version 3 */ -#define NFSX_V3FH (sizeof (fhandle_t)) /* size this server uses */ -#define NFSX_V3FHMAX 64 /* max. allowed by protocol */ -#define NFSX_V3FATTR 84 -#define NFSX_V3SATTR 60 /* max. all fields filled in */ -#define NFSX_V3SRVSATTR (sizeof (struct nfsv3_sattr)) -#define NFSX_V3POSTOPATTR (NFSX_V3FATTR + NFSX_UNSIGNED) -#define NFSX_V3WCCDATA (NFSX_V3POSTOPATTR + 8 * NFSX_UNSIGNED) -#define NFSX_V3COOKIEVERF 8 -#define NFSX_V3WRITEVERF 8 -#define NFSX_V3CREATEVERF 8 -#define NFSX_V3STATFS 52 -#define NFSX_V3FSINFO 48 -#define NFSX_V3PATHCONF 24 +#define NFSX_V3FH (sizeof(fhandle_t)) /* size this server uses */ +#define NFSX_V3FHMAX 64 /* max. allowed by protocol */ +#define NFSX_V3FATTR 84 +#define NFSX_V3SATTR 60 /* max. all fields filled in */ +#define NFSX_V3SRVSATTR (sizeof (struct nfsv3_sattr)) +#define NFSX_V3POSTOPATTR (NFSX_V3FATTR + NFSX_UNSIGNED) +#define NFSX_V3WCCDATA (NFSX_V3POSTOPATTR + 8 * NFSX_UNSIGNED) +#define NFSX_V3COOKIEVERF 8 +#define NFSX_V3WRITEVERF 8 +#define NFSX_V3CREATEVERF 8 +#define NFSX_V3STATFS 52 +#define NFSX_V3FSINFO 48 +#define NFSX_V3PATHCONF 24 /* NFS RPC procedure numbers (before version mapping) */ -#define NFSPROC_NULL 0 -#define NFSPROC_GETATTR 1 -#define NFSPROC_SETATTR 2 -#define NFSPROC_LOOKUP 3 -#define NFSPROC_ACCESS 4 -#define NFSPROC_READLINK 5 -#define NFSPROC_READ 6 -#define NFSPROC_WRITE 7 -#define NFSPROC_CREATE 8 -#define NFSPROC_MKDIR 9 -#define NFSPROC_SYMLINK 10 -#define NFSPROC_MKNOD 11 -#define NFSPROC_REMOVE 12 -#define NFSPROC_RMDIR 13 -#define NFSPROC_RENAME 14 -#define NFSPROC_LINK 15 -#define NFSPROC_READDIR 16 -#define NFSPROC_READDIRPLUS 17 -#define NFSPROC_FSSTAT 18 -#define NFSPROC_FSINFO 19 -#define NFSPROC_PATHCONF 20 -#define NFSPROC_COMMIT 21 -#define NFSPROC_NOOP 22 -#define NFS_NPROCS 23 +#define NFSPROC_NULL 0 +#define NFSPROC_GETATTR 1 +#define NFSPROC_SETATTR 2 +#define NFSPROC_LOOKUP 3 +#define NFSPROC_ACCESS 4 +#define NFSPROC_READLINK 5 +#define NFSPROC_READ 6 +#define NFSPROC_WRITE 7 +#define NFSPROC_CREATE 8 +#define NFSPROC_MKDIR 9 +#define NFSPROC_SYMLINK 10 +#define NFSPROC_MKNOD 11 +#define NFSPROC_REMOVE 12 +#define NFSPROC_RMDIR 13 +#define NFSPROC_RENAME 14 +#define NFSPROC_LINK 15 +#define NFSPROC_READDIR 16 +#define NFSPROC_READDIRPLUS 17 +#define NFSPROC_FSSTAT 18 +#define NFSPROC_FSINFO 19 +#define NFSPROC_PATHCONF 20 +#define NFSPROC_COMMIT 21 +#define NFSPROC_NOOP 22 +#define NFS_NPROCS 23 /* Constants used by the Version 3 protocol for various RPCs */ @@ -173,25 +173,25 @@ extern "C" { #define NFSV3SATTRTIME_TOSERVER 1 #define NFSV3SATTRTIME_TOCLIENT 2 -#define NFSV3ACCESS_READ 0x01 -#define NFSV3ACCESS_LOOKUP 0x02 -#define NFSV3ACCESS_MODIFY 0x04 -#define NFSV3ACCESS_EXTEND 0x08 -#define NFSV3ACCESS_DELETE 0x10 -#define NFSV3ACCESS_EXECUTE 0x20 +#define NFSV3ACCESS_READ 0x01 +#define NFSV3ACCESS_LOOKUP 0x02 +#define NFSV3ACCESS_MODIFY 0x04 +#define NFSV3ACCESS_EXTEND 0x08 +#define NFSV3ACCESS_DELETE 0x10 +#define NFSV3ACCESS_EXECUTE 0x20 -#define NFSV3WRITE_UNSTABLE 0 -#define NFSV3WRITE_DATASYNC 1 -#define NFSV3WRITE_FILESYNC 2 +#define NFSV3WRITE_UNSTABLE 0 +#define NFSV3WRITE_DATASYNC 1 +#define NFSV3WRITE_FILESYNC 2 -#define NFSV3CREATE_UNCHECKED 0 -#define NFSV3CREATE_GUARDED 1 -#define NFSV3CREATE_EXCLUSIVE 2 +#define NFSV3CREATE_UNCHECKED 0 +#define NFSV3CREATE_GUARDED 1 +#define NFSV3CREATE_EXCLUSIVE 2 -#define NFSV3FSINFO_LINK 0x01 -#define NFSV3FSINFO_SYMLINK 0x02 -#define NFSV3FSINFO_HOMOGENEOUS 0x08 -#define NFSV3FSINFO_CANSETTIME 0x10 +#define NFSV3FSINFO_LINK 0x01 +#define NFSV3FSINFO_SYMLINK 0x02 +#define NFSV3FSINFO_HOMOGENEOUS 0x08 +#define NFSV3FSINFO_CANSETTIME 0x10 /* Conversion macros */ @@ -202,25 +202,25 @@ extern "C" { /* Mode bit values */ -#define NFSMODE_IXOTH (1 << 0) /* Execute permission for others on a file */ -#define NFSMODE_IWOTH (1 << 1) /* Write permission for others */ -#define NFSMODE_IROTH (1 << 2) /* Read permission for others */ -#define NFSMODE_IXGRP (1 << 3) /* Execute permission for group on a file */ -#define NFSMODE_IWGRP (1 << 4) /* Write permission for group */ -#define NFSMODE_IRGRP (1 << 5) /* Read permission for group */ -#define NFSMODE_IXUSR (1 << 6) /* Execute permission for owner on a file */ -#define NFSMODE_IWUSR (1 << 7) /* Write permission for owner */ -#define NFSMODE_IRUSR (1 << 8) /* Read permission for owner */ -#define NFSMODE_SAVETEXT (1 << 9) /* Save swapped text */ -#define NFSMODE_ISGID (1 << 10) /* Set group ID on execution */ -#define NFSMODE_ISUID (1 << 11) /* Set user ID on execution */ +#define NFSMODE_IXOTH (1 << 0) /* Execute permission for others on a file */ +#define NFSMODE_IWOTH (1 << 1) /* Write permission for others */ +#define NFSMODE_IROTH (1 << 2) /* Read permission for others */ +#define NFSMODE_IXGRP (1 << 3) /* Execute permission for group on a file */ +#define NFSMODE_IWGRP (1 << 4) /* Write permission for group */ +#define NFSMODE_IRGRP (1 << 5) /* Read permission for group */ +#define NFSMODE_IXUSR (1 << 6) /* Execute permission for owner on a file */ +#define NFSMODE_IWUSR (1 << 7) /* Write permission for owner */ +#define NFSMODE_IRUSR (1 << 8) /* Read permission for owner */ +#define NFSMODE_SAVETEXT (1 << 9) /* Save swapped text */ +#define NFSMODE_ISGID (1 << 10) /* Set group ID on execution */ +#define NFSMODE_ISUID (1 << 11) /* Set user ID on execution */ #define DIRENT_NFS_MAXHANDLE 64 /* Maximum length of an NFSv3 file handle */ #define DIRENT_NFS_VERFLEN 8 /* Length of the copy verifier */ /* File identifier */ -#define MAXFIDSZ 16 +#define MAXFIDSZ 16 /**************************************************************************** * Public Types @@ -414,9 +414,9 @@ struct wcc_attr struct wcc_data { - uint32_t wcc_attr_follows; /* True if data follows */ + uint32_t wcc_attr_follows; /* True if data follows */ struct wcc_attr before; - uint32_t nfs_attr_follow; /* True if attributes present */ + uint32_t nfs_attr_follow; /* True if attributes present */ struct nfs_fattr after; }; @@ -429,9 +429,9 @@ struct file_handle struct diropargs3 { - struct file_handle fhandle; /* Variable length */ - uint32_t length; /* Size of name[] */ - uint32_t name[(NAME_MAX+3) >> 2]; /* Variable length */ + struct file_handle fhandle; /* Variable length */ + uint32_t length; /* Size of name[] */ + uint32_t name[(NAME_MAX + 3) >> 2]; /* Variable length */ }; struct CREATE3args @@ -450,20 +450,21 @@ struct CREATE3resok struct wcc_data dir_wcc; }; -/* The actual size of the lookup argument is variable. These structures are, therefore, - * only useful in setting aside maximum memory usage for the LOOKUP arguments. +/* The actual size of the lookup argument is variable. + * These structures are, therefore, only useful in setting + * aside maximum memory usage for the LOOKUP arguments. */ struct LOOKUP3filename { - uint32_t namelen; /* Size of name[] */ - uint32_t name[(NAME_MAX+3) >> 2]; /* Variable length */ + uint32_t namelen; /* Size of name[] */ + uint32_t name[(NAME_MAX + 3) >> 2]; /* Variable length */ }; struct LOOKUP3args { - struct file_handle dirhandle; /* Variable length */ - struct LOOKUP3filename name; /* Variable length */ + struct file_handle dirhandle; /* Variable length */ + struct LOOKUP3filename name; /* Variable length */ }; struct SETATTR3args @@ -480,7 +481,7 @@ struct SETATTR3resok /* Actual size of LOOKUP3args */ -#define SIZEOF_LOOKUP3filename(b) (sizeof(uint32_t) + (((b)+3) & ~3)) +#define SIZEOF_LOOKUP3filename(b) (sizeof(uint32_t) + (((b) + 3) & ~3)) #define SIZEOF_LOOKUP3args(a,b) (SIZEOF_file_handle(a) + SIZEOF_LOOKUP3filename(b)) struct LOOKUP3resok @@ -494,31 +495,31 @@ struct LOOKUP3resok struct READ3args { - struct file_handle fhandle; /* Variable length */ - uint64_t offset; + struct file_handle fhandle; /* Variable length */ + nfsuint64 offset; uint32_t count; }; struct nfs_rdhdr_s { uint32_t attributes_follow; - struct nfs_fattr attributes; /* Will not be present if attributes_follow == 0 */ - uint32_t count; /* Number of bytes read */ - uint32_t eof; /* Non-zero if at the end of file */ - uint32_t length; /* Length of data (same as count?) */ + struct nfs_fattr attributes; /* Will not be present if attributes_follow == 0 */ + uint32_t count; /* Number of bytes read */ + uint32_t eof; /* Non-zero if at the end of file */ + uint32_t length; /* Length of data (same as count?) */ }; struct READ3resok { struct nfs_rdhdr_s hdr; - uint8_t data[1]; /* Actual data size depends on count */ + uint8_t data[1]; /* Actual data size depends on count */ }; #define SIZEOF_READ3resok(n) (sizeof(struct nfs_rdhdr_s) + (n)) struct nfs_wrhdr_s { - struct file_handle fhandle; /* Variable length */ - uint64_t offset; + struct file_handle fhandle; /* Variable length */ + nfsuint64 offset; uint32_t count; uint32_t stable; }; @@ -526,7 +527,7 @@ struct nfs_wrhdr_s struct WRITE3args { struct nfs_wrhdr_s hdr; - uint8_t data[1]; /* Actual data size depends on count */ + uint8_t data[1]; /* Actual data size depends on count */ }; #define SIZEOF_WRITE3args(n) (sizeof(struct nfs_wrhdr_s) + (n)) @@ -568,10 +569,10 @@ struct MKDIR3args struct MKDIR3resok { - uint32_t handle_follows; /* True, handle follows */ - struct file_handle fhandle; /* Variable length */ - uint32_t attributes_follows; /* True, attributes follows */ - struct nfs_fattr attributes; /* Directory attributes */ + uint32_t handle_follows; /* True, handle follows */ + struct file_handle fhandle; /* Variable length */ + uint32_t attributes_follows; /* True, attributes follows */ + struct nfs_fattr attributes; /* Directory attributes */ struct wcc_data dir_wcc; }; @@ -591,7 +592,7 @@ struct RMDIR3resok struct READDIR3args { - struct file_handle dir; /* Variable length */ + struct file_handle dir; /* Variable length */ nfsuint64 cookie; uint8_t cookieverf[NFSX_V3COOKIEVERF]; uint32_t count; @@ -615,7 +616,7 @@ struct READDIR3resok struct nfs_fattr dir_attributes; uint8_t cookieverf[NFSX_V3COOKIEVERF]; uint32_t value_follows; - uint32_t reply[1]; /* Variable length reply begins here */ + uint32_t reply[1]; /* Variable length reply begins here */ }; #define SIZEOF_READDIR3resok(n) \ diff --git a/fs/nfs/nfs_util.c b/fs/nfs/nfs_util.c index b66b455..7a0e31e 100644 --- a/fs/nfs/nfs_util.c +++ b/fs/nfs/nfs_util.c @@ -175,7 +175,33 @@ tryagain: if (error != 0) { nfs_error("rpcclnt_request failed: %d\n", error); - return error; + + + if (error != -ENOTCONN) + { + return error; + } + + /* Reconnect */ + + + error = rpcclnt_connect(nmp->nm_rpcclnt); + + if(error != 0) + { + return error; + } + + /* Send the request again */ + + error = rpcclnt_request(clnt, procnum, NFS_PROG, NFS_VER3, + request, reqlen, response, resplen); + + if(error != 0) + { + return error; + } + } memcpy(&replyh, response, sizeof(struct nfs_reply_header)); diff --git a/fs/romfs/Kconfig b/fs/romfs/Kconfig deleted file mode 100644 index 4014cf6..0000000 --- a/fs/romfs/Kconfig +++ /dev/null @@ -1,15 +0,0 @@ -# -# For a description of the syntax of this configuration file, -# see the file kconfig-language.txt in the NuttX tools repository. -# - -config FS_ROMFS - bool "ROMFS file system" - default n - depends on !DISABLE_MOUNTPOINT - select FS_READABLE - ---help--- - Enable ROMFS filesystem support - -if FS_ROMFS -endif diff --git a/fs/romfs/Make.defs b/fs/romfs/Make.defs deleted file mode 100644 index 80d128d..0000000 --- a/fs/romfs/Make.defs +++ /dev/null @@ -1,31 +0,0 @@ -############################################################################ -# fs/romfs/Make.defs -# -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. The -# ASF licenses this file to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance with the -# License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -# -############################################################################ - -ifeq ($(CONFIG_FS_ROMFS),y) -# Files required for ROMFS file system support - -CSRCS += fs_romfs.c fs_romfsutil.c - -# Include ROMFS build support - -DEPPATH += --dep-path romfs -VPATH += :romfs - -endif diff --git a/fs/romfs/fs_romfs.c b/fs/romfs/fs_romfs.c deleted file mode 100644 index d0273cf..0000000 --- a/fs/romfs/fs_romfs.c +++ /dev/null @@ -1,903 +0,0 @@ -/**************************************************************************** - * fs/romfs/fs_romfs.c - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "fs_romfs.h" - -#include "los_tables.h" -#include "user_copy.h" -#include "los_vm_filemap.h" - -#ifdef LOSCFG_FS_ROMFS - -/* forward define */ -struct VnodeOps g_romfsVops; -struct file_operations_vfs g_romfsFops; - -/**************************************************************************** - * Name: romfs_lookup - ****************************************************************************/ - -int romfs_lookup(struct Vnode *parentVnode, const char *path, int len, struct Vnode **ppVnode) -{ - int ret; - struct Vnode *newVnode = NULL; - struct romfs_dirinfo_s *dirinfo = NULL; - struct romfs_dirinfo_s *parent_dirinfo = NULL; - struct romfs_mountpt_s *rm = NULL; - struct romfs_file_s *rf = NULL; - - /* Get mountpoint private data from the inode reference from the file - * structure - */ - - rm = (struct romfs_mountpt_s *)parentVnode->originMount->data; - - /* Check if the mount is still healthy */ - - romfs_semtake(rm); - ret = romfs_checkmount(rm); - if (ret != OK) - { - PRINTK("ERROR: romfs_checkmount failed: %d\n", ret); - goto errout_with_semaphore; - } - - parent_dirinfo = (struct romfs_dirinfo_s *)parentVnode->data; - /* Initialize the directory info structure */ - - dirinfo = (struct romfs_dirinfo_s *)zalloc(sizeof(struct romfs_dirinfo_s)); - if (!dirinfo) - { - ret = -ENOMEM; - PRINTK("ERROR: Failed to allocate dirinfo structure, error: %d\n", -ret); - goto errout_with_semaphore; - } - - /* Locate the directory entry for this path */ - - ret = romfs_searchdir(rm, path, len, parent_dirinfo->rd_dir.fr_firstoffset, dirinfo); - if (ret < 0) - { - goto errout_with_semaphore; - } - - /* The full path exists -- but is the final component a file - * or a directory? Or some other Unix file type that is not - * appropriate in this contex. - * - * REVISIT: This logic should follow hard/soft link file - * types. At present, it returns the ENXIO. - */ - - if (!IS_DIRECTORY(dirinfo->rd_next) && !IS_FILE(dirinfo->rd_next)) - { - /* ENXIO indicates "The named file is a character special or - * block special file, and the device associated with this - * special file does not exist." - * - * Here we also return ENXIO if the file is not a directory - * or a regular file. - */ - - ret = -ENXIO; - PRINTK("ERROR: '%s' is a special file\n", path); - goto errout_with_semaphore; - } - - if (IS_DIRECTORY(dirinfo->rd_next)) - { - ret = VnodeAlloc(&g_romfsVops, &newVnode); - if (ret != 0) - { - PRINTK("%s-%d: can't alloc vnode, error: %d\n", __FUNCTION__, __LINE__, ret); - goto errout_with_semaphore; - } - newVnode->type = VNODE_TYPE_DIR; - newVnode->parent = parentVnode; - newVnode->fop = &g_romfsFops; - newVnode->data = dirinfo; - newVnode->originMount = parentVnode->originMount; - newVnode->uid = parentVnode->uid; - newVnode->gid = parentVnode->gid; - newVnode->mode = parentVnode->mode | (S_IFDIR | S_IROTH | S_IXOTH | S_IRGRP | S_IXGRP | - S_IRUSR | S_IXUSR); - } - else - { - rf = (struct romfs_file_s *)zalloc(sizeof(struct romfs_file_s)); - if (!rf) - { - ret = -ENOMEM; - PRINTK("ERROR: Failed to allocate private data: %d\n", ret); - goto errout_with_semaphore; - } - - /* Initialize the file private data (only need to initialize - * non-zero elements) - */ - - rf->rf_size = dirinfo->rd_size; - rf->rf_type = (uint8_t)(dirinfo->rd_next & RFNEXT_ALLMODEMASK); - - /* Get the start of the file data */ - - ret = romfs_datastart(rm, dirinfo->rd_dir.fr_curroffset, - &rf->rf_startoffset); - if (ret < 0) - { - PRINTK("ERROR: Failed to locate start of file data: %d\n", ret); - goto errout_with_mem; - } - - /* Then insert the new instance into the mountpoint structure. - * It needs to be there (1) to handle error conditions that effect - * all files, and (2) to inform the umount logic that we are busy - * (but a simple reference count could have done that). - */ - - rf->rf_next = rm->rm_head; - rm->rm_head = rf->rf_next; - - ret = VnodeAlloc(&g_romfsVops, &newVnode); - if (ret != 0) - { - PRINTK("%s-%d: can't alloc vnode, error: %d\n", __FUNCTION__, __LINE__, ret); - goto errout_with_mem; - } - - newVnode->originMount = parentVnode->originMount; - newVnode->type = VNODE_TYPE_REG; - newVnode->parent = parentVnode; - newVnode->fop = &g_romfsFops; - newVnode->data = rf; - newVnode->uid = parentVnode->uid; - newVnode->gid = parentVnode->gid; - newVnode->mode = S_IFREG | S_IROTH | S_IXOTH | S_IRGRP | S_IXGRP | S_IRUSR | S_IXUSR; - - free(dirinfo); - } - - *ppVnode = newVnode; - - romfs_semgive(rm); - return OK; - - /* Error exits */ - -errout_with_mem: - free(rf); - -errout_with_semaphore: - romfs_semgive(rm); - return ret; -} - -/**************************************************************************** - * Name: romfs_close - ****************************************************************************/ - -int romfs_close(struct file *filep) -{ - return 0; -} - -int romfs_reclaim(struct Vnode *vp) -{ - struct romfs_file_s *rf = vp->data; - if (rf->rf_buffer) - { - free(rf->rf_buffer); - } - - /* Then free the file structure itself. */ - - free(rf); - vp->data = NULL; - - return 0; -} - -/**************************************************************************** - * Name: romfs_read - ****************************************************************************/ - -static ssize_t romfs_read(struct file *filep, char *buffer, - size_t buflen) -{ - struct romfs_mountpt_s *rm = NULL; - struct romfs_file_s *rf = NULL; - uint32_t offset; - size_t bytesleft; - int ret; - - /* Recover our private data from the struct file instance */ - - rf = (struct romfs_file_s *)filep->f_vnode->data; - rm = (struct romfs_mountpt_s *)filep->f_vnode->originMount->data; - - /* Make sure that the mount is still healthy */ - - romfs_semtake(rm); - ret = romfs_checkmount(rm); - if (ret != OK) - { - PRINTK("ERROR: romfs_checkmount failed: %d\n", ret); - goto errout_with_semaphore; - } - - /* Get the number of bytes left in the file */ - - bytesleft = rf->rf_size - filep->f_pos; - - /* Truncate read count so that it does not exceed the number - * of bytes left in the file. - */ - - if (buflen > bytesleft) - { - buflen = bytesleft; - } - - offset = rf->rf_startoffset + filep->f_pos; - LOS_CopyFromKernel(buffer, buflen, &rm->rm_buffer[offset], buflen); - filep->f_pos += buflen; - - romfs_semgive(rm); - return buflen; - -errout_with_semaphore: - romfs_semgive(rm); - return ret; -} - -/**************************************************************************** - * Name: romfs_readpage - ****************************************************************************/ - -static ssize_t romfs_readpage(struct Vnode *vnode, char *buffer, off_t off) -{ - size_t bytesleft; - int ret = 0; - int buflen = PAGE_SIZE; - struct romfs_mountpt_s *rm = NULL; - struct romfs_file_s *rf = NULL; - - /* Recover our private data from the struct file instance */ - - rf = (struct romfs_file_s *)vnode->data; - rm = (struct romfs_mountpt_s *)vnode->originMount->data; - - /* Make sure that the mount is still healthy */ - - romfs_semtake(rm); - ret = romfs_checkmount(rm); - if (ret != OK) - { - PRINTK("ERROR: romfs_checkmount failed: %d\n", ret); - goto errout_with_semaphore; - } - - if (off >= rf->rf_size) - { - ret = -ERANGE; - PRINTK("ERROR: readpage out of range, ret: %d.\n", ret); - goto errout_with_semaphore; - } - - /* Get the number of bytes left in the file */ - - bytesleft = rf->rf_size - off; - - /* Truncate read count so that it does not exceed the number - * of bytes left in the file. - */ - - if (buflen > bytesleft) - { - buflen = bytesleft; - } - - off = rf->rf_startoffset + off; - LOS_CopyFromKernel(buffer, buflen, &rm->rm_buffer[off], buflen); - - romfs_semgive(rm); - return buflen; - -errout_with_semaphore: - romfs_semgive(rm); - return ret; -} - -/**************************************************************************** - * Name: romfs_seek - ****************************************************************************/ - -off_t romfs_seek(struct file *filep, off_t offset, int whence) -{ - struct romfs_file_s *rf = NULL; - loff_t position; - - /* Recover our private data from the struct file instance */ - - rf = (struct romfs_file_s *)filep->f_vnode->data; - position = filep->f_pos; - - /* Map the offset according to the whence option */ - - switch (whence) - { - case SEEK_SET: /* The offset is set to offset bytes. */ - position = offset; - break; - - case SEEK_CUR: /* The offset is set to its current location plus - * offset bytes. */ - - position += offset; - break; - - case SEEK_END: /* The offset is set to the size of the file plus - * offset bytes. */ - - position = offset + rf->rf_size; - break; - - default: - PRINTK("ERROR: Whence is invalid: %d\n", whence); - return -EINVAL; - } - - /* Limit positions to the end of the file. */ - - if (position > rf->rf_size) - { - /* Otherwise, the position is limited to the file size */ - - position = rf->rf_size; - } - - if (position < 0) - { - return -EINVAL; - } - return position; -} - -/**************************************************************************** - * Name: romfs_seek64 - ****************************************************************************/ - -loff_t romfs_seek64(struct file *filep, loff_t offset, int whence) -{ - return (loff_t)romfs_seek(filep, (off_t)offset, whence); -} - -/**************************************************************************** - * Name: romfs_ioctl - ****************************************************************************/ - -static int romfs_ioctl(struct file *filep, int cmd, unsigned long arg) -{ - return -ENOSYS; -} - -/**************************************************************************** - * Name: romfs_opendir - * - * Description: - * Open a directory for read access - * - ****************************************************************************/ - -int romfs_opendir(struct Vnode *vp, struct fs_dirent_s *dir) -{ - int ret; - struct romfs_mountpt_s *rm = NULL; - struct romfs_dirinfo_s *dirinfo = NULL; - struct fs_romfsdir_s *ptr = NULL; - - /* Recover our private data from the vnode instance */ - - rm = (struct romfs_mountpt_s *)vp->originMount->data; - - /* Make sure that the mount is still healthy */ - - romfs_semtake(rm); - ret = romfs_checkmount(rm); - if (ret != OK) - { - PRINTK("ERROR: romfs_checkmount failed: %d\n", ret); - goto errout_with_semaphore; - } - - ptr = (struct fs_romfsdir_s *)zalloc(sizeof(struct fs_romfsdir_s)); - if (ptr == NULL) - { - ret = -ENOMEM; - PRINTK("ERROR: zalloc error for romfsdir. error: %d\n", ret); - goto errout_with_semaphore; - } - - dirinfo = (struct romfs_dirinfo_s *)vp->data; - memcpy(ptr, &dirinfo->rd_dir, sizeof(struct fs_romfsdir_s)); - dir->u.fs_dir = (fs_dir_s *)ptr; - - romfs_semgive(rm); - return OK; - -errout_with_semaphore: - romfs_semgive(rm); - return ret; -} - -/**************************************************************************** - * Name: romfs_closedir - * - * Description: - * Close a directory for read access - * - ****************************************************************************/ - -int romfs_closedir(struct Vnode *vp, struct fs_dirent_s *dir) -{ - struct fs_romfsdir_s *ptr = NULL; - - ptr = (struct fs_romfsdir_s *)dir->u.fs_dir; - if (ptr == NULL) - { - PRINTK("ERROR: romfs_closedir failed, fs_romfsdir_s is NULL.\n"); - return -EINVAL; - } - free(ptr); - dir->u.fs_dir = NULL; - return 0; -} - -/**************************************************************************** - * Name: romfs_readdir - * - * Description: Read the next directory entry - * - ****************************************************************************/ - -static int romfs_readdir(struct Vnode *vp, struct fs_dirent_s *dir) -{ - struct romfs_mountpt_s *rm = NULL; - struct fs_romfsdir_s *romfsdir = NULL; - uint32_t linkoffset; - uint32_t next; - uint32_t info; - uint32_t size; - int ret; - int i = 0; - - /* Recover our private data from the vnode instance */ - - rm = (struct romfs_mountpt_s *)vp->originMount->data; - - /* Make sure that the mount is still healthy */ - - romfs_semtake(rm); - ret = romfs_checkmount(rm); - if (ret != OK) - { - PRINTK("ERROR: omfs_checkmount failed: %d\n", ret); - goto errout_with_semaphore; - } - - romfsdir = (struct fs_romfsdir_s *)dir->u.fs_dir; - /* Loop, skipping over unsupported items in the file system */ - - while (i < dir->read_cnt) - { - /* Have we reached the end of the directory */ - - if (!romfsdir->fr_curroffset) - { - /* We signal the end of the directory by returning the - * special error -ENOENT - */ - - ret = -ENOENT; - break; - } - - /* Parse the directory entry */ - - ret = romfs_parsedirentry(rm, romfsdir->fr_curroffset, &linkoffset, - &next, &info, &size); - if (ret < 0) - { - PRINTK("ERROR: romfs_parsedirentry failed: %d\n", ret); - goto errout_with_semaphore; - } - - /* Save the filename */ - - ret = romfs_parsefilename(rm, (uint32_t)romfsdir->fr_curroffset, dir->fd_dir[i].d_name); - if (ret < 0) - { - PRINTK("ERROR: romfs_parsefilename failed: %d\n", ret); - goto errout_with_semaphore; - } - - /* Set up the next directory entry offset */ - - romfsdir->fr_curroffset = (off_t)next & RFNEXT_OFFSETMASK; - - if (!strcmp(dir->fd_dir[i].d_name, ".") || !strcmp(dir->fd_dir[i].d_name, "..")) - { - continue; - } - - /* Check the file type */ - - if (IS_DIRECTORY(next)) - { - dir->fd_dir[i].d_type = DT_DIR; - } - else if (IS_FILE(next)) - { - dir->fd_dir[i].d_type = DT_REG; - } - - dir->fd_position++; - dir->fd_dir[i].d_off = dir->fd_position; - dir->fd_dir[i].d_reclen = (uint16_t)sizeof(struct dirent); - - i++; - } - romfs_semgive(rm); - return i; - -errout_with_semaphore: - romfs_semgive(rm); - return ret; -} - -/**************************************************************************** - * Name: romfs_rewindir - * - * Description: Reset directory read to the first entry - * - ****************************************************************************/ - -static int romfs_rewinddir(struct Vnode *vp, struct fs_dirent_s *dir) -{ - int ret; - struct romfs_mountpt_s *rm = NULL; - struct fs_romfsdir_s *romfsdir = NULL; - - /* Recover our private data from the vnode instance */ - - rm = (struct romfs_mountpt_s *)vp->originMount->data; - - /* Make sure that the mount is still healthy */ - - romfs_semtake(rm); - ret = romfs_checkmount(rm); - if (ret == OK) - { - romfsdir = (struct fs_romfsdir_s *)dir->u.fs_dir; - romfsdir->fr_curroffset = romfsdir->fr_firstoffset; - } - - romfs_semgive(rm); - return ret; -} - -/**************************************************************************** - * Name: romfs_bind - * - * Description: This implements a portion of the mount operation. This - * function allocates and initializes the mountpoint private data and - * binds the blockdriver inode to the filesystem private data. The final - * binding of the private data (containing the blockdriver) to the - * mountpoint is performed by mount(). - * - ****************************************************************************/ - -int romfs_bind(struct Mount *mnt, struct Vnode *blkDriver, const void *data) -{ - struct romfs_mountpt_s *rm = NULL; - struct romfs_dirinfo_s *dirinfo = NULL; - struct Vnode *pv = NULL; - int ret; - - rm = (struct romfs_mountpt_s *)zalloc(sizeof(struct romfs_mountpt_s)); - if (!rm) - { - PRINTK("ERROR: Failed to allocate mountpoint structure, error: %d\n", -ENOMEM); - return -ENOMEM; - } - - /* Initialize the allocated mountpt state structure. The filesystem is - * responsible for one reference ont the blkdriver inode and does not - * have to addref() here (but does have to release in ubind(). - */ - - (void)sem_init(&rm->rm_sem, 0, 0); /* Initialize the semaphore that controls access */ - - /* Get the hardware configuration and setup buffering appropriately */ - - rm->rm_buffer = (uint8_t *)data; - ret = romfs_hwconfigure(rm); - if (ret) - { - PRINTK("ERROR: romfs_hwconfigure failed: %d\n", ret); - goto errout_with_sem; - } - - /* Then complete the mount by getting the ROMFS configuratrion from - * the ROMF header - */ - - ret = romfs_fsconfigure(rm); - if (ret < 0) - { - PRINTK("ERROR: romfs_fsconfigure failed: %d\n", ret); - goto errout_with_buffer; - } - - dirinfo = (struct romfs_dirinfo_s *)zalloc(sizeof(struct romfs_dirinfo_s)); - if (!dirinfo) - { - PRINTK("ERROR: Failed to allocate dirinfo structure, error: %d\n", -ENOMEM); - goto errout_with_buffer; - } - - dirinfo->rd_dir.fr_firstoffset = rm->rm_rootoffset; - dirinfo->rd_dir.fr_curroffset = rm->rm_rootoffset; - dirinfo->rd_next = RFNEXT_DIRECTORY; - dirinfo->rd_size = 0; - - /* Mounted! */ - - ret = VnodeAlloc(&g_romfsVops, &pv); - if (ret) - { - goto errout_with_dirinfo; - } - - pv->type = VNODE_TYPE_DIR; - pv->data = dirinfo; - pv->originMount = mnt; - pv->fop = &g_romfsFops; - pv->uid = mnt->vnodeBeCovered->uid; - pv->gid = mnt->vnodeBeCovered->gid; - pv->mode = S_IFDIR | S_IROTH | S_IXOTH | S_IRGRP | S_IXGRP | S_IRUSR | S_IXUSR; - mnt->data = rm; - mnt->vnodeCovered = pv; - - romfs_semgive(rm); - return OK; - -errout_with_dirinfo: - free(dirinfo); - -errout_with_buffer: - free(rm->rm_buffer); - -errout_with_sem: - (void)sem_destroy(&rm->rm_sem); - free(rm); - return ret; -} - -/**************************************************************************** - * Name: romfs_unbind - * - * Description: This implements the filesystem portion of the umount - * operation. - * - ****************************************************************************/ - -static int romfs_unbind(struct Mount *mnt, struct Vnode **blkDriver) -{ - struct romfs_mountpt_s *rm = (struct romfs_mountpt_s *)mnt->data; - - if (!rm) - { - return -EINVAL; - } - - /* VFS can assure the mountpoint can be umounted. */ - - romfs_semtake(rm); - /* Release the mountpoint private data */ - - if (rm->rm_buffer) - { - free(rm->rm_buffer); - } - - (void)sem_destroy(&rm->rm_sem); - free(rm); - return OK; -} - -/**************************************************************************** - * Name: romfs_statfs - * - * Description: Return filesystem statistics - * - ****************************************************************************/ - -static int romfs_statfs(struct Mount *mnt, struct statfs *buf) -{ - struct romfs_mountpt_s *rm; - int ret; - - rm = (struct romfs_mountpt_s *)mnt->data; - - /* Check if the mount is still healthy */ - - romfs_semtake(rm); - ret = romfs_checkmount(rm); - if (ret < 0) - { - PRINTK("ERROR: romfs_checkmount failed: %d\n", ret); - goto errout_with_semaphore; - } - - /* Fill in the statfs info */ - - memset(buf, 0, sizeof(struct statfs)); - buf->f_type = ROMFS_MAGIC; - - /* We will claim that the optimal transfer size is the size of one sector */ - - buf->f_bsize = rm->rm_hwsectorsize; - - /* Everything else follows in units of sectors */ - - buf->f_blocks = SEC_NSECTORS(rm, rm->rm_volsize + SEC_NDXMASK(rm)); - buf->f_bfree = 0; - buf->f_bavail = rm->rm_volsize; - buf->f_namelen = NAME_MAX; - - romfs_semgive(rm); - return OK; - -errout_with_semaphore: - romfs_semgive(rm); - return ret; -} - -/**************************************************************************** - * Name: romfs_stat - * - * Description: Return information about a file or directory - * - ****************************************************************************/ - -static int romfs_stat(struct Vnode *vp, struct stat *buf) -{ - struct romfs_mountpt_s *rm = NULL; - struct romfs_dirinfo_s *dirinfo = NULL; - struct romfs_file_s *rf = NULL; - int ret; - - rm = (struct romfs_mountpt_s *)vp->originMount->data; - - /* Check if the mount is still healthy */ - - romfs_semtake(rm); - ret = romfs_checkmount(rm); - if (ret != OK) - { - PRINTK("ERROR: romfs_checkmount failed: %d\n", ret); - goto errout_with_semaphore; - } - - if (vp->type == VNODE_TYPE_DIR) - { - dirinfo = (struct romfs_dirinfo_s *)vp->data; - buf->st_mode = vp->mode; - buf->st_size = dirinfo->rd_size; - } - else if (vp->type == VNODE_TYPE_REG) - { - rf = (struct romfs_file_s *)vp->data; - buf->st_mode = vp->mode; - buf->st_size = rf->rf_size; - } - else - { - PRINTK("ERROR: Unsupported file type: %d\n", vp->type); - ret = -EINVAL; - goto errout_with_semaphore; - } - - buf->st_blksize = rm->rm_hwsectorsize; - buf->st_dev = 0; - buf->st_ino = 0; - buf->st_nlink = 0; - buf->st_uid = vp->uid; - buf->st_gid = vp->gid; - buf->st_atime = 0; - buf->st_mtime = 0; - buf->st_ctime = 0; - -errout_with_semaphore: - romfs_semgive(rm); - return ret; -} - -const struct MountOps romfs_operations = -{ - .Mount = romfs_bind, - .Unmount = romfs_unbind, - .Statfs = romfs_statfs, -}; - -struct VnodeOps g_romfsVops = -{ - .Lookup = romfs_lookup, - .Create = NULL, - .ReadPage = romfs_readpage, - .WritePage = NULL, - .Rename = NULL, - .Mkdir = NULL, - .Getattr = romfs_stat, - .Opendir = romfs_opendir, - .Readdir = romfs_readdir, - .Closedir = romfs_closedir, - .Rewinddir = romfs_rewinddir, - .Unlink = NULL, - .Rmdir = NULL, - .Chattr = NULL, - .Reclaim = romfs_reclaim, - .Truncate = NULL, - .Truncate64 = NULL, -}; - -struct file_operations_vfs g_romfsFops = -{ - .read = romfs_read, - .write = NULL, - .mmap = OsVfsFileMmap, - .seek = romfs_seek, - .ioctl = romfs_ioctl, - .close = romfs_close, - .fsync = NULL, -}; - -FSMAP_ENTRY(romfs_fsmap, "romfs", romfs_operations, FALSE, FALSE); - -#endif diff --git a/fs/romfs/fs_romfs.h b/fs/romfs/fs_romfs.h deleted file mode 100644 index 31fbd94..0000000 --- a/fs/romfs/fs_romfs.h +++ /dev/null @@ -1,222 +0,0 @@ -/**************************************************************************** - * fs/romfs/fs_romfs.h - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -#ifndef __FS_ROMFS_FS_ROMFS_H -#define __FS_ROMFS_FS_ROMFS_H - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include -#include - -#include "fs/dirent_fs.h" -#include "fs/fs.h" -#include "fs/file.h" -#include "disk.h" -#include "vnode.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/* Volume header (multi-byte values are big-endian) */ -#define ROMFS_MAGIC 0x7275 - -#define ROMFS_VHDR_ROM1FS 0 /* 0-7: "-rom1fs-" */ -#define ROMFS_VHDR_SIZE 8 /* 8-11: Number of accessible bytes in this fs. */ -#define ROMFS_VHDR_CHKSUM 12 /* 12-15: Checksum of the first 512 bytes. */ -#define ROMFS_VHDR_VOLNAME 16 /* 16-..: Zero terminated volume name, padded to - * 16 byte boundary. */ - -#define ROMFS_VHDR_MAGIC "-rom1fs-" - -/* File header offset (multi-byte values are big-endian) */ - -#define ROMFS_FHDR_NEXT 0 /* 0-3: Offset of the next file header - * (zero if no more files) */ -#define ROMFS_FHDR_INFO 4 /* 4-7: Info for directories/hard links/ - * devices */ -#define ROMFS_FHDR_SIZE 8 /* 8-11: Size of this file in bytes */ -#define ROMFS_FHDR_CHKSUM 12 /* 12-15: Checksum covering the meta data, - * including the file name, and - * padding. */ -#define ROMFS_FHDR_NAME 16 /* 16-..: Zero terminated volume name, padded - * to 16 byte boundary. */ - -/* Bits 0-3 of the rf_next offset provide mode information. These are the - * values specified in */ - -#define RFNEXT_MODEMASK 7 /* Bits 0-2: Mode; bit 3: Executable */ -#define RFNEXT_ALLMODEMASK 15 /* Bits 0-3: All mode bits */ -#define RFNEXT_OFFSETMASK (~15) /* Bits n-3: Offset to next entry */ - -#define RFNEXT_HARDLINK 0 /* rf_info = Link destination file header */ -#define RFNEXT_DIRECTORY 1 /* rf_info = First file's header */ -#define RFNEXT_FILE 2 /* rf_info = Unused, must be zero */ -#define RFNEXT_SOFTLINK 3 /* rf_info = Unused, must be zero */ -#define RFNEXT_BLOCKDEV 4 /* rf_info = 16/16 bits major/minor number */ -#define RFNEXT_CHARDEV 5 /* rf_info = 16/16 bits major/minor number */ -#define RFNEXT_SOCKET 6 /* rf_info = Unused, must be zero */ -#define RFNEXT_FIFO 7 /* rf_info = Unused, must be zero */ -#define RFNEXT_EXEC 8 /* Modifier of RFNEXT_DIRECTORY and RFNEXT_FILE */ - -#define IS_MODE(rfn,mode) ((((uint32_t)(rfn))&RFNEXT_MODEMASK)==(mode)) -#define IS_HARDLINK(rfn) IS_MODE(rfn,RFNEXT_HARDLINK) -#define IS_DIRECTORY(rfn) IS_MODE(rfn,RFNEXT_DIRECTORY) -#define IS_FILE(rfn) IS_MODE(rfn,RFNEXT_FILE) -#define IS_EXECUTABLE(rfn) (((rfn) & RFNEXT_EXEC) != 0) - -/* RFNEXT_SOFTLINK, RFNEXT_BLOCKDEV, RFNEXT_CHARDEV, RFNEXT_SOCKET, and - * RFNEXT_FIFO are not presently supported in NuttX. - */ - -/* Alignment macros */ - -#define ROMFS_ALIGNMENT 16 -#define ROMFS_MAXPADDING (ROMFS_ALIGNMENT-1) -#define ROMFS_ALIGNMASK (~ROMFS_MAXPADDING) -#define ROMFS_ALIGNUP(addr) ((((uint32_t)(addr))+ROMFS_MAXPADDING)&ROMFS_ALIGNMASK) -#define ROMFS_ALIGNDOWN(addr) (((uint32_t)(addr))&ROMFS_ALIGNMASK) - -/* Offset and sector conversions */ - -#define SEC_NDXMASK(r) ((r)->rm_hwsectorsize - 1) -#define SEC_NSECTORS(r,o) ((o) / (r)->rm_hwsectorsize) -#define SEC_ALIGN(r,o) ((o) & ~SEC_NDXMASK(r)) - -/* Maximum numbr of links that will be followed before we decide that there - * is a problem. - */ - -#define ROMF_MAX_LINKS 64 - -/**************************************************************************** - * Public Types - ****************************************************************************/ - -/* This structure represents the overall mountpoint state. An instance of - * this structure is retained as inode private data on each mountpoint that - * is mounted with a fat32 filesystem. - */ - -struct romfs_file_s; -struct romfs_mountpt_s -{ - struct inode *rm_blkdriver; /* The block driver inode that hosts the FAT32 fs */ - struct romfs_file_s *rm_head; /* A list to all files opened on this mountpoint */ - - bool rm_mounted; /* true: The file system is ready */ - uint16_t rm_hwsectorsize; /* HW: Sector size reported by block driver */ - sem_t rm_sem; /* Used to assume thread-safe access */ - uint32_t rm_rootoffset; /* Saved offset to the first root directory entry */ - uint32_t rm_hwnsectors; /* HW: The number of sectors reported by the hardware */ - uint32_t rm_volsize; /* Size of the ROMFS volume */ - uint32_t rm_cachesector; /* Current sector in the rm_buffer */ - uint8_t *rm_xipbase; /* Base address of directly accessible media */ - uint8_t *rm_buffer; /* Device sector buffer, allocated if rm_xipbase==0 */ -}; - -/* This structure represents on open file under the mountpoint. An instance - * of this structure is retained as struct file specific information on each - * opened file. - */ - -struct romfs_file_s -{ - struct romfs_file_s *rf_next; /* Retained in a singly linked list */ - uint32_t rf_startoffset; /* Offset to the start of the file data */ - uint32_t rf_size; /* Size of the file in bytes */ - uint32_t rf_cachesector; /* Current sector in the rf_buffer */ - uint8_t *rf_buffer; /* File sector buffer, allocated if rm_xipbase==0 */ - uint8_t rf_type; /* File type (for fstat()) */ -}; - -/* This structure is used internally for describing the result of - * walking a path - */ - -struct fs_romfsdir_s -{ - off_t fr_firstoffset; - off_t fr_curroffset; -}; -struct romfs_dirinfo_s -{ - /* These values describe the directory containing the terminal - * path component (of the terminal component itself if it is - * a directory. - */ - - struct fs_romfsdir_s rd_dir; /* Describes directory. */ - - /* Values from the ROMFS file entry */ - - uint32_t rd_next; /* Offset of the next file header+flags */ - uint32_t rd_size; /* Size (if file) */ -}; - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -#undef EXTERN -#if defined(__cplusplus) -#define EXTERN extern "C" -extern "C" -{ -#else -#define EXTERN extern -#endif - -/**************************************************************************** - * Public Function Prototypes - ****************************************************************************/ - -void romfs_semtake(struct romfs_mountpt_s *rm); -void romfs_semgive(struct romfs_mountpt_s *rm); -int romfs_hwread(struct romfs_mountpt_s *rm, uint8_t *buffer, - uint32_t sector, unsigned int nsectors); -int romfs_filecacheread(struct romfs_mountpt_s *rm, - struct romfs_file_s *rf, uint32_t sector); -int romfs_hwconfigure(struct romfs_mountpt_s *rm); -int romfs_fsconfigure(struct romfs_mountpt_s *rm); -int romfs_checkmount(struct romfs_mountpt_s *rm); -int romfs_finddirentry(struct romfs_mountpt_s *rm, - struct romfs_dirinfo_s *dirinfo, - const char *path); -int romfs_parsedirentry(struct romfs_mountpt_s *rm, - uint32_t offset, uint32_t *poffset, uint32_t *pnext, - uint32_t *pinfo, uint32_t *psize); -int romfs_parsefilename(struct romfs_mountpt_s *rm, uint32_t offset, - char *pname); -int romfs_datastart(struct romfs_mountpt_s *rm, uint32_t offset, - uint32_t *start); -int romfs_searchdir(struct romfs_mountpt_s *rm, - const char *entryname, int entrylen, uint32_t firstoffset, - struct romfs_dirinfo_s *dirinfo); - -#undef EXTERN -#if defined(__cplusplus) -} -#endif - -#endif /* __FS_ROMFS_FS_ROMFS_H */ diff --git a/fs/romfs/fs_romfsutil.c b/fs/romfs/fs_romfsutil.c deleted file mode 100644 index d7fd423..0000000 --- a/fs/romfs/fs_romfsutil.c +++ /dev/null @@ -1,594 +0,0 @@ -/**************************************************************************** - * fs/romfs/fs_romfsutil.c - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include -#include -#include -#include -#include -#include - -#ifdef LOSCFG_FS_ROMFS -#include "fs_romfs.h" - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: romfs_swap32 - * - * Description: - * Convert the 32-bit big-endian value to little endian - * - ****************************************************************************/ - -inline uint32_t romfs_swap32(uint32_t value) -{ - return ((((value) & 0x000000ff) << 24) | (((value) & 0x0000ff00) << 8) | - (((value) & 0x00ff0000) >> 8) | (((value) & 0xff000000) >> 24)); -} - -/**************************************************************************** - * Name: romfs_devread32 - * - * Description: - * Read the big-endian 32-bit value from the mount device buffer - * - * Assumption: - * All values are aligned to 32-bit boundaries - * - ****************************************************************************/ - -static uint32_t romfs_devread32(struct romfs_mountpt_s *rm, int ndx) -{ - /* Extract the value */ - - uint32_t value = *(uint32_t *)&rm->rm_buffer[ndx]; - - /* Convert the big-endian value to native host endianness. */ - - return romfs_swap32(value); -} - -/**************************************************************************** - * Name: romfs_checkentry - * - * Description: - * Check if the entry at offset is a directory or file path segment - * - ****************************************************************************/ - -static inline int romfs_checkentry(struct romfs_mountpt_s *rm, - uint32_t offset, const char *entryname, - int entrylen, - struct romfs_dirinfo_s *dirinfo) -{ - char name[NAME_MAX + 1]; - uint32_t linkoffset; - uint32_t next; - uint32_t info; - uint32_t size; - int ret; - - /* Parse the directory entry at this offset (which may be re-directed - * to some other entry if HARLINKED). - */ - - ret = romfs_parsedirentry(rm, offset, &linkoffset, &next, &info, &size); - if (ret < 0) - { - return ret; - } - - /* Now we are pointing to the real entry of interest. Is it a - * directory? Or a file? - */ - - if (IS_DIRECTORY(next) || IS_FILE(next)) - { - /* Get the name of the directory entry. */ - - ret = romfs_parsefilename(rm, offset, name); - if (ret < 0) - { - return ret; - } - - /* Then check if this the name segment we are looking for. The - * string comparison is awkward because there is no terminator - * on entryname (there is a terminator on name, however) - */ - - if (memcmp(entryname, name, entrylen) == 0 && - strlen(name) == entrylen) - { - /* Found it -- save the component info and return success */ - - if (IS_DIRECTORY(next)) - { - dirinfo->rd_dir.fr_firstoffset = info; - dirinfo->rd_dir.fr_curroffset = info; - dirinfo->rd_size = 0; - } - else - { - dirinfo->rd_dir.fr_curroffset = offset; - dirinfo->rd_size = size; - } - - dirinfo->rd_next = next; - return OK; - } - } - - /* The entry is not a directory or it does not have the matching name */ - - return -ENOENT; -} - -/**************************************************************************** - * Name: romfs_devcacheread - * - * Description: - * Read the specified sector for specified offset into the sector cache. - * Return the index into the sector corresponding to the offset - * - ****************************************************************************/ - -uint32_t romfs_devcacheread(struct romfs_mountpt_s *rm, uint32_t offset) -{ - return offset; -} - -/**************************************************************************** - * Name: romfs_followhardlinks - * - * Description: - * Given the offset to a file header, check if the file is a hardlink. - * If so, traverse the hard links until the terminal, non-linked header - * so found and return that offset. - * - ****************************************************************************/ - -static int romfs_followhardlinks(struct romfs_mountpt_s *rm, uint32_t offset, - uint32_t *poffset) -{ - uint32_t next; - uint32_t ndx; - int i; - - /* Loop while we are redirected by hardlinks */ - - for (i = 0; i < ROMF_MAX_LINKS; i++) - { - /* Read the sector containing the offset into memory */ - - ndx = romfs_devcacheread(rm, offset); - if (ndx < 0) - { - return ndx; - } - - /* Check if this is a hard link */ - - next = romfs_devread32(rm, ndx + ROMFS_FHDR_NEXT); - if (!IS_HARDLINK(next)) - { - *poffset = offset; - return OK; - } - - /* Follow the hard-link */ - - offset = romfs_devread32(rm, ndx + ROMFS_FHDR_INFO); - } - - return -ELOOP; -} - -/**************************************************************************** - * Name: romfs_searchdir - * - * Description: - * This is part of the romfs_finddirentry log. Search the directory - * beginning at dirinfo->fr_firstoffset for entryname. - * - ****************************************************************************/ - -int romfs_searchdir(struct romfs_mountpt_s *rm, - const char *entryname, int entrylen, uint32_t firstoffset, - struct romfs_dirinfo_s *dirinfo) -{ - uint32_t offset; - uint32_t next; - uint32_t ndx; - int ret; - - /* Then loop through the current directory until the directory - * with the matching name is found. Or until all of the entries - * the directory have been examined. - */ - - offset = firstoffset; - do - { - /* Read the sector into memory (do this before calling - * romfs_checkentry() so we won't have to read the sector - * twice in the event that the offset refers to a hardlink). - */ - - ndx = romfs_devcacheread(rm, offset); - if (ndx < 0) - { - return ndx; - } - - /* Because everything is chunked and aligned to 16-bit boundaries, - * we know that most the basic node info fits into the sector. - */ - - next = romfs_devread32(rm, ndx + ROMFS_FHDR_NEXT) & RFNEXT_OFFSETMASK; - - /* Check if the name this entry is a directory with the matching - * name - */ - - ret = romfs_checkentry(rm, offset, entryname, entrylen, dirinfo); - if (ret == OK) - { - /* Its a match! Return success */ - - return OK; - } - - /* No match... select the offset to the next entry */ - - offset = next; - } - while (next != 0); - - /* There is nothing in this directory with that name */ - - return -ENOENT; -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: romfs_semtake - ****************************************************************************/ - -void romfs_semtake(struct romfs_mountpt_s *rm) -{ - int ret; - - do - { - /* Take the semaphore (perhaps waiting) */ - - ret = sem_wait(&rm->rm_sem); - - /* The only case that an error should occur here is if the wait was - * awakened by a signal. - */ - - DEBUGASSERT(ret == OK || ret == -EINTR); - } - while (ret == -EINTR); -} - -/**************************************************************************** - * Name: romfs_semgive - ****************************************************************************/ - -void romfs_semgive(struct romfs_mountpt_s *rm) -{ - (void)sem_post(&rm->rm_sem); -} - -/**************************************************************************** - * Name: romfs_hwconfigure - * - * Description: - * This function is called as part of the ROMFS mount operation It - * configures the ROMFS filestem for use on this block driver. This includes - * the accounting for the geometry of the device, setting up any XIP modes - * of operation, and/or allocating any cache buffers. - * - ****************************************************************************/ - -int romfs_hwconfigure(struct romfs_mountpt_s *rm) -{ - uint32_t total_size; - - if (!rm->rm_buffer) - { - return -ENOMEM; - } - - - total_size = romfs_devread32(rm, ROMFS_VHDR_SIZE); - - rm->rm_hwnsectors = total_size; - rm->rm_hwsectorsize = 1; - rm->rm_cachesector = (uint32_t)-1; - rm->rm_volsize = total_size; - - return OK; -} - -/**************************************************************************** - * Name: romfs_fsconfigure - * - * Description: - * This function is called as part of the ROMFS mount operation It - * sets up the mount structure to include configuration information contained - * in the ROMFS header. This is the place where we actually determine if - * the media contains a ROMFS filesystem. - * - ****************************************************************************/ - -int romfs_fsconfigure(struct romfs_mountpt_s *rm) -{ - const char *name; - uint32_t ndx; - - /* Then get information about the ROMFS filesystem on the devices managed - * by this block driver. Read sector zero which contains the volume header. - */ - - ndx = romfs_devcacheread(rm, 0); - if (ndx < 0) - { - return ndx; - } - - /* Verify the magic number at that identifies this as a ROMFS filesystem */ - - if (memcmp(rm->rm_buffer, ROMFS_VHDR_MAGIC, 8) != 0) - { - return -EINVAL; - } - - /* The root directory entry begins right after the header */ - - name = (const char *)&rm->rm_buffer[ROMFS_VHDR_VOLNAME]; - rm->rm_rootoffset = ROMFS_ALIGNUP(ROMFS_VHDR_VOLNAME + strlen(name) + 1); - - /* and return success */ - - rm->rm_mounted = true; - return OK; -} - -/**************************************************************************** - * Name: romfs_checkmount - * - * Description: Check if the mountpoint is still valid. - * - * The caller should hold the mountpoint semaphore - * - ****************************************************************************/ - -int romfs_checkmount(struct romfs_mountpt_s *rm) -{ - return OK; -} - -/**************************************************************************** - * Name: romfs_parsedirentry - * - * Description: - * Return the directory entry at this offset. If rf is NULL, then the - * mount device resources are used. Otherwise, file resources are used. - * - ****************************************************************************/ - -int romfs_parsedirentry(struct romfs_mountpt_s *rm, uint32_t offset, - uint32_t *poffset, uint32_t *pnext, uint32_t *pinfo, - uint32_t *psize) -{ - uint32_t save; - uint32_t next; - uint32_t ndx; - int ret; - - /* Read the sector into memory */ - - ndx = romfs_devcacheread(rm, offset); - if (ndx < 0) - { - return ndx; - } - - /* Yes.. Save the first 'next' value. That has the offset needed to - * traverse the parent directory. But we may need to change the type - * after we follow the hard links. - */ - - save = romfs_devread32(rm, ndx + ROMFS_FHDR_NEXT); - - /* Traverse hardlinks as necessary to get to the real file header */ - - ret = romfs_followhardlinks(rm, offset, poffset); - if (ret < 0) - { - return ret; - } - - if (*poffset != offset) - { - ndx = romfs_devcacheread(rm, *poffset); - if (ndx < 0) - { - return ndx; - } - } - - /* Because everything is chunked and aligned to 16-bit boundaries, - * we know that most the basic node info fits into the sector. The - * associated name may not, however. - */ - - next = romfs_devread32(rm, ndx + ROMFS_FHDR_NEXT); - *pnext = (save & RFNEXT_OFFSETMASK) | (next & RFNEXT_ALLMODEMASK); - *pinfo = romfs_devread32(rm, ndx + ROMFS_FHDR_INFO); - *psize = romfs_devread32(rm, ndx + ROMFS_FHDR_SIZE); - - return OK; -} - -/**************************************************************************** - * Name: romfs_parsefilename - * - * Description: - * Return the filename from directory entry at this offset - * - ****************************************************************************/ - -int romfs_parsefilename(struct romfs_mountpt_s *rm, uint32_t offset, - char *pname) -{ - uint32_t ndx; - uint16_t namelen; - uint16_t chunklen; - bool done; - - /* Loop until the whole name is obtained or until NAME_MAX characters - * of the name have been parsed. - */ - - offset += ROMFS_FHDR_NAME; - for (namelen = 0, done = false; namelen < NAME_MAX && !done; ) - { - /* Read the sector into memory */ - - ndx = romfs_devcacheread(rm, offset + namelen); - if (ndx < 0) - { - return ndx; - } - - /* Is the name terminated in this 16-byte block */ - - if (rm->rm_buffer[ndx + 15] == '\0') - { - /* Yes.. then this chunk is less than 16 */ - - chunklen = strlen((char *)&rm->rm_buffer[ndx]); - done = true; - } - else - { - /* No.. then this chunk is 16 bytes in length */ - - chunklen = 16; - } - - /* Check if we would exceed the NAME_MAX */ - - if (namelen + chunklen > NAME_MAX) - { - chunklen = NAME_MAX - namelen; - done = true; - } - - /* Copy the chunk */ - - memcpy(&pname[namelen], &rm->rm_buffer[ndx], chunklen); - namelen += chunklen; - } - - /* Terminate the name (NAME_MAX+1 chars total) and return success */ - - pname[namelen] = '\0'; - - return OK; -} - -/**************************************************************************** - * Name: romfs_datastart - * - * Description: - * Given the offset to a file header, return the offset to the start of - * the file data - * - ****************************************************************************/ - -int romfs_datastart(struct romfs_mountpt_s *rm, uint32_t offset, - uint32_t *start) -{ - uint32_t ndx; - int ret; - - /* Traverse hardlinks as necessary to get to the real file header */ - - ret = romfs_followhardlinks(rm, offset, &offset); - if (ret < 0) - { - return ret; - } - - /* Loop until the header size is obtained. */ - - offset += ROMFS_FHDR_NAME; - for (; ; ) - { - /* Read the sector into memory */ - - ndx = romfs_devcacheread(rm, offset); - if (ndx < 0) - { - return ndx; - } - - /* Get the offset to the next chunk */ - - offset += 16; - if (offset >= rm->rm_volsize) - { - return -EIO; - } - - /* Is the name terminated in this 16-byte block */ - - if (rm->rm_buffer[ndx + 15] == '\0') - { - /* Yes.. then the data starts at the next chunk */ - - *start = offset; - return OK; - } - } - - return -EINVAL; /* Won't get here */ -} - -#endif diff --git a/fs/tmpfs/fs_tmpfs.c b/fs/tmpfs/fs_tmpfs.c index e143ce3..10dcb90 100644 --- a/fs/tmpfs/fs_tmpfs.c +++ b/fs/tmpfs/fs_tmpfs.c @@ -112,6 +112,7 @@ static int tmpfs_find_directory(struct tmpfs_s *fs, int tmpfs_close(struct file *filep); off_t tmpfs_seek(struct file *filep, off_t offset, int whence); int tmpfs_ioctl(struct file *filep, int cmd, unsigned long arg); +int tmpfs_sync(struct file *filep); int tmpfs_closedir(struct Vnode *node, struct fs_dirent_s *dir); int tmpfs_rewinddir(struct Vnode *vp, struct fs_dirent_s *dir); int tmpfs_truncate(struct Vnode *vp, off_t len); @@ -173,7 +174,7 @@ struct file_operations_vfs tmpfs_fops = { .ioctl = tmpfs_ioctl, .mmap = OsVfsFileMmap, .close = tmpfs_close, - .fsync = NULL, + .fsync = tmpfs_sync, }; static struct tmpfs_s tmpfs_superblock = {0}; @@ -1401,6 +1402,15 @@ int tmpfs_ioctl(struct file *filep, int cmd, unsigned long arg) return -EINVAL; } +/**************************************************************************** + * Name: tmpfs_sync + ****************************************************************************/ + +int tmpfs_sync(struct file *filep) +{ + return 0; +} + /**************************************************************************** * Name: tmpfs_opendir ****************************************************************************/ diff --git a/include/sys/statfs.h b/include/sys/statfs.h index 37b71bc..dd6a148 100644 --- a/include/sys/statfs.h +++ b/include/sys/statfs.h @@ -101,14 +101,14 @@ struct statfs { - uint32_t f_type; /* Type of filesystem (see definitions above) */ - size_t f_namelen; /* Maximum length of filenames */ - size_t f_bsize; /* Optimal block size for transfers */ - off_t f_blocks; /* Total data blocks in the file system of this size */ - off_t f_bfree; /* Free blocks in the file system */ - off_t f_bavail; /* Free blocks avail to non-superuser */ - off_t f_files; /* Total file nodes in the file system */ - off_t f_ffree; /* Free file nodes in the file system */ + uint32_t f_type; /* Type of filesystem (see definitions above) */ + size_t f_namelen; /* Maximum length of filenames */ + size_t f_bsize; /* Optimal block size for transfers */ + fsblkcnt_t f_blocks; /* Total data blocks in the file system of this size */ + fsblkcnt_t f_bfree; /* Free blocks in the file system */ + fsblkcnt_t f_bavail; /* Free blocks avail to non-superuser */ + fsfilcnt_t f_files; /* Total file nodes in the file system */ + fsfilcnt_t f_ffree; /* Free file nodes in the file system */ }; /****************************************************************************