Commit 2d9048e2 authored by Amy Griffis's avatar Amy Griffis Committed by Al Viro

[PATCH] inotify (1/5): split kernel API from userspace support

The following series of patches introduces a kernel API for inotify,
making it possible for kernel modules to benefit from inotify's
mechanism for watching inodes.  With these patches, inotify will
maintain for each caller a list of watches (via an embedded struct
inotify_watch), where each inotify_watch is associated with a
corresponding struct inode.  The caller registers an event handler and
specifies for which filesystem events their event handler should be
called per inotify_watch.
Signed-off-by: default avatarAmy Griffis <amy.griffis@hp.com>
Acked-by: default avatarRobert Love <rml@novell.com>
Acked-by: default avatarJohn McCutchan <john@johnmccutchan.com>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 90204e0b
...@@ -393,18 +393,30 @@ config INOTIFY ...@@ -393,18 +393,30 @@ config INOTIFY
bool "Inotify file change notification support" bool "Inotify file change notification support"
default y default y
---help--- ---help---
Say Y here to enable inotify support and the associated system Say Y here to enable inotify support. Inotify is a file change
calls. Inotify is a file change notification system and a notification system and a replacement for dnotify. Inotify fixes
replacement for dnotify. Inotify fixes numerous shortcomings in numerous shortcomings in dnotify and introduces several new features
dnotify and introduces several new features. It allows monitoring including multiple file events, one-shot support, and unmount
of both files and directories via a single open fd. Other features
include multiple file events, one-shot support, and unmount
notification. notification.
For more information, see Documentation/filesystems/inotify.txt For more information, see Documentation/filesystems/inotify.txt
If unsure, say Y. If unsure, say Y.
config INOTIFY_USER
bool "Inotify support for userspace"
depends on INOTIFY
default y
---help---
Say Y here to enable inotify support for userspace, including the
associated system calls. Inotify allows monitoring of both files and
directories via a single open fd. Events are read from the file
descriptor, which is also select()- and poll()-able.
For more information, see Documentation/filesystems/inotify.txt
If unsure, say Y.
config QUOTA config QUOTA
bool "Quota support" bool "Quota support"
help help
......
...@@ -13,6 +13,7 @@ obj-y := open.o read_write.o file_table.o buffer.o bio.o super.o \ ...@@ -13,6 +13,7 @@ obj-y := open.o read_write.o file_table.o buffer.o bio.o super.o \
ioprio.o pnode.o drop_caches.o splice.o sync.o ioprio.o pnode.o drop_caches.o splice.o sync.o
obj-$(CONFIG_INOTIFY) += inotify.o obj-$(CONFIG_INOTIFY) += inotify.o
obj-$(CONFIG_INOTIFY_USER) += inotify_user.o
obj-$(CONFIG_EPOLL) += eventpoll.o obj-$(CONFIG_EPOLL) += eventpoll.o
obj-$(CONFIG_COMPAT) += compat.o compat_ioctl.o obj-$(CONFIG_COMPAT) += compat.o compat_ioctl.o
......
This diff is collapsed.
This diff is collapsed.
...@@ -68,8 +68,37 @@ struct inotify_event { ...@@ -68,8 +68,37 @@ struct inotify_event {
#include <linux/dcache.h> #include <linux/dcache.h>
#include <linux/fs.h> #include <linux/fs.h>
/*
* struct inotify_watch - represents a watch request on a specific inode
*
* h_list is protected by ih->mutex of the associated inotify_handle.
* i_list, mask are protected by inode->inotify_mutex of the associated inode.
* ih, inode, and wd are never written to once the watch is created.
*
* Callers must use the established inotify interfaces to access inotify_watch
* contents. The content of this structure is private to the inotify
* implementation.
*/
struct inotify_watch {
struct list_head h_list; /* entry in inotify_handle's list */
struct list_head i_list; /* entry in inode's list */
atomic_t count; /* reference count */
struct inotify_handle *ih; /* associated inotify handle */
struct inode *inode; /* associated inode */
__s32 wd; /* watch descriptor */
__u32 mask; /* event mask for this watch */
};
struct inotify_operations {
void (*handle_event)(struct inotify_watch *, u32, u32, u32,
const char *);
void (*destroy_watch)(struct inotify_watch *);
};
#ifdef CONFIG_INOTIFY #ifdef CONFIG_INOTIFY
/* Kernel API for producing events */
extern void inotify_d_instantiate(struct dentry *, struct inode *); extern void inotify_d_instantiate(struct dentry *, struct inode *);
extern void inotify_d_move(struct dentry *); extern void inotify_d_move(struct dentry *);
extern void inotify_inode_queue_event(struct inode *, __u32, __u32, extern void inotify_inode_queue_event(struct inode *, __u32, __u32,
...@@ -80,6 +109,18 @@ extern void inotify_unmount_inodes(struct list_head *); ...@@ -80,6 +109,18 @@ extern void inotify_unmount_inodes(struct list_head *);
extern void inotify_inode_is_dead(struct inode *); extern void inotify_inode_is_dead(struct inode *);
extern u32 inotify_get_cookie(void); extern u32 inotify_get_cookie(void);
/* Kernel Consumer API */
extern struct inotify_handle *inotify_init(const struct inotify_operations *);
extern void inotify_destroy(struct inotify_handle *);
extern __s32 inotify_find_update_watch(struct inotify_handle *, struct inode *,
u32);
extern __s32 inotify_add_watch(struct inotify_handle *, struct inotify_watch *,
struct inode *, __u32);
extern int inotify_rm_wd(struct inotify_handle *, __u32);
extern void get_inotify_watch(struct inotify_watch *);
extern void put_inotify_watch(struct inotify_watch *);
#else #else
static inline void inotify_d_instantiate(struct dentry *dentry, static inline void inotify_d_instantiate(struct dentry *dentry,
...@@ -116,6 +157,41 @@ static inline u32 inotify_get_cookie(void) ...@@ -116,6 +157,41 @@ static inline u32 inotify_get_cookie(void)
return 0; return 0;
} }
static inline struct inotify_handle *inotify_init(const struct inotify_operations *ops)
{
return ERR_PTR(-EOPNOTSUPP);
}
static inline void inotify_destroy(struct inotify_handle *ih)
{
}
static inline __s32 inotify_find_update_watch(struct inotify_handle *ih,
struct inode *inode, u32 mask)
{
return -EOPNOTSUPP;
}
static inline __s32 inotify_add_watch(struct inotify_handle *ih,
struct inotify_watch *watch,
struct inode *inode, __u32 mask)
{
return -EOPNOTSUPP;
}
static inline int inotify_rm_wd(struct inotify_handle *ih, __u32 wd)
{
return -EOPNOTSUPP;
}
static inline void get_inotify_watch(struct inotify_watch *watch)
{
}
static inline void put_inotify_watch(struct inotify_watch *watch)
{
}
#endif /* CONFIG_INOTIFY */ #endif /* CONFIG_INOTIFY */
#endif /* __KERNEL __ */ #endif /* __KERNEL __ */
......
...@@ -494,7 +494,7 @@ struct user_struct { ...@@ -494,7 +494,7 @@ struct user_struct {
atomic_t processes; /* How many processes does this user have? */ atomic_t processes; /* How many processes does this user have? */
atomic_t files; /* How many open files does this user have? */ atomic_t files; /* How many open files does this user have? */
atomic_t sigpending; /* How many pending signals does this user have? */ atomic_t sigpending; /* How many pending signals does this user have? */
#ifdef CONFIG_INOTIFY #ifdef CONFIG_INOTIFY_USER
atomic_t inotify_watches; /* How many inotify watches does this user have? */ atomic_t inotify_watches; /* How many inotify watches does this user have? */
atomic_t inotify_devs; /* How many inotify devs does this user have opened? */ atomic_t inotify_devs; /* How many inotify devs does this user have opened? */
#endif #endif
......
...@@ -150,7 +150,7 @@ extern ctl_table random_table[]; ...@@ -150,7 +150,7 @@ extern ctl_table random_table[];
#ifdef CONFIG_UNIX98_PTYS #ifdef CONFIG_UNIX98_PTYS
extern ctl_table pty_table[]; extern ctl_table pty_table[];
#endif #endif
#ifdef CONFIG_INOTIFY #ifdef CONFIG_INOTIFY_USER
extern ctl_table inotify_table[]; extern ctl_table inotify_table[];
#endif #endif
...@@ -1028,7 +1028,7 @@ static ctl_table fs_table[] = { ...@@ -1028,7 +1028,7 @@ static ctl_table fs_table[] = {
.mode = 0644, .mode = 0644,
.proc_handler = &proc_doulongvec_minmax, .proc_handler = &proc_doulongvec_minmax,
}, },
#ifdef CONFIG_INOTIFY #ifdef CONFIG_INOTIFY_USER
{ {
.ctl_name = FS_INOTIFY, .ctl_name = FS_INOTIFY,
.procname = "inotify", .procname = "inotify",
......
...@@ -140,7 +140,7 @@ struct user_struct * alloc_uid(uid_t uid) ...@@ -140,7 +140,7 @@ struct user_struct * alloc_uid(uid_t uid)
atomic_set(&new->processes, 0); atomic_set(&new->processes, 0);
atomic_set(&new->files, 0); atomic_set(&new->files, 0);
atomic_set(&new->sigpending, 0); atomic_set(&new->sigpending, 0);
#ifdef CONFIG_INOTIFY #ifdef CONFIG_INOTIFY_USER
atomic_set(&new->inotify_watches, 0); atomic_set(&new->inotify_watches, 0);
atomic_set(&new->inotify_devs, 0); atomic_set(&new->inotify_devs, 0);
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment