LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [RFC/PATCH] inotify -- a dnotify replacement
@ 2004-05-10  1:35 John McCutchan
  2004-05-10  2:11 ` Chris Wedgwood
                   ` (2 more replies)
  0 siblings, 3 replies; 29+ messages in thread
From: John McCutchan @ 2004-05-10  1:35 UTC (permalink / raw)
  To: linux-kernel, nautilus-list

[-- Attachment #1: Type: text/plain, Size: 1643 bytes --]

Hi,

I have been working on inotify a dnotify replacement. 

inotify is a char device that has two ioctls: INOTIFY_WATCH and
INOTIFY_IGNORE Which expect an inode number and an inode device number.
I know that on some file systems the inode number and inode device
number are not guaranteed to be unique. This driver is only meant for
file systems that have unique inode numbers. 

The two biggest complaints people have about dnotify are

1) dnotify delivers events using signals. 

2) dnotify needs a file to be kept open on the device, causing problems
during unmount. 


As for 1) -- since inotify is a char device the events are delivered
when the user calls read (). This easily integrates in to an
applications select() loop.

I have a solution for 2) but I haven't implemented it yet, as I don't
have the expertise. What I want to do is distinguish between some one
holding a 'real' reference on an inode, and a reference that is used
only for watching. This way in the unmount code we can make sure that no
one is holding a real reference to an inode on the device, then while
invalidating the inodes, clear the inodes watch list and send UNMOUNT
events to the inotify device. Changes would have to be made so that
inodes are kept in the inode cache when a watching reference is held.

I would like some pointers on how to implement 2). I am not sure the
code path that takes place on unmount, or the best place to change the
inode cache semantics.

I would also appreciate comments on the design in general and code
review (this is my first kernel project).

Attached is a patch implementing everything described in the email.

John


[-- Attachment #2: inotify.patch --]
[-- Type: text/x-patch, Size: 4635 bytes --]

diff -ru clean/linux-2.6.5/fs/attr.c linux-2.6.5/fs/attr.c
--- clean/linux-2.6.5/fs/attr.c	2004-04-03 22:36:24.000000000 -0500
+++ linux-2.6.5/fs/attr.c	2004-05-09 21:02:24.000000000 -0400
@@ -11,6 +11,7 @@
 #include <linux/string.h>
 #include <linux/smp_lock.h>
 #include <linux/dnotify.h>
+#include <linux/inotify.h>
 #include <linux/fcntl.h>
 #include <linux/quotaops.h>
 #include <linux/security.h>
@@ -127,6 +128,7 @@
 	return dn_mask;
 }
 
+
 int notify_change(struct dentry * dentry, struct iattr * attr)
 {
 	struct inode *inode = dentry->d_inode;
@@ -184,8 +186,10 @@
 	}
 	if (!error) {
 		unsigned long dn_mask = setattr_mask(ia_valid);
-		if (dn_mask)
+		if (dn_mask) {
 			dnotify_parent(dentry, dn_mask);
+			inotify_dentry_queue_event (dentry, dn_mask);
+		}
 	}
 	return error;
 }
diff -ru clean/linux-2.6.5/fs/inode.c linux-2.6.5/fs/inode.c
--- clean/linux-2.6.5/fs/inode.c	2004-04-03 22:38:23.000000000 -0500
+++ linux-2.6.5/fs/inode.c	2004-05-09 21:10:12.000000000 -0400
@@ -151,6 +151,10 @@
 			mapping->backing_dev_info = sb->s_bdev->bd_inode->i_mapping->backing_dev_info;
 		memset(&inode->u, 0, sizeof(inode->u));
 		inode->i_mapping = mapping;
+
+		INIT_LIST_HEAD(&inode->watchers);
+		atomic_set (&inode->watcher_count, 0);
+		inode->watchers_mask = 0;
 	}
 	return inode;
 }
@@ -159,11 +163,15 @@
 {
 	if (inode_has_buffers(inode))
 		BUG();
+	/* When an inode gets destroyed it shouldn't have any watchers left on it */
+	if (!list_empty (&inode->watchers))
+		BUG();
 	security_inode_free(inode);
 	if (inode->i_sb->s_op->destroy_inode)
 		inode->i_sb->s_op->destroy_inode(inode);
 	else
 		kmem_cache_free(inode_cachep, (inode));
+
 }
 
 
diff -ru clean/linux-2.6.5/fs/Makefile linux-2.6.5/fs/Makefile
--- clean/linux-2.6.5/fs/Makefile	2004-04-03 22:37:23.000000000 -0500
+++ linux-2.6.5/fs/Makefile	2004-04-20 23:35:17.000000000 -0400
@@ -10,7 +10,7 @@
 		namei.o fcntl.o ioctl.o readdir.o select.o fifo.o locks.o \
 		dcache.o inode.o attr.o bad_inode.o file.o dnotify.o \
 		filesystems.o namespace.o seq_file.o xattr.o libfs.o \
-		fs-writeback.o mpage.o direct-io.o aio.o
+		fs-writeback.o mpage.o direct-io.o aio.o inotify.o 
 
 obj-$(CONFIG_EPOLL)		+= eventpoll.o
 obj-$(CONFIG_COMPAT)		+= compat.o
diff -ru clean/linux-2.6.5/fs/read_write.c linux-2.6.5/fs/read_write.c
--- clean/linux-2.6.5/fs/read_write.c	2004-04-03 22:37:36.000000000 -0500
+++ linux-2.6.5/fs/read_write.c	2004-05-09 21:02:14.000000000 -0400
@@ -11,6 +11,7 @@
 #include <linux/uio.h>
 #include <linux/smp_lock.h>
 #include <linux/dnotify.h>
+#include <linux/inotify.h>
 #include <linux/security.h>
 #include <linux/module.h>
 
@@ -214,8 +215,10 @@
 				ret = file->f_op->read(file, buf, count, pos);
 			else
 				ret = do_sync_read(file, buf, count, pos);
-			if (ret > 0)
+			if (ret > 0) {
 				dnotify_parent(file->f_dentry, DN_ACCESS);
+				inotify_dentry_queue_event (file->f_dentry, IN_ACCESS);
+			}
 		}
 	}
 
@@ -258,8 +261,10 @@
 				ret = file->f_op->write(file, buf, count, pos);
 			else
 				ret = do_sync_write(file, buf, count, pos);
-			if (ret > 0)
+			if (ret > 0) {
 				dnotify_parent(file->f_dentry, DN_MODIFY);
+				inotify_dentry_queue_event (file->f_dentry, IN_MODIFY);
+			}
 		}
 	}
 
@@ -473,9 +478,12 @@
 out:
 	if (iov != iovstack)
 		kfree(iov);
-	if ((ret + (type == READ)) > 0)
+	if ((ret + (type == READ)) > 0) {
 		dnotify_parent(file->f_dentry,
 				(type == READ) ? DN_ACCESS : DN_MODIFY);
+		inotify_dentry_queue_event (file->f_dentry, 
+				(type == READ) ? IN_ACCESS : IN_MODIFY);
+	}
 	return ret;
 }
 
diff -ru clean/linux-2.6.5/include/linux/fs.h linux-2.6.5/include/linux/fs.h
--- clean/linux-2.6.5/include/linux/fs.h	2004-04-03 22:36:52.000000000 -0500
+++ linux-2.6.5/include/linux/fs.h	2004-05-09 21:06:42.000000000 -0400
@@ -414,6 +414,10 @@
 	unsigned long		i_dnotify_mask; /* Directory notify events */
 	struct dnotify_struct	*i_dnotify; /* for directory notifications */
 
+	struct list_head 	watchers;
+	unsigned long		watchers_mask;
+	atomic_t		watcher_count;
+
 	unsigned long		i_state;
 	unsigned long		dirtied_when;	/* jiffies of first dirtying */
 
diff -ru clean/linux-2.6.5/include/linux/miscdevice.h linux-2.6.5/include/linux/miscdevice.h
--- clean/linux-2.6.5/include/linux/miscdevice.h	2004-04-03 22:37:23.000000000 -0500
+++ linux-2.6.5/include/linux/miscdevice.h	2004-05-08 19:34:04.000000000 -0400
@@ -36,6 +36,8 @@
 
 #define TUN_MINOR	     200
 
+#define INOTIFY_MINOR 99
+
 struct device;
 
 struct miscdevice 

