fsnotify: support overlayfs
When an event occurs direct it to the overlay inode instead of the real underlying inode. This will work even if the file was first on the lower layer and then copied up, while the watch is there. This is because the watch is on the overlay inode, which stays the same through the copy-up. For filesystems other than overlayfs this is a no-op, except for the performance impact of an extra pointer dereferece. Verified to work correctly with the inotify/fanotify tests in LTP. Signed-off-by: Aihua Zhang <zhangaihua1@huawei.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> Cc: Jan Kara <jack@suse.cz> Cc: Eric Paris <eparis@redhat.com>
This commit is contained in:
parent
598e3c8f72
commit
f3fbbb0792
|
@ -29,7 +29,11 @@ static inline int fsnotify_parent(struct path *path, struct dentry *dentry, __u3
|
||||||
static inline int fsnotify_perm(struct file *file, int mask)
|
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 = file_inode(file);
|
/*
|
||||||
|
* Do not use file_inode() here or anywhere in this file to get the
|
||||||
|
* inode. That would break *notity on overlayfs.
|
||||||
|
*/
|
||||||
|
struct inode *inode = path->dentry->d_inode;
|
||||||
__u32 fsnotify_mask = 0;
|
__u32 fsnotify_mask = 0;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -173,7 +177,7 @@ static inline void fsnotify_mkdir(struct inode *inode, struct dentry *dentry)
|
||||||
static inline void fsnotify_access(struct file *file)
|
static inline void fsnotify_access(struct file *file)
|
||||||
{
|
{
|
||||||
struct path *path = &file->f_path;
|
struct path *path = &file->f_path;
|
||||||
struct inode *inode = file_inode(file);
|
struct inode *inode = path->dentry->d_inode;
|
||||||
__u32 mask = FS_ACCESS;
|
__u32 mask = FS_ACCESS;
|
||||||
|
|
||||||
if (S_ISDIR(inode->i_mode))
|
if (S_ISDIR(inode->i_mode))
|
||||||
|
@ -191,7 +195,7 @@ static inline void fsnotify_access(struct file *file)
|
||||||
static inline void fsnotify_modify(struct file *file)
|
static inline void fsnotify_modify(struct file *file)
|
||||||
{
|
{
|
||||||
struct path *path = &file->f_path;
|
struct path *path = &file->f_path;
|
||||||
struct inode *inode = file_inode(file);
|
struct inode *inode = path->dentry->d_inode;
|
||||||
__u32 mask = FS_MODIFY;
|
__u32 mask = FS_MODIFY;
|
||||||
|
|
||||||
if (S_ISDIR(inode->i_mode))
|
if (S_ISDIR(inode->i_mode))
|
||||||
|
@ -209,7 +213,7 @@ static inline void fsnotify_modify(struct file *file)
|
||||||
static inline void fsnotify_open(struct file *file)
|
static inline void fsnotify_open(struct file *file)
|
||||||
{
|
{
|
||||||
struct path *path = &file->f_path;
|
struct path *path = &file->f_path;
|
||||||
struct inode *inode = file_inode(file);
|
struct inode *inode = path->dentry->d_inode;
|
||||||
__u32 mask = FS_OPEN;
|
__u32 mask = FS_OPEN;
|
||||||
|
|
||||||
if (S_ISDIR(inode->i_mode))
|
if (S_ISDIR(inode->i_mode))
|
||||||
|
@ -225,7 +229,7 @@ static inline void fsnotify_open(struct file *file)
|
||||||
static inline void fsnotify_close(struct file *file)
|
static inline void fsnotify_close(struct file *file)
|
||||||
{
|
{
|
||||||
struct path *path = &file->f_path;
|
struct path *path = &file->f_path;
|
||||||
struct inode *inode = file_inode(file);
|
struct inode *inode = path->dentry->d_inode;
|
||||||
fmode_t mode = file->f_mode;
|
fmode_t mode = file->f_mode;
|
||||||
__u32 mask = (mode & FMODE_WRITE) ? FS_CLOSE_WRITE : FS_CLOSE_NOWRITE;
|
__u32 mask = (mode & FMODE_WRITE) ? FS_CLOSE_WRITE : FS_CLOSE_NOWRITE;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue