diff options
-rw-r--r-- | fs/dcache.c | 7 | ||||
-rw-r--r-- | fs/namei.c | 3 | ||||
-rw-r--r-- | include/linux/fsnotify.h | 20 |
3 files changed, 27 insertions, 3 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index 3aa8a7e980d8..a15a2e1f5520 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/string.h> | 19 | #include <linux/string.h> |
20 | #include <linux/mm.h> | 20 | #include <linux/mm.h> |
21 | #include <linux/fs.h> | 21 | #include <linux/fs.h> |
22 | #include <linux/fsnotify.h> | ||
22 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
23 | #include <linux/init.h> | 24 | #include <linux/init.h> |
24 | #include <linux/smp_lock.h> | 25 | #include <linux/smp_lock.h> |
@@ -101,6 +102,7 @@ static inline void dentry_iput(struct dentry * dentry) | |||
101 | list_del_init(&dentry->d_alias); | 102 | list_del_init(&dentry->d_alias); |
102 | spin_unlock(&dentry->d_lock); | 103 | spin_unlock(&dentry->d_lock); |
103 | spin_unlock(&dcache_lock); | 104 | spin_unlock(&dcache_lock); |
105 | fsnotify_inoderemove(inode); | ||
104 | if (dentry->d_op && dentry->d_op->d_iput) | 106 | if (dentry->d_op && dentry->d_op->d_iput) |
105 | dentry->d_op->d_iput(dentry, inode); | 107 | dentry->d_op->d_iput(dentry, inode); |
106 | else | 108 | else |
@@ -1165,13 +1167,16 @@ out: | |||
1165 | 1167 | ||
1166 | void d_delete(struct dentry * dentry) | 1168 | void d_delete(struct dentry * dentry) |
1167 | { | 1169 | { |
1170 | int isdir = 0; | ||
1168 | /* | 1171 | /* |
1169 | * Are we the only user? | 1172 | * Are we the only user? |
1170 | */ | 1173 | */ |
1171 | spin_lock(&dcache_lock); | 1174 | spin_lock(&dcache_lock); |
1172 | spin_lock(&dentry->d_lock); | 1175 | spin_lock(&dentry->d_lock); |
1176 | isdir = S_ISDIR(dentry->d_inode->i_mode); | ||
1173 | if (atomic_read(&dentry->d_count) == 1) { | 1177 | if (atomic_read(&dentry->d_count) == 1) { |
1174 | dentry_iput(dentry); | 1178 | dentry_iput(dentry); |
1179 | fsnotify_nameremove(dentry, isdir); | ||
1175 | return; | 1180 | return; |
1176 | } | 1181 | } |
1177 | 1182 | ||
@@ -1180,6 +1185,8 @@ void d_delete(struct dentry * dentry) | |||
1180 | 1185 | ||
1181 | spin_unlock(&dentry->d_lock); | 1186 | spin_unlock(&dentry->d_lock); |
1182 | spin_unlock(&dcache_lock); | 1187 | spin_unlock(&dcache_lock); |
1188 | |||
1189 | fsnotify_nameremove(dentry, isdir); | ||
1183 | } | 1190 | } |
1184 | 1191 | ||
1185 | static void __d_rehash(struct dentry * entry, struct hlist_head *list) | 1192 | static void __d_rehash(struct dentry * entry, struct hlist_head *list) |
diff --git a/fs/namei.c b/fs/namei.c index 32accb6a672f..57046d98a746 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -1802,7 +1802,6 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
1802 | up(&dentry->d_inode->i_sem); | 1802 | up(&dentry->d_inode->i_sem); |
1803 | if (!error) { | 1803 | if (!error) { |
1804 | d_delete(dentry); | 1804 | d_delete(dentry); |
1805 | fsnotify_rmdir(dentry, dentry->d_inode, dir); | ||
1806 | } | 1805 | } |
1807 | dput(dentry); | 1806 | dput(dentry); |
1808 | 1807 | ||
@@ -1874,9 +1873,7 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry) | |||
1874 | 1873 | ||
1875 | /* We don't d_delete() NFS sillyrenamed files--they still exist. */ | 1874 | /* We don't d_delete() NFS sillyrenamed files--they still exist. */ |
1876 | if (!error && !(dentry->d_flags & DCACHE_NFSFS_RENAMED)) { | 1875 | if (!error && !(dentry->d_flags & DCACHE_NFSFS_RENAMED)) { |
1877 | struct inode *inode = dentry->d_inode; | ||
1878 | d_delete(dentry); | 1876 | d_delete(dentry); |
1879 | fsnotify_unlink(dentry, inode, dir); | ||
1880 | } | 1877 | } |
1881 | 1878 | ||
1882 | return error; | 1879 | return error; |
diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index 1cb4935348d8..9db31d251c20 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h | |||
@@ -68,6 +68,26 @@ static inline void fsnotify_rmdir(struct dentry *dentry, struct inode *inode, | |||
68 | } | 68 | } |
69 | 69 | ||
70 | /* | 70 | /* |
71 | * fsnotify_nameremove - a filename was removed from a directory | ||
72 | */ | ||
73 | static inline void fsnotify_nameremove(struct dentry *dentry, int isdir) | ||
74 | { | ||
75 | if (isdir) | ||
76 | isdir = IN_ISDIR; | ||
77 | dnotify_parent(dentry, DN_DELETE); | ||
78 | inotify_dentry_parent_queue_event(dentry, IN_DELETE|isdir, 0, dentry->d_name.name); | ||
79 | } | ||
80 | |||
81 | /* | ||
82 | * fsnotify_inoderemove - an inode is going away | ||
83 | */ | ||
84 | static inline void fsnotify_inoderemove(struct inode *inode) | ||
85 | { | ||
86 | inotify_inode_queue_event(inode, IN_DELETE_SELF, 0, NULL); | ||
87 | inotify_inode_is_dead(inode); | ||
88 | } | ||
89 | |||
90 | /* | ||
71 | * fsnotify_create - 'name' was linked in | 91 | * fsnotify_create - 'name' was linked in |
72 | */ | 92 | */ |
73 | static inline void fsnotify_create(struct inode *inode, const char *name) | 93 | static inline void fsnotify_create(struct inode *inode, const char *name) |