diff --git a/fs/namespace.c b/fs/namespace.c index a2d681a6b5e9b01b494deefe6471463e8e699357..1969d6b2571eb3267b38f29412bff86179883edd 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -614,6 +614,7 @@ static inline void __mntput(struct vfsmount *mnt) * provides barriers, so count_mnt_writers() below is safe. AV */ WARN_ON(count_mnt_writers(mnt)); + fsnotify_vfsmount_delete(mnt); dput(mnt->mnt_root); free_vfsmnt(mnt); deactivate_super(sb); diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c index e0bf86953e1b8d20f9ed4c22475ea4fed9a7a1c5..7f14ddc3efc2249a6ab3c475e1fbedc63b39a993 100644 --- a/fs/notify/fsnotify.c +++ b/fs/notify/fsnotify.c @@ -36,6 +36,11 @@ void __fsnotify_inode_delete(struct inode *inode) } EXPORT_SYMBOL_GPL(__fsnotify_inode_delete); +void __fsnotify_vfsmount_delete(struct vfsmount *mnt) +{ + fsnotify_clear_marks_by_mount(mnt); +} + /* * Given an inode, first check if we care what happens to our children. Inotify * and dnotify both tell their parents about events. If we care about any event diff --git a/fs/notify/fsnotify.h b/fs/notify/fsnotify.h index 38f3fb5cef28bfadd942b7c7518de175bd5905b0..204353c0f663957899d275e290aca242f0c0563d 100644 --- a/fs/notify/fsnotify.h +++ b/fs/notify/fsnotify.h @@ -42,6 +42,8 @@ extern void fsnotify_destroy_vfsmount_mark(struct fsnotify_mark *mark); extern void fsnotify_destroy_inode_mark(struct fsnotify_mark *mark); /* run the list of all marks associated with inode and flag them to be freed */ extern void fsnotify_clear_marks_by_inode(struct inode *inode); +/* run the list of all marks associated with vfsmount and flag them to be freed */ +extern void fsnotify_clear_marks_by_mount(struct vfsmount *mnt); /* * update the dentry->d_flags of all of inode's children to indicate if inode cares * about events that happen to its children. diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index 5184a2b786c1e817cf3432354056f6298773f9dd..06c0e50c7968046347917b7997b5b4406e26b00a 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h @@ -95,6 +95,14 @@ static inline void fsnotify_inode_delete(struct inode *inode) __fsnotify_inode_delete(inode); } +/* + * fsnotify_vfsmount_delete - a vfsmount is being destroyed, clean up is needed + */ +static inline void fsnotify_vfsmount_delete(struct vfsmount *mnt) +{ + __fsnotify_vfsmount_delete(mnt); +} + /* * fsnotify_nameremove - a filename was removed from a directory */ diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index f21ff1bd4b5aa9c985f417a113b74de38e0ac61f..1af42cbfc4294edda82e3f785a17b7dc3c776c71 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h @@ -282,6 +282,7 @@ extern void fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is, const char *name, u32 cookie); extern void __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask); extern void __fsnotify_inode_delete(struct inode *inode); +extern void __fsnotify_vfsmount_delete(struct vfsmount *mnt); extern u32 fsnotify_get_cookie(void); static inline int fsnotify_inode_watches_children(struct inode *inode) @@ -402,6 +403,9 @@ static inline void __fsnotify_parent(struct path *path, struct dentry *dentry, _ static inline void __fsnotify_inode_delete(struct inode *inode) {} +static inline void __fsnotify_vfsmount_delete(struct vfsmount *mnt) +{} + static inline void __fsnotify_update_dcache_flags(struct dentry *dentry) {}