@@ -61,54 +61,56 @@ int deepin_err_notify_enabled(void)
6161 return deepin_err_notify_initialized && deepin_err_notify_enable ;
6262}
6363
64+ /**
65+ * deepin_err_notify_should_send - Check if error notification should be sent
66+ *
67+ * This function checks both the enable status and rate limiting to determine
68+ * whether an error notification should be sent.
69+ *
70+ * Return: 1 if notification should be sent, 0 otherwise
71+ */
72+ int deepin_err_notify_should_send (void )
73+ {
74+
75+ /*
76+ * Rate limiting: Allow 20 calls per 5 seconds.
77+ * Rationale: Prevent excessive error notifications under high load,
78+ * which could overwhelm the monitoring system or cause log flooding.
79+ * 20 notifications per 5 seconds is sufficient to capture relevant
80+ * filesystem errors without missing critical events.
81+ */
82+ static DEFINE_RATELIMIT_STATE (deepin_err_notify_ratelimit , 5 * HZ , 20 );
83+
84+ if (!deepin_err_notify_enabled ())
85+ return 0 ;
86+
87+ return __ratelimit (& deepin_err_notify_ratelimit );
88+ }
89+
90+ static int
91+ prepare_and_notify_fs_error (const struct deepin_path_last * path_lasts ,
92+ int path_last_count )
93+ {
94+ /* TODO: Implement in next commit */
95+ return - EOPNOTSUPP ;
96+ }
97+
6498/* Check if overlay filesystem is mounted on /usr and send read only error notification */
65- void deepin_check_and_notify_ro_fs_err (const struct path * path ,
99+ void deepin_check_and_notify_ro_fs_err (const struct deepin_path_last * path_last ,
66100 const char * func_name )
67101{
68- char * path_buf = NULL ;
69- char * full_path = "" ;
70- /* Rate limiting: allow 100 calls per 5 seconds */
71- static DEFINE_RATELIMIT_STATE (deepin_ro_fs_err_ratelimit ,
72- 5 * HZ , /* 5 seconds interval */
73- 100 ); /* 100 calls per interval */
74-
75- /* Check rate limit before proceeding */
76- if (!__ratelimit (& deepin_ro_fs_err_ratelimit ))
77- return ;
78-
79- /* Early return if path or path->mnt is invalid */
80- if (!path || !path -> mnt || !path -> mnt -> mnt_sb )
81- return ;
102+ int ret ;
82103
83- /* Use filesystem callback to decide if notification should be sent.
84- * If filesystem implements the callback, use it.
85- */
86- if (path -> mnt -> mnt_sb -> s_op &&
87- path -> mnt -> mnt_sb -> s_op -> deepin_should_notify_error ) {
88- if (!path -> mnt -> mnt_sb -> s_op -> deepin_should_notify_error (path -> mnt -> mnt_sb ))
89- return ;
90- } else {
91- /* If filesystem does not implement the callback, return immediately. */
104+ /* Early return if path_last is invalid */
105+ if (!path_last )
92106 return ;
93- }
107+ ret = prepare_and_notify_fs_error ( path_last , 1 );
94108
95- /* Attempt to get the full path.
96- * Dynamic allocation is used to avoid excessive frame size.
97- */
98- if (path -> dentry ) {
99- path_buf = kmalloc (PATH_MAX , GFP_KERNEL );
100- if (path_buf ) {
101- char * p = NULL ;
102-
103- p = d_path (path , path_buf , PATH_MAX );
104- if (!IS_ERR (p ))
105- full_path = p ;
106- }
109+ if (ret < 0 ) {
110+ pr_debug (
111+ "deepin_err_notify: Failed to send notification to userspace: %d\n" ,
112+ ret );
107113 }
108-
109- deepin_send_ro_fs_err_notification (full_path , func_name );
110-
111- kfree (path_buf );
112114}
113115
114116/* Define multicast group */
@@ -192,6 +194,22 @@ void deepin_send_ro_fs_err_notification(const char *filename,
192194 kfree_skb (skb );
193195}
194196
197+ /**
198+ * deepin_put_path_last - Release resources held by deepin_path_last structure
199+ * @path_last: Pointer to the deepin_path_last structure to release
200+ *
201+ * This function releases the path reference and frees the allocated filename
202+ * string in the deepin_path_last structure.
203+ */
204+ void deepin_put_path_last (struct deepin_path_last * path_last )
205+ {
206+ if (path_last ) {
207+ path_put (& path_last -> path );
208+ kfree (path_last -> last );
209+ path_last -> last = NULL ;
210+ }
211+ }
212+
195213/* sysctl table and initialization */
196214#ifdef CONFIG_SYSCTL
197215static struct ctl_table deepin_err_notify_sysctls [] = {
@@ -239,5 +257,23 @@ static int __init deepin_err_notify_init(void)
239257 return 0 ;
240258}
241259
260+ /**
261+ * deepin_notify_rename_ro_fs_err - Notify read-only filesystem errors during rename
262+ * @old_last: qstr for old filename
263+ * @new_last: qstr for new filename
264+ * @old_path: path of old parent directory
265+ * @new_path: path of new parent directory
266+ *
267+ * This function is called when a rename operation fails with EROFS error.
268+ */
269+ void deepin_notify_rename_ro_fs_err (const struct qstr * old_last ,
270+ const struct qstr * new_last ,
271+ const struct path * old_path ,
272+ const struct path * new_path )
273+ {
274+ /* Simplified implementation - will be enhanced in next commit */
275+ pr_debug ("deepin_err_notify: EROFS error in rename\n" );
276+ }
277+
242278/* Use fs_initcall to ensure initialization before file system operations */
243279fs_initcall (deepin_err_notify_init );
0 commit comments