Skip to content

Commit

Permalink
fsnotify: send struct file when sending events to parents when possible
Browse files Browse the repository at this point in the history
fanotify needs a path in order to open an fd to the object which changed.
Currently notifications to inode's parents are done using only the inode.
For some parental notification we have the entire file, send that so
fanotify can use it.

Signed-off-by: Eric Paris <eparis@redhat.com>
  • Loading branch information
Eric Paris committed Jul 28, 2010
1 parent 2a12a9d commit 28c60e3
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 24 deletions.
13 changes: 10 additions & 3 deletions fs/notify/fsnotify.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,16 @@ void __fsnotify_update_child_dentry_flags(struct inode *inode)
}

/* Notify this dentry's parent about a child's events. */
void __fsnotify_parent(struct dentry *dentry, __u32 mask)
void __fsnotify_parent(struct file *file, struct dentry *dentry, __u32 mask)
{
struct dentry *parent;
struct inode *p_inode;
bool send = false;
bool should_update_children = false;

if (file)
dentry = file->f_path.dentry;

if (!(dentry->d_flags & DCACHE_FSNOTIFY_PARENT_WATCHED))
return;

Expand Down Expand Up @@ -115,8 +118,12 @@ void __fsnotify_parent(struct dentry *dentry, __u32 mask)
* specifies these are events which came from a child. */
mask |= FS_EVENT_ON_CHILD;

fsnotify(p_inode, mask, dentry->d_inode, FSNOTIFY_EVENT_INODE,
dentry->d_name.name, 0);
if (file)
fsnotify(p_inode, mask, file, FSNOTIFY_EVENT_FILE,
dentry->d_name.name, 0);
else
fsnotify(p_inode, mask, dentry->d_inode, FSNOTIFY_EVENT_INODE,
dentry->d_name.name, 0);
dput(parent);
}

Expand Down
40 changes: 21 additions & 19 deletions include/linux/fsnotify.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,14 @@ static inline void fsnotify_d_instantiate(struct dentry *entry,
}

/* Notify this dentry's parent about a child's events. */
static inline void fsnotify_parent(struct dentry *dentry, __u32 mask)
static inline void fsnotify_parent(struct file *file, struct dentry *dentry, __u32 mask)
{
__fsnotify_parent(dentry, mask);
BUG_ON(file && dentry);

if (file)
dentry = file->f_path.dentry;

__fsnotify_parent(file, dentry, mask);
}

/*
Expand Down Expand Up @@ -102,7 +107,7 @@ static inline void fsnotify_nameremove(struct dentry *dentry, int isdir)
if (isdir)
mask |= FS_IN_ISDIR;

fsnotify_parent(dentry, mask);
fsnotify_parent(NULL, dentry, mask);
}

/*
Expand Down Expand Up @@ -155,14 +160,13 @@ static inline void fsnotify_mkdir(struct inode *inode, struct dentry *dentry)
*/
static inline void fsnotify_access(struct file *file)
{
struct dentry *dentry = file->f_path.dentry;
struct inode *inode = dentry->d_inode;
struct inode *inode = file->f_path.dentry->d_inode;
__u32 mask = FS_ACCESS;

if (S_ISDIR(inode->i_mode))
mask |= FS_IN_ISDIR;

fsnotify_parent(dentry, mask);
fsnotify_parent(file, NULL, mask);
fsnotify(inode, mask, file, FSNOTIFY_EVENT_FILE, NULL, 0);
}

Expand All @@ -171,14 +175,13 @@ static inline void fsnotify_access(struct file *file)
*/
static inline void fsnotify_modify(struct file *file)
{
struct dentry *dentry = file->f_path.dentry;
struct inode *inode = dentry->d_inode;
struct inode *inode = file->f_path.dentry->d_inode;
__u32 mask = FS_MODIFY;

if (S_ISDIR(inode->i_mode))
mask |= FS_IN_ISDIR;

fsnotify_parent(dentry, mask);
fsnotify_parent(file, NULL, mask);
fsnotify(inode, mask, file, FSNOTIFY_EVENT_FILE, NULL, 0);
}

