mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-07-23 07:12:09 +00:00
fsnotify: call fsnotify_parent in perm events
fsnotify perm events do not call fsnotify parent. That means you cannot register a perm event on a directory and enforce permissions on all inodes in that directory. This patch fixes that situation. Signed-off-by: Eric Paris <eparis@redhat.com>
This commit is contained in:
parent
ff8bcbd03d
commit
52420392c8
3 changed files with 21 additions and 11 deletions
|
@ -84,16 +84,17 @@ void __fsnotify_update_child_dentry_flags(struct inode *inode)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Notify this dentry's parent about a child's events. */
|
/* Notify this dentry's parent about a child's events. */
|
||||||
void __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask)
|
int __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask)
|
||||||
{
|
{
|
||||||
struct dentry *parent;
|
struct dentry *parent;
|
||||||
struct inode *p_inode;
|
struct inode *p_inode;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
if (!dentry)
|
if (!dentry)
|
||||||
dentry = path->dentry;
|
dentry = path->dentry;
|
||||||
|
|
||||||
if (!(dentry->d_flags & DCACHE_FSNOTIFY_PARENT_WATCHED))
|
if (!(dentry->d_flags & DCACHE_FSNOTIFY_PARENT_WATCHED))
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
parent = dget_parent(dentry);
|
parent = dget_parent(dentry);
|
||||||
p_inode = parent->d_inode;
|
p_inode = parent->d_inode;
|
||||||
|
@ -106,14 +107,16 @@ void __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask)
|
||||||
mask |= FS_EVENT_ON_CHILD;
|
mask |= FS_EVENT_ON_CHILD;
|
||||||
|
|
||||||
if (path)
|
if (path)
|
||||||
fsnotify(p_inode, mask, path, FSNOTIFY_EVENT_PATH,
|
ret = fsnotify(p_inode, mask, path, FSNOTIFY_EVENT_PATH,
|
||||||
dentry->d_name.name, 0);
|
dentry->d_name.name, 0);
|
||||||
else
|
else
|
||||||
fsnotify(p_inode, mask, dentry->d_inode, FSNOTIFY_EVENT_INODE,
|
ret = fsnotify(p_inode, mask, dentry->d_inode, FSNOTIFY_EVENT_INODE,
|
||||||
dentry->d_name.name, 0);
|
dentry->d_name.name, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
dput(parent);
|
dput(parent);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(__fsnotify_parent);
|
EXPORT_SYMBOL_GPL(__fsnotify_parent);
|
||||||
|
|
||||||
|
|
|
@ -26,12 +26,12 @@ static inline void fsnotify_d_instantiate(struct dentry *dentry,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Notify this dentry's parent about a child's events. */
|
/* Notify this dentry's parent about a child's events. */
|
||||||
static inline void fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask)
|
static inline int fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask)
|
||||||
{
|
{
|
||||||
if (!dentry)
|
if (!dentry)
|
||||||
dentry = path->dentry;
|
dentry = path->dentry;
|
||||||
|
|
||||||
__fsnotify_parent(path, dentry, mask);
|
return __fsnotify_parent(path, dentry, mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* simple call site for access decisions */
|
/* simple call site for access decisions */
|
||||||
|
@ -40,6 +40,7 @@ static inline int fsnotify_perm(struct file *file, int mask)
|
||||||
struct path *path = &file->f_path;
|
struct path *path = &file->f_path;
|
||||||
struct inode *inode = path->dentry->d_inode;
|
struct inode *inode = path->dentry->d_inode;
|
||||||
__u32 fsnotify_mask = 0;
|
__u32 fsnotify_mask = 0;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (file->f_mode & FMODE_NONOTIFY)
|
if (file->f_mode & FMODE_NONOTIFY)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -52,6 +53,10 @@ static inline int fsnotify_perm(struct file *file, int mask)
|
||||||
else
|
else
|
||||||
BUG();
|
BUG();
|
||||||
|
|
||||||
|
ret = fsnotify_parent(path, NULL, fsnotify_mask);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
return fsnotify(inode, fsnotify_mask, path, FSNOTIFY_EVENT_PATH, NULL, 0);
|
return fsnotify(inode, fsnotify_mask, path, FSNOTIFY_EVENT_PATH, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -304,7 +304,7 @@ struct fsnotify_mark {
|
||||||
/* main fsnotify call to send events */
|
/* main fsnotify call to send events */
|
||||||
extern int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is,
|
extern int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is,
|
||||||
const unsigned char *name, u32 cookie);
|
const unsigned char *name, u32 cookie);
|
||||||
extern void __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask);
|
extern int __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask);
|
||||||
extern void __fsnotify_inode_delete(struct inode *inode);
|
extern void __fsnotify_inode_delete(struct inode *inode);
|
||||||
extern void __fsnotify_vfsmount_delete(struct vfsmount *mnt);
|
extern void __fsnotify_vfsmount_delete(struct vfsmount *mnt);
|
||||||
extern u32 fsnotify_get_cookie(void);
|
extern u32 fsnotify_get_cookie(void);
|
||||||
|
@ -433,8 +433,10 @@ static inline int fsnotify(struct inode *to_tell, __u32 mask, void *data, int da
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask)
|
static inline int __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask)
|
||||||
{}
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void __fsnotify_inode_delete(struct inode *inode)
|
static inline void __fsnotify_inode_delete(struct inode *inode)
|
||||||
{}
|
{}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue