aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn McCutchan <ttb@tentacle.dhs.org>2005-12-12 03:37:14 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2005-12-12 11:57:43 -0500
commit8140a5005bc6f1c9d0fa103460d50d472e6e3426 (patch)
tree9c5ae431bf1db43e3a1e7a4cceb472c76077ac18
parentb4788f6d55548e587ced330ece711456f40ec8f1 (diff)
[PATCH] inotify: add two inotify_add_watch flags
The below patch lets userspace have more control over the inodes that inotify will watch. It introduces two new flags. IN_ONLYDIR -- only watch the inode if it is a directory. This is needed to avoid the race that can occur when we want to be sure that we are watching a directory. IN_DONT_FOLLOW -- don't follow a symlink. In combination with IN_ONLYDIR we can make sure that we don't watch the target of symlinks. The issues the flags fix came up when writing the gnome-vfs inotify backend. Default behaviour is unchanged. Signed-off-by: John McCutchan <ttb@tentacle.dhs.org> Acked-by: Robert Love <rml@novell.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--fs/inotify.c13
-rw-r--r--include/linux/inotify.h2
2 files changed, 12 insertions, 3 deletions
diff --git a/fs/inotify.c b/fs/inotify.c
index bf7ce1d2412b..2fecb7af4a77 100644
--- a/fs/inotify.c
+++ b/fs/inotify.c
@@ -364,11 +364,12 @@ static int inotify_dev_get_wd(struct inotify_device *dev,
364/* 364/*
365 * find_inode - resolve a user-given path to a specific inode and return a nd 365 * find_inode - resolve a user-given path to a specific inode and return a nd
366 */ 366 */
367static int find_inode(const char __user *dirname, struct nameidata *nd) 367static int find_inode(const char __user *dirname, struct nameidata *nd,
368 unsigned flags)
368{ 369{
369 int error; 370 int error;
370 371
371 error = __user_walk(dirname, LOOKUP_FOLLOW, nd); 372 error = __user_walk(dirname, flags, nd);
372 if (error) 373 if (error)
373 return error; 374 return error;
374 /* you can only watch an inode if you have read permissions on it */ 375 /* you can only watch an inode if you have read permissions on it */
@@ -933,6 +934,7 @@ asmlinkage long sys_inotify_add_watch(int fd, const char __user *path, u32 mask)
933 struct file *filp; 934 struct file *filp;
934 int ret, fput_needed; 935 int ret, fput_needed;
935 int mask_add = 0; 936 int mask_add = 0;
937 unsigned flags = 0;
936 938
937 filp = fget_light(fd, &fput_needed); 939 filp = fget_light(fd, &fput_needed);
938 if (unlikely(!filp)) 940 if (unlikely(!filp))
@@ -944,7 +946,12 @@ asmlinkage long sys_inotify_add_watch(int fd, const char __user *path, u32 mask)
944 goto fput_and_out; 946 goto fput_and_out;
945 } 947 }
946 948
947 ret = find_inode(path, &nd); 949 if (!(mask & IN_DONT_FOLLOW))
950 flags |= LOOKUP_FOLLOW;
951 if (mask & IN_ONLYDIR)
952 flags |= LOOKUP_DIRECTORY;
953
954 ret = find_inode(path, &nd, flags);
948 if (unlikely(ret)) 955 if (unlikely(ret))
949 goto fput_and_out; 956 goto fput_and_out;
950 957
diff --git a/include/linux/inotify.h b/include/linux/inotify.h
index ee5b239092ed..267c88b5f742 100644
--- a/include/linux/inotify.h
+++ b/include/linux/inotify.h
@@ -47,6 +47,8 @@ struct inotify_event {
47#define IN_MOVE (IN_MOVED_FROM | IN_MOVED_TO) /* moves */ 47#define IN_MOVE (IN_MOVED_FROM | IN_MOVED_TO) /* moves */
48 48
49/* special flags */ 49/* special flags */
50#define IN_ONLYDIR 0x01000000 /* only watch the path if it is a directory */
51#define IN_DONT_FOLLOW 0x02000000 /* don't follow a sym link */
50#define IN_MASK_ADD 0x20000000 /* add to the mask of an already existing watch */ 52#define IN_MASK_ADD 0x20000000 /* add to the mask of an already existing watch */
51#define IN_ISDIR 0x40000000 /* event occurred against dir */ 53#define IN_ISDIR 0x40000000 /* event occurred against dir */
52#define IN_ONESHOT 0x80000000 /* only send event once */ 54#define IN_ONESHOT 0x80000000 /* only send event once */