This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit a69d3d78fe39c602c351de7a2e8d65db271fbac0
Author: guohao15 <[email protected]>
AuthorDate: Fri May 31 16:30:53 2024 +0800

    inotify: add filter of notify options to reduce overload of system
    
    Signed-off-by: guohao15 <[email protected]>
---
 fs/notify/inotify.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 61 insertions(+), 4 deletions(-)

diff --git a/fs/notify/inotify.c b/fs/notify/inotify.c
index 74585c23b6..d621f42ebd 100644
--- a/fs/notify/inotify.c
+++ b/fs/notify/inotify.c
@@ -88,10 +88,12 @@ struct inotify_watch_s
 
 struct inotify_global_s
 {
-  mutex_t lock;               /* Enforces global exclusive access */
-  int     event_cookie;       /* Event cookie */
-  int     watch_cookie;       /* Watch cookie */
-  struct  hsearch_data hash;  /* Hash table for watch lists */
+  mutex_t  lock;               /* Enforces global exclusive access */
+  int      event_cookie;       /* Event cookie */
+  int      watch_cookie;       /* Watch cookie */
+  uint32_t read_count;         /* Number of read events */
+  uint32_t write_count;        /* Number of write events */
+  struct   hsearch_data hash;  /* Hash table for watch lists */
 };
 
 /****************************************************************************
@@ -145,6 +147,49 @@ static struct inotify_global_s g_inotify =
  * Private Functions
  ****************************************************************************/
 
+/****************************************************************************
+ * Name: notify_add_count
+ *
+ * Description:
+ *   Add the count.
+ *
+ ****************************************************************************/
+
+static void inotify_add_count(uint32_t mask)
+{
+  g_inotify.read_count += (mask & IN_ACCESS) ? 1 : 0;
+  g_inotify.write_count += (mask & IN_MODIFY) ? 1 : 0;
+}
+
+/****************************************************************************
+ * Name: inotify_sub_count
+ *
+ * Description:
+ *   Reduce the count.
+ *
+ ****************************************************************************/
+
+static void inotify_sub_count(uint32_t mask)
+{
+  g_inotify.read_count -= (mask & IN_ACCESS) ? 1 : 0;
+  g_inotify.write_count -= (mask & IN_MODIFY) ? 1 : 0;
+}
+
+/****************************************************************************
+ * Name: notify_check_mask
+ *
+ * Description:
+ *   Check if the count is valid.
+ *
+ ****************************************************************************/
+
+static int notify_check_mask(uint32_t mask)
+{
+  return (((mask & IN_ACCESS) && g_inotify.read_count == 0) ||
+          ((mask & IN_MODIFY) && g_inotify.write_count == 0)) ?
+          -EBADF : OK;
+}
+
 /****************************************************************************
  * Name: inotify_alloc_event
  *
@@ -262,6 +307,7 @@ inotify_remove_watch_no_event(FAR struct inotify_watch_s 
*watch)
 
   list_delete(&watch->d_node);
   list_delete(&watch->l_node);
+  inotify_sub_count(watch->mask);
   kmm_free(watch);
 
   if (list_is_empty(&list->watches))
@@ -931,6 +977,14 @@ static inline void notify_queue_filep_event(FAR struct 
file *filep,
       return;
     }
 
+  nxmutex_lock(&g_inotify.lock);
+  ret = notify_check_mask(mask);
+  nxmutex_unlock(&g_inotify.lock);
+  if (ret < 0)
+    {
+      return;
+    }
+
   pathbuffer = lib_get_pathbuffer();
   if (pathbuffer == NULL)
     {
@@ -1037,6 +1091,7 @@ int inotify_add_watch(int fd, FAR const char *pathname, 
uint32_t mask)
   old = inotify_get_watch_from_list(dev, list);
   if (old != NULL)
     {
+      uint32_t tmpmask = old->mask;
       if (mask & IN_MASK_CREATE)
         {
           ret = -EEXIST;
@@ -1052,6 +1107,7 @@ int inotify_add_watch(int fd, FAR const char *pathname, 
uint32_t mask)
         }
 
       ret = old->wd;
+      inotify_add_count(tmpmask ^ old->mask);
     }
   else
     {
@@ -1066,6 +1122,7 @@ int inotify_add_watch(int fd, FAR const char *pathname, 
uint32_t mask)
         }
 
       ret = watch->wd;
+      inotify_add_count(mask);
     }
 
 out:

Reply via email to