diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-07-10 23:09:17 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-07-10 23:09:17 -0400 |
commit | e6983afd9254c559acf67dd5f62df824d19851eb (patch) | |
tree | 06ab8b4457f90b5776b4d7cd7b340bd81b907eb0 | |
parent | 988052f47adc5c3b0b004180b59bb3761d91b752 (diff) | |
parent | 7377f5bec13332bc470856f337935be6cabbcf24 (diff) |
Merge tag 'fsnotify_for_v5.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs
Pull fsnotify updates from Jan Kara:
"This contains cleanups of the fsnotify name removal hook and also a
patch to disable fanotify permission events for 'proc' filesystem"
* tag 'fsnotify_for_v5.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs:
fsnotify: get rid of fsnotify_nameremove()
fsnotify: move fsnotify_nameremove() hook out of d_delete()
configfs: call fsnotify_rmdir() hook
debugfs: call fsnotify_{unlink,rmdir}() hooks
debugfs: simplify __debugfs_remove_file()
devpts: call fsnotify_unlink() hook
tracefs: call fsnotify_{unlink,rmdir}() hooks
rpc_pipefs: call fsnotify_{unlink,rmdir}() hooks
btrfs: call fsnotify_rmdir() hook
fsnotify: add empty fsnotify_{unlink,rmdir}() hooks
fanotify: Disallow permission events for proc filesystem
-rw-r--r-- | fs/afs/dir_silly.c | 5 | ||||
-rw-r--r-- | fs/btrfs/ioctl.c | 4 | ||||
-rw-r--r-- | fs/configfs/dir.c | 3 | ||||
-rw-r--r-- | fs/dcache.c | 2 | ||||
-rw-r--r-- | fs/debugfs/inode.c | 21 | ||||
-rw-r--r-- | fs/devpts/inode.c | 1 | ||||
-rw-r--r-- | fs/namei.c | 2 | ||||
-rw-r--r-- | fs/nfs/unlink.c | 6 | ||||
-rw-r--r-- | fs/notify/fanotify/fanotify_user.c | 22 | ||||
-rw-r--r-- | fs/notify/fsnotify.c | 41 | ||||
-rw-r--r-- | fs/proc/root.c | 2 | ||||
-rw-r--r-- | fs/tracefs/inode.c | 3 | ||||
-rw-r--r-- | include/linux/fs.h | 1 | ||||
-rw-r--r-- | include/linux/fsnotify.h | 26 | ||||
-rw-r--r-- | include/linux/fsnotify_backend.h | 4 | ||||
-rw-r--r-- | net/sunrpc/rpc_pipe.c | 4 |
16 files changed, 76 insertions, 71 deletions
diff --git a/fs/afs/dir_silly.c b/fs/afs/dir_silly.c index 057b8d322422..361088a5edb9 100644 --- a/fs/afs/dir_silly.c +++ b/fs/afs/dir_silly.c | |||
@@ -60,11 +60,6 @@ static int afs_do_silly_rename(struct afs_vnode *dvnode, struct afs_vnode *vnode | |||
60 | if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) | 60 | if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) |
61 | afs_edit_dir_add(dvnode, &new->d_name, | 61 | afs_edit_dir_add(dvnode, &new->d_name, |
62 | &vnode->fid, afs_edit_dir_for_silly_1); | 62 | &vnode->fid, afs_edit_dir_for_silly_1); |
63 | |||
64 | /* vfs_unlink and the like do not issue this when a file is | ||
65 | * sillyrenamed, so do it here. | ||
66 | */ | ||
67 | fsnotify_nameremove(old, 0); | ||
68 | } | 63 | } |
69 | 64 | ||
70 | kfree(scb); | 65 | kfree(scb); |
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 2a1be0d1a698..56ae2f659b6d 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -2928,8 +2928,10 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file, | |||
2928 | inode_lock(inode); | 2928 | inode_lock(inode); |
2929 | err = btrfs_delete_subvolume(dir, dentry); | 2929 | err = btrfs_delete_subvolume(dir, dentry); |
2930 | inode_unlock(inode); | 2930 | inode_unlock(inode); |
2931 | if (!err) | 2931 | if (!err) { |
2932 | fsnotify_rmdir(dir, dentry); | ||
2932 | d_delete(dentry); | 2933 | d_delete(dentry); |
2934 | } | ||
2933 | 2935 | ||
2934 | out_dput: | 2936 | out_dput: |
2935 | dput(dentry); | 2937 | dput(dentry); |
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index d2ca5287762d..92112915de8e 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #undef DEBUG | 13 | #undef DEBUG |
14 | 14 | ||
15 | #include <linux/fs.h> | 15 | #include <linux/fs.h> |
16 | #include <linux/fsnotify.h> | ||
16 | #include <linux/mount.h> | 17 | #include <linux/mount.h> |
17 | #include <linux/module.h> | 18 | #include <linux/module.h> |
18 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
@@ -1788,6 +1789,7 @@ void configfs_unregister_group(struct config_group *group) | |||
1788 | configfs_detach_group(&group->cg_item); | 1789 | configfs_detach_group(&group->cg_item); |
1789 | d_inode(dentry)->i_flags |= S_DEAD; | 1790 | d_inode(dentry)->i_flags |= S_DEAD; |
1790 | dont_mount(dentry); | 1791 | dont_mount(dentry); |
1792 | fsnotify_rmdir(d_inode(parent), dentry); | ||
1791 | d_delete(dentry); | 1793 | d_delete(dentry); |
1792 | inode_unlock(d_inode(parent)); | 1794 | inode_unlock(d_inode(parent)); |
1793 | 1795 | ||
@@ -1916,6 +1918,7 @@ void configfs_unregister_subsystem(struct configfs_subsystem *subsys) | |||
1916 | configfs_detach_group(&group->cg_item); | 1918 | configfs_detach_group(&group->cg_item); |
1917 | d_inode(dentry)->i_flags |= S_DEAD; | 1919 | d_inode(dentry)->i_flags |= S_DEAD; |
1918 | dont_mount(dentry); | 1920 | dont_mount(dentry); |
1921 | fsnotify_rmdir(d_inode(root), dentry); | ||
1919 | inode_unlock(d_inode(dentry)); | 1922 | inode_unlock(d_inode(dentry)); |
1920 | 1923 | ||
1921 | d_delete(dentry); | 1924 | d_delete(dentry); |
diff --git a/fs/dcache.c b/fs/dcache.c index c435398f2c81..f41121e5d1ec 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -2372,7 +2372,6 @@ EXPORT_SYMBOL(d_hash_and_lookup); | |||
2372 | void d_delete(struct dentry * dentry) | 2372 | void d_delete(struct dentry * dentry) |
2373 | { | 2373 | { |
2374 | struct inode *inode = dentry->d_inode; | 2374 | struct inode *inode = dentry->d_inode; |
2375 | int isdir = d_is_dir(dentry); | ||
2376 | 2375 | ||
2377 | spin_lock(&inode->i_lock); | 2376 | spin_lock(&inode->i_lock); |
2378 | spin_lock(&dentry->d_lock); | 2377 | spin_lock(&dentry->d_lock); |
@@ -2387,7 +2386,6 @@ void d_delete(struct dentry * dentry) | |||
2387 | spin_unlock(&dentry->d_lock); | 2386 | spin_unlock(&dentry->d_lock); |
2388 | spin_unlock(&inode->i_lock); | 2387 | spin_unlock(&inode->i_lock); |
2389 | } | 2388 | } |
2390 | fsnotify_nameremove(dentry, isdir); | ||
2391 | } | 2389 | } |
2392 | EXPORT_SYMBOL(d_delete); | 2390 | EXPORT_SYMBOL(d_delete); |
2393 | 2391 | ||
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index acef14ad53db..1e444fe1f778 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c | |||
@@ -617,13 +617,10 @@ struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent, | |||
617 | } | 617 | } |
618 | EXPORT_SYMBOL_GPL(debugfs_create_symlink); | 618 | EXPORT_SYMBOL_GPL(debugfs_create_symlink); |
619 | 619 | ||
620 | static void __debugfs_remove_file(struct dentry *dentry, struct dentry *parent) | 620 | static void __debugfs_file_removed(struct dentry *dentry) |
621 | { | 621 | { |
622 | struct debugfs_fsdata *fsd; | 622 | struct debugfs_fsdata *fsd; |
623 | 623 | ||
624 | simple_unlink(d_inode(parent), dentry); | ||
625 | d_delete(dentry); | ||
626 | |||
627 | /* | 624 | /* |
628 | * Paired with the closing smp_mb() implied by a successful | 625 | * Paired with the closing smp_mb() implied by a successful |
629 | * cmpxchg() in debugfs_file_get(): either | 626 | * cmpxchg() in debugfs_file_get(): either |
@@ -644,16 +641,18 @@ static int __debugfs_remove(struct dentry *dentry, struct dentry *parent) | |||
644 | 641 | ||
645 | if (simple_positive(dentry)) { | 642 | if (simple_positive(dentry)) { |
646 | dget(dentry); | 643 | dget(dentry); |
647 | if (!d_is_reg(dentry)) { | 644 | if (d_is_dir(dentry)) { |
648 | if (d_is_dir(dentry)) | 645 | ret = simple_rmdir(d_inode(parent), dentry); |
649 | ret = simple_rmdir(d_inode(parent), dentry); | ||
650 | else | ||
651 | simple_unlink(d_inode(parent), dentry); | ||
652 | if (!ret) | 646 | if (!ret) |
653 | d_delete(dentry); | 647 | fsnotify_rmdir(d_inode(parent), dentry); |
654 | } else { | 648 | } else { |
655 | __debugfs_remove_file(dentry, parent); | 649 | simple_unlink(d_inode(parent), dentry); |
650 | fsnotify_unlink(d_inode(parent), dentry); | ||
656 | } | 651 | } |
652 | if (!ret) | ||
653 | d_delete(dentry); | ||
654 | if (d_is_reg(dentry)) | ||
655 | __debugfs_file_removed(dentry); | ||
657 | dput(dentry); | 656 | dput(dentry); |
658 | } | 657 | } |
659 | return ret; | 658 | return ret; |
diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c index 2c14ae044dce..beeadca23b05 100644 --- a/fs/devpts/inode.c +++ b/fs/devpts/inode.c | |||
@@ -621,6 +621,7 @@ void devpts_pty_kill(struct dentry *dentry) | |||
621 | 621 | ||
622 | dentry->d_fsdata = NULL; | 622 | dentry->d_fsdata = NULL; |
623 | drop_nlink(dentry->d_inode); | 623 | drop_nlink(dentry->d_inode); |
624 | fsnotify_unlink(d_inode(dentry->d_parent), dentry); | ||
624 | d_delete(dentry); | 625 | d_delete(dentry); |
625 | dput(dentry); /* d_alloc_name() in devpts_pty_new() */ | 626 | dput(dentry); /* d_alloc_name() in devpts_pty_new() */ |
626 | } | 627 | } |
diff --git a/fs/namei.c b/fs/namei.c index 20831c2fbb34..209c51a5226c 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -3883,6 +3883,7 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
3883 | dentry->d_inode->i_flags |= S_DEAD; | 3883 | dentry->d_inode->i_flags |= S_DEAD; |
3884 | dont_mount(dentry); | 3884 | dont_mount(dentry); |
3885 | detach_mounts(dentry); | 3885 | detach_mounts(dentry); |
3886 | fsnotify_rmdir(dir, dentry); | ||
3886 | 3887 | ||
3887 | out: | 3888 | out: |
3888 | inode_unlock(dentry->d_inode); | 3889 | inode_unlock(dentry->d_inode); |
@@ -3999,6 +4000,7 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry, struct inode **delegate | |||
3999 | if (!error) { | 4000 | if (!error) { |
4000 | dont_mount(dentry); | 4001 | dont_mount(dentry); |
4001 | detach_mounts(dentry); | 4002 | detach_mounts(dentry); |
4003 | fsnotify_unlink(dir, dentry); | ||
4002 | } | 4004 | } |
4003 | } | 4005 | } |
4004 | } | 4006 | } |
diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c index 52d533967485..0effeee28352 100644 --- a/fs/nfs/unlink.c +++ b/fs/nfs/unlink.c | |||
@@ -396,12 +396,6 @@ nfs_complete_sillyrename(struct rpc_task *task, struct nfs_renamedata *data) | |||
396 | nfs_cancel_async_unlink(dentry); | 396 | nfs_cancel_async_unlink(dentry); |
397 | return; | 397 | return; |
398 | } | 398 | } |
399 | |||
400 | /* | ||
401 | * vfs_unlink and the like do not issue this when a file is | ||
402 | * sillyrenamed, so do it here. | ||
403 | */ | ||
404 | fsnotify_nameremove(dentry, 0); | ||
405 | } | 399 | } |
406 | 400 | ||
407 | #define SILLYNAME_PREFIX ".nfs" | 401 | #define SILLYNAME_PREFIX ".nfs" |
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index a90bb19dcfa2..91006f47e420 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c | |||
@@ -920,6 +920,22 @@ static int fanotify_test_fid(struct path *path, __kernel_fsid_t *fsid) | |||
920 | return 0; | 920 | return 0; |
921 | } | 921 | } |
922 | 922 | ||
923 | static int fanotify_events_supported(struct path *path, __u64 mask) | ||
924 | { | ||
925 | /* | ||
926 | * Some filesystems such as 'proc' acquire unusual locks when opening | ||
927 | * files. For them fanotify permission events have high chances of | ||
928 | * deadlocking the system - open done when reporting fanotify event | ||
929 | * blocks on this "unusual" lock while another process holding the lock | ||
930 | * waits for fanotify permission event to be answered. Just disallow | ||
931 | * permission events for such filesystems. | ||
932 | */ | ||
933 | if (mask & FANOTIFY_PERM_EVENTS && | ||
934 | path->mnt->mnt_sb->s_type->fs_flags & FS_DISALLOW_NOTIFY_PERM) | ||
935 | return -EINVAL; | ||
936 | return 0; | ||
937 | } | ||
938 | |||
923 | static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask, | 939 | static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask, |
924 | int dfd, const char __user *pathname) | 940 | int dfd, const char __user *pathname) |
925 | { | 941 | { |
@@ -1018,6 +1034,12 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask, | |||
1018 | if (ret) | 1034 | if (ret) |
1019 | goto fput_and_out; | 1035 | goto fput_and_out; |
1020 | 1036 | ||
1037 | if (flags & FAN_MARK_ADD) { | ||
1038 | ret = fanotify_events_supported(&path, mask); | ||
1039 | if (ret) | ||
1040 | goto path_put_and_out; | ||
1041 | } | ||
1042 | |||
1021 | if (FAN_GROUP_FLAG(group, FAN_REPORT_FID)) { | 1043 | if (FAN_GROUP_FLAG(group, FAN_REPORT_FID)) { |
1022 | ret = fanotify_test_fid(&path, &__fsid); | 1044 | ret = fanotify_test_fid(&path, &__fsid); |
1023 | if (ret) | 1045 | if (ret) |
diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c index 4eb2ebfac468..2ecef6155fc0 100644 --- a/fs/notify/fsnotify.c +++ b/fs/notify/fsnotify.c | |||
@@ -95,47 +95,6 @@ void fsnotify_sb_delete(struct super_block *sb) | |||
95 | } | 95 | } |
96 | 96 | ||
97 | /* | 97 | /* |
98 | * fsnotify_nameremove - a filename was removed from a directory | ||
99 | * | ||
100 | * This is mostly called under parent vfs inode lock so name and | ||
101 | * dentry->d_parent should be stable. However there are some corner cases where | ||
102 | * inode lock is not held. So to be on the safe side and be reselient to future | ||
103 | * callers and out of tree users of d_delete(), we do not assume that d_parent | ||
104 | * and d_name are stable and we use dget_parent() and | ||
105 | * take_dentry_name_snapshot() to grab stable references. | ||
106 | */ | ||
107 | void fsnotify_nameremove(struct dentry *dentry, int isdir) | ||
108 | { | ||
109 | struct dentry *parent; | ||
110 | struct name_snapshot name; | ||
111 | __u32 mask = FS_DELETE; | ||
112 | |||
113 | /* d_delete() of pseudo inode? (e.g. __ns_get_path() playing tricks) */ | ||
114 | if (IS_ROOT(dentry)) | ||
115 | return; | ||
116 | |||
117 | if (isdir) | ||
118 | mask |= FS_ISDIR; | ||
119 | |||
120 | parent = dget_parent(dentry); | ||
121 | /* Avoid unneeded take_dentry_name_snapshot() */ | ||
122 | if (!(d_inode(parent)->i_fsnotify_mask & FS_DELETE) && | ||
123 | !(dentry->d_sb->s_fsnotify_mask & FS_DELETE)) | ||
124 | goto out_dput; | ||
125 | |||
126 | take_dentry_name_snapshot(&name, dentry); | ||
127 | |||
128 | fsnotify(d_inode(parent), mask, d_inode(dentry), FSNOTIFY_EVENT_INODE, | ||
129 | &name.name, 0); | ||
130 | |||
131 | release_dentry_name_snapshot(&name); | ||
132 | |||
133 | out_dput: | ||
134 | dput(parent); | ||
135 | } | ||
136 | EXPORT_SYMBOL(fsnotify_nameremove); | ||
137 | |||
138 | /* | ||
139 | * Given an inode, first check if we care what happens to our children. Inotify | 98 | * Given an inode, first check if we care what happens to our children. Inotify |
140 | * and dnotify both tell their parents about events. If we care about any event | 99 | * and dnotify both tell their parents about events. If we care about any event |
141 | * on a child we run all of our children and set a dentry flag saying that the | 100 | * on a child we run all of our children and set a dentry flag saying that the |
diff --git a/fs/proc/root.c b/fs/proc/root.c index 8b145e7b9661..522199e9525e 100644 --- a/fs/proc/root.c +++ b/fs/proc/root.c | |||
@@ -211,7 +211,7 @@ static struct file_system_type proc_fs_type = { | |||
211 | .init_fs_context = proc_init_fs_context, | 211 | .init_fs_context = proc_init_fs_context, |
212 | .parameters = &proc_fs_parameters, | 212 | .parameters = &proc_fs_parameters, |
213 | .kill_sb = proc_kill_sb, | 213 | .kill_sb = proc_kill_sb, |
214 | .fs_flags = FS_USERNS_MOUNT, | 214 | .fs_flags = FS_USERNS_MOUNT | FS_DISALLOW_NOTIFY_PERM, |
215 | }; | 215 | }; |
216 | 216 | ||
217 | void __init proc_root_init(void) | 217 | void __init proc_root_init(void) |
diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c index a5bab190a297..eeeae0475da9 100644 --- a/fs/tracefs/inode.c +++ b/fs/tracefs/inode.c | |||
@@ -505,9 +505,12 @@ static int __tracefs_remove(struct dentry *dentry, struct dentry *parent) | |||
505 | switch (dentry->d_inode->i_mode & S_IFMT) { | 505 | switch (dentry->d_inode->i_mode & S_IFMT) { |
506 | case S_IFDIR: | 506 | case S_IFDIR: |
507 | ret = simple_rmdir(parent->d_inode, dentry); | 507 | ret = simple_rmdir(parent->d_inode, dentry); |
508 | if (!ret) | ||
509 | fsnotify_rmdir(parent->d_inode, dentry); | ||
508 | break; | 510 | break; |
509 | default: | 511 | default: |
510 | simple_unlink(parent->d_inode, dentry); | 512 | simple_unlink(parent->d_inode, dentry); |
513 | fsnotify_unlink(parent->d_inode, dentry); | ||
511 | break; | 514 | break; |
512 | } | 515 | } |
513 | if (!ret) | 516 | if (!ret) |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 4fb399b77327..201ebb1e062d 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -2184,6 +2184,7 @@ struct file_system_type { | |||
2184 | #define FS_BINARY_MOUNTDATA 2 | 2184 | #define FS_BINARY_MOUNTDATA 2 |
2185 | #define FS_HAS_SUBTYPE 4 | 2185 | #define FS_HAS_SUBTYPE 4 |
2186 | #define FS_USERNS_MOUNT 8 /* Can be mounted by userns root */ | 2186 | #define FS_USERNS_MOUNT 8 /* Can be mounted by userns root */ |
2187 | #define FS_DISALLOW_NOTIFY_PERM 16 /* Disable fanotify permission events */ | ||
2187 | #define FS_RENAME_DOES_D_MOVE 32768 /* FS will handle d_move() during rename() internally. */ | 2188 | #define FS_RENAME_DOES_D_MOVE 32768 /* FS will handle d_move() during rename() internally. */ |
2188 | int (*init_fs_context)(struct fs_context *); | 2189 | int (*init_fs_context)(struct fs_context *); |
2189 | const struct fs_parameter_description *parameters; | 2190 | const struct fs_parameter_description *parameters; |
diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index 94972e8eb6d1..a2d5d175d3c1 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h | |||
@@ -189,6 +189,19 @@ static inline void fsnotify_link(struct inode *dir, struct inode *inode, struct | |||
189 | } | 189 | } |
190 | 190 | ||
191 | /* | 191 | /* |
192 | * fsnotify_unlink - 'name' was unlinked | ||
193 | * | ||
194 | * Caller must make sure that dentry->d_name is stable. | ||
195 | */ | ||
196 | static inline void fsnotify_unlink(struct inode *dir, struct dentry *dentry) | ||
197 | { | ||
198 | /* Expected to be called before d_delete() */ | ||
199 | WARN_ON_ONCE(d_is_negative(dentry)); | ||
200 | |||
201 | fsnotify_dirent(dir, dentry, FS_DELETE); | ||
202 | } | ||
203 | |||
204 | /* | ||
192 | * fsnotify_mkdir - directory 'name' was created | 205 | * fsnotify_mkdir - directory 'name' was created |
193 | */ | 206 | */ |
194 | static inline void fsnotify_mkdir(struct inode *inode, struct dentry *dentry) | 207 | static inline void fsnotify_mkdir(struct inode *inode, struct dentry *dentry) |
@@ -199,6 +212,19 @@ static inline void fsnotify_mkdir(struct inode *inode, struct dentry *dentry) | |||
199 | } | 212 | } |
200 | 213 | ||
201 | /* | 214 | /* |
215 | * fsnotify_rmdir - directory 'name' was removed | ||
216 | * | ||
217 | * Caller must make sure that dentry->d_name is stable. | ||
218 | */ | ||
219 | static inline void fsnotify_rmdir(struct inode *dir, struct dentry *dentry) | ||
220 | { | ||
221 | /* Expected to be called before d_delete() */ | ||
222 | WARN_ON_ONCE(d_is_negative(dentry)); | ||
223 | |||
224 | fsnotify_dirent(dir, dentry, FS_DELETE | FS_ISDIR); | ||
225 | } | ||
226 | |||
227 | /* | ||
202 | * fsnotify_access - file was read | 228 | * fsnotify_access - file was read |
203 | */ | 229 | */ |
204 | static inline void fsnotify_access(struct file *file) | 230 | static inline void fsnotify_access(struct file *file) |
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index d4844cad2c2b..2de3b2ddd19a 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h | |||
@@ -357,7 +357,6 @@ extern int __fsnotify_parent(const struct path *path, struct dentry *dentry, __u | |||
357 | extern void __fsnotify_inode_delete(struct inode *inode); | 357 | extern void __fsnotify_inode_delete(struct inode *inode); |
358 | extern void __fsnotify_vfsmount_delete(struct vfsmount *mnt); | 358 | extern void __fsnotify_vfsmount_delete(struct vfsmount *mnt); |
359 | extern void fsnotify_sb_delete(struct super_block *sb); | 359 | extern void fsnotify_sb_delete(struct super_block *sb); |
360 | extern void fsnotify_nameremove(struct dentry *dentry, int isdir); | ||
361 | extern u32 fsnotify_get_cookie(void); | 360 | extern u32 fsnotify_get_cookie(void); |
362 | 361 | ||
363 | static inline int fsnotify_inode_watches_children(struct inode *inode) | 362 | static inline int fsnotify_inode_watches_children(struct inode *inode) |
@@ -527,9 +526,6 @@ static inline void __fsnotify_vfsmount_delete(struct vfsmount *mnt) | |||
527 | static inline void fsnotify_sb_delete(struct super_block *sb) | 526 | static inline void fsnotify_sb_delete(struct super_block *sb) |
528 | {} | 527 | {} |
529 | 528 | ||
530 | static inline void fsnotify_nameremove(struct dentry *dentry, int isdir) | ||
531 | {} | ||
532 | |||
533 | static inline void fsnotify_update_flags(struct dentry *dentry) | 529 | static inline void fsnotify_update_flags(struct dentry *dentry) |
534 | {} | 530 | {} |
535 | 531 | ||
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 126d31472a99..73bd62979fe7 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c | |||
@@ -598,6 +598,8 @@ static int __rpc_rmdir(struct inode *dir, struct dentry *dentry) | |||
598 | 598 | ||
599 | dget(dentry); | 599 | dget(dentry); |
600 | ret = simple_rmdir(dir, dentry); | 600 | ret = simple_rmdir(dir, dentry); |
601 | if (!ret) | ||
602 | fsnotify_rmdir(dir, dentry); | ||
601 | d_delete(dentry); | 603 | d_delete(dentry); |
602 | dput(dentry); | 604 | dput(dentry); |
603 | return ret; | 605 | return ret; |
@@ -609,6 +611,8 @@ static int __rpc_unlink(struct inode *dir, struct dentry *dentry) | |||
609 | 611 | ||
610 | dget(dentry); | 612 | dget(dentry); |
611 | ret = simple_unlink(dir, dentry); | 613 | ret = simple_unlink(dir, dentry); |
614 | if (!ret) | ||
615 | fsnotify_unlink(dir, dentry); | ||
612 | d_delete(dentry); | 616 | d_delete(dentry); |
613 | dput(dentry); | 617 | dput(dentry); |
614 | return ret; | 618 | return ret; |