From 23de88e70ecf75178cd03c3cb12fee2f5bc515b8 Mon Sep 17 00:00:00 2001 From: Antoine Juckler <6445757+ajuckler@users.noreply.github.com> Date: Thu, 3 Jul 2025 13:36:36 +0900 Subject: [PATCH] fs/fs.h: Add register_driver_with_size function It acts as register_driver but also populates the inode size. This allows to return a non-zero size when calling stat() on an eeprom driver. The conditions (CONFIG_PSEUDOFS_FILE or CONFIG_FS_SHMFS) for the declaration of the inode size field have also been removed so that other drivers can populate this field in the future. Signed-off-by: Antoine Juckler <6445757+ajuckler@users.noreply.github.com> --- drivers/eeprom/i2c_xx24xx.c | 3 +- drivers/eeprom/spi_xx25xx.c | 3 +- fs/driver/fs_registerdriver.c | 97 ++++++++++++++++++++++++----------- fs/vfs/fs_stat.c | 2 +- include/nuttx/fs/fs.h | 31 ++++++++++- 5 files changed, 100 insertions(+), 36 deletions(-) diff --git a/drivers/eeprom/i2c_xx24xx.c b/drivers/eeprom/i2c_xx24xx.c index 8806dcd20ec..92d40dd2a27 100644 --- a/drivers/eeprom/i2c_xx24xx.c +++ b/drivers/eeprom/i2c_xx24xx.c @@ -924,5 +924,6 @@ int ee24xx_initialize(FAR struct i2c_master_s *bus, uint8_t devaddr, } #endif - return register_driver(devname, &g_ee24xx_fops, 0666, eedev); + return register_driver_with_size(devname, &g_ee24xx_fops, 0666, eedev, + eedev->size); } diff --git a/drivers/eeprom/spi_xx25xx.c b/drivers/eeprom/spi_xx25xx.c index 04b9a1238b7..e0c9de53591 100644 --- a/drivers/eeprom/spi_xx25xx.c +++ b/drivers/eeprom/spi_xx25xx.c @@ -860,5 +860,6 @@ int ee25xx_initialize(FAR struct spi_dev_s *dev, FAR char *devname, "%u per page, addrlen %u, readonly %d\n", devname, eedev->size, eedev->pgsize, eedev->addrlen, eedev->readonly); - return register_driver(devname, &g_ee25xx_fops, 0666, eedev); + return register_driver_with_size(devname, &g_ee25xx_fops, 0666, eedev, + eedev->size); } diff --git a/fs/driver/fs_registerdriver.c b/fs/driver/fs_registerdriver.c index c14052ff782..f6c5512d6e3 100644 --- a/fs/driver/fs_registerdriver.c +++ b/fs/driver/fs_registerdriver.c @@ -39,11 +39,75 @@ * Public Functions ****************************************************************************/ +/**************************************************************************** + * Name: register_driver_with_size + * + * Description: + * Register a character driver inode into the pseudo file system and + * assign a size to it. + * + * Input Parameters: + * path - The path to the inode to create + * fops - The file operations structure + * mode - inmode privileges + * priv - Private, user data that will be associated with the inode. + * size - Size in bytes to assign to the driver + * + * Returned Value: + * Zero on success (with the inode point in 'inode'); A negated errno + * value is returned on a failure (all error values returned by + * inode_reserve): + * + * EINVAL - 'path' is invalid for this operation + * EEXIST - An inode already exists at 'path' + * ENOMEM - Failed to allocate in-memory resources for the operation + * + ****************************************************************************/ + +int register_driver_with_size(FAR const char *path, + FAR const struct file_operations *fops, + mode_t mode, FAR void *priv, size_t size) +{ + FAR struct inode *node; + int ret; + + sched_note_mark(NOTE_TAG_DRIVERS, path); + + /* Insert a dummy node -- we need to hold the inode semaphore because we + * will have a momentarily bad structure. + */ + + inode_lock(); + ret = inode_reserve(path, mode, &node); + if (ret >= 0) + { + /* We have it, now populate it with driver specific information. + * NOTE that the initial reference count on the new inode is zero. + */ + + INODE_SET_DRIVER(node); + + node->u.i_ops = fops; + node->i_private = priv; + node->i_size = size; + + inode_unlock(); +#ifdef CONFIG_FS_NOTIFY + notify_create(path); +#endif + + return OK; + } + + inode_unlock(); + return ret; +} + /**************************************************************************** * Name: register_driver * * Description: - * Register a character driver inode the pseudo file system. + * Register a character driver inode into the pseudo file system. * * Input Parameters: * path - The path to the inode to create @@ -66,34 +130,5 @@ int register_driver(FAR const char *path, FAR const struct file_operations *fops, mode_t mode, FAR void *priv) { - FAR struct inode *node; - int ret; - - sched_note_mark(NOTE_TAG_DRIVERS, path); - - /* Insert a dummy node -- we need to hold the inode semaphore because we - * will have a momentarily bad structure. - */ - - inode_lock(); - ret = inode_reserve(path, mode, &node); - if (ret >= 0) - { - /* We have it, now populate it with driver specific information. - * NOTE that the initial reference count on the new inode is zero. - */ - - INODE_SET_DRIVER(node); - - node->u.i_ops = fops; - node->i_private = priv; - inode_unlock(); -#ifdef CONFIG_FS_NOTIFY - notify_create(path); -#endif - return OK; - } - - inode_unlock(); - return ret; + return register_driver_with_size(path, fops, mode, priv, 0); } diff --git a/fs/vfs/fs_stat.c b/fs/vfs/fs_stat.c index e956fd1f9eb..22209d6e8c6 100644 --- a/fs/vfs/fs_stat.c +++ b/fs/vfs/fs_stat.c @@ -428,9 +428,9 @@ int inode_stat(FAR struct inode *inode, FAR struct stat *buf, int resolve) { /* What is it if it also has child inodes? */ -#ifdef CONFIG_PSEUDOFS_FILE buf->st_size = inode->i_size; +#ifdef CONFIG_PSEUDOFS_FILE if (inode_is_pseudofile(inode)) { buf->st_mode |= S_IFREG; diff --git a/include/nuttx/fs/fs.h b/include/nuttx/fs/fs.h index 2b738f01eb4..c819d464b8d 100644 --- a/include/nuttx/fs/fs.h +++ b/include/nuttx/fs/fs.h @@ -407,9 +407,7 @@ struct inode uint16_t i_flags; /* Flags for inode */ union inode_ops_u u; /* Inode operations */ ino_t i_ino; /* Inode serial number */ -#if defined(CONFIG_PSEUDOFS_FILE) || defined(CONFIG_FS_SHMFS) size_t i_size; /* The size of per inode driver */ -#endif #ifdef CONFIG_PSEUDOFS_ATTRIBUTES mode_t i_mode; /* Access mode flags */ uid_t i_owner; /* Owner */ @@ -625,6 +623,35 @@ int register_driver(FAR const char *path, FAR const struct file_operations *fops, mode_t mode, FAR void *priv); +/**************************************************************************** + * Name: register_driver_with_size + * + * Description: + * Register a character driver inode into the pseudo file system and + * assign a size to it. + * + * Input Parameters: + * path - The path to the inode to create + * fops - The file operations structure + * mode - inmode privileges + * priv - Private, user data that will be associated with the inode. + * size - Size in bytes to assign to the driver + * + * Returned Value: + * Zero on success (with the inode point in 'inode'); A negated errno + * value is returned on a failure (all error values returned by + * inode_reserve): + * + * EINVAL - 'path' is invalid for this operation + * EEXIST - An inode already exists at 'path' + * ENOMEM - Failed to allocate in-memory resources for the operation + * + ****************************************************************************/ + +int register_driver_with_size(FAR const char *path, + FAR const struct file_operations *fops, + mode_t mode, FAR void *priv, size_t size); + /**************************************************************************** * Name: register_blockdriver *