Expand All @@ -187,14 +190,13 @@ static inline void fsnotify_modify(struct file *file)
*/
static inline void fsnotify_open(struct file *file)
{
struct dentry *dentry = file->f_path.dentry;
struct inode *inode = dentry->d_inode;
struct inode *inode = file->f_path.dentry->d_inode;
__u32 mask = FS_OPEN;

if (S_ISDIR(inode->i_mode))
mask |= FS_IN_ISDIR;

fsnotify_parent(dentry, mask);
fsnotify_parent(file, NULL, mask);
fsnotify(inode, mask, file, FSNOTIFY_EVENT_FILE, NULL, 0);
}

Expand All @@ -203,15 +205,14 @@ static inline void fsnotify_open(struct file *file)
*/
static inline void fsnotify_close(struct file *file)
{
struct dentry *dentry = file->f_path.dentry;
struct inode *inode = dentry->d_inode;
struct inode *inode = file->f_path.dentry->d_inode;
fmode_t mode = file->f_mode;
__u32 mask = (mode & FMODE_WRITE) ? FS_CLOSE_WRITE : FS_CLOSE_NOWRITE;

if (S_ISDIR(inode->i_mode))
mask |= FS_IN_ISDIR;

fsnotify_parent(dentry, mask);
fsnotify_parent(file, NULL, mask);
fsnotify(inode, mask, file, FSNOTIFY_EVENT_FILE, NULL, 0);
}

Expand All @@ -226,7 +227,7 @@ static inline void fsnotify_xattr(struct dentry *dentry)
if (S_ISDIR(inode->i_mode))
mask |= FS_IN_ISDIR;

fsnotify_parent(dentry, mask);
fsnotify_parent(NULL, dentry, mask);
fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0);
}

Expand Down Expand Up @@ -260,7 +261,8 @@ static inline void fsnotify_change(struct dentry *dentry, unsigned int ia_valid)
if (mask) {
if (S_ISDIR(inode->i_mode))
mask |= FS_IN_ISDIR;
fsnotify_parent(dentry, mask);

fsnotify_parent(NULL, dentry, mask);
fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0);
}
}
Expand All @@ -283,7 +285,7 @@ static inline void fsnotify_oldname_free(const char *old_name)
kfree(old_name);
}

#else /* CONFIG_INOTIFY || CONFIG_FSNOTIFY */
#else /* CONFIG_FSNOTIFY */

static inline const char *fsnotify_oldname_init(const char *name)
{
Expand All @@ -294,6 +296,6 @@ static inline void fsnotify_oldname_free(const char *old_name)
{
}

#endif /* ! CONFIG_INOTIFY */
#endif /* CONFIG_FSNOTIFY */

#endif /* _LINUX_FS_NOTIFY_H */
4 changes: 2 additions & 2 deletions include/linux/fsnotify_backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ struct fsnotify_mark_entry {
/* main fsnotify call to send events */
extern void fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is,
const char *name, u32 cookie);
extern void __fsnotify_parent(struct dentry *dentry, __u32 mask);
extern void __fsnotify_parent(struct file *file, struct dentry *dentry, __u32 mask);
extern void __fsnotify_inode_delete(struct inode *inode);
extern u32 fsnotify_get_cookie(void);

Expand Down Expand Up @@ -367,7 +367,7 @@ static inline void fsnotify(struct inode *to_tell, __u32 mask, void *data, int d
const char *name, u32 cookie)
{}

static inline void __fsnotify_parent(struct dentry *dentry, __u32 mask)
static inline void __fsnotify_parent(struct file *file, struct dentry *dentry, __u32 mask)
{}

static inline void __fsnotify_inode_delete(struct inode *inode)
Expand Down

0 comments on commit 28c60e3

Please sign in to comment.