[-- Attachment #3: inotify.h --]
[-- Type: text/x-chdr, Size: 1479 bytes --]

/*
 * Inode based directory notification for Linux
 *
 * Copyright (C) 2004 John McCutchan
 */

#ifndef _LINUX_INOTIFY_H
#define _LINUX_INOTIFY_H

#include <linux/fs.h>
#include <linux/ioctl.h>

/* When reading from the device the format is:
 * 	INODE_NUMBER [unsigned long]
 * 	INODE_DEVICE_NUMBER [unsigned long]
 * 	EVENT_MASK [unsigned long]
 */

#define IN_ACCESS	0x00000001	/* File was accessed */
#define IN_MODIFY	0x00000002	/* File was modified */
#define IN_CREATE	0x00000004	/* File was created */
#define IN_DELETE	0x00000008	/* File was deleted */
#define IN_RENAME	0x00000010	/* File was renamed */
#define IN_ATTRIB	0x00000020	/* File changed attributes */
#define IN_MOVE		0x00000040	/* File was moved */
#define IN_UNMOUNT	0x00000080	/* Device file was on, was unmounted */

/* Fill this and pass it to the ioctl */
struct inotify_packet {
	unsigned long i_no; // from stat
	unsigned long i_dev; // from stat
	unsigned long mask; // combination of above
};

/* ioctl */

#define INOTIFY_IOCTL_MAGIC 'Q'
#define INOTIFY_IOCTL_MAXNR 2

#define INOTIFY_WATCH	_IOW(INOTIFY_IOCTL_MAGIC, 1, struct inotify_watch)
#define INOTIFY_IGNORE	_IOW(INOTIFY_IOCTL_MAGIC, 2, struct inotify_watch)

/* Kernel API */
void inotify_inode_queue_event (struct inode *inode, unsigned long mask);
void inotify_dentry_queue_event (struct dentry *dentry, unsigned long mask);
void inotify_inode_update_mask (struct inode *inode);

#endif


[-- Attachment #4: inotify.c --]
[-- Type: text/x-csrc, Size: 13193 bytes --]

/*
 * Inode based directory notifications for Linux.
 *
 * Copyright (C) 2004 John McCutchan
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2, or (at your option) any
 * later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/poll.h>
#include <linux/miscdevice.h>
#include <linux/device.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/stddef.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/inotify.h>

/* TODO:
 * get more events sent to the queue
 * 	rename
 * 	move
 * 	unmount
 * check that any inodes we are asked to watch are actually directories
 * write user space test app
 * change umount code
 */

#define MAX_WATCHER_COUNT 8 /* We only support 8 watchers */
#define MAX_WATCH_COUNT 128 /* A watcher can only be watching 128 inodes */

static int watcher_count = 0;

struct inotify_watch {
	struct list_head	list;
	struct inode *		inode;
};
#define list_to_inotify_watch(pos) list_entry((pos),struct inotify_watch,list)

/* A list of these structures is attached to each inode that is being watched.
 *  * each item in the list represents a unique watcher.
 *   * it tell us what events we are looking at and who is watching the inode.
 *    */
struct inotify_inode_watcher {
	struct list_head        list;
	unsigned long           mask;
	struct inode *          inode;
	void *                  private_data; // the driver instance
};
#define list_to_inotify_inode_watcher(pos) list_entry((pos), struct inofiy_inode_watcher, list)

/* A list of these is attached to each instance of the driver
 * when the drivers read() gets called, this list is walked and
 * all events that can fit in the buffer get delivered
 */
struct inotify_event {
        struct list_head        list;
        unsigned long           i_no;
        unsigned long           i_dev;
        unsigned long           mask;
};
#define list_to_inotify_event(pos) list_entry((pos), struct inotify_event, list)



/* For each inotify device we need to keep a list of events queued on it
 * aswell as a list of inodes that we are watching
 */
struct inotify_device {
	struct list_head *	events;
	struct list_head *	watch;
	atomic_t		watch_count;
	char 			read_state;
	wait_queue_head_t 	wait;
};

static struct inotify_inode_watcher *inotify_inode_find_watcher (struct inotify_device *dev, struct inode *inode)
{
	struct inotify_inode_watcher *watcher;

	list_for_each_entry (watcher, &inode->watchers, list)
	{
		/* This watcher is from this device */
		if (watcher->private_data == dev)
		{
			return watcher;
		}
	}
	return NULL;
}

static void inotify_inode_add_watcher (struct inotify_device *dev, struct inode *inode, unsigned long mask)
{
	struct inotify_inode_watcher *watcher;

	watcher = inotify_inode_find_watcher (dev, inode);

		/* Check if we are already watching this inode */
	if (NULL != watcher) {
		watcher->mask = mask;
	} else {
		watcher = kmalloc (sizeof (struct inotify_inode_watcher), GFP_KERNEL);
		watcher->private_data = dev;
		watcher->inode = inode;
		watcher->mask = mask;
		
		atomic_inc (&inode->watcher_count);
		list_add (&watcher->list, &inode->watchers);
	}

	inotify_inode_update_mask (inode);
}

static void inotify_inode_rm_watcher (struct inotify_device *dev, struct inode *inode)
{
	struct inotify_inode_watcher *watcher;

	watcher = inotify_inode_find_watcher (dev, inode);

	if (NULL != watcher) {
		list_del(&watcher->list);
		kfree (watcher);

		atomic_dec (&inode->watcher_count);
	}
}

static struct inotify_watch *inotify_dev_find_watcher (struct inotify_device *dev, struct inode *inode)
{	
	struct inotify_watch *watch;

	list_for_each_entry (watch, dev->watch, list)
	{
		if (watch->inode == inode) {
			return watch;
		}
	}

	return NULL;
}

static void inotify_dev_add_watcher (struct inotify_device *dev, struct inode *inode)
{
	struct inotify_watch *watch;

	watch = inotify_dev_find_watcher (dev, inode);

	if (watch == NULL)
	{
		watch = kmalloc (sizeof (struct inotify_watch), GFP_KERNEL);
		watch->inode = inode;

		atomic_inc (&dev->watch_count);
		list_add (&watch->list, dev->watch);
	}
}

static void inotify_dev_rm_watcher (struct inotify_device *dev, struct inode *inode)
{
	struct inotify_watch *watch;

	watch = inotify_dev_find_watcher (dev, inode);

	if (NULL != watch) {
		list_del (&watch->list);
		kfree (watch);

		atomic_dec (&dev->watch_count);
	} 
}

static char inotify_dev_has_events (struct inotify_device *dev)
{
	return dev->events && !list_empty(dev->events);
}

static void inotify_dev_event_dequeue (struct inotify_device *dev)
{
	struct inotify_event *event;

	if (list_empty (dev->events)) {
		return;
	}

	/* Get the first entry from the event queue */
	event = list_to_inotify_event (dev->events->next);
	list_del (&event->list);

	kfree (event);
}

static void inotify_dev_event_queue (struct inotify_device *dev, unsigned long i_no, unsigned long i_dev, unsigned long mask)
{
	struct inotify_event *event;

	event = kmalloc (sizeof (struct inotify_event), GFP_KERNEL);
	event->i_no = i_no;
	event->i_dev = i_dev;
	event->mask = mask;

	list_add_tail (&event->list, dev->events);
}

/* Kernel API */
void inotify_inode_queue_event (struct inode *inode, unsigned long mask)
{
	struct inotify_inode_watcher *watcher;

	/* If this inode isn't interested in the event */
	if (!(inode->watchers_mask & mask)) {
		return;
	}

	list_for_each_entry (watcher, &inode->watchers, list) {
		if (watcher->mask & mask) {
			inotify_dev_event_queue (watcher->private_data, inode->i_ino, new_encode_dev (inode->i_sb->s_dev), mask);
		}
	}
}
EXPORT_SYMBOL_GPL(inotify_inode_queue_event);

/* Based on dnotify_parent -- locking may be broken */
void inotify_dentry_queue_event (struct dentry *dentry, unsigned long mask)
{
	struct dentry *parent;

	spin_lock(&dentry->d_lock);
	parent = dentry->d_parent;
	dget (parent);
	inotify_inode_queue_event (parent->d_inode, mask);
	dput (parent);
	spin_unlock(&dentry->d_lock);
}
EXPORT_SYMBOL_GPL(inotify_dentry_queue_event);


void inotify_inode_update_mask (struct inode *inode)
{
	struct inotify_inode_watcher *watcher;
	unsigned long new_mask;

	new_mask = 0;
	list_for_each_entry (watcher, &inode->watchers, list) {
		new_mask |= watcher->mask;
	}
	inode->watchers_mask = new_mask;
}
EXPORT_SYMBOL_GPL(inotify_inode_update_mask);

/* The driver interface is implemented below */

#define INOTIFY_READ_STATE_INODE 0
#define INOTIFY_READ_STATE_DEV	 1
#define INOTIFY_READ_STATE_MASK  2

static ssize_t inotify_read(struct file *file, char *buf,
			   size_t count, loff_t *pos) {
	struct inotify_device *dev;
	size_t out;

	out = 0;

	dev = file->private_data;

	if (!inotify_dev_has_events (dev)) {
		return 0;
	}

	while (out < count && inotify_dev_has_events (dev)) {
		struct inotify_event *event;

		event = list_to_inotify_event (dev->events->next);

		switch (dev->read_state) {
			case INOTIFY_READ_STATE_INODE:
				if (put_user (event->i_no, buf))
					return -EFAULT;
				buf += sizeof (event->i_no);
				dev->read_state++;
			break;
			case INOTIFY_READ_STATE_DEV:
				if (put_user (event->i_dev, buf))
					return -EFAULT;
				buf += sizeof (event->i_dev);
				dev->read_state++;
			break;
			case INOTIFY_READ_STATE_MASK:
				if (put_user (event->mask, buf))
					return -EFAULT;
				buf += sizeof (event->mask);
				dev->read_state = INOTIFY_READ_STATE_INODE;
				/* We have finished delivering the complete event, so dequeue it */
				inotify_dev_event_dequeue (dev);
			break;
			default:
				/* BUG */
			break;
		}

		out++;
	}

	return out;
}

static unsigned int inotify_poll(struct file *file, poll_table *wait) {
	struct inotify_device *dev;

	dev = file->private_data;

	poll_wait (file, &dev->wait, wait);

	if (inotify_dev_has_events (dev))
		return POLLIN | POLLRDNORM;

	return 0;
}

static int inotify_open(struct inode *inode, struct file *file) {
	struct inotify_device *dev;

	if (watcher_count == MAX_WATCHER_COUNT)
		return -ENODEV;

	watcher_count++;

	dev = kmalloc (sizeof (struct inotify_device), GFP_KERNEL);
	dev->events = kmalloc (sizeof (struct list_head), GFP_KERNEL);
	INIT_LIST_HEAD(dev->events);
	dev->watch = kmalloc (sizeof (struct list_head), GFP_KERNEL);
	INIT_LIST_HEAD(dev->watch);
	atomic_set(&dev->watch_count, 0);
	dev->read_state = INOTIFY_READ_STATE_INODE;
	init_waitqueue_head (&dev->wait);

	file->private_data = dev;

	return 0;
}

static void inotify_release_all_watchers (struct inotify_device *dev)
{
	struct inotify_watch *watch;

	list_for_each_entry (watch, dev->watch, list) {
		/* Remove the watcher from the inode */
		inotify_inode_rm_watcher (dev, watch->inode);
		/* Remove the inode from the device */
		inotify_dev_rm_watcher (dev, watch->inode);

	}
}

static void inotify_release_all_events (struct inotify_device *dev)
{
	while (inotify_dev_has_events (dev)) {
		inotify_dev_event_dequeue (dev);
	}
}


static int inotify_release(struct inode *inode, struct file *file)
{
	if (file->private_data) {
		struct inotify_device *dev;

		dev = (struct inotify_device *)file->private_data;

		inotify_release_all_watchers (dev);
		kfree (dev->watch);

		inotify_release_all_events (dev);
		kfree (dev->events);

		kfree (dev);
	}

	watcher_count--;
	return 0;
}

static struct inode *inotify_find_inode (struct inotify_packet *packet)
{
	struct super_block *s;
	struct inode *inode;

	s = user_get_super (new_decode_dev(packet->i_dev));

	if (!s) {
		return NULL;
	}

	inode = ilookup (s, packet->i_no);

	drop_super(s);

	if (!inode) {
		return NULL;
	}

	/* ilookup takes a reference on the inode, release it */
	iput (inode);
	return inode;
}

static int inotify_watch(struct inotify_device *dev, struct inotify_packet *packet)
{
	int err;
	struct inode *inode;
	err = 0;

	inode = inotify_find_inode (packet);

	if (!inode) {
		err = -ENOENT;
		goto out;
	}

	inotify_inode_add_watcher (dev, inode, packet->mask);
	inotify_dev_add_watcher (dev, inode);
out:
	return err;
}

static int inotify_ignore(struct inotify_device *dev, struct inotify_packet *packet)
{
	int err;
	struct inode *inode;
	err = 0;

	inode = inotify_find_inode (packet);

	if (!inode) {
		err = -ENOENT;
		goto out;
	}

	inotify_inode_rm_watcher (dev, inode);
	inotify_dev_rm_watcher (dev, inode);
out:
	return err;
}

static int inotify_ioctl(struct inode *ip, struct file *fp,
			 unsigned int cmd, unsigned long arg) {
	int err;
	struct inotify_device *dev;
	struct inotify_packet *packet;

	dev = fp->private_data;
	err = 0;

	if (_IOC_TYPE(cmd) != INOTIFY_IOCTL_MAGIC) return -EINVAL;
	if (_IOC_NR(cmd) > INOTIFY_IOCTL_MAXNR) return -EINVAL;

	if (_IOC_DIR(cmd) & _IOC_READ)
		err = !access_ok (VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd));
	if (_IOC_DIR(cmd) & _IOC_WRITE)
		err = !access_ok (VERIFY_READ, (void *)arg, _IOC_SIZE(cmd));

	if (err) return -EFAULT;

	packet = kmalloc (sizeof (struct inotify_packet), GFP_KERNEL);

	if (copy_from_user (packet, (void *)arg, sizeof (struct inotify_packet))) {
		err = -EFAULT;
		goto out;
	}

	err = -EINVAL;

	switch (cmd) {
		case INOTIFY_WATCH:
			printk(KERN_ALERT "inotify WATCH: %ld %ld %ld\n", packet->i_no, packet->i_dev, packet->mask);
			err = inotify_watch (dev, packet);
		break;
		case INOTIFY_IGNORE:
			printk(KERN_ALERT "inotify IGNORE: %ld %ld\n", packet->i_no, packet->i_dev);
			err = inotify_ignore (dev, packet);
		break;
	}
out:
	kfree (packet);
	return err;
}

static struct file_operations inotify_fops = {
	.owner		= THIS_MODULE,
	.read		= inotify_read,
	.poll		= inotify_poll,
	.open		= inotify_open,
	.release	= inotify_release,
	.ioctl		= inotify_ioctl,
};

struct miscdevice inotify_device = {
	.minor  = INOTIFY_MINOR,
	.name	= "inotify",
	.fops	= &inotify_fops,
};


static int __init inotify_init (void)
{
	int ret;

	ret = misc_register (&inotify_device);

	if (ret) {
		goto out;
	}

	ret = 0;
	printk(KERN_ALERT "inotify 0.1 startup\n");
out:
	return ret;
}

static void inotify_exit (void)
{
	misc_deregister (&inotify_device);
	printk(KERN_ALERT "inotify 0.1 shutdown\n");
}


MODULE_AUTHOR("John McCutchan <ttb@tentacle.dhs.org>");
MODULE_DESCRIPTION("Inode event driver");
MODULE_LICENSE("GPL");

module_init (inotify_init);
module_exit (inotify_exit);

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC/PATCH] inotify -- a dnotify replacement
  2004-05-10  1:35 [RFC/PATCH] inotify -- a dnotify replacement John McCutchan
