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 <michallenc@seznam.cz>
This commit is contained in:
Michal Lenc 2024-10-07 10:55:43 +02:00 committed by Xiang Xiao
parent 939c10ea34
commit 531dbaf561
3 changed files with 51 additions and 5 deletions

View file

@ -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);
}
}

View file

@ -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);

View file

@ -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);
}
}