aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAihua Zhang <zhangaihua1@huawei.com>2016-07-07 03:37:53 -0400
committerMiklos Szeredi <mszeredi@redhat.com>2016-09-16 06:44:20 -0400
commitf3fbbb079263bd29ae592478de6808db7e708267 (patch)
treeb34bc4b61e6993806773e4fa57ca26c2db63d9dc
parent598e3c8f72f5b77c84d2cb26cfd936ffb3cfdbaa (diff)
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>
-rw-r--r--include/linux/fsnotify.h14
1 files changed, 9 insertions, 5 deletions
diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h
index eed9e853a06f..b8bcc058e031 100644
--- a/include/linux/fsnotify.h
+++ b/include/linux/fsnotify.h
@@ -29,7 +29,11 @@ static inline int fsnotify_parent(struct path *path, struct dentry *dentry, __u3
29static inline int fsnotify_perm(struct file *file, int mask) 29static inline int fsnotify_perm(struct file *file, int mask)
30{ 30{
31 struct path *path = &file->f_path; 31 struct path *path = &file->f_path;
32 struct inode *inode = file_inode(file); 32 /*
33 * Do not use file_inode() here or anywhere in this file to get the
34 * inode. That would break *notity on overlayfs.
35 */
36 struct inode *inode = path->dentry->d_inode;
33 __u32 fsnotify_mask = 0; 37 __u32 fsnotify_mask = 0;
34 int ret; 38 int ret;
35 39
@@ -173,7 +177,7 @@ static inline void fsnotify_mkdir(struct inode *inode, struct dentry *dentry)
173static inline void fsnotify_access(struct file *file) 177static inline void fsnotify_access(struct file *file)
174{ 178{
175 struct path *path = &file->f_path; 179 struct path *path = &file->f_path;
176 struct inode *inode = file_inode(file); 180 struct inode *inode = path->dentry->d_inode;
177 __u32 mask = FS_ACCESS; 181 __u32 mask = FS_ACCESS;
178 182
179 if (S_ISDIR(inode->i_mode)) 183 if (S_ISDIR(inode->i_mode))
@@ -191,7 +195,7 @@ static inline void fsnotify_access(struct file *file)
191static inline void fsnotify_modify(struct file *file) 195static inline void fsnotify_modify(struct file *file)
192{ 196{
193 struct path *path = &file->f_path; 197 struct path *path = &file->f_path;
194 struct inode *inode = file_inode(file); 198 struct inode *inode = path->dentry->d_inode;
195 __u32 mask = FS_MODIFY; 199 __u32 mask = FS_MODIFY;
196 200
197 if (S_ISDIR(inode->i_mode)) 201 if (S_ISDIR(inode->i_mode))
@@ -209,7 +213,7 @@ static inline void fsnotify_modify(struct file *file)
209static inline void fsnotify_open(struct file *file) 213static inline void fsnotify_open(struct file *file)
210{ 214{
211 struct path *path = &file->f_path; 215 struct path *path = &file->f_path;
212 struct inode *inode = file_inode(file); 216 struct inode *inode = path->dentry->d_inode;
213 __u32 mask = FS_OPEN; 217 __u32 mask = FS_OPEN;
214 218
215 if (S_ISDIR(inode->i_mode)) 219 if (S_ISDIR(inode->i_mode))
@@ -225,7 +229,7 @@ static inline void fsnotify_open(struct file *file)
225static inline void fsnotify_close(struct file *file) 229static inline void fsnotify_close(struct file *file)
226{ 230{
227 struct path *path = &file->f_path; 231 struct path *path = &file->f_path;
228 struct inode *inode = file_inode(file); 232 struct inode *inode = path->dentry->d_inode;
229 fmode_t mode = file->f_mode; 233 fmode_t mode = file->f_mode;
230 __u32 mask = (mode & FMODE_WRITE) ? FS_CLOSE_WRITE : FS_CLOSE_NOWRITE; 234 __u32 mask = (mode & FMODE_WRITE) ? FS_CLOSE_WRITE : FS_CLOSE_NOWRITE;
231 235