@ 2004-05-10  2:11 ` Chris Wedgwood
  2004-05-10 22:17   ` John McCutchan
  2004-05-13 15:36 ` raven
  2004-05-15  4:52 ` raven
  2 siblings, 1 reply; 29+ messages in thread
From: Chris Wedgwood @ 2004-05-10  2:11 UTC (permalink / raw)
  To: John McCutchan; +Cc: linux-kernel, nautilus-list

On Sun, May 09, 2004 at 09:35:41PM -0400, John McCutchan wrote:

> The two biggest complaints people have about dnotify are
>
> 1) dnotify delivers events using signals.

is that really a problem?

>
> 2) dnotify needs a file to be kept open on the device, causing
> problems during unmount.

i never thought of that...  what about

3) dnotify cannot easily watch changes for a directory hierarchy

> @@ -127,6 +128,7 @@
>  	return dn_mask;
>  }
>
> +
>  int notify_change(struct dentry * dentry, struct iattr * attr)
>  {
>  	struct inode *inode = dentry->d_inode;

plz don't add unnecessary whitespace

> diff -ru clean/linux-2.6.5/fs/inode.c linux-2.6.5/fs/inode.c
> +++ linux-2.6.5/fs/inode.c	2004-05-09 21:10:12.000000000 -0400
> @@ -151,6 +151,10 @@
>  			mapping->backing_dev_info = sb->s_bdev->bd_inode->i_mapping->backing_dev_info;
>  		memset(&inode->u, 0, sizeof(inode->u));
>  		inode->i_mapping = mapping;
> +
> +		INIT_LIST_HEAD(&inode->watchers);
> +		atomic_set (&inode->watcher_count, 0);
                          ^

whitespace after if/for/while but not functions:

 if (..)
 func(...)

> +#define INOTIFY_MINOR 99

there is a registry for these, i think you can use -1 (to get one
dynamically allocated) if you've not been assigned one

> #define MAX_WATCHER_COUNT 8 /* We only support 8 watchers */

seems like this could be a problem for gui stuff

> #define MAX_WATCH_COUNT 128 /* A watcher can only be watching 128 inodes */

likewise

> static int watcher_count = 0;

global variables don't need explicitly initialized to zero and in fact
this will make the kernel larger when using older gcc versions

> /* A list of these structures is attached to each inode that is being watched.
>  *  * each item in the list represents a unique watcher.
>  *   * it tell us what events we are looking at and who is watching the inode.
>  *    */

heh, odd comment style

> struct inotify_event {
>         struct list_head        list;
>         unsigned long           i_no;
>         unsigned long           i_dev;
>         unsigned long           mask;
> };

i'm not so sure using unsigned long is a good idea here,  it's size
varies depending on arch (also consider 32-bit code on 64-bit
platforms)

we might also have a 64-bit ino_t on i386 some day?  (what a revolting
idea but we have PAE, etc. so it's possible)

> 		if (watcher->private_data == dev)
> 		{
> 			return watcher;
> 		}

minor nit:

	if (...)
	   return ...;

> 	if (NULL != watcher) {

i really hate that, what is wrong with

  if (watcher)

> 	list_for_each_entry (watch, dev->watch, list)

  list_for_each_entry (...) {

> static char inotify_dev_has_events (struct inotify_device *dev)
> {
> 	return dev->events && !list_empty(dev->events);
> }

why does this need to be a separate function?

> static int __init inotify_init (void)
> {
> 	int ret;
>
> 	ret = misc_register (&inotify_device);
>
> 	if (ret) {
> 		goto out;
> 	}
>
> 	ret = 0;

if we got here, ret must be 0



  --cw

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC/PATCH] inotify -- a dnotify replacement
  2004-05-10  2:11 ` Chris Wedgwood
@ 2004-05-10 22:17   ` John McCutchan
  2004-05-10 22:31     ` Davide Libenzi
                       ` (3 more replies)
  0 siblings, 4 replies; 29+ messages in thread
From: John McCutchan @ 2004-05-10 22:17 UTC (permalink / raw)
  To: Chris Wedgwood; +Cc: nautilus-list, linux-kernel

On Sun, 2004-05-09 at 22:11, Chris Wedgwood wrote:
> On Sun, May 09, 2004 at 09:35:41PM -0400, John McCutchan wrote:
> 
> > The two biggest complaints people have about dnotify are
> >
> > 1) dnotify delivers events using signals.
> 
> is that really a problem?

According to everyone who uses dnotify it is.

> >
> > 2) dnotify needs a file to be kept open on the device, causing
> > problems during unmount.
> 
> i never thought of that...  what about
> 
> 3) dnotify cannot easily watch changes for a directory hierarchy

People don't seem to really care about this one. Alexander Larsson has
said he doesn't care about it. It might be nice to add in the future.

> 
> > @@ -127,6 +128,7 @@
> >  	return dn_mask;
> >  }
> >
> > +
> >  int notify_change(struct dentry * dentry, struct iattr * attr)
> >  {
> >  	struct inode *inode = dentry->d_inode;
> 
> plz don't add unnecessary whitespace

fixed

> 
> > diff -ru clean/linux-2.6.5/fs/inode.c linux-2.6.5/fs/inode.c
> > +++ linux-2.6.5/fs/inode.c	2004-05-09 21:10:12.000000000 -0400
> > @@ -151,6 +151,10 @@
> >  			mapping->backing_dev_info = sb->s_bdev->bd_inode->i_mapping->backing_dev_info;
> >  		memset(&inode->u, 0, sizeof(inode->u));
> >  		inode->i_mapping = mapping;
> > +
> > +		INIT_LIST_HEAD(&inode->watchers);
> > +		atomic_set (&inode->watcher_count, 0);
>                           ^
> 
> whitespace after if/for/while but not functions:
> 
>  if (..)
>  func(...)

fixed

> 
> > +#define INOTIFY_MINOR 99
> 
> there is a registry for these, i think you can use -1 (to get one
> dynamically allocated) if you've not been assigned one

fixed

> 
> > #define MAX_WATCHER_COUNT 8 /* We only support 8 watchers */
> 
> seems like this could be a problem for gui stuff

see below

> 
> > #define MAX_WATCH_COUNT 128 /* A watcher can only be watching 128 inodes */
> 
> likewise

The idea is to encourage use of a user-space daemon that will multiplex
all requests, so if 5 people want to watch /somedir the daemon will only
use one watcher in the kernel. The number might be too low, but its
easily upped.

> 
> > static int watcher_count = 0;
> 
> global variables don't need explicitly initialized to zero and in fact
> this will make the kernel larger when using older gcc versions

fixed

> 
> > struct inotify_event {
> >         struct list_head        list;
> >         unsigned long           i_no;
> >         unsigned long           i_dev;
> >         unsigned long           mask;
> > };
> 
> i'm not so sure using unsigned long is a good idea here,  it's size
> varies depending on arch (also consider 32-bit code on 64-bit
> platforms)
> 
> we might also have a 64-bit ino_t on i386 some day?  (what a revolting
> idea but we have PAE, etc. so it's possible)

I now use ino_t and dev_t , though in struct inode, i_no is unsigned
long?

> > static char inotify_dev_has_events (struct inotify_device *dev)
> > {
> > 	return dev->events && !list_empty(dev->events);
> > }
> 
> why does this need to be a separate function?

Modularity. I changed it to a macro though.

> 
> > static int __init inotify_init (void)
> > {
> > 	int ret;
> >
> > 	ret = misc_register (&inotify_device);
> >
> > 	if (ret) {
> > 		goto out;
> > 	}
> >
> > 	ret = 0;
> 
> if we got here, ret must be 0
> 
> 

fixed


Thanks for the review. 

John

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC/PATCH] inotify -- a dnotify replacement
  2004-05-10 22:17   ` John McCutchan
@ 2004-05-10 22:31     ` Davide Libenzi
  2004-05-10 22:41       ` John McCutchan
  2004-05-11  2:00     ` Ian Kent
                       ` (2 subsequent siblings)
  3 siblings, 1 reply; 29+ messages in thread
From: Davide Libenzi @ 2004-05-10 22:31 UTC (permalink / raw)
  To: John McCutchan; +Cc: Linux Kernel Mailing List

On Mon, 10 May 2004, John McCutchan wrote:

> > 3) dnotify cannot easily watch changes for a directory hierarchy
> 
> People don't seem to really care about this one. Alexander Larsson has
> said he doesn't care about it. It might be nice to add in the future.

Please excuse my ignorance, but who is Alexander Larsson? A dnotify 
replacement that does not have the ability to watch for a hierarchy is 
pretty much useless. Or do you want to drop thousands of single watches to 
accomplish that?



- Davide


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC/PATCH] inotify -- a dnotify replacement
  2004-05-10 22:31     ` Davide Libenzi
@ 2004-05-10 22:41       ` John McCutchan
  2004-05-10 22:52         ` Davide Libenzi
  2004-05-11  4:11         ` Chris Wedgwood
  0 siblings, 2 replies; 29+ messages in thread
From: John McCutchan @ 2004-05-10 22:41 UTC (permalink / raw)
  To: Davide Libenzi; +Cc: Linux Kernel Mailing List

On Mon, 2004-05-10 at 18:31, Davide Libenzi wrote:
> On Mon, 10 May 2004, John McCutchan wrote:
> 
> > > 3) dnotify cannot easily watch changes for a directory hierarchy
> > 
> > People don't seem to really care about this one. Alexander Larsson has
> > said he doesn't care about it. It might be nice to add in the future.
> 
> Please excuse my ignorance, but who is Alexander Larsson? A dnotify 
> replacement that does not have the ability to watch for a hierarchy is 
> pretty much useless. Or do you want to drop thousands of single watches to 
> accomplish that?

Alexander Larsson is the maintainer of nautilus, gnome-vfs and I think
the dnotify patch for fam. He made a post to l-k a month or two ago
about why he doesn't care about it. I do plan on adding this feature in
the near future though.

John


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC/PATCH] inotify -- a dnotify replacement
  2004-05-10 22:41       ` John McCutchan
@ 2004-05-10 22:52         ` Davide Libenzi
  2004-05-10 23:10           ` Valdis.Kletnieks
  2004-05-11  4:11         ` Chris Wedgwood
  1 sibling, 1 reply; 29+ messages in thread
From: Davide Libenzi @ 2004-05-10 22:52 UTC (permalink / raw)
  To: John McCutchan; +Cc: Linux Kernel Mailing List

On Mon, 10 May 2004, John McCutchan wrote:

> On Mon, 2004-05-10 at 18:31, Davide Libenzi wrote:
> > On Mon, 10 May 2004, John McCutchan wrote:
> > 
> > > > 3) dnotify cannot easily watch changes for a directory hierarchy
> > > 
> > > People don't seem to really care about this one. Alexander Larsson has
> > > said he doesn't care about it. It might be nice to add in the future.
> > 
> > Please excuse my ignorance, but who is Alexander Larsson? A dnotify 
> > replacement that does not have the ability to watch for a hierarchy is 
> > pretty much useless. Or do you want to drop thousands of single watches to 
> > accomplish that?
> 
> Alexander Larsson is the maintainer of nautilus, gnome-vfs and I think
> the dnotify patch for fam. He made a post to l-k a month or two ago
> about why he doesn't care about it. I do plan on adding this feature in
> the near future though.

GUIs have different requirements. They display a finite number of views on 
directories, so for them it is fine to not have hierarchy watching 
capabilities. A sane dnotify API should have the ability to watch hierarchies.
And it should not even be that much hard to do, since you can just 
backtrace the the point where the change happened to see if there are 
watchers on the parent directories.



- Davide


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC/PATCH] inotify -- a dnotify replacement 
  2004-05-10 22:52         ` Davide Libenzi
@ 2004-05-10 23:10           ` Valdis.Kletnieks
  2004-05-10 23:42             ` Davide Libenzi
  0 siblings, 1 reply; 29+ messages in thread
From: Valdis.Kletnieks @ 2004-05-10 23:10 UTC (permalink / raw)
  To: Davide Libenzi; +Cc: Linux Kernel Mailing List

[-- Attachment #1: Type: text/plain, Size: 841 bytes --]

On Mon, 10 May 2004 15:52:58 PDT, Davide Libenzi said:

> And it should not even be that much hard to do, since you can just 
> backtrace the the point where the change happened to see if there are 
> watchers on the parent directories.

Umm.. can you?  That sounds suspiciously like "given an inode, how
do I find the pathname?".

How do you handle the case of a file that's hard-linked into 2 different
directories a "long way" apart in the heirarchy?  It's easy enough to
backtrack and find *A* path - the problem is if the watcher was on
some *other* directory:

mkdir -p /tmp/a/foo/bar/baz
mkdir -p /tmp/b/que/er/ty
touch /tmp/a/foo/bar/baz/flag
ln /tmp/a/foo/bar/baz/flag /tmp/b/qu/er/ty/flag

If you modify 'flag' again, how do you ensure that you find a watcher on
/tmp/a/foo or /tmp/b/qu, given that either or both might be there?


[-- Attachment #2: Type: application/pgp-signature, Size: 226 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC/PATCH] inotify -- a dnotify replacement 
  2004-05-10 23:10           ` Valdis.Kletnieks
@ 2004-05-10 23:42             ` Davide Libenzi
  0 siblings, 0 replies; 29+ messages in thread
From: Davide Libenzi @ 2004-05-10 23:42 UTC (permalink / raw)
  To: Valdis.Kletnieks; +Cc: Linux Kernel Mailing List

On Mon, 10 May 2004 Valdis.Kletnieks@vt.edu wrote:

> On Mon, 10 May 2004 15:52:58 PDT, Davide Libenzi said:
> 
> > And it should not even be that much hard to do, since you can just 
> > backtrace the the point where the change happened to see if there are 
> > watchers on the parent directories.
> 
> Umm.. can you?  That sounds suspiciously like "given an inode, how
> do I find the pathname?".

It'd be from a file* not from an inode* (where you have a dentry and a 
vfsmount). So *one* path can be found.



> How do you handle the case of a file that's hard-linked into 2 different
> directories a "long way" apart in the heirarchy?  It's easy enough to
> backtrack and find *A* path - the problem is if the watcher was on
> some *other* directory:
> 
> mkdir -p /tmp/a/foo/bar/baz
> mkdir -p /tmp/b/que/er/ty
> touch /tmp/a/foo/bar/baz/flag
> ln /tmp/a/foo/bar/baz/flag /tmp/b/qu/er/ty/flag
> 
> If you modify 'flag' again, how do you ensure that you find a watcher on
> /tmp/a/foo or /tmp/b/qu, given that either or both might be there?

Yep, links are a problem to be implemented right. OTOH I don't think that 
an rmap-fs can be asked only to solve such problem ;)



- Davide


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC/PATCH] inotify -- a dnotify replacement
  2004-05-10 22:17   ` John McCutchan
  2004-05-10 22:31     ` Davide Libenzi
@ 2004-05-11  2:00     ` Ian Kent
  2004-05-11  2:47     ` Chris Wedgwood
  2004-05-12 12:38     ` Jörn Engel
  3 siblings, 0 replies; 29+ messages in thread
From: Ian Kent @ 2004-05-11  2:00 UTC (permalink / raw)
  To: John McCutchan; +Cc: Chris Wedgwood, nautilus-list, linux-kernel

On Mon, 10 May 2004, John McCutchan wrote:

> > 
> 
> fixed
> 

May I see the update please?

Ian


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC/PATCH] inotify -- a dnotify replacement
  2004-05-10 22:17   ` John McCutchan
  2004-05-10 22:31     ` Davide Libenzi
  2004-05-11  2:00     ` Ian Kent
@ 2004-05-11  2:47     ` Chris Wedgwood
  2004-05-11 11:52       ` nf
                         ` (2 more replies)
  2004-05-12 12:38     ` Jörn Engel
  3 siblings, 3 replies; 29+ messages in thread
From: Chris Wedgwood @ 2004-05-11  2:47 UTC (permalink / raw)
  To: John McCutchan; +Cc: nautilus-list, linux-kernel

On Mon, May 10, 2004 at 06:17:40PM -0400, John McCutchan wrote:

> According to everyone who uses dnotify it is.

I don't buy that.  I have used dnotify and signals where not an issue.
Why is this an issue for others?

> > 3) dnotify cannot easily watch changes for a directory hierarchy

