[RFC][PATCH] Inotify kernel API

Timothy R. Chavez tinytim at us.ibm.com
Wed Aug 24 15:04:28 UTC 2005


On Wednesday 24 August 2005 08:42, Amy Griffis wrote:
> On Tue, Aug 23, 2005 at 04:28:54PM -0500, Timothy R. Chavez wrote:
> > On Tuesday 23 August 2005 15:50, Chris Wright wrote:
> > > * Amy Griffis (amy.griffis at hp.com) wrote:
> > > > diff -r 8ecff93e704a -r 58e1301e9661 fs/inotify.c
> > > > --- a/fs/inotify.c	Thu Aug 18 19:53:59 2005
> > > > +++ b/fs/inotify.c	Thu Aug 18 23:19:52 2005
> > > > @@ -83,14 +83,18 @@
> > > >  	wait_queue_head_t 	wq;		/* wait queue for i/o */
> > > >  	struct idr		idr;		/* idr mapping wd -> watch */
> > > >  	struct semaphore	sem;		/* protects this bad boy */
> > > > -	struct list_head 	events;		/* list of queued events */
> > > >  	struct list_head	watches;	/* list of watches */
> > > >  	atomic_t		count;		/* reference count */
> > > > +	u32			last_wd;	/* the last wd allocated */
> > > > +	/* userland consumer API */
> > > > +	struct list_head 	events;		/* list of queued events */
> > > >  	struct user_struct	*user;		/* user who opened this dev */
> > > >  	unsigned int		queue_size;	/* size of the queue (bytes) */
> > > >  	unsigned int		event_count;	/* number of pending events */
> > > >  	unsigned int		max_events;	/* maximum number of events */
> > > > -	u32			last_wd;	/* the last wd allocated */
> > > > +	/* kernel consumer API */
> > > > +	void (*callback)(struct inotify_event *, const char *,
> > > > +			 void *); 		/* event callback */
> > > 
> > > Is there a compelling reason for the arg to be typeless?  Are you trying
> > > to multiplex each event through a single callback?
> > 
> > Seems like she's just trying to be as generic as possible.  Each Inotify 
> > kernel client has its own inotify device with its own callback.  It passes to 
> > it among the obvious, a generic bit of per-watch information (in our case it 
> > would be audit related information, perhaps a filter key of sorts).  Is this 
> > correct?
> 
> The purpose of the void callback argument is to provide the consumer
> with a quick-access method back to a data structure it has associated
> with a given Inotify watch.
> 
> Audit, and likely any other kernel consumer, will want to maintain
> some of its own data about the watches it has created with Inotify.
> When an event occurs and the callback is called, the consumer has a
> couple of options for associating that event callback with its own
> data:
> 
>     (1) walk its own lists, searching for the wd.  Alternatively hash
>         the wd to speed up the process.
> 
>     (2) use the callback argument to jump directly to its own watch data
> 
> In order to do (2), the consumer passes the pointer to its own watch
> structure when it calls inotify_add_watch().  Inotify never looks at
> the callback argument, it just stores it in the inotify_watch.  When
> the callback occurs, Inotify passes the pointer back to the consumer.
> 
> This is the best way I've come up with to avoid wasting a lot of time
> in the callback, especially when there are a lot of watches involved.
> 

The alternative approach is to embed Inotify watches in a per-client
specific watch, ie:

struct my_watch {
        char *my_char;
        uint *my_uint;
        inotify_watch watch;
};

my_watch foo;

And then pass to the Inotify add function, the inotify_watch, 

&foo->watch;

Then, when the watch is triggered, use container_of to
obtain the encompassing structure (my_watch), and 
presto, you have all the information client-specific
watch info.

-tim


> --
> Linux-audit mailing list
> Linux-audit at redhat.com
> http://www.redhat.com/mailman/listinfo/linux-audit
> 
> 




More information about the Linux-audit mailing list