From c7eca3d176baef559dc2ca6c921c231a1fad7f75 Mon Sep 17 00:00:00 2001 From: dongjiuzhu1 Date: Thu, 22 Dec 2022 22:15:40 +0800 Subject: [PATCH] timerfd/eventfd: using file_allocate to replace register_driver Signed-off-by: dongjiuzhu1 --- fs/vfs/Kconfig | 12 ----- fs/vfs/fs_eventfd.c | 128 ++++++++++++++------------------------------ fs/vfs/fs_timerfd.c | 119 ++++++++++++---------------------------- 3 files changed, 76 insertions(+), 183 deletions(-) diff --git a/fs/vfs/Kconfig b/fs/vfs/Kconfig index b722b09903..9b3c63ec6a 100644 --- a/fs/vfs/Kconfig +++ b/fs/vfs/Kconfig @@ -11,12 +11,6 @@ config EVENT_FD if EVENT_FD -config EVENT_FD_VFS_PATH - string "Path to eventfd storage" - default "/var/event" - ---help--- - The path to where eventfd will exist in the VFS namespace. - config EVENT_FD_POLL bool "EventFD poll support" default y @@ -40,12 +34,6 @@ config TIMER_FD if TIMER_FD -config TIMER_FD_VFS_PATH - string "Path to timerfd storage" - default "/var/timer" - ---help--- - The path to where timerfd will exist in the VFS namespace. - config TIMER_FD_POLL bool "TimerFD poll support" default y diff --git a/fs/vfs/fs_eventfd.c b/fs/vfs/fs_eventfd.c index 1f2ef29a83..30321d20bc 100644 --- a/fs/vfs/fs_eventfd.c +++ b/fs/vfs/fs_eventfd.c @@ -43,20 +43,18 @@ typedef struct eventfd_waiter_sem_s { sem_t sem; - struct eventfd_waiter_sem_s *next; + FAR struct eventfd_waiter_sem_s *next; } eventfd_waiter_sem_t; /* This structure describes the internal state of the driver */ struct eventfd_priv_s { - mutex_t lock; /* Enforces device exclusive access */ - FAR eventfd_waiter_sem_t *rdsems; /* List of blocking readers */ - FAR eventfd_waiter_sem_t *wrsems; /* List of blocking writers */ - eventfd_t counter; /* eventfd counter */ - unsigned int minor; /* eventfd minor number */ - uint8_t crefs; /* References counts on eventfd (max: 255) */ - bool mode_semaphore; /* eventfd mode (semaphore or counter) */ + mutex_t lock; /* Enforces device exclusive access */ + FAR eventfd_waiter_sem_t *rdsems; /* List of blocking readers */ + FAR eventfd_waiter_sem_t *wrsems; /* List of blocking writers */ + eventfd_t counter; /* eventfd counter */ + uint8_t crefs; /* References counts on eventfd (max: 255) */ /* The following is a list if poll structures of threads waiting for * driver events. @@ -87,9 +85,6 @@ static int eventfd_blocking_io(FAR struct eventfd_priv_s *dev, FAR eventfd_waiter_sem_t *sem, FAR eventfd_waiter_sem_t **slist); -static unsigned int eventfd_get_unique_minor(void); -static void eventfd_release_minor(unsigned int minor); - static FAR struct eventfd_priv_s *eventfd_allocdev(void); static void eventfd_destroy(FAR struct eventfd_priv_s *dev); @@ -115,6 +110,18 @@ static const struct file_operations g_eventfd_fops = #endif }; +static struct inode g_eventfd_inode = +{ + NULL, /* i_parent */ + NULL, /* i_peer */ + NULL, /* i_child */ + 1, /* i_crefs */ + FSNODEFLAG_TYPE_DRIVER, /* i_flags */ + { + &g_eventfd_fops /* u */ + } +}; + /**************************************************************************** * Private Functions ****************************************************************************/ @@ -138,25 +145,14 @@ static FAR struct eventfd_priv_s *eventfd_allocdev(void) static void eventfd_destroy(FAR struct eventfd_priv_s *dev) { + nxmutex_unlock(&dev->lock); nxmutex_destroy(&dev->lock); kmm_free(dev); } -static unsigned int eventfd_get_unique_minor(void) -{ - static unsigned int minor; - - return minor++; -} - -static void eventfd_release_minor(unsigned int minor) -{ -} - static int eventfd_do_open(FAR struct file *filep) { - FAR struct inode *inode = filep->f_inode; - FAR struct eventfd_priv_s *priv = inode->i_private; + FAR struct eventfd_priv_s *priv = filep->f_priv; int ret; /* Get exclusive access to the device structures */ @@ -167,8 +163,6 @@ static int eventfd_do_open(FAR struct file *filep) return ret; } - finfo("crefs: %d <%s>\n", priv->crefs, inode->i_name); - if (priv->crefs >= 255) { /* More than 255 opens; uint8_t would overflow to zero */ @@ -189,13 +183,8 @@ static int eventfd_do_open(FAR struct file *filep) static int eventfd_do_close(FAR struct file *filep) { + FAR struct eventfd_priv_s *priv = filep->f_priv; int ret; - FAR struct inode *inode = filep->f_inode; - FAR struct eventfd_priv_s *priv = inode->i_private; - - /* devpath: EVENT_FD_VFS_PATH + /efd (4) + %u (10) + null char (1) */ - - char devpath[sizeof(CONFIG_EVENT_FD_VFS_PATH) + 4 + 10 + 1]; /* Get exclusive access to the device structures */ @@ -205,8 +194,6 @@ static int eventfd_do_close(FAR struct file *filep) return ret; } - finfo("crefs: %d <%s>\n", priv->crefs, inode->i_name); - /* Decrement the references to the driver. If the reference count will * decrement to 0, then uninitialize the driver. */ @@ -223,16 +210,8 @@ static int eventfd_do_close(FAR struct file *filep) /* Re-create the path to the driver. */ finfo("destroy\n"); - sprintf(devpath, CONFIG_EVENT_FD_VFS_PATH "/efd%u", priv->minor); - /* Will be unregistered later after close is done */ - - unregister_driver(devpath); - - DEBUGASSERT(nxmutex_is_locked(&priv->lock)); - eventfd_release_minor(priv->minor); eventfd_destroy(priv); - return OK; } @@ -241,6 +220,7 @@ static int eventfd_blocking_io(FAR struct eventfd_priv_s *dev, FAR eventfd_waiter_sem_t **slist) { int ret; + sem->next = *slist; *slist = sem; @@ -287,8 +267,7 @@ static int eventfd_blocking_io(FAR struct eventfd_priv_s *dev, static ssize_t eventfd_do_read(FAR struct file *filep, FAR char *buffer, size_t len) { - FAR struct inode *inode = filep->f_inode; - FAR struct eventfd_priv_s *dev = inode->i_private; + FAR struct eventfd_priv_s *dev = filep->f_priv; FAR eventfd_waiter_sem_t *cur_sem; ssize_t ret; @@ -332,7 +311,7 @@ static ssize_t eventfd_do_read(FAR struct file *filep, FAR char *buffer, /* Device ready for read */ - if (dev->mode_semaphore) + if ((filep->f_oflags & EFD_SEMAPHORE) != 0) { *(FAR eventfd_t *)buffer = 1; dev->counter -= 1; @@ -367,11 +346,10 @@ static ssize_t eventfd_do_read(FAR struct file *filep, FAR char *buffer, static ssize_t eventfd_do_write(FAR struct file *filep, FAR const char *buffer, size_t len) { - FAR struct inode *inode = filep->f_inode; - FAR struct eventfd_priv_s *dev = inode->i_private; + FAR struct eventfd_priv_s *dev = filep->f_priv; FAR eventfd_waiter_sem_t *cur_sem; - ssize_t ret; eventfd_t new_counter; + ssize_t ret; if (len < sizeof(eventfd_t) || buffer == NULL || (*(FAR eventfd_t *)buffer == (eventfd_t)-1) || @@ -443,10 +421,9 @@ static ssize_t eventfd_do_write(FAR struct file *filep, #ifdef CONFIG_EVENT_FD_POLL static int eventfd_do_poll(FAR struct file *filep, FAR struct pollfd *fds, - bool setup) + bool setup) { - FAR struct inode *inode = filep->f_inode; - FAR struct eventfd_priv_s *dev = inode->i_private; + FAR struct eventfd_priv_s *dev = filep->f_priv; int ret; int i; pollevent_t eventset; @@ -528,13 +505,15 @@ out: int eventfd(unsigned int count, int flags) { - int ret; - int new_fd; FAR struct eventfd_priv_s *new_dev; + int new_fd; + int ret; - /* devpath: EVENT_FD_VFS_PATH + /efd (4) + %u (10) + null char (1) */ - - char devpath[sizeof(CONFIG_EVENT_FD_VFS_PATH) + 4 + 10 + 1]; + if ((flags & ~(EFD_NONBLOCK | EFD_SEMAPHORE | EFD_CLOEXEC)) != 0) + { + ret = -EINVAL; + goto exit_set_errno; + } /* Allocate instance data for this driver */ @@ -548,46 +527,21 @@ int eventfd(unsigned int count, int flags) } new_dev->counter = count; - new_dev->mode_semaphore = !!(flags & EFD_SEMAPHORE); - - /* Request a unique minor device number */ - - new_dev->minor = eventfd_get_unique_minor(); - - /* Get device path */ - - sprintf(devpath, CONFIG_EVENT_FD_VFS_PATH "/efd%u", new_dev->minor); - - /* Register the driver */ - - ret = register_driver(devpath, &g_eventfd_fops, 0666, new_dev); - if (ret < 0) + new_fd = file_allocate(&g_eventfd_inode, O_RDWR | flags, + 0, new_dev, 0, true); + if (new_fd < 0) { - ferr("Failed to register new device %s: %d\n", devpath, ret); - goto exit_release_minor; + ret = new_fd; + goto exit_with_dev; } /* Device is ready for use */ nxmutex_unlock(&new_dev->lock); - /* Try open new device */ - - new_fd = nx_open(devpath, O_RDWR | - (flags & (EFD_NONBLOCK | EFD_SEMAPHORE | EFD_CLOEXEC))); - - if (new_fd < 0) - { - ret = new_fd; - goto exit_unregister_driver; - } - return new_fd; -exit_unregister_driver: - unregister_driver(devpath); -exit_release_minor: - eventfd_release_minor(new_dev->minor); +exit_with_dev: eventfd_destroy(new_dev); exit_set_errno: set_errno(-ret); diff --git a/fs/vfs/fs_timerfd.c b/fs/vfs/fs_timerfd.c index d6c5460aa6..6fe502c6d0 100644 --- a/fs/vfs/fs_timerfd.c +++ b/fs/vfs/fs_timerfd.c @@ -55,7 +55,7 @@ typedef struct timerfd_waiter_sem_s { sem_t sem; - struct timerfd_waiter_sem_s *next; + FAR struct timerfd_waiter_sem_s *next; } timerfd_waiter_sem_t; /* This structure describes the internal state of the driver */ @@ -71,7 +71,6 @@ struct timerfd_priv_s struct work_s work; /* For deferred timeout operations */ timerfd_t counter; /* timerfd counter */ spinlock_t splock; /* timerfd counter specific lock */ - unsigned int minor; /* timerfd minor number */ uint8_t crefs; /* References counts on timerfd (max: 255) */ /* The following is a list if poll structures of threads waiting for @@ -101,9 +100,6 @@ static int timerfd_blocking_io(FAR struct timerfd_priv_s *dev, FAR timerfd_waiter_sem_t *sem, FAR timerfd_waiter_sem_t **slist); -static unsigned int timerfd_get_unique_minor(void); -static void timerfd_release_minor(unsigned int minor); - static FAR struct timerfd_priv_s *timerfd_allocdev(void); static void timerfd_destroy(FAR struct timerfd_priv_s *dev); @@ -132,6 +128,18 @@ static const struct file_operations g_timerfd_fops = #endif }; +static struct inode g_timerfd_inode = +{ + NULL, /* i_parent */ + NULL, /* i_peer */ + NULL, /* i_child */ + 1, /* i_crefs */ + FSNODEFLAG_TYPE_DRIVER, /* i_flags */ + { + &g_timerfd_fops /* u */ + } +}; + /**************************************************************************** * Private Functions ****************************************************************************/ @@ -157,6 +165,7 @@ static void timerfd_destroy(FAR struct timerfd_priv_s *dev) { wd_cancel(&dev->wdog); work_cancel(TIMER_FD_WORK, &dev->work); + nxmutex_unlock(&dev->lock); nxmutex_destroy(&dev->lock); kmm_free(dev); } @@ -173,21 +182,9 @@ static timerfd_t timerfd_get_counter(FAR struct timerfd_priv_s *dev) return counter; } -static unsigned int timerfd_get_unique_minor(void) -{ - static unsigned int minor; - - return minor++; -} - -static void timerfd_release_minor(unsigned int minor) -{ -} - static int timerfd_open(FAR struct file *filep) { - FAR struct inode *inode = filep->f_inode; - FAR struct timerfd_priv_s *priv = inode->i_private; + FAR struct timerfd_priv_s *priv = filep->f_priv; int ret; /* Get exclusive access to the device structures */ @@ -198,8 +195,6 @@ static int timerfd_open(FAR struct file *filep) return ret; } - finfo("crefs: %d <%s>\n", priv->crefs, inode->i_name); - if (priv->crefs >= 255) { /* More than 255 opens; uint8_t would overflow to zero */ @@ -220,13 +215,8 @@ static int timerfd_open(FAR struct file *filep) static int timerfd_close(FAR struct file *filep) { + FAR struct timerfd_priv_s *priv = filep->f_priv; int ret; - FAR struct inode *inode = filep->f_inode; - FAR struct timerfd_priv_s *priv = inode->i_private; - - /* devpath: TIMER_FD_VFS_PATH + /tfd (4) + %u (10) + null char (1) */ - - char devpath[sizeof(CONFIG_TIMER_FD_VFS_PATH) + 4 + 10 + 1]; /* Get exclusive access to the device structures */ @@ -236,8 +226,6 @@ static int timerfd_close(FAR struct file *filep) return ret; } - finfo("crefs: %d <%s>\n", priv->crefs, inode->i_name); - /* Decrement the references to the driver. If the reference count will * decrement to 0, then uninitialize the driver. */ @@ -254,16 +242,8 @@ static int timerfd_close(FAR struct file *filep) /* Re-create the path to the driver. */ finfo("destroy\n"); - sprintf(devpath, CONFIG_TIMER_FD_VFS_PATH "/tfd%u", priv->minor); - /* Will be unregistered later after close is done */ - - unregister_driver(devpath); - - DEBUGASSERT(nxmutex_is_locked(&priv->lock)); - timerfd_release_minor(priv->minor); timerfd_destroy(priv); - return OK; } @@ -272,6 +252,7 @@ static int timerfd_blocking_io(FAR struct timerfd_priv_s *dev, FAR timerfd_waiter_sem_t **slist) { int ret; + sem->next = *slist; *slist = sem; @@ -318,8 +299,7 @@ static int timerfd_blocking_io(FAR struct timerfd_priv_s *dev, static ssize_t timerfd_read(FAR struct file *filep, FAR char *buffer, size_t len) { - FAR struct inode *inode = filep->f_inode; - FAR struct timerfd_priv_s *dev = inode->i_private; + FAR struct timerfd_priv_s *dev = filep->f_priv; irqstate_t intflags; ssize_t ret; @@ -381,8 +361,7 @@ static ssize_t timerfd_read(FAR struct file *filep, FAR char *buffer, static int timerfd_poll(FAR struct file *filep, FAR struct pollfd *fds, bool setup) { - FAR struct inode *inode = filep->f_inode; - FAR struct timerfd_priv_s *dev = inode->i_private; + FAR struct timerfd_priv_s *dev = filep->f_priv; int ret; int i; @@ -402,8 +381,8 @@ static int timerfd_poll(FAR struct file *filep, FAR struct pollfd *fds, /* Remove all memory of the poll setup */ - *slot = NULL; - fds->priv = NULL; + *slot = NULL; + fds->priv = NULL; goto out; } @@ -518,18 +497,15 @@ int timerfd_create(int clockid, int flags) /* Sanity checks. */ - if (clockid != CLOCK_REALTIME && - clockid != CLOCK_MONOTONIC && - clockid != CLOCK_BOOTTIME) + if ((clockid != CLOCK_REALTIME && + clockid != CLOCK_MONOTONIC && + clockid != CLOCK_BOOTTIME) || + (flags & ~(TFD_NONBLOCK | TFD_CLOEXEC)) != 0) { ret = -EINVAL; goto errout; } - /* devpath: TIMER_FD_VFS_PATH + /tfd (4) + %u (10) + null char (1) */ - - char devpath[sizeof(CONFIG_TIMER_FD_VFS_PATH) + 4 + 10 + 1]; - /* Allocate instance data for this driver */ new_dev = timerfd_allocdev(); @@ -544,46 +520,21 @@ int timerfd_create(int clockid, int flags) /* Initialize the timer instance */ new_dev->clock = clockid; - - /* Request a unique minor device number */ - - new_dev->minor = timerfd_get_unique_minor(); - - /* Get device path */ - - sprintf(devpath, CONFIG_TIMER_FD_VFS_PATH "/tfd%u", new_dev->minor); - - /* Register the driver */ - - ret = register_driver(devpath, &g_timerfd_fops, 0444, new_dev); - if (ret < 0) + new_fd = file_allocate(&g_timerfd_inode, O_RDONLY | flags, + 0, new_dev, 0, true); + if (new_fd < 0) { - ferr("Failed to register new device %s: %d\n", devpath, ret); - ret = -ENODEV; - goto errout_release_minor; + ret = new_fd; + goto errout_with_dev; } /* Device is ready for use */ nxmutex_unlock(&new_dev->lock); - /* Try open new device */ - - new_fd = nx_open(devpath, O_RDONLY | - (flags & (TFD_NONBLOCK | TFD_CLOEXEC))); - - if (new_fd < 0) - { - ret = new_fd; - goto errout_unregister_driver; - } - return new_fd; -errout_unregister_driver: - unregister_driver(devpath); -errout_release_minor: - timerfd_release_minor(new_dev->minor); +errout_with_dev: timerfd_destroy(new_dev); errout: set_errno(-ret); @@ -594,8 +545,8 @@ int timerfd_settime(int fd, int flags, FAR const struct itimerspec *new_value, FAR struct itimerspec *old_value) { - FAR struct file *filep; FAR struct timerfd_priv_s *dev; + FAR struct file *filep; irqstate_t intflags; sclock_t delay; int ret; @@ -630,7 +581,7 @@ int timerfd_settime(int fd, int flags, goto errout; } - dev = (FAR struct timerfd_priv_s *)filep->f_inode->i_private; + dev = (FAR struct timerfd_priv_s *)filep->f_priv; if (old_value) { @@ -743,8 +694,8 @@ errout: int timerfd_gettime(int fd, FAR struct itimerspec *curr_value) { - FAR struct file *filep; FAR struct timerfd_priv_s *dev; + FAR struct file *filep; sclock_t ticks; int ret; @@ -772,7 +723,7 @@ int timerfd_gettime(int fd, FAR struct itimerspec *curr_value) goto errout; } - dev = (FAR struct timerfd_priv_s *)filep->f_inode->i_private; + dev = (FAR struct timerfd_priv_s *)filep->f_priv; /* Get the number of ticks before the underlying watchdog expires */