> People don't seem to really care about this one. Alexander Larsson
> has said he doesn't care about it. It might be nice to add in the
> future.

I don't know who that is and why it matters.

Without being able to watch a hierarchy, I'm not sure inotify buys
anything that we can't get from dnotify right now though.  It's also
more complex.

> The idea is to encourage use of a user-space daemon that will
> multiplex all requests, so if 5 people want to watch /somedir the
> daemon will only use one watcher in the kernel. The number might be
> too low, but its easily upped.

If you are to use a daemon for this, why no use dnotify?



   --cw

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC/PATCH] inotify -- a dnotify replacement
  2004-05-10 22:41       ` John McCutchan
  2004-05-10 22:52         ` Davide Libenzi
@ 2004-05-11  4:11         ` Chris Wedgwood
  1 sibling, 0 replies; 29+ messages in thread
From: Chris Wedgwood @ 2004-05-11  4:11 UTC (permalink / raw)
  To: John McCutchan; +Cc: Davide Libenzi, Linux Kernel Mailing List

On Mon, May 10, 2004 at 06:41:40PM -0400, John McCutchan wrote:

> Alexander Larsson is the maintainer of nautilus, gnome-vfs and I
> think the dnotify patch for fam. He made a post to l-k a month or
> two ago about why he doesn't care about it. I do plan on adding this
> feature in the near future though.

I found the posting, it doesn't explain why dnotify using signals is
bad and I still don't see how inotify makes the situation any better.


  --cw

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC/PATCH] inotify -- a dnotify replacement
  2004-05-11  2:47     ` Chris Wedgwood
