123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613 |
- /****************************************************************************
- * include/nuttx/fs/userfs.h
- *
- * Copyright (C) 2017-2018 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- * used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- ****************************************************************************/
- #ifndef __INCLUDE_NUTTX_FS_USERFSFS_H
- #define __INCLUDE_NUTTX_FS_USERFSFS_H
- /* UserFS is implemented by two components:
- *
- * 1. A component as part of the internal OS file system logic. This
- * file system receives the file system requests and marshals the request
- * as described by the following structures, and sends this marshaled
- * request on a FIFO that was created by userfs_run(). It also receives
- * the marshal led response by the application file system, unmarshals the
- * response, and provides the file system response to the caller.
- * 2. userfs_run() is part of the NuttX C library. It receives the marshaled
- * operating system requests on the FIFO, unmarshals it, and calls the
- * application file system methods on behalf of the OS. It the marshals
- * the application response data and sends this back to the waiting
- * OS file system logic.
- *
- * Overview of general operation flow:
- *
- * 1. The UserFS OS support will be instantiated when the UserFS is mounted
- * based upon the configuration passed in the optional data of the
- * mount command.
- * 2. The UserFS server port number will be configured to communicate on a
- * LocalHost UDP socket with the server portof 0x83nn where nn is the
- * value that was provided when file system was created.
- * 3. The UserFs will receive system file system requests and forward them
- * on the the MqUfsReqN to the user-space file system server
- * (userfs_run()). These requests may be accompanied by additional data in
- * an provided request buffer that was provided when the UserFS was
- * created. This buffer would hold, for example, the data to be
- * written that would accompany a write request.
- * 4. The user-space logic of userfs_run() listens at the other end of the
- * LocalHost socket. It will receive the requests and forward them
- * to the user file system implementation via the methods of struct
- * userfs_operations_s
- * 5. Responses generated by the struct userfs_operations_s method will be
- * returned to UserFS via the LocalHost socket.
- * 6. The UserFS kernel thread will listen on the LocalHost socket
- * and will receive the user file system responses and forward them to
- * the kernel-space file system client.
- */
- /****************************************************************************
- * Included Files
- ****************************************************************************/
- #include <nuttx/config.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <sys/statfs.h>
- #include <sys/stat.h>
- #include <dirent.h>
- #include <nuttx/fs/fs.h>
- #ifdef CONFIG_FS_USERFS
- /****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
- /* UserFS IOCTLs are defined in included/nuttx/fs/ioctl.h. There is only one:
- *
- * FIONUSERFS. The is the IOCTL that is used with the dev/userfs factory to
- * create a UserFS instance.
- *
- * Input: This function receives an pointer to a read-only instance of
- * struct userfs_config_s that contains information needed to
- * configure the UserFS instance.
- * Output: On success the UserFS nn instance is created. nn is non-negative
- * and will be provided as the IOCTL return value on success. On
- * failure, ioctl() will return -1 with the errno variable set to
- * indicate the cause of the failure.
- */
- /* This is the base value of the server port number. The actual range is
- * 0x8300 through 0x83ff.
- */
- #define USERFS_SERVER_PORTBASE 0x8300
- /* It looks like the maximum size of a request is 16 bytes. We will allow a
- * little more for the maximum size of a request structure.
- */
- #define USERFS_REQ_MAXSIZE (32)
- /****************************************************************************
- * Public Data
- ****************************************************************************/
- /* This enumeration provides the type of each request sent from the OS file
- * system client to the user file system.
- */
- enum userfs_req_e
- {
- USERFS_REQ_OPEN = 0,
- USERFS_REQ_CLOSE,
- USERFS_REQ_READ,
- USERFS_REQ_WRITE,
- USERFS_REQ_SEEK,
- USERFS_REQ_IOCTL,
- USERFS_REQ_SYNC,
- USERFS_REQ_DUP,
- USERFS_REQ_FSTAT,
- USERFS_REQ_TRUNCATE,
- USERFS_REQ_OPENDIR,
- USERFS_REQ_CLOSEDIR,
- USERFS_REQ_READDIR,
- USERFS_REQ_REWINDDIR,
- USERFS_REQ_STATFS,
- USERFS_REQ_UNLINK,
- USERFS_REQ_MKDIR,
- USERFS_REQ_RMDIR,
- USERFS_REQ_RENAME,
- USERFS_REQ_STAT,
- USERFS_REQ_DESTROY
- };
- /* This enumeration provides the type of each response returned from the
- * user file system to OS file system client.
- */
- enum userfs_resp_e
- {
- USERFS_RESP_OPEN = 0,
- USERFS_RESP_CLOSE,
- USERFS_RESP_READ,
- USERFS_RESP_WRITE,
- USERFS_RESP_SEEK,
- USERFS_RESP_IOCTL,
- USERFS_RESP_SYNC,
- USERFS_RESP_DUP,
- USERFS_RESP_FSTAT,
- USERFS_RESP_OPENDIR,
- USERFS_RESP_CLOSEDIR,
- USERFS_RESP_READDIR,
- USERFS_RESP_REWINDDIR,
- USERFS_RESP_STATFS,
- USERFS_RESP_UNLINK,
- USERFS_RESP_MKDIR,
- USERFS_RESP_RMDIR,
- USERFS_RESP_RENAME,
- USERFS_RESP_STAT,
- USERFS_RESP_DESTROY
- };
- /* These structures are used by internal UserFS implementation and should not
- * be of interest to application level logic.
- *
- * This is passed to the mount() function as optional data when the UserFS
- * file system is mounted.
- */
- struct userfs_config_s
- {
- size_t mxwrite; /* The max size of a write data */
- uint16_t portno; /* The server port number (host order) */
- };
- /* This structure identifies the user-space file system operations. */
- struct stat; /* Forward reference */
- struct statfs; /* Forward reference */
- struct userfs_operations_s
- {
- int (*open)(FAR void *volinfo, FAR const char *relpath,
- int oflags, mode_t mode, FAR void **openinfo);
- int (*close)(FAR void *volinfo, FAR void *openinfo);
- ssize_t (*read)(FAR void *volinfo, FAR void *openinfo,
- FAR char *buffer, size_t buflen);
- ssize_t (*write)(FAR void *volinfo, FAR void *openinfo,
- FAR const char *buffer, size_t buflen);
- off_t (*seek)(FAR void *volinfo, FAR void *openinfo, off_t offset,
- int whence);
- int (*ioctl)(FAR void *volinfo, FAR void *openinfo, int cmd,
- unsigned long arg);
- int (*sync)(FAR void *volinfo, FAR void *openinfo);
- int (*dup)(FAR void *volinfo, FAR void *oldinfo, FAR void **newinfo);
- int (*fstat)(FAR void *volinfo, FAR void *openinfo,
- FAR struct stat *buf);
- int (*truncate)(FAR void *volinfo, FAR void *openinfo, off_t length);
- int (*opendir)(FAR void *volinfo, FAR const char *relpath,
- FAR void **dir);
- int (*closedir)(FAR void *volinfo, FAR void *dir);
- int (*readdir)(FAR void *volinfo, FAR void *dir,
- FAR struct dirent *entry);
- int (*rewinddir)(FAR void *volinfo, FAR void *dir);
- int (*statfs)(FAR void *volinfo, FAR struct statfs *buf);
- int (*unlink)(FAR void *volinfo, FAR const char *relpath);
- int (*mkdir)(FAR void *volinfo, FAR const char *relpath, mode_t mode);
- int (*rmdir)(FAR void *volinfo, FAR const char *relpath);
- int (*rename)(FAR void *volinfo, FAR const char *oldrelpath,
- FAR const char *newrelpath);
- int (*stat)(FAR void *volinfo, FAR const char *relpath,
- FAR struct stat *buf);
- int (*destroy)(FAR void *volinfo);
- };
- /* The following structures describe the header on the marshaled data sent
- * on the FIFOs. See struct userfs_operations_s for the form of the
- * marshaled function calls.
- */
- struct userfs_open_request_s
- {
- uint8_t req; /* Must be USERFS_REQ_OPEN */
- int oflags; /* Open flags */
- mode_t mode; /* Open mode */
- char relpath[1]; /* Mountpoint relative path to the file to open */
- };
- #define SIZEOF_USERFS_OPEN_REQUEST_S(n) (sizeof(struct userfs_open_request_s) + (n) - 1)
- struct userfs_open_response_s
- {
- uint8_t resp; /* Must be USERFS_RESP_OPEN */
- FAR void *openinfo; /* Open file info for use in other operations */
- int ret; /* Result of the operation */
- };
- struct userfs_close_request_s
- {
- uint8_t req; /* Must be USERFS_REQ_CLOSE */
- FAR void *openinfo; /* Open file info as returned by open() */
- };
- struct userfs_close_response_s
- {
- uint8_t resp; /* Must be USERFS_RESP_CLOSE */
- int ret; /* Result of the operation */
- };
- struct userfs_read_request_s
- {
- uint8_t req; /* Must be USERFS_REQ_READ */
- FAR void *openinfo; /* Open file info as returned by open() */
- size_t readlen; /* Maximum number of bytes to read */
- };
- struct userfs_read_response_s
- {
- uint8_t resp; /* Must be USERFS_RESP_READ */
- ssize_t nread; /* Result of the operation */
- char rddata[1]; /* Read data follows. Actual size is nread */
- };
- #define SIZEOF_USERFS_READ_RESPONSE_S(n) (sizeof(struct userfs_read_response_s) + (n) - 1)
- struct userfs_write_request_s
- {
- uint8_t req; /* Must be USERFS_REQ_WRITE */
- FAR void *openinfo; /* Open file info as returned by open() */
- size_t writelen; /* Number of bytes to write */
- char wrdata[1]; /* Read data follows. Actual size is wrsize */
- };
- #define SIZEOF_USERFS_WRITE_REQUEST_S(n) (sizeof(struct userfs_write_request_s) + (n) - 1)
- struct userfs_write_response_s
- {
- uint8_t resp; /* Must be USERFS_RESP_WRITE */
- ssize_t nwritten; /* Result of the operation */
- };
- struct userfs_seek_request_s
- {
- uint8_t req; /* Must be USERFS_REQ_SEEK */
- FAR void *openinfo; /* Open file info as returned by open() */
- off_t offset; /* Seek offset */
- int whence; /* Determines how offset is interpreted */
- };
- struct userfs_seek_response_s
- {
- uint8_t resp; /* Must be USERFS_RESP_SEEK */
- off_t ret; /* Result of the operation */
- };
- struct userfs_ioctl_request_s
- {
- uint8_t req; /* Must be USERFS_REQ_IOCTL */
- FAR void *openinfo; /* Open file info as returned by open() */
- int cmd; /* IOCTL command */
- unsigned long arg; /* Argument that accompanies the command */
- };
- struct userfs_ioctl_response_s
- {
- uint8_t resp; /* Must be USERFS_RESP_IOCTL */
- int ret; /* Result of the operation */
- };
- struct userfs_sync_request_s
- {
- uint8_t req; /* Must be USERFS_REQ_SYNC */
- FAR void *openinfo; /* Open file info as returned by open() */
- };
- struct userfs_sync_response_s
- {
- uint8_t resp; /* Must be USERFS_RESP_SYNC */
- int ret; /* Result of the operation */
- };
- struct userfs_dup_request_s
- {
- uint8_t req; /* Must be USERFS_REQ_DUP */
- FAR void *openinfo; /* Open file info as returned by open() */
- };
- struct userfs_dup_response_s
- {
- uint8_t resp; /* Must be USERFS_RESP_DUP */
- FAR void *openinfo; /* Open file info for the dup'ed file */
- int ret; /* Result of the operation */
- };
- struct userfs_fstat_request_s
- {
- uint8_t req; /* Must be USERFS_REQ_FSTAT */
- FAR void *openinfo; /* Open file info as returned by open() */
- };
- struct userfs_fstat_response_s
- {
- uint8_t resp; /* Must be USERFS_RESP_FSTAT */
- int ret; /* Result of the operation */
- FAR struct stat buf; /* Returned file system status */
- };
- struct userfs_truncate_request_s
- {
- uint8_t req; /* Must be USERFS_REQ_TRUNCATE */
- FAR void *openinfo; /* Open file info as returned by open() */
- off_t length; /* New length of the file */
- };
- struct userfs_truncate_response_s
- {
- uint8_t resp; /* Must be USERFS_RESP_FSTAT */
- int ret; /* Result of the operation */
- };
- struct userfs_opendir_request_s
- {
- uint8_t req; /* Must be USERFS_REQ_OPENDIR */
- char relpath[1]; /* Mountpoint relative path to the directory to open */
- };
- #define SIZEOF_USERFS_OPENDIR_REQUEST_S(n) (sizeof(struct userfs_opendir_request_s) + (n) - 1)
- struct userfs_opendir_response_s
- {
- uint8_t resp; /* Must be USERFS_RESP_OPENDIR */
- int ret; /* Result of the operation */
- FAR void *dir; /* Opaque pointer to directory information */
- };
- struct userfs_closedir_request_s
- {
- uint8_t req; /* Must be USERFS_REQ_CLOSEDIR */
- FAR void *dir; /* Opaque pointer to directory information */
- };
- struct userfs_closedir_response_s
- {
- uint8_t resp; /* Must be USERFS_RESP_CLOSEDIR */
- int ret; /* Result of the operation */
- };
- struct userfs_readdir_request_s
- {
- uint8_t req; /* Must be USERFS_REQ_READDIR */
- FAR void *dir; /* Opaque pointer to directory information */
- };
- struct userfs_readdir_response_s
- {
- uint8_t resp; /* Must be USERFS_RESP_READDIR */
- int ret; /* Result of the operation */
- struct dirent entry; /* Directory entry that was read */
- };
- struct userfs_rewinddir_request_s
- {
- uint8_t req; /* Must be USERFS_REQ_REWINDDIR */
- FAR void *dir; /* Opaque pointer to directory information */
- };
- struct userfs_rewinddir_response_s
- {
- uint8_t resp; /* Must be USERFS_RESP_REWINDDIR */
- int ret; /* Result of the operation */
- };
- struct userfs_statfs_request_s
- {
- uint8_t req; /* Must be USERFS_REQ_STATFS */
- };
- struct userfs_statfs_response_s
- {
- uint8_t resp; /* Must be USERFS_RESP_STATFS */
- int ret; /* Result of the operation */
- FAR struct statfs buf; /* Returned file system status */
- };
- struct userfs_unlink_request_s
- {
- uint8_t req; /* Must be USERFS_REQ_UNLINK */
- char relpath[1]; /* Relative path to the entry to unlink */
- };
- #define SIZEOF_USERFS_UNLINK_REQUEST_S(n) (sizeof(struct userfs_unlink_request_s) + (n) - 1)
- struct userfs_unlink_response_s
- {
- uint8_t resp; /* Must be USERFS_RESP_UNLINK */
- int ret; /* Result of the operation */
- };
- struct userfs_mkdir_request_s
- {
- uint8_t req; /* Must be USERFS_REQ_MKDIR */
- mode_t mode; /* Directory mode flags */
- char relpath[1]; /* Relative path to the directory to create */
- };
- #define SIZEOF_USERFS_MKDIR_REQUEST_S(n) (sizeof(struct userfs_mkdir_request_s) + (n) - 1)
- struct userfs_mkdir_response_s
- {
- uint8_t resp; /* Must be USERFS_RESP_MKDIR */
- int ret; /* Result of the operation */
- };
- struct userfs_rmdir_request_s
- {
- uint8_t req; /* Must be USERFS_REQ_RMDIR */
- char relpath[1]; /* Relative path to the directory to remove */
- };
- #define SIZEOF_USERFS_RMDIR_REQUEST_S(n) (sizeof(struct userfs_rmdir_request_s) + (n) - 1)
- struct userfs_rmdir_response_s
- {
- uint8_t resp; /* Must be USERFS_RESP_RMDIR */
- int ret; /* Result of the operation */
- };
- struct userfs_rename_request_s
- {
- uint8_t req; /* Must be USERFS_REQ_RENAME */
- uint16_t newoffset; /* Offset from old to new relpath */
- char oldrelpath[1]; /* Old relative path to be renamed */
- };
- #define SIZEOF_USERFS_RENAME_REQUEST_S(o,n) (sizeof(struct userfs_rename_request_s) + (o) + (n))
- struct userfs_rename_response_s
- {
- uint8_t resp; /* Must be USERFS_RESP_RENAME */
- int ret; /* Result of the operation */
- };
- struct userfs_stat_request_s
- {
- uint8_t req; /* Must be USERFS_REQ_STAT */
- char relpath[1]; /* Relative path to the directory entry to be queried */
- };
- #define SIZEOF_USERFS_STAT_REQUEST_S(n) (sizeof(struct userfs_stat_request_s) + (n) - 1)
- struct userfs_stat_response_s
- {
- uint8_t resp; /* Must be USERFS_RESP_STAT */
- int ret; /* Result of the operation */
- FAR struct stat buf; /* Returned status of the directory entry */
- };
- struct userfs_destroy_request_s
- {
- uint8_t req; /* Must be USERFS_REQ_DESTROY */
- };
- struct userfs_destroy_response_s
- {
- uint8_t resp; /* Must be USERFS_RESP_DESTROY */
- int ret; /* Result of the operation */
- };
- /****************************************************************************
- * Public Function Prototypes
- ****************************************************************************/
- #ifdef __cplusplus
- #define EXTERN extern "C"
- extern "C"
- {
- #else
- #define EXTERN extern
- #endif
- /****************************************************************************
- * Name: userfs_register
- *
- * Description:
- * Register the UserFS factory driver at dev/userfs.
- *
- * NOTE: This is an OS internal function that should not be called from
- * application logic.
- *
- * Input Parameters:
- * None
- *
- * Returned Value:
- * Zero (OK) is returned if the dev/userfs driver was initialized and
- * registered properly. Otherwise, a negated errno value is returned
- * to indicate the nature of the failure.
- *
- ****************************************************************************/
- int userfs_register(void);
- /****************************************************************************
- * Name: userfs_run
- *
- * Description:
- * Start the UserFS server on the current thread. This function will mount
- * the UserFS file system and will not return until that file system has
- * been unmounted.
- *
- * userfs_run() implements the UserFS server. It performs there operations:
- *
- * 1. It configures and creates the UserFS file system and
- * 2. Mounts the user file system at the provide mount point path.
- * 2. Receives file system requests on the LocalHost socket with
- * server port 0x83nn where nn is the same as above,
- * 3. Received file system requests are marshaled and dispatch to the
- * user file system via callbacks to the operations provided by
- * "userops", and
- * 3. Returns file system responses generated by the callbacks to the
- * LocalHost client socket.
- *
- * NOTE: This is a user function that is implemented as part of the
- * NuttX C library and is intended to be called by application logic.
- *
- * Input Parameters:
- * mountpt - Mountpoint path
- * userops - The caller operations that implement the file system
- * interface.
- * volinfo - Private volume data that will be provided in all struct
- * userfs_operations_s methods.
- * mxwrite - The max size of a write data
- *
- * Returned Value:
- * This function does not return unless the file system is unmounted (OK)
- * or unless an error is encountered. In the event of an error, the
- * returned value is a negated errno value indicating the nature of the
- * error.
- *
- ****************************************************************************/
- int userfs_run(FAR const char *mountpt,
- FAR const struct userfs_operations_s *userops,
- FAR void *volinfo, size_t mxwrite);
- #undef EXTERN
- #ifdef __cplusplus
- }
- #endif
- #endif /* CONFIG_FS_USERFS */
- #endif /* __INCLUDE_NUTTX_FS_USERFSFS_H */
|