Skip to content

Commit 291cfa8

Browse files
committed
fs/deepin_err_notify: Implement path combination function and
improve read-only error notification for renaming - Implement the combine_path_and_last function to combine a base path and the final component to form a complete path. - Implement the deepin_notify_rename_ro_fs_err function, which calls prepare_and_notify_fs_error to send the error notification. Signed-off-by: electricface <songwentai@uniontech.com>
1 parent dd00fe0 commit 291cfa8

File tree

1 file changed

+62
-4
lines changed

1 file changed

+62
-4
lines changed

fs/deepin_err_notify.c

Lines changed: 62 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <linux/init.h>
1010
#include <linux/slab.h>
1111
#include <linux/fs.h>
12+
#include <linux/stat.h>
1213
#include <linux/namei.h>
1314
#include <linux/mount.h>
1415
#include <linux/path.h>
@@ -50,7 +51,6 @@ enum {
5051
DEEPIN_ERR_NOTIFY_ATTR_UID = 7, /* User ID (u32) */
5152
DEEPIN_ERR_NOTIFY_ATTR_GID = 8, /* Group ID (u32) */
5253
DEEPIN_ERR_NOTIFY_ATTR_STATUS = 9, /* Enable/Disable Status (u8) */
53-
DEEPIN_ERR_NOTIFY_ATTR_FUNC_NAME = 10, /* Function Name (string) */
5454
__DEEPIN_ERR_NOTIFY_ATTR_MAX,
5555
};
5656

@@ -139,11 +139,56 @@ int deepin_err_notify_should_send(void)
139139
return __ratelimit(&deepin_err_notify_ratelimit);
140140
}
141141

142+
/**
143+
* combine_path_and_last - Combine base path with last component
144+
* @buffer: Pre-allocated buffer to store the combined path (size PATH_MAX)
145+
* @path: The base path to combine
146+
* @last: The last component to append
147+
*
148+
* This function combines a base path with a last component, constructing
149+
* the full path: base_path + "/" + last. The result is stored in buffer.
150+
*
151+
* Returns: Pointer to the combined path string on success, NULL on failure
152+
*/
142153
static char *combine_path_and_last(char *buffer, const struct path *path,
143154
const char *last)
144155
{
145-
/* TODO: Implement in next commit */
146-
return NULL;
156+
char *base_path;
157+
size_t base_len, last_len, total_len;
158+
159+
base_path = d_absolute_path(path, buffer, PATH_MAX);
160+
if (IS_ERR(base_path))
161+
return NULL;
162+
163+
/* Construct full path: base_path + "/" + last */
164+
base_len = strlen(base_path);
165+
last_len = strlen(last);
166+
total_len = base_len + 1 + last_len + 1;
167+
168+
if (total_len > PATH_MAX)
169+
return NULL;
170+
171+
/*
172+
* Move base_path to start of buffer if needed.
173+
* d_absolute_path() may return a pointer to the middle of the buffer,
174+
* not the start. We need the path at the beginning so we can
175+
* append "/" + last to it.
176+
*/
177+
if (base_path != buffer)
178+
memmove(buffer, base_path, base_len);
179+
180+
/* Avoid appending an extra "/" after root directory "/" which would
181+
* result in "//filename".
182+
*/
183+
if (base_len > 0 && buffer[base_len - 1] != '/') {
184+
buffer[base_len] = '/';
185+
memcpy(buffer + base_len + 1, last, last_len + 1);
186+
} else {
187+
/* base_path is already "/" or ends with "/" (rare case) */
188+
memcpy(buffer + base_len, last, last_len + 1);
189+
}
190+
191+
return buffer;
147192
}
148193

149194
/* Check if overlay filesystem is mounted on /usr and send read only error notification */
@@ -673,13 +718,26 @@ static int __init deepin_err_notify_init(void)
673718
* @new_path: path of new parent directory
674719
*
675720
* This function is called when a rename operation fails with EROFS error.
721+
* It attempts to look up the old and new paths and send error notification
722+
* if both paths are valid.
676723
*/
677724
void deepin_notify_rename_ro_fs_err(const struct qstr *old_last,
678725
const struct qstr *new_last,
679726
const struct path *old_path,
680727
const struct path *new_path)
681728
{
682-
/* Simplified implementation - will be enhanced in next commit */
729+
const struct deepin_path_last path_lasts[2] = {
730+
{ .path = *old_path, .last = old_last->name },
731+
{ .path = *new_path, .last = new_last->name }
732+
};
733+
int ret;
734+
735+
ret = prepare_and_notify_fs_error(path_lasts, 2);
736+
if (ret < 0) {
737+
pr_debug(
738+
"deepin_err_notify: Failed to send notification to userspace: %d\n",
739+
ret);
740+
}
683741
}
684742

685743
/* Use fs_initcall to ensure initialization before file system operations */

0 commit comments

Comments
 (0)