@ 2004-05-11 11:52       ` nf
  2004-05-11 12:17         ` Stephen Rothwell
                           ` (2 more replies)
  2004-05-11 12:20       ` John McCutchan
  2004-05-11 15:02       ` Alexander Larsson
  2 siblings, 3 replies; 29+ messages in thread
From: nf @ 2004-05-11 11:52 UTC (permalink / raw)
  To: Chris Wedgwood; +Cc: John McCutchan, nautilus-list, linux-kernel

On Tue, 2004-05-11 at 04:47, Chris Wedgwood wrote: 
> On Mon, May 10, 2004 at 06:17:40PM -0400, John McCutchan wrote:
> 
> > According to everyone who uses dnotify it is.
> 
> I don't buy that.  I have used dnotify and signals where not an issue.
> Why is this an issue for others?

I believe the worst thing about dnotify is the "umount blocking"
behaviour. It drives me crazy since i use the Linux desktop. So if this
is the "Year of the linux desktop", please please switch OFF dnotify
until it does not open files for monitoring anymore! Or until "inotify"
works.

Btw, i have written a little tool to assist people with the
umount-problem and collected some links
http://www.scheinwelt.at/~norbertf/wbumount/. 

> > The idea is to encourage use of a user-space daemon that will
> > multiplex all requests, so if 5 people want to watch /somedir the
> > daemon will only use one watcher in the kernel. The number might be
> > too low, but its easily upped.
> 
> If you are to use a daemon for this, why no use dnotify?

I don't understand, why the author of inotify wants to force people to
use user-space daemons like fam (which requires xinetd, ...)? Does using
a daemon for multiplexing really add efficiency? Is it really worth
adding all the complexity of things like "fam" to the system, just
because more than one application monitor the same directory once in a
while? I doubt it.

I would even claim, that simple polling ("stat"-ing) the filesystem for
changes is more efficient in 95% of the cases, than all this dnotify,
fam, etc... stuff.

Just to be fair - i don't think that dnotify or fam are bad tools, but
the combination of them seems poisonous for the desktop.

Norbert



^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC/PATCH] inotify -- a dnotify replacement
  2004-05-11 11:52       ` nf
@ 2004-05-11 12:17         ` Stephen Rothwell
  2004-05-11 12:24         ` John McCutchan
       [not found]         ` <1084278605.3839.47.camel@carados.180sw.com>
  2 siblings, 0 replies; 29+ messages in thread
From: Stephen Rothwell @ 2004-05-11 12:17 UTC (permalink / raw)
  To: nf2; +Cc: cw, ttb, nautilus-list, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 391 bytes --]

On Tue, 11 May 2004 13:52:44 +0200 nf <nf2@scheinwelt.at> wrote:
>
> I would even claim, that simple polling ("stat"-ing) the filesystem for
> changes is more efficient in 95% of the cases, than all this dnotify,
> fam, etc... stuff.

Not if you want power savings in your idle loop ...

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC/PATCH] inotify -- a dnotify replacement
  2004-05-11  2:47     ` Chris Wedgwood
  2004-05-11 11:52       ` nf
@ 2004-05-11 12:20       ` John McCutchan
  2004-05-11 12:46         ` viro
  2004-05-11 15:02       ` Alexander Larsson
  2 siblings, 1 reply; 29+ messages in thread
From: John McCutchan @ 2004-05-11 12:20 UTC (permalink / raw)
  To: Chris Wedgwood; +Cc: nautilus-list, linux-kernel

On Mon, 2004-05-10 at 22:47, Chris Wedgwood wrote:
> On Mon, May 10, 2004 at 06:17:40PM -0400, John McCutchan wrote:
> 
> > According to everyone who uses dnotify it is.
> 
> I don't buy that.  I have used dnotify and signals where not an issue.
> Why is this an issue for others?
> 

