From 531dbaf5617a6fd6f2868bcce5b799917df5077b Mon Sep 17 00:00:00 2001 From: Michal Lenc Date: Mon, 7 Oct 2024 10:55:43 +0200 Subject: [PATCH] fs_close: provide inotify call for close Close operation on file should lead to IN_CLOSE_WRITE or IN_CLOSE_NOWRITE notifications. This commits adds the notification support. Notifying on close is a little bit trickier as a lower layer may not have the full file path after successful close and inode release. Calling notification before close is not a solution since close might not end successfully. The solution is to obtain and buffer the path before calling close and then pass the buffered path to the notify_close. This required the change in notify_close function arguments: filep is no longer required, path and oflags are passed instead. Signed-off-by: Michal Lenc --- fs/notify/inotify.c | 8 ++++---- fs/notify/notify.h | 2 +- fs/vfs/fs_close.c | 46 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 5 deletions(-) diff --git a/fs/notify/inotify.c b/fs/notify/inotify.c index f7e34bd34e..5b47bc54e8 100644 --- a/fs/notify/inotify.c +++ b/fs/notify/inotify.c @@ -1342,15 +1342,15 @@ void notify_open(FAR const char *path, int oflags) * ****************************************************************************/ -void notify_close(FAR struct file *filep) +void notify_close(FAR const char *path, int oflags) { - if (filep->f_oflags & O_WROK) + if (oflags & O_WROK) { - notify_queue_filep_event(filep, IN_CLOSE_WRITE); + notify_queue_path_event(path, IN_CLOSE_WRITE); } else { - notify_queue_filep_event(filep, IN_CLOSE_NOWRITE); + notify_queue_path_event(path, IN_CLOSE_NOWRITE); } } diff --git a/fs/notify/notify.h b/fs/notify/notify.h index 4a0fc11b02..dad750513f 100644 --- a/fs/notify/notify.h +++ b/fs/notify/notify.h @@ -42,7 +42,7 @@ /* These are internal OS interface and are not available to applications */ void notify_open(FAR const char *path, int oflags); -void notify_close(FAR struct file *filep); +void notify_close(FAR const char *path, int oflags); void notify_close2(FAR struct inode *inode); void notify_read(FAR struct file *filep); void notify_write(FAR struct file *filep); diff --git a/fs/vfs/fs_close.c b/fs/vfs/fs_close.c index 52924030df..514a8bf71a 100644 --- a/fs/vfs/fs_close.c +++ b/fs/vfs/fs_close.c @@ -36,6 +36,33 @@ #include "inode/inode.h" #include "vfs/lock.h" +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +#ifdef CONFIG_FS_NOTIFY +static FAR char *file_get_path(FAR struct file *filep) +{ + FAR char *pathbuffer; + int ret; + + pathbuffer = lib_get_pathbuffer(); + if (pathbuffer == NULL) + { + return NULL; + } + + ret = file_fcntl(filep, F_GETPATH, pathbuffer); + if (ret < 0) + { + lib_put_pathbuffer(pathbuffer); + return NULL; + } + + return pathbuffer; +} +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -60,11 +87,22 @@ int file_close_without_clear(FAR struct file *filep) { struct inode *inode; +#ifdef CONFIG_FS_NOTIFY + FAR char *path; +#endif int ret = OK; DEBUGASSERT(filep != NULL); inode = filep->f_inode; +#ifdef CONFIG_FS_NOTIFY + /* We lose the path and inode during close and release, so obtain it + * in advance. Then we pass it to notify_close function. + */ + + path = file_get_path(filep); +#endif + /* Check if the struct file is open (i.e., assigned an inode) */ if (inode) @@ -84,6 +122,14 @@ int file_close_without_clear(FAR struct file *filep) if (ret >= 0) { +#ifdef CONFIG_FS_NOTIFY + if (path != NULL) + { + notify_close(path, filep->f_oflags); + lib_put_pathbuffer(path); + } +#endif + inode_release(inode); } }