open() has been extended. You can now open block drivers and access them just as you can character drivers. For example, you can hexdump a block device.

This commit is contained in:
Gregory Nutt 2015-11-21 11:24:55 -06:00
parent dcb85af387
commit 84a5f846c9
4 changed files with 84 additions and 11 deletions

View File

@ -11132,4 +11132,9 @@
* drivers/timers/pcf85263.c and include/nuttx/times/pcf85263.h: Add
a driver for the NXP PCF85263 I2C RTC. Untested on initial commit
(2015-11-20).
* fs/driver/fs_blockproxy.c: Add logic to create a temporary char driver
using drivers/bch to mediate character oriented accessed to a block
driver (2015-11-21).
* fs/vfs/open.c: If the use attempts to open a block driver, use
block_proxy() to insert a character driver conversion layer in front
of the block driver (2015-11-21).

View File

@ -91,8 +91,43 @@ extern "C"
*
****************************************************************************/
#ifndef CONFIG_DISABLE_MOUNTPOINT
int find_blockdriver(FAR const char *pathname, int mountflags,
FAR struct inode **ppinode);
#endif
/* fs/drivers/fs_blockproxy.c ***********************************************/
/****************************************************************************
* Name: block_proxy
*
* Description:
* Create a temporary char driver using drivers/bch to mediate character
* oriented accessed to the block driver.
*
* Input parameters:
* blkdev - The path to the block driver
* oflags - Character driver open flags
*
* Returned Value:
* If positive, non-zero file descriptor is returned on success. This
* is the file descriptor of the nameless character driver that mediates
* accesses to the block driver.
*
* Errors that may be returned:
*
* ENOMEM - Failed to create a temporay path name.
*
* Plus:
*
* - Errors reported from bchdev_register()
* - Errors reported from open() or unlink()
*
****************************************************************************/
#if !defined(CONFIG_DISABLE_PSEUDOFS_OPERATIONS) && \
!defined(CONFIG_DISABLE_MOUNTPOINT)
int block_proxy(FAR const char *blkdev, int oflags);
#endif
#undef EXTERN
#if defined(__cplusplus)

View File

@ -148,12 +148,12 @@ static FAR char *unique_chardev(void)
* Name: block_proxy
*
* Description:
* Create a temporary char driver using drivers/bch that mediate character
* Create a temporary char driver using drivers/bch to mediate character
* oriented accessed to the block driver.
*
* Input parameters:
* blkdev - The path to the block driver
* mode - Character driver access priviledges
* oflags - Character driver open flags
*
* Returned Value:
* If positive, non-zero file descriptor is returned on success. This
@ -171,7 +171,7 @@ static FAR char *unique_chardev(void)
*
****************************************************************************/
int block_proxy(FAR const char *blkdev, mode_t mode)
int block_proxy(FAR const char *blkdev, int oflags)
{
FAR char *chardev;
bool readonly;
@ -179,7 +179,7 @@ int block_proxy(FAR const char *blkdev, mode_t mode)
int fd;
DEBUGASSERT(blkdev);
DEBUGASSERT((mode & (O_CREAT | O_EXCL | O_APPEND | O_TRUNC)) == 0);
DEBUGASSERT((oflags & (O_CREAT | O_EXCL | O_APPEND | O_TRUNC)) == 0);
/* Create a unique temporary file name for the character device */
@ -192,7 +192,7 @@ int block_proxy(FAR const char *blkdev, mode_t mode)
/* Should this character driver be read-only? */
readonly = ((mode & O_WROK) == 0);
readonly = ((oflags & O_WROK) == 0);
/* Wrap the block driver with an instance of the BCH driver */
@ -207,8 +207,8 @@ int block_proxy(FAR const char *blkdev, mode_t mode)
/* Open the newly created character driver */
mode &= ~(O_CREAT | O_EXCL | O_APPEND | O_TRUNC);
fd = open(chardev, mode);
oflags &= ~(O_CREAT | O_EXCL | O_APPEND | O_TRUNC);
fd = open(chardev, oflags);
if (fd < 0)
{
ret = -errno;

View File

@ -130,9 +130,42 @@ int open(const char *path, int oflags, ...)
goto errout;
}
/* Verify that the inode is valid and either a "normal" character driver or a
* mountpoint. We specifically exclude block drivers and and "special"
* inodes (semaphores, message queues, shared memory).
#if !defined(CONFIG_DISABLE_PSEUDOFS_OPERATIONS) && \
!defined(CONFIG_DISABLE_MOUNTPOINT)
/* If the inode is block driver, then we may return a character driver
* proxy for the block driver. block_proxy() will instantiate a BCH
* character driver wrapper around the block driver, open(), then
* unlink() the character driver. On success, block_proxy() will
* return the file descriptor of the opened character driver.
*
* NOTE: This will recurse to open the character driver proxy.
*/
if (INODE_IS_BLOCK(inode))
{
/* Release the inode reference */
inode_release(inode);
/* Get the file descriptor of the opened character driver proxy */
fd = block_proxy(path, oflags);
if (fd < 0)
{
ret = fd;
goto errout;
}
/* Return the file descriptor */
return fd;
}
else
#endif
/* Verify that the inode is either a "normal" character driver or a
* mountpoint. We specifically "special" inodes (semaphores, message
* queues, shared memory).
*/
#ifndef CONFIG_DISABLE_MOUNTPOINT