Signals cause a big performance penalty when you are receiving a lot of
them. Signals interrupt your program, switch the signal handler and then
restarts your program. And signals in multi-threaded programs is a pain
as well. Signals just are not suitable for receiving lots of messages
quickly.

> > > 3) dnotify cannot easily watch changes for a directory hierarchy
> 
> > People don't seem to really care about this one. Alexander Larsson
> > has said he doesn't care about it. It might be nice to add in the
> > future.
> 
> I don't know who that is and why it matters.
> 
> Without being able to watch a hierarchy, I'm not sure inotify buys
> anything that we can't get from dnotify right now though.  It's also
> more complex.

Inotify will support watching a hierarchy. The reason it was not
implemented yet is because the one app that I really care about is
nautilus and the maintainer of it says he doesn't care. 

The big feature that inotify is trying to provide is not having to keep
a file open (So that unmounting is not affected). I asked for some
guidance from people more familiar with the kernel so that I can
implement this feature, it requires changes made to the inode cache, and
how unmounting is done.

> 
> > The idea is to encourage use of a user-space daemon that will
> > multiplex all requests, so if 5 people want to watch /somedir the
> > daemon will only use one watcher in the kernel. The number might be
> > too low, but its easily upped.
> 
> If you are to use a daemon for this, why no use dnotify?

Because of the problems that dnotify has, as well if people would prefer
to just use a direct interface, those #defines can be upped. Its very
easy to play with the limits on the number of watchers. I am not sure
what kind of impact this will have on the kernel resources, so I wanted
to keep it small.

John

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC/PATCH] inotify -- a dnotify replacement
  2004-05-11 11:52       ` nf
  2004-05-11 12:17         ` Stephen Rothwell
@ 2004-05-11 12:24         ` John McCutchan
       [not found]         ` <1084278605.3839.47.camel@carados.180sw.com>
  2 siblings, 0 replies; 29+ messages in thread
From: John McCutchan @ 2004-05-11 12:24 UTC (permalink / raw)
  To: nf2; +Cc: Chris Wedgwood, nautilus-list, linux-kernel

On Tue, 2004-05-11 at 07:52, nf wrote:
> On Tue, 2004-05-11 at 04:47, Chris Wedgwood wrote: 
> > On Mon, May 10, 2004 at 06:17:40PM -0400, John McCutchan wrote:
> > 
> > > According to everyone who uses dnotify it is.
> > 
> > I don't buy that.  I have used dnotify and signals where not an issue.
> > Why is this an issue for others?
> 
> I believe the worst thing about dnotify is the "umount blocking"
> behaviour. It drives me crazy since i use the Linux desktop. So if this
> is the "Year of the linux desktop", please please switch OFF dnotify
> until it does not open files for monitoring anymore! Or until "inotify"
> works.
> 
> Btw, i have written a little tool to assist people with the
> umount-problem and collected some links
> http://www.scheinwelt.at/~norbertf/wbumount/. 

That will be fixed with inotify.

> 
> > > The idea is to encourage use of a user-space daemon that will
> > > multiplex all requests, so if 5 people want to watch /somedir the
> > > daemon will only use one watcher in the kernel. The number might be
> > > too low, but its easily upped.
> > 
> > If you are to use a daemon for this, why no use dnotify?
> 
> I don't understand, why the author of inotify wants to force people to
> use user-space daemons like fam (which requires xinetd, ...)? Does using
> a daemon for multiplexing really add efficiency? Is it really worth
> adding all the complexity of things like "fam" to the system, just
> because more than one application monitor the same directory once in a
> while? I doubt it.
> 

I doesn't have to be fam. I am not sure if having a daemon is the best
way to go either, but I think that having a daemon (not necessarily fam)
could be beneficial. Beyond multiplexing you could keep a buffer of
events and try and combine some events before sending them to the apps.
But if it turns out that a daemon is not the best way, we can adjust the
limits set on the driver and everyone can just use it directly. So relax
I am not trying to force anything, it was just an idea.

John

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC/PATCH] inotify -- a dnotify replacement
  2004-05-11 12:20       ` John McCutchan
@ 2004-05-11 12:46         ` viro
  2004-05-11 19:02           ` John McCutchan
  0 siblings, 1 reply; 29+ messages in thread
From: viro @ 2004-05-11 12:46 UTC (permalink / raw)
  To: John McCutchan; +Cc: Chris Wedgwood, nautilus-list, linux-kernel

On Tue, May 11, 2004 at 08:20:01AM -0400, John McCutchan wrote:
 
> Inotify will support watching a hierarchy. The reason it was not
> implemented yet is because the one app that I really care about is
> nautilus and the maintainer of it says he doesn't care. 

How are you going to implement that?

> The big feature that inotify is trying to provide is not having to keep
> a file open (So that unmounting is not affected). I asked for some
> guidance from people more familiar with the kernel so that I can
> implement this feature, it requires changes made to the inode cache, and
> how unmounting is done.

Bzzert.  First of all, on quite a few filesystems inumbers are stable
only when object is pinned down.  What's more, if it's not pinned down
you've got nothing even remotely resembling a reliable way to tell if
two events had happened to the same object - inumbers can be reused.

Besides, your "doesn't pin down" is racy as hell - not to mention the
way you manage the lists, pretty much every function is an exploitable
hole.  Hell, just take a look at your "find inode" stuff - you grab
superblock, find an inode by inumber (great idea, that - especially
since on a bunch of filesystems it will get you BUG() or equivalent)
then drop refernce to superblock (at which point it can be destroyed by
umount()) _and_ do iput() (which will do lovely, lovely things if that
umount did happen).  Moreover, you return a pointer to inode, even
though there's nothing to hold it alive anymore.  And dereference that
pointer later on, not caring if it had been freed/reused/whatever.

Overall: hopeless crap.  And that's a direct result of your main feature -
it's really broken by design.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC/PATCH] inotify -- a dnotify replacement
  2004-05-11  2:47     ` Chris Wedgwood
  2004-05-11 11:52       ` nf
  2004-05-11 12:20       ` John McCutchan
@ 2004-05-11 15:02       ` Alexander Larsson
  2004-05-11 21:41         ` Chris Wedgwood
  2 siblings, 1 reply; 29+ messages in thread
From: Alexander Larsson @ 2004-05-11 15:02 UTC (permalink / raw)
  To: Chris Wedgwood; +Cc: John McCutchan, Nautilus, linux-kernel

On Tue, 2004-05-11 at 04:47, Chris Wedgwood wrote:
> On Mon, May 10, 2004 at 06:17:40PM -0400, John McCutchan wrote:
> 
> > According to everyone who uses dnotify it is.
> 
> I don't buy that.  I have used dnotify and signals where not an issue.
> Why is this an issue for others?

Its the single thing which forces users of dnotify to have an otherwise
useless daemon. Signals are process global resources. As such, a library
can't allocate them, so dnotify can't be used in a library.

> > > 3) dnotify cannot easily watch changes for a directory hierarchy
> 
> > People don't seem to really care about this one. Alexander Larsson
> > has said he doesn't care about it. It might be nice to add in the
> > future.
> 
> I don't know who that is and why it matters.
> 
> Without being able to watch a hierarchy, I'm not sure inotify buys
> anything that we can't get from dnotify right now though.  It's also
> more complex.

Hierarchical watches are not important to Nautilus, and the lack of them
has not generally been a problem for Gnome. Furthermore, they are
basically impossible to implement in a way that is sane wrt resource
management in the kernel. Unlimited queues in the kernel is an instant
DOS, and if the queue can overflow there is bascially no way to handle
that correctly from userspace without keeping the entire subtree in
memory (and even that breaks in the presence of aliases).

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 Alexander Larsson                                            Red Hat, Inc 
                   alexl@redhat.com    alla@lysator.liu.se 
He's a gun-slinging pirate gangster on the hunt for the last specimen of a 
great and near-mythical creature. She's a manipulative winged Hell's Angel who 
can talk to animals. They fight crime! 


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC/PATCH] inotify -- a dnotify replacement
  2004-05-11 12:46         ` viro
@ 2004-05-11 19:02           ` John McCutchan
  2004-05-11 20:28             ` carbonated beverage
  0 siblings, 1 reply; 29+ messages in thread
From: John McCutchan @ 2004-05-11 19:02 UTC (permalink / raw)
  To: viro; +Cc: nautilus-list, linux-kernel

On Tue, May 11, 2004 at 01:46:47PM +0100, viro@parcelfarce.linux.theplanet.co.uk wrote:
> On Tue, May 11, 2004 at 08:20:01AM -0400, John McCutchan wrote:
>  
> > Inotify will support watching a hierarchy. The reason it was not
> > implemented yet is because the one app that I really care about is
> > nautilus and the maintainer of it says he doesn't care. 
> 
> How are you going to implement that?

>From a quick glance at someone elses implementation of it, I plan on
walking up the dentries and checking at each level if a watcher on that
level is interested in events from subdirectories. Is this good practice in
the kernel?

> > The big feature that inotify is trying to provide is not having to keep
> > a file open (So that unmounting is not affected). I asked for some
> > guidance from people more familiar with the kernel so that I can
> > implement this feature, it requires changes made to the inode cache, and
> > how unmounting is done.
> 
> Bzzert.  First of all, on quite a few filesystems inumbers are stable
> only when object is pinned down.  What's more, if it's not pinned down
> you've got nothing even remotely resembling a reliable way to tell if
> two events had happened to the same object - inumbers can be reused.

The inode will be pinned down, I haven't implemented this yet but I am
going to change the inode cache (is this the right place? )
so that if inode->watcher_count > 0 the inode stays pinned. Then when
the filesystem is unmounted, we will kick off all the watchers on
each inode.

> 
> Besides, your "doesn't pin down" is racy as hell - not to mention the
> way you manage the lists, pretty much every function is an exploitable
> hole.  Hell, just take a look at your "find inode" stuff - you grab
> superblock, find an inode by inumber (great idea, that - especially
> since on a bunch of filesystems it will get you BUG() or equivalent)
> then drop refernce to superblock (at which point it can be destroyed by
> umount()) _and_ do iput() (which will do lovely, lovely things if that
> umount did happen).  Moreover, you return a pointer to inode, even
> though there's nothing to hold it alive anymore.  And dereference that
> pointer later on, not caring if it had been freed/reused/whatever.

Like I said above,as long as an inode has a watcher it will be pinned. As
for the races, I plan on implementing locking around all of the list operations.
Perhaps I wasn't very clear that this is very much a WIP and lots of work is
needed.

> 
> Overall: hopeless crap.  And that's a direct result of your main feature -
> it's really broken by design.

Having directory event notification without needing to keep a file open on the
device is not broken by design. It is the only reasonable solution to
a problem that needs fixing. You can't simply say that a file manager
needing to be notified when directories change is broken. How would
you solve this problem?

John

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC/PATCH] inotify -- a dnotify replacement
  2004-05-11 19:02           ` John McCutchan
@ 2004-05-11 20:28             ` carbonated beverage
  2004-05-11 21:28               ` John McCutchan
  0 siblings, 1 reply; 29+ messages in thread
From: carbonated beverage @ 2004-05-11 20:28 UTC (permalink / raw)
  To: John McCutchan; +Cc: linux-kernel

On Tue, May 11, 2004 at 03:02:31PM -0400, John McCutchan wrote:
> >From a quick glance at someone elses implementation of it, I plan on
> walking up the dentries and checking at each level if a watcher on that
> level is interested in events from subdirectories. Is this good practice in
> the kernel?

Curious, why is it being implemented in this fashion instead of broadcasting
it over a netlink socket?

That way, the user-space listeners can determine whether they want to pay
attention to it or not, and figure out for themselves most of the "do I
care about this event" issue.

As for the directory heirarchy watching, does that mean the user can do:
<process 1>   <process 2>
              while : ; do mkdir a ; cd a ; done
    .... wait 10 seconds ....
listen to a/

What's the kernel going to do then?  Hopefully, you don't mean you'll
be crawling down the entire chain each and every time...

Just random thoughts.

-- DN
Daniel

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC/PATCH] inotify -- a dnotify replacement
  2004-05-11 20:28             ` carbonated beverage
@ 2004-05-11 21:28               ` John McCutchan
  0 siblings, 0 replies; 29+ messages in thread
From: John McCutchan @ 2004-05-11 21:28 UTC (permalink / raw)
  To: carbonated beverage; +Cc: linux-kernel

On Tue, 2004-05-11 at 16:28, carbonated beverage wrote:
> On Tue, May 11, 2004 at 03:02:31PM -0400, John McCutchan wrote:
> > >From a quick glance at someone elses implementation of it, I plan on
> > walking up the dentries and checking at each level if a watcher on that
> > level is interested in events from subdirectories. Is this good practice in
> > the kernel?
> 
> Curious, why is it being implemented in this fashion instead of broadcasting
> it over a netlink socket?

I think this would be a security issue. How would you control access to
the events so that you can't watch directories you shouldn't be able to
access?

> As for the directory heirarchy watching, does that mean the user can do:
> <process 1>   <process 2>
>               while : ; do mkdir a ; cd a ; done
>     .... wait 10 seconds ....
> listen to a/
> 
> What's the kernel going to do then?  Hopefully, you don't mean you'll
> be crawling down the entire chain each and every time...

You are right this would be a big problem. I am not sure the best way to
handle events from sub-directories. 

John

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC/PATCH] inotify -- a dnotify replacement
  2004-05-11 15:02       ` Alexander Larsson
@ 2004-05-11 21:41         ` Chris Wedgwood
  0 siblings, 0 replies; 29+ messages in thread
From: Chris Wedgwood @ 2004-05-11 21:41 UTC (permalink / raw)
  To: Alexander Larsson; +Cc: John McCutchan, Nautilus, linux-kernel

On Tue, May 11, 2004 at 05:02:42PM +0200, Alexander Larsson wrote:

> Its the single thing which forces users of dnotify to have an
> otherwise useless daemon.

fam?  fam is useless for reasons other than dnotify.

> Signals are process global resources. As such, a library can't
> allocate them, so dnotify can't be used in a library.

That's simply bogus.  Pass in the signal number to the library if
necessary.  inotify sounds more like a hack to keep some gnome crap
happy than anything else.



  --cw

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC/PATCH] inotify -- a dnotify replacement
  2004-05-10 22:17   ` John McCutchan
                       ` (2 preceding siblings ...)
  2004-05-11  2:47     ` Chris Wedgwood
@ 2004-05-12 12:38     ` Jörn Engel
  3 siblings, 0 replies; 29+ messages in thread
From: Jörn Engel @ 2004-05-12 12:38 UTC (permalink / raw)
  To: John McCutchan; +Cc: Chris Wedgwood, nautilus-list, linux-kernel

On Mon, 10 May 2004 18:17:40 -0400, John McCutchan wrote:
> 
> I now use ino_t and dev_t , though in struct inode, i_no is unsigned
> long?

Correct.  That definition should be changed as well, I just didn't
care enough to submit a patch yet.  Anyway, old mistakes never justify
new mistakes.

Jörn

-- 
People will accept your ideas much more readily if you tell them
that Benjamin Franklin said it first.
-- unknown

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC/PATCH] inotify -- a dnotify replacement
  2004-05-10  1:35 [RFC/PATCH] inotify -- a dnotify replacement John McCutchan
  2004-05-10  2:11 ` Chris Wedgwood
@ 2004-05-13 15:36 ` raven
  2004-05-13 19:04   ` Chris Wedgwood
  2004-05-13 21:24   ` John McCutchan
  2004-05-15  4:52 ` raven
  2 siblings, 2 replies; 29+ messages in thread
From: raven @ 2004-05-13 15:36 UTC (permalink / raw)
  To: John McCutchan; +Cc: linux-kernel, nautilus-list


Hi John.

On Sun, 9 May 2004, John McCutchan wrote:

> Hi,
> 
> I have been working on inotify a dnotify replacement. 

I have a rather unusual requirement for notification events.

I've had a brief look at the code but it doesn't look like it would 
cater for it.

Would this allow me to receive a notification when a directory is 
passed over during a path walk?

Could this strategy be adapted to notify an in kernel module?
Or is this overkill for what I'm asking?

Ian


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC/PATCH] inotify -- a dnotify replacement
  2004-05-13 15:36 ` raven
@ 2004-05-13 19:04   ` Chris Wedgwood
  2004-05-14  7:04     ` Ian Kent
  2004-05-13 21:24   ` John McCutchan
  1 sibling, 1 reply; 29+ messages in thread
From: Chris Wedgwood @ 2004-05-13 19:04 UTC (permalink / raw)
  To: raven; +Cc: John McCutchan, linux-kernel, nautilus-list

On Thu, May 13, 2004 at 11:36:38PM +0800, raven@themaw.net wrote:

> Would this allow me to receive a notification when a directory is
> passed over during a path walk?

No.  And are you sure you want this?

> Could this strategy be adapted to notify an in kernel module?

Maybe you should explain what you are trying to do...  getting a
notification when a path element is walked sounds problematic of many
levels.


  --cw

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC/PATCH] inotify -- a dnotify replacement
  2004-05-13 15:36 ` raven
  2004-05-13 19:04   ` Chris Wedgwood
@ 2004-05-13 21:24   ` John McCutchan
  2004-05-14  2:02     ` Ian Kent
  1 sibling, 1 reply; 29+ messages in thread
From: John McCutchan @ 2004-05-13 21:24 UTC (permalink / raw)
  To: raven; +Cc: linux-kernel, nautilus-list

On Thu, 2004-05-13 at 11:36, raven@themaw.net wrote:
> Hi John.
> 
> On Sun, 9 May 2004, John McCutchan wrote:
> 
> > Hi,
> > 
> > I have been working on inotify a dnotify replacement. 
> 
> I have a rather unusual requirement for notification events.
> 
> I've had a brief look at the code but it doesn't look like it would 
> cater for it.
> 
> Would this allow me to receive a notification when a directory is 
> passed over during a path walk?

You can easily add event types to inotify, and just hook in at the
proper point in the kernel to get the events sent. That being said, I
don't think this would be a worth while event to have.

John

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC/PATCH] inotify -- a dnotify replacement
  2004-05-13 21:24   ` John McCutchan
@ 2004-05-14  2:02     ` Ian Kent
  0 siblings, 0 replies; 29+ messages in thread
From: Ian Kent @ 2004-05-14  2:02 UTC (permalink / raw)
  To: John McCutchan; +Cc: linux-kernel, nautilus-list

On Thu, 13 May 2004, John McCutchan wrote:

> On Thu, 2004-05-13 at 11:36, raven@themaw.net wrote:
> > Hi John.
> > 
> > On Sun, 9 May 2004, John McCutchan wrote:
> > 
> > > Hi,
> > > 
> > > I have been working on inotify a dnotify replacement. 
> > 
> > I have a rather unusual requirement for notification events.
> > 
> > I've had a brief look at the code but it doesn't look like it would 
> > cater for it.
> > 
> > Would this allow me to receive a notification when a directory is 
> > passed over during a path walk?
> 
> You can easily add event types to inotify, and just hook in at the
> proper point in the kernel to get the events sent. That being said, I
> don't think this would be a worth while event to have.
> 

But you don't know what I need it for. 

Maybe it is a bit of sledge hammer.

Hopefully I'll have some time to check it out further on the weekend.

Ian


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC/PATCH] inotify -- a dnotify replacement
  2004-05-13 19:04   ` Chris Wedgwood
@ 2004-05-14  7:04     ` Ian Kent
  0 siblings, 0 replies; 29+ messages in thread
From: Ian Kent @ 2004-05-14  7:04 UTC (permalink / raw)
  To: Chris Wedgwood; +Cc: John McCutchan, linux-kernel, nautilus-list

On Thu, 13 May 2004, Chris Wedgwood wrote:

> On Thu, May 13, 2004 at 11:36:38PM +0800, raven@themaw.net wrote:
> 
> > Would this allow me to receive a notification when a directory is
> > passed over during a path walk?
> 
> No.  And are you sure you want this?
> 
> > Could this strategy be adapted to notify an in kernel module?
> 
> Maybe you should explain what you are trying to do...  getting a
> notification when a path element is walked sounds problematic of many
> levels.

I'm not trying to do anything atm.

I'm just fishing for ideas.

Ian


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC/PATCH] inotify -- a dnotify replacement
  2004-05-10  1:35 [RFC/PATCH] inotify -- a dnotify replacement John McCutchan
  2004-05-10  2:11 ` Chris Wedgwood
  2004-05-13 15:36 ` raven
@ 2004-05-15  4:52 ` raven
  2 siblings, 0 replies; 29+ messages in thread
From: raven @ 2004-05-15  4:52 UTC (permalink / raw)
  To: John McCutchan; +Cc: linux-kernel, nautilus-list

On Sun, 9 May 2004, John McCutchan wrote:

> Hi,
> 
> I have been working on inotify a dnotify replacement. 

Help me here a little John I'm a little slow on the uptake.

> 
> inotify is a char device that has two ioctls: INOTIFY_WATCH and
> INOTIFY_IGNORE Which expect an inode number and an inode device number.
> I know that on some file systems the inode number and inode device
> number are not guaranteed to be unique. This driver is only meant for
> file systems that have unique inode numbers. 
> 
> The two biggest complaints people have about dnotify are
> 
> 1) dnotify delivers events using signals. 
> 
> 2) dnotify needs a file to be kept open on the device, causing problems
> during unmount. 

So we are saying we open the device file to do our stuff instead of 
keeping a file open?

In kernel functionality could be provided by calling appropriately exported 
routines?

This implementation caters read/write notifications only at this stage?

Ian
 


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC/PATCH] inotify -- a dnotify replacement
       [not found]             ` <1085127066.20393.440.camel@localhost.localdomain>
@ 2004-05-21 12:04               ` nf
  0 siblings, 0 replies; 29+ messages in thread
From: nf @ 2004-05-21 12:04 UTC (permalink / raw)
  To: Alexander Larsson; +Cc: Ross Burton, Nautilus, kernel mailing list

On Fri, 2004-05-21 at 10:11, Alexander Larsson wrote:
> On Tue, 2004-05-18 at 15:06, nf wrote:
> > On Tue, 2004-05-11 at 14:30, Ross Burton wrote:
> > > On Tue, 2004-05-11 at 12:52, nf wrote:
> > > > I would even claim, that simple polling ("stat"-ing) the filesystem for
> > > > changes is more efficient in 95% of the cases, than all this dnotify,
> > > > fam, etc... stuff.
> > > 
> > > Do you have any idea how many files GNOME is watching?  Every file in
> > > your open Nautilus windows, plus the desktop, plus every .desktop file
> > > in your panel menu.  Stat-ing that lot would be seriously slow, and
> > > rather intense.
> > > 
> > > Ross
> > 
> > One million stat() calls take less than 2 seconds on my computer (athlon
> > xp2000). - 2 microseconds per call! This seems negligible compared to
> > all the trouble and complexity we get with xinetd, fam, dnotify,...
> > At least on an average workstation...
> 
> Of course. You're stating the same file, and one that is in cache
> already. You're just measuring syscall overhead, not hd seek times and
> rotational delays.

But: If a filemanager or fam regularly stat() the SAME files - and
that's what they do when monitoring directories - the inodes would all
stay cached. So measuring the syscall() overhead seems quite precise.

I just try to conclude my little kernel newbie research. I believe both
models - generating events versus polling - have disadvantages:

1) Generating events (dnotify and inotify): By hooking into sys_write()
functions far too many events, than any GUI can deal with, get
generated. The result: clients need all kind of timers to group events
which doesn't make a lot of difference to polling (I think).

- You also earn the problem of queues in the kernel and how to limit
those queues (inotify).

- sys_write() calls certainly slow down a lot, because of all the things
attached to them.

- dnotify needs files open on the directory, which seems unacceptable
because of the umount problems. Blocking things is not a good practice
for a monitor ;-).

- inotify has to play tricks to keep inodes cached (watcher counters).

- both (inotify and dnotify) event systems only report changes in
directories, but not which files have changes. Here comes massive
stating() again on the client side. In case the client does not group
events with a timer, hundreds of stat() calls might get generated
whenever an application calls sys_write() to a file in a directory.

2) Polling with stat():

- I think the main problem about stat()ing is the big number of files
which need to get stat()ed when monitoring big directories. But: because
of directory caching of the kernel this might not be a big problem.

- The other problem is the delay, changes in directories get realized
plus more "idle" activity.

3) My conclusion:

--> Return to polling for the moment. The advantages of generating
events (dnotify, inotify) don't outweigh the disadvantages. And polling
is simpler.

--> Make sure polling doesn't take over your system by dynamically
expanding the polling-interval depending on the time one polling()ing
loop takes.

--> Make polling more efficient by adding a kernel sys_dirstat() call,
which returns the max() of all timestamps of the inodes in a directory -
which reduces the overhead of sys_stat - (calling user_path_walk() every
time for instance).
sys_dirstat() could also sum up the filesizes and file-count in the
directory for more convenience.

--> Or - even better: write a driver which hooks into sys_write, which
propagates the "modify" timestamps up the directory hierarchy. This
would make polling really efficient, because only a few queries would be
necessary to find out if there were any changes at all/ in a certain
directory...

Just my thoughts as a kernel-newbie. Maybe i'm completely wrong. And i
don't want to put down "inotify". I think it's a lot nicer than
dnotify...

Regards,

Norbert





























^ permalink raw reply	[flat|nested] 29+ messages in thread

end of thread, other threads:[~2004-05-21 12:05 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-05-10  1:35 [RFC/PATCH] inotify -- a dnotify replacement John McCutchan
2004-05-10  2:11 ` Chris Wedgwood
2004-05-10 22:17   ` John McCutchan
2004-05-10 22:31     ` Davide Libenzi
2004-05-10 22:41       ` John McCutchan
2004-05-10 22:52         ` Davide Libenzi
2004-05-10 23:10           ` Valdis.Kletnieks
2004-05-10 23:42             ` Davide Libenzi
2004-05-11  4:11         ` Chris Wedgwood
2004-05-11  2:00     ` Ian Kent
2004-05-11  2:47     ` Chris Wedgwood
2004-05-11 11:52       ` nf
2004-05-11 12:17         ` Stephen Rothwell
2004-05-11 12:24         ` John McCutchan
     [not found]         ` <1084278605.3839.47.camel@carados.180sw.com>
     [not found]           ` <1084885604.4062.48.camel@lilota.lamp.priv>
     [not found]             ` <1085127066.20393.440.camel@localhost.localdomain>
2004-05-21 12:04               ` nf
2004-05-11 12:20       ` John McCutchan
2004-05-11 12:46         ` viro
2004-05-11 19:02           ` John McCutchan
2004-05-11 20:28             ` carbonated beverage
2004-05-11 21:28               ` John McCutchan
2004-05-11 15:02       ` Alexander Larsson
2004-05-11 21:41         ` Chris Wedgwood
2004-05-12 12:38     ` Jörn Engel
2004-05-13 15:36 ` raven
2004-05-13 19:04   ` Chris Wedgwood
2004-05-14  7:04     ` Ian Kent
2004-05-13 21:24   ` John McCutchan
2004-05-14  2:02     ` Ian Kent
2004-05-15  4:52 ` raven

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).