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(a)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(a)redhat.com
http://www.redhat.com/mailman/listinfo/linux-audit