aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namei.c
diff options
context:
space:
mode:
authorRobert Love <rml@novell.com>2005-07-12 17:06:03 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-07-12 23:38:38 -0400
commit0eeca28300df110bd6ed54b31193c83b87921443 (patch)
tree7db42d8a18d80eca538f5b7d25e0532b8fa38b85 /fs/namei.c
parentbd4c625c061c2a38568d0add3478f59172455159 (diff)
[PATCH] inotify
inotify is intended to correct the deficiencies of dnotify, particularly its inability to scale and its terrible user interface: * dnotify requires the opening of one fd per each directory that you intend to watch. This quickly results in too many open files and pins removable media, preventing unmount. * dnotify is directory-based. You only learn about changes to directories. Sure, a change to a file in a directory affects the directory, but you are then forced to keep a cache of stat structures. * dnotify's interface to user-space is awful. Signals? inotify provides a more usable, simple, powerful solution to file change notification: * inotify's interface is a system call that returns a fd, not SIGIO. You get a single fd, which is select()-able. * inotify has an event that says "the filesystem that the item you were watching is on was unmounted." * inotify can watch directories or files. Inotify is currently used by Beagle (a desktop search infrastructure), Gamin (a FAM replacement), and other projects. See Documentation/filesystems/inotify.txt. Signed-off-by: Robert Love <rml@novell.com> Cc: John McCutchan <ttb@tentacle.dhs.org> Cc: Christoph Hellwig <hch@lst.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/namei.c')
-rw-r--r--fs/namei.c30
1 files changed, 16 insertions, 14 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 1d93cb4f7c5f..02a824cd3c5c 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -21,7 +21,7 @@
21#include <linux/namei.h> 21#include <linux/namei.h>
22#include <linux/quotaops.h> 22#include <linux/quotaops.h>
23#include <linux/pagemap.h> 23#include <linux/pagemap.h>
24#include <linux/dnotify.h> 24#include <linux/fsnotify.h>
25#include <linux/smp_lock.h> 25#include <linux/smp_lock.h>
26#include <linux/personality.h> 26#include <linux/personality.h>
27#include <linux/security.h> 27#include <linux/security.h>
@@ -1312,7 +1312,7 @@ int vfs_create(struct inode *dir, struct dentry *dentry, int mode,
1312 DQUOT_INIT(dir); 1312 DQUOT_INIT(dir);
1313 error = dir->i_op->create(dir, dentry, mode, nd); 1313 error = dir->i_op->create(dir, dentry, mode, nd);
1314 if (!error) { 1314 if (!error) {
1315 inode_dir_notify(dir, DN_CREATE); 1315 fsnotify_create(dir, dentry->d_name.name);
1316 security_inode_post_create(dir, dentry, mode); 1316 security_inode_post_create(dir, dentry, mode);
1317 } 1317 }
1318 return error; 1318 return error;
@@ -1637,7 +1637,7 @@ int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
1637 DQUOT_INIT(dir); 1637 DQUOT_INIT(dir);
1638 error = dir->i_op->mknod(dir, dentry, mode, dev); 1638 error = dir->i_op->mknod(dir, dentry, mode, dev);
1639 if (!error) { 1639 if (!error) {
1640 inode_dir_notify(dir, DN_CREATE); 1640 fsnotify_create(dir, dentry->d_name.name);
1641 security_inode_post_mknod(dir, dentry, mode, dev); 1641 security_inode_post_mknod(dir, dentry, mode, dev);
1642 } 1642 }
1643 return error; 1643 return error;
@@ -1710,7 +1710,7 @@ int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
1710 DQUOT_INIT(dir); 1710 DQUOT_INIT(dir);
1711 error = dir->i_op->mkdir(dir, dentry, mode); 1711 error = dir->i_op->mkdir(dir, dentry, mode);
1712 if (!error) { 1712 if (!error) {
1713 inode_dir_notify(dir, DN_CREATE); 1713 fsnotify_mkdir(dir, dentry->d_name.name);
1714 security_inode_post_mkdir(dir,dentry, mode); 1714 security_inode_post_mkdir(dir,dentry, mode);
1715 } 1715 }
1716 return error; 1716 return error;
@@ -1801,7 +1801,7 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry)
1801 } 1801 }
1802 up(&dentry->d_inode->i_sem); 1802 up(&dentry->d_inode->i_sem);
1803 if (!error) { 1803 if (!error) {
1804 inode_dir_notify(dir, DN_DELETE); 1804 fsnotify_rmdir(dentry, dentry->d_inode, dir);
1805 d_delete(dentry); 1805 d_delete(dentry);
1806 } 1806 }
1807 dput(dentry); 1807 dput(dentry);
@@ -1874,9 +1874,10 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry)
1874 1874
1875 /* We don't d_delete() NFS sillyrenamed files--they still exist. */ 1875 /* We don't d_delete() NFS sillyrenamed files--they still exist. */
1876 if (!error && !(dentry->d_flags & DCACHE_NFSFS_RENAMED)) { 1876 if (!error && !(dentry->d_flags & DCACHE_NFSFS_RENAMED)) {
1877 fsnotify_unlink(dentry, dir);
1877 d_delete(dentry); 1878 d_delete(dentry);
1878 inode_dir_notify(dir, DN_DELETE);
1879 } 1879 }
1880
1880 return error; 1881 return error;
1881} 1882}
1882 1883
@@ -1950,7 +1951,7 @@ int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname, i
1950 DQUOT_INIT(dir); 1951 DQUOT_INIT(dir);
1951 error = dir->i_op->symlink(dir, dentry, oldname); 1952 error = dir->i_op->symlink(dir, dentry, oldname);
1952 if (!error) { 1953 if (!error) {
1953 inode_dir_notify(dir, DN_CREATE); 1954 fsnotify_create(dir, dentry->d_name.name);
1954 security_inode_post_symlink(dir, dentry, oldname); 1955 security_inode_post_symlink(dir, dentry, oldname);
1955 } 1956 }
1956 return error; 1957 return error;
@@ -2023,7 +2024,7 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de
2023 error = dir->i_op->link(old_dentry, dir, new_dentry); 2024 error = dir->i_op->link(old_dentry, dir, new_dentry);
2024 up(&old_dentry->d_inode->i_sem); 2025 up(&old_dentry->d_inode->i_sem);
2025 if (!error) { 2026 if (!error) {
2026 inode_dir_notify(dir, DN_CREATE); 2027 fsnotify_create(dir, new_dentry->d_name.name);
2027 security_inode_post_link(old_dentry, dir, new_dentry); 2028 security_inode_post_link(old_dentry, dir, new_dentry);
2028 } 2029 }
2029 return error; 2030 return error;
@@ -2187,6 +2188,7 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
2187{ 2188{
2188 int error; 2189 int error;
2189 int is_dir = S_ISDIR(old_dentry->d_inode->i_mode); 2190 int is_dir = S_ISDIR(old_dentry->d_inode->i_mode);
2191 const char *old_name;
2190 2192
2191 if (old_dentry->d_inode == new_dentry->d_inode) 2193 if (old_dentry->d_inode == new_dentry->d_inode)
2192 return 0; 2194 return 0;
@@ -2208,18 +2210,18 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
2208 DQUOT_INIT(old_dir); 2210 DQUOT_INIT(old_dir);
2209 DQUOT_INIT(new_dir); 2211 DQUOT_INIT(new_dir);
2210 2212
2213 old_name = fsnotify_oldname_init(old_dentry->d_name.name);
2214
2211 if (is_dir) 2215 if (is_dir)
2212 error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry); 2216 error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
2213 else 2217 else
2214 error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry); 2218 error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
2215 if (!error) { 2219 if (!error) {
2216 if (old_dir == new_dir) 2220 const char *new_name = old_dentry->d_name.name;
2217 inode_dir_notify(old_dir, DN_RENAME); 2221 fsnotify_move(old_dir, new_dir, old_name, new_name, is_dir);
2218 else {
2219 inode_dir_notify(old_dir, DN_DELETE);
2220 inode_dir_notify(new_dir, DN_CREATE);
2221 }
2222 } 2222 }
2223 fsnotify_oldname_free(old_name);
2224
2223 return error; 2225 return error;
2224} 2226}
2225 2227