latest inotify.
Subsystems (7)
PATCH 1/1 latest inotify.
Below is the latest inotify patch, against 2.6.12.
I incorporated Andrew's FAQ patch from 2.6-mm, plus a couple of other documentation updates.
Also, skip over I_FREEING inodes on unmount.
Robert Love
inotify!
inotify is intended to correct the deficiencies of dnotify, particularly its inability to scale and its terrible user interface:
* dnotify requires the opening of one fd per each directory that you intend to watch. This quickly results in too many open files and pins removable media, preventing unmount.
* dnotify is directory-based. You only learn about changes to directories. Sure, a change to a file in a directory affects the directory, but you are then forced to keep a cache of stat structures.
* dnotify's interface to user-space is awful. Signals?
inotify provides a more usable, simple, powerful solution to file change notification:
* inotify's interface is a device node, not SIGIO. You open a single fd to the device node, which is select()-able.
* inotify has an event that says "the filesystem that the item you were watching is on was unmounted."
* inotify can watch directories or files.
Inotify is currently used by Beagle (a desktop search infrastructure), Gamin (a FAM replacement), and other projects.
See Documentation/filesystems/inotify.txt.
Documentation/filesystems/inotify.txt | 155 +++++ fs/Kconfig | 13 fs/Makefile | 1 fs/attr.c | 33 - fs/compat.c | 12 fs/file_table.c | 3 fs/inode.c | 6 fs/inotify.c | 984 ++++++++++++++++++++++++++++++++++ fs/namei.c | 30 - fs/nfsd/vfs.c | 6 fs/open.c | 4 fs/read_write.c | 15 fs/sysfs/file.c | 7 fs/xattr.c | 5 include/linux/fs.h | 6 include/linux/fsnotify.h | 257 ++++++++ include/linux/inotify.h | 124 ++++ include/linux/sched.h | 4 kernel/user.c | 4 19 files changed, 1605 insertions(+), 64 deletions(-)
Documentation/filesystems/inotify.txt +155 -0
@@ -0,0 +1,155 @@ + inotify + a powerful yet simple file change notification system + + + +Document started 15 Mar 2005 by Robert Love <[email protected]> + +(i) User Interface + +Inotify is controlled by a device node, /dev/inotify. If you do not use udev, +this device may need to be created manually. + +First step in using inotify is to open the device file: + + int dev_fd = open ("/dev/inotify", O_RDONLY); + +Change events are managed by "watches". A watch is an (object,mask) pair where +the object is a file or directory and the mask is a bitmask of one or more +inotify events that the application wishes to receive. See <linux/inotify.h> +for valid events. A watch is referenced by a watch descriptor, or wd. + +Watches are added via a file descriptor to the file. + +Watches on a directory will return events on any files inside of the directory. + +Adding a watch is simple, + + /* 'wd' represents the watch on fd with mask */ + struct inotify_request req = { fd, mask }; + int wd = ioctl (dev_fd, INOTIFY_WATCH, &req); + +You can add a large number of files via something like + + for each file to watch { + struct inotify_request req; + int file_fd; + + file_fd = open (file, O_RDONLY); + if (fd < 0) { + perror ("open"); + break; + } + + req.fd = file_fd; + req.mask = mask; + + wd = ioctl (dev_fd, INOTIFY_WATCH, &req); + + close (fd); + } + +You can update an existing watch in the same manner, by passing in a new mask. + +An existing watch is removed via the INOTIFY_IGNORE ioctl, for example + + ioctl (dev_fd, INOTIFY_IGNORE, wd); + +Events are provided in the form of an inotify_event structure that is read(2) +from /dev/inotify. The filename is of dynamic length and follows the struct. +It is of size len. The filename is padded with null bytes to ensure proper +alignment. This padding is reflected in len. + +You can slurp multiple events by passing a large buffer, for example + + size_t len = read (fd, buf, BUF_LEN); + +Will return as many events as are available and fit in BUF_LEN. + +/dev/inotify is also select()- and poll()-able. + +You can find the size of the current event queue via the FIONREAD ioctl. + +All watches are destroyed and cleaned up on close. + + +(ii) Internal Kernel Implementation + +Each open inotify device is associated with an inotify_device structure. + +Each watch is associated with an inotify_watch structure. Watches are chained +off of each associated device and each associated inode. + +See fs/inotify.c for the locking and lifetime rules. + + +(iii) Rationale + +Q: What is the design decision behind not tying the watch to the open fd of + the watched object? + +A: Watches are associated with an open inotify device, not an open file. + This solves the primary problem with dnotify: keeping the file open pins + the file and thus, worse, pins the mount. Dnotify is therefore infeasible + for use on a desktop system with removable media as the media cannot be + unmounted. + +Q: What is the design decision behind using an-fd-per-device as opposed to + an fd-per-watch? + +A: An fd-per-watch quickly consumes more file descriptors than are allowed, + more fd's than are feasible to manage, and more fd's than are optimally + select()-able. Yes, root can bump the per-process fd limit and yes, users + can use epoll, but requiring both is a silly and extraneous requirement. + A watch consumes less memory than an open file, separating the number + spaces is thus sensible. The current design is what user-space developers + want: Users open the device, once, and add n watches, requiring but one fd + and no twiddling with fd limits. Opening /dev/inotify two thousand times + is silly. If we can implement user-space's preferences cleanly--and we + can, the idr layer makes stuff like this trivial--then we should. + + There are other good arguments. With a single fd, there is a single + item to block on, which is mapped to a single queue of events. The single + fd returns all watch events and also any potential out-of-band data. If + every fd was a separate watch, + + - There would be no way to get event ordering. Events on file foo and + file bar would pop poll() on both fd's, but there would be no way to tell + which happened first. A single queue trivially gives you ordering. Such + ordering is crucial to existing applications such as Beagle. Imagine + "mv a b ; mv b a" events without ordering. + + - We'd have to maintain n fd's and n internal queues with state, + versus just one. It is a lot messier in the kernel. A single, linear + queue is the data structure that makes sense. + + - User-space developers prefer the current API. The Beagle guys, for + example, love it. Trust me, I asked. It is not a surprise: Who'd want + to manage and block on 1000 fd's via select? + + - You'd have to manage the fd's, as an example: Call close() when you + received a delete event. + + - No way to get out of band data. + + - 1024 is still too low. ;-) + + When you talk about designing a file change notification system that + scales to 1000s of directories, juggling 1000s of fd's just does not seem + the right interface. It is too heavy. + +Q: Why a device node? + +A: The second biggest problem with dnotify is that the user interface sucks + ass. Signals are a terrible, terrible interface for file notification. Or + for anything, for that matter. The idea solution, from all perspectives, + is a file descriptor-based one that allows basic file I/O and poll/select. + Obtaining the fd and managing the watches could of been done either via a + device file or a family of new system calls. We decided to implement a + device file because adding three or four new system calls that mirrored + open, close, and ioctl seemed silly. A character device makes sense from + user-space and was easy to implement inside of the kernel. + + Additionally, it _is_ possible to open /dev/inotify more than once and + juggle more than one queue and thus more than one associated fd. +
fs/attr.c +4 -29
@@ -10,7 +10,7 @@#include <linux/mm.h> #include <linux/string.h> #include <linux/smp_lock.h> -#include <linux/dnotify.h> +#include <linux/fsnotify.h> #include <linux/fcntl.h> #include <linux/quotaops.h> #include <linux/security.h>
@@ -107,31 +107,8 @@ out:return error; } -EXPORT_SYMBOL (inode_setattr); -int setattr_mask (unsigned int ia_valid) -{ -unsigned long dn_mask =0 ; - -if (ia_valid &ATTR_UID ) - dn_mask |=DN_ATTRIB ; -if (ia_valid &ATTR_GID ) - dn_mask |=DN_ATTRIB ; -if (ia_valid &ATTR_SIZE ) - dn_mask |=DN_MODIFY ; -/* both times implies a utime(s) call */ -if ((ia_valid & (ATTR_ATIME |ATTR_MTIME )) == (ATTR_ATIME |ATTR_MTIME )) - dn_mask |=DN_ATTRIB ; -else if (ia_valid &ATTR_ATIME ) - dn_mask |=DN_ACCESS ; -else if (ia_valid &ATTR_MTIME ) - dn_mask |=DN_MODIFY ; -if (ia_valid &ATTR_MODE ) - dn_mask |=DN_ATTRIB ; -return dn_mask; -} -int notify_change (struct dentry * dentry,struct iattr * attr) {struct inode *inode = dentry->d_inode;
@@ -197,11 +174,9 @@if (ia_valid &ATTR_SIZE )up_write (&dentry->d_inode->i_alloc_sem); -if (!error) { -unsigned long dn_mask =setattr_mask (ia_valid); -if (dn_mask) -dnotify_parent (dentry, dn_mask); - } +if (!error) +fsnotify_change (dentry, ia_valid); +return error; }
fs/compat.c +8 -4
@@ -37,7 +37,7 @@#include <linux/ctype.h> #include <linux/module.h> #include <linux/dirent.h> -#include <linux/dnotify.h> +#include <linux/fsnotify.h> #include <linux/highuid.h> #include <linux/sunrpc/svc.h> #include <linux/nfsd/nfsd.h>
@@ -1307,9 +1307,13 @@ out:if (iov != iovstack)kfree (iov); -if ((ret + (type ==READ )) >0 ) -dnotify_parent (file->f_dentry, - (type ==READ ) ?DN_ACCESS :DN_MODIFY ); +if ((ret + (type ==READ )) >0 ) { +struct dentry *dentry = file->f_dentry; +if (type ==READ ) +fsnotify_access (dentry); +else +fsnotify_modify (dentry); + }return ret; }
fs/file_table.c +3 -0
@@ -16,6 +16,7 @@#include <linux/eventpoll.h> #include <linux/mount.h> #include <linux/cdev.h> +#include <linux/fsnotify.h> /* sysctl tunables... */ struct files_stat_struct files_stat = {
@@ -123,6 +124,8 @@struct inode *inode = dentry->d_inode;might_sleep (); + +fsnotify_close (file);/* * The function eventpoll_release() should be the first called * in the file cleanup chain.
fs/inode.c +6 -0
@@ -21,6 +21,7 @@#include <linux/pagemap.h> #include <linux/cdev.h> #include <linux/bootmem.h> +#include <linux/inotify.h> /* * This is needed for the following functions:
@@ -202,6 +203,10 @@INIT_LIST_HEAD (&inode->i_data.i_mmap_nonlinear);spin_lock_init (&inode->i_lock);i_size_ordered_init (inode); +#ifdef CONFIG_INOTIFY +INIT_LIST_HEAD (&inode->inotify_watches); +sema_init (&inode->inotify_sem,1 ); +#endif }EXPORT_SYMBOL (inode_init_once);
@@ -346,6 +351,7 @@down (&iprune_sem);spin_lock (&inode_lock); +inotify_unmount_inodes (&sb->s_inodes); busy =invalidate_list (&sb->s_inodes, &throw_away);spin_unlock (&inode_lock);
Files linux-2.6.12/fs/.inode.c.swp and linux/fs/.inode.c.swp differ
fs/inotify.c +984 -0
984 lines not on this page · raw message
Files linux-2.6.12/fs/.inotify.c.swp and linux/fs/.inotify.c.swp differ
fs/Kconfig +13 -0
@@ -339,6 +339,19 @@ If you don't know whether you need it, then you don't need it: answer N. +config INOTIFY + bool "Inotify file change notification support" + default y + ---help--- + Say Y here to enable inotify support and the /dev/inotify character + device. Inotify is a file change notification system and a + replacement for dnotify. Inotify fixes numerous shortcomings in + dnotify and introduces several new features. It allows monitoring + of both files and directories via a single open fd. Multiple file + events are supported. + + If unsure, say Y. + config QUOTA bool "Quota support" help
fs/Makefile +1 -0
@@ -11,6 +11,7 @@ attr.o bad_inode.o file.o filesystems.o namespace.o aio.o \ seq_file.o xattr.o libfs.o fs-writeback.o mpage.o direct-io.o \ +obj-$(CONFIG_INOTIFY) += inotify.o obj-$(CONFIG_EPOLL) += eventpoll.o obj-$(CONFIG_COMPAT) += compat.o
fs/namei.c +16 -14
@@ -21,7 +21,7 @@#include <linux/namei.h> #include <linux/quotaops.h> #include <linux/pagemap.h> -#include <linux/dnotify.h> +#include <linux/fsnotify.h> #include <linux/smp_lock.h> #include <linux/personality.h> #include <linux/security.h>
@@ -1312,7 +1312,7 @@DQUOT_INIT (dir); error = dir->i_op->create (dir, dentry, mode, nd);if (!error) { -inode_dir_notify (dir,DN_CREATE ); +fsnotify_create (dir, dentry->d_name.name);security_inode_post_create (dir, dentry, mode); }return error;
@@ -1621,7 +1621,7 @@DQUOT_INIT (dir); error = dir->i_op->mknod (dir, dentry, mode, dev);if (!error) { -inode_dir_notify (dir,DN_CREATE ); +fsnotify_create (dir, dentry->d_name.name);security_inode_post_mknod (dir, dentry, mode, dev); }return error;
@@ -1694,7 +1694,7 @@DQUOT_INIT (dir); error = dir->i_op->mkdir (dir, dentry, mode);if (!error) { -inode_dir_notify (dir,DN_CREATE ); +fsnotify_mkdir (dir, dentry->d_name.name);security_inode_post_mkdir (dir,dentry, mode); }return error;
@@ -1785,7 +1785,7 @@ }up (&dentry->d_inode->i_sem);if (!error) { -inode_dir_notify (dir,DN_DELETE ); +fsnotify_rmdir (dentry, dentry->d_inode, dir);d_delete (dentry); }dput (dentry);
@@ -1858,9 +1858,10 @@/* We don't d_delete() NFS sillyrenamed files--they still exist. */ if (!error && !(dentry->d_flags &DCACHE_NFSFS_RENAMED )) { +fsnotify_unlink (dentry, dir);d_delete (dentry); -inode_dir_notify (dir,DN_DELETE ); } +return error; }
@@ -1934,7 +1935,7 @@DQUOT_INIT (dir); error = dir->i_op->symlink (dir, dentry, oldname);if (!error) { -inode_dir_notify (dir,DN_CREATE ); +fsnotify_create (dir, dentry->d_name.name);security_inode_post_symlink (dir, dentry, oldname); }return error;
@@ -2007,7 +2008,7 @@ error = dir->i_op->link (old_dentry, dir, new_dentry);up (&old_dentry->d_inode->i_sem);if (!error) { -inode_dir_notify (dir,DN_CREATE ); +fsnotify_create (dir, new_dentry->d_name.name);security_inode_post_link (old_dentry, dir, new_dentry); }return error;
@@ -2171,6 +2172,7 @@ {int error;int is_dir =S_ISDIR (old_dentry->d_inode->i_mode); +const char *old_name;if (old_dentry->d_inode == new_dentry->d_inode)return 0 ;
@@ -2192,18 +2194,18 @@DQUOT_INIT (old_dir);DQUOT_INIT (new_dir); + old_name =fsnotify_oldname_init (old_dentry->d_name.name); +if (is_dir) error =vfs_rename_dir (old_dir,old_dentry,new_dir,new_dentry);else error =vfs_rename_other (old_dir,old_dentry,new_dir,new_dentry);if (!error) { -if (old_dir == new_dir) -inode_dir_notify (old_dir,DN_RENAME ); -else { -inode_dir_notify (old_dir,DN_DELETE ); -inode_dir_notify (new_dir,DN_CREATE ); - } +const char *new_name = old_dentry->d_name.name; +fsnotify_move (old_dir, new_dir, old_name, new_name, is_dir); } +fsnotify_oldname_free (old_name); +return error; }
fs/nfsd/vfs.c +3 -3
@@ -45,7 +45,7 @@#endif /* CONFIG_NFSD_V3 */ #include <linux/nfsd/nfsfh.h> #include <linux/quotaops.h> -#include <linux/dnotify.h> +#include <linux/fsnotify.h> #ifdef CONFIG_NFSD_V4 #include <linux/posix_acl.h> #include <linux/posix_acl_xattr.h>
@@ -861,7 +861,7 @@ nfsdstats.io_read += err; *count = err; err =0 ; -dnotify_parent (file->f_dentry,DN_ACCESS ); +fsnotify_access (file->f_dentry); }else err =nfserrno (err); out:
@@ -917,7 +917,7 @@set_fs (oldfs);if (err >=0 ) { nfsdstats.io_write += cnt; -dnotify_parent (file->f_dentry,DN_MODIFY ); +fsnotify_modify (file->f_dentry); }/* clear setuid/setgid flag after write */
fs/open.c +3 -1
@@ -10,7 +10,7 @@#include <linux/file.h> #include <linux/smp_lock.h> #include <linux/quotaops.h> -#include <linux/dnotify.h> +#include <linux/fsnotify.h> #include <linux/module.h> #include <linux/slab.h> #include <linux/tty.h>
@@ -944,9 +944,11 @@ fd =get_unused_fd ();if (fd >=0 ) {struct file *f =filp_open (tmp, flags, mode); + error =PTR_ERR (f);if (IS_ERR (f)) goto out_error; +fsnotify_open (f->f_dentry);fd_install (fd, f); } out:
fs/read_write.c +9 -6
@@ -10,7 +10,7 @@#include <linux/file.h> #include <linux/uio.h> #include <linux/smp_lock.h> -#include <linux/dnotify.h> +#include <linux/fsnotify.h> #include <linux/security.h> #include <linux/module.h> #include <linux/syscalls.h>
@@ -239,7 +239,7 @@else ret =do_sync_read (file, buf, count, pos);if (ret >0 ) { -dnotify_parent (file->f_dentry,DN_ACCESS ); +fsnotify_access (file->f_dentry); current->rchar += ret; } current->syscr++;
@@ -287,7 +287,7 @@else ret =do_sync_write (file, buf, count, pos);if (ret >0 ) { -dnotify_parent (file->f_dentry,DN_MODIFY ); +fsnotify_modify (file->f_dentry); current->wchar += ret; } current->syscw++;
@@ -523,9 +523,12 @@ out:if (iov != iovstack)kfree (iov); -if ((ret + (type ==READ )) >0 ) -dnotify_parent (file->f_dentry, - (type ==READ ) ?DN_ACCESS :DN_MODIFY ); +if ((ret + (type ==READ )) >0 ) { +if (type ==READ ) +fsnotify_access (file->f_dentry); +else +fsnotify_modify (file->f_dentry); + }return ret; Efault: ret = -EFAULT ;
fs/sysfs/file.c +2 -5
@@ -3,7 +3,7 @@*/ #include <linux/module.h> -#include <linux/dnotify.h> +#include <linux/fsnotify.h> #include <linux/kobject.h> #include <asm/uaccess.h> #include <asm/semaphore.h>
@@ -389,9 +389,6 @@* sysfs_update_file - update the modified timestamp on an object attribute. * @kobj: object we're acting for. * @attr: attribute descriptor. -* -* Also call dnotify for the dentry, which lots of userspace programs -* use. */ int sysfs_update_file (struct kobject * kobj,const struct attribute * attr) {
@@ -406,7 +403,7 @@if (victim->d_inode && (victim->d_parent->d_inode == dir->d_inode)) { victim->d_inode->i_mtime =CURRENT_TIME ; -dnotify_parent (victim,DN_MODIFY ); +fsnotify_modify (victim);/** * Drop reference from initial sysfs_get_dentry().
fs/xattr.c +4 -1
@@ -16,6 +16,7 @@#include <linux/security.h> #include <linux/syscalls.h> #include <linux/module.h> +#include <linux/fsnotify.h> #include <asm/uaccess.h> /*
@@ -57,8 +58,10 @@if (error) goto out; error = d->d_inode->i_op->setxattr (d, kname, kvalue, size, flags); -if (!error) +if (!error) { +fsnotify_xattr (d);security_inode_post_setxattr (d, kname, kvalue, size, flags); + } out:up (&d->d_inode->i_sem); }
include/linux/fs.h +5 -1
@@ -471,6 +471,11 @@struct dnotify_struct *i_dnotify;/* for directory notifications */ #endif +#ifdef CONFIG_INOTIFY +struct list_head inotify_watches;/* watches on this inode */ +struct semaphore inotify_sem;/* protects the watches list */ +#endif +unsigned long i_state;unsigned long dirtied_when;/* jiffies of first dirtying */
@@ -1369,7 +1374,6 @@extern int do_remount_sb (struct super_block *sb,int flags,void *data,int force);extern sector_t bmap (struct inode *,sector_t ); -extern int setattr_mask (unsigned int );extern int notify_change (struct dentry *,struct iattr *);extern int permission (struct inode *,int ,struct nameidata *); extern int generic_permission(struct inode *, int,
include/linux/fsnotify.h +257 -0
257 lines not on this page · raw message
include/linux/inotify.h +124 -0
124 lines not on this page · raw message
include/linux/sched.h +4 -0
@@ -404,6 +404,10 @@atomic_t processes;/* How many processes 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? */ +#ifdef CONFIG_INOTIFY +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? */ +#endif /* protected by mq_lock */ unsigned long mq_bytes;/* How many bytes can be allocated to mqueue? */ unsigned long locked_shm;/* How many pages of mlocked shm ? */
kernel/user.c +4 -0
@@ -120,6 +120,10 @@atomic_set (&new->processes,0 );atomic_set (&new->files,0 );atomic_set (&new->sigpending,0 ); +#ifdef CONFIG_INOTIFY +atomic_set (&new->inotify_watches,0 ); +atomic_set (&new->inotify_devs,0 ); +#endif new->mq_bytes =0 ; new->locked_shm =0 ;
Hi,
Are you aware of the following:
Jun 21 18:34:04 kangur ------------[ cut here ]------------ Jun 21 18:34:04 kangur kernel BUG at fs/inode.c:1100! Jun 21 18:34:04 kangur invalid operand: 0000 [#1] Jun 21 18:34:04 kangur PREEMPT Jun 21 18:34:04 kangur Modules linked in: nls_iso8859_2 ntfs nls_base pppoatm snd_seq_midi snd_emu10k1_synth snd_emux_synth snd_seq_virmidi snd_seq_midi_emul snd_pcm_oss snd_mixer_oss snd_seq_dummy snd_seq_oss snd_seq_midi_event snd_seq psmouse 8250_pnp 8250 serial_core floppy pcspkr rtc nvidia 8139too mii emu10k1_gp gameport snd_emu10k1 snd_rawmidi snd_seq_device snd_ac97_codec snd_pcm snd_timer snd_page_alloc snd_util_mem snd_hwdep snd soundcore tuner tvaudio bttv video_buf i2c_algo_bit v4l2_common btcx_risc tveeprom videodev speedtch firmware_class usb_atm atm via686a i2c_sensor i2c_core uhci_hcd parport_pc parport evdev usbcore nvram cpuid edd msr loop button ppp_generic slhc unix Jun 21 18:34:04 kangur CPU: 0 Jun 21 18:34:04 kangur EIP: 0060:[<b0173342>] Tainted: P VLI Jun 21 18:34:04 kangur EFLAGS: 00010246 (2.6.12-rc6-ck2-gk1) Jun 21 18:34:04 kangur EIP is at iput+0x62/0x70 Jun 21 18:34:04 kangur eax: d11fbc00 ebx: c65a20dc ecx: c65a20e4 edx: c0ede000 Jun 21 18:34:04 kangur esi: c65a21e8 edi: c65a21e8 ebp: c65a20dc esp: c0edeeec Jun 21 18:34:04 kangur ds: 007b es: 007b ss: 0068 Jun 21 18:34:04 kangur Process umount (pid: 10472, threadinfo=c0ede000 task=cac79a40) Jun 21 18:34:04 kangur Stack: cf63bc74 b017feff 00000000 00000000 c0ede000 c65a21f0 c65a20dc cf63bc74 Jun 21 18:34:04 kangur cf63bc74 c0ede000 c0edef20 c0ede000 b01722ea c0edef20 c0edef20 c8fcea8c Jun 21 18:34:04 kangur cf63bc00 d11fbc00 b015e3b3 0804d35c b14df3c0 cf63bc00 0804d35c b015efa5 Jun 21 18:34:04 kangur Call Trace: Jun 21 18:34:04 kangur [<b017feff>] inotify_unmount_inodes+0xcf/0x110 Jun 21 18:34:04 kangur [<b01722ea>] invalidate_inodes+0x3a/0x80 Jun 21 18:34:04 kangur [<b015e3b3>] generic_shutdown_super+0x63/0x160 Jun 21 18:34:04 kangur [<b015efa5>] kill_block_super+0x25/0x40 Jun 21 18:34:04 kangur [<b015e240>] deactivate_super+0x50/0x80 Jun 21 18:34:04 kangur [<b0175515>] sys_umount+0x35/0x80 Jun 21 18:34:04 kangur [<b014c708>] do_munmap+0xe8/0x150 Jun 21 18:34:04 kangur [<b0175577>] sys_oldumount+0x17/0x20 Jun 21 18:34:04 kangur [<b01030cb>] sysenter_past_esp+0x54/0x75 Jun 21 18:34:04 kangur Code: 94 00 00 00 ba c0 32 17 b0 8b 40 24 85 c0 74 08 8b 40 18 85 c0 0f 45 d0 89 d8 ff d2 5b c3 89 d8 ff d2 8d b4 26 00 00 00 00 eb c2 <0f> 0b 4c 04 6c 6d 2d b0 eb ad 8d 74 26 00 83 ec 08 89 74 24 04 Jun 21 18:34:04 kangur Badness in do_exit at kernel/exit.c:781 Jun 21 18:34:04 kangur [<b011be0c>] do_exit+0x3cc/0x3e0 Jun 21 18:34:04 kangur [<b01043db>] die+0x16b/0x170 Jun 21 18:34:04 kangur [<b0104700>] do_invalid_op+0x0/0xa0 Jun 21 18:34:04 kangur [<b0104790>] do_invalid_op+0x90/0xa0 Jun 21 18:34:04 kangur [<b0144342>] pagevec_lookup+0x22/0x30 Jun 21 18:34:04 kangur [<b0173342>] iput+0x62/0x70 Jun 21 18:34:04 kangur [<b017c343>] write_inode_now+0x73/0xe0 Jun 21 18:34:04 kangur [<d11eb764>] __ntfs_clear_inode+0x54/0x160 [ntfs] Jun 21 18:34:04 kangur [<d11eb909>] ntfs_clear_big_inode+0x59/0xc0 [ntfs] Jun 21 18:34:04 kangur [<b0187b00>] dquot_drop+0x0/0x70 Jun 21 18:34:04 kangur [<b01720ae>] clear_inode+0xae/0x130 Jun 21 18:34:04 kangur [<b01447f7>] truncate_inode_pages+0x17/0x20 Jun 21 18:34:04 kangur [<b0103c23>] error_code+0x4f/0x54 Jun 21 18:34:04 kangur [<b0173342>] iput+0x62/0x70 Jun 21 18:34:04 kangur [<b017feff>] inotify_unmount_inodes+0xcf/0x110 Jun 21 18:34:04 kangur [<b01722ea>] invalidate_inodes+0x3a/0x80 Jun 21 18:34:04 kangur [<b015e3b3>] generic_shutdown_super+0x63/0x160 Jun 21 18:34:04 kangur [<b015efa5>] kill_block_super+0x25/0x40 Jun 21 18:34:04 kangur [<b015e240>] deactivate_super+0x50/0x80 Jun 21 18:34:04 kangur [<b0175515>] sys_umount+0x35/0x80 Jun 21 18:34:04 kangur [<b014c708>] do_munmap+0xe8/0x150 Jun 21 18:34:04 kangur [<b0175577>] sys_oldumount+0x17/0x20 Jun 21 18:34:04 kangur [<b01030cb>] sysenter_past_esp+0x54/0x75
I know that the kernel was tainted but I am afraid that this can be easily reproduced with any 2.6.12 like kernel + inotify after mounting and using NTFS for a while (maybe even mounting and reading of single file and then trying to umount suffices). This breaks the box pretty bad and I needed to reboot with SysRq because init could not.
This was with kernel:
kangur ~ # uname -a
Linux kangur 2.6.12-rc6-ck2-gk1 #1 Mon Jun 6 21:07:12 CEST 2005 i686 Unknown CPU Type AuthenticAMD GNU/Linux
probably with this:
0aa3dfb1940a12a4245ec87b4246db85b55abe40 inotify-0.23-rml-2.6.12-rc4-8.patch
inoftify patch.
Are you aware of this bug (or maybe you already fixed it)?
Thanks,
Grzegorz Kulewski
Quoted 1 line · Grzegorz Kulewski
0aa3dfb1940a12a4245ec87b4246db85b55abe40inotify-0.23-rml-2.6.12-rc4-8.patch
Oh, I just noticed this.
Can you please try with this latest release
(inotify-0.23-rml-2.6.12-14.patch)?
There is some code that might fix this for you, or reveal further what is going on.
Robert Love
Quoted 11 lines · Robert Love
Quoted 1 line · Grzegorz Kulewski
0aa3dfb1940a12a4245ec87b4246db85b55abe40inotify-0.23-rml-2.6.12-rc4-8.patchOh, I just noticed this.
Can you please try with this latest release
(inotify-0.23-rml-2.6.12-14.patch)?There is some code that might fix this for you, or reveal further what is going on.
I will try that as fast as I can. I am not using -mm's since 2.6.2-mm2 because they are usually too broken for me :-(.
IIRC, similar bug was discussed on #gentoo-bugs recently and is probably somewhere in Gentoo Bugzilla (http://bugs.gentoo.org). Several people noticed this. So probably if you can mount and use NTFS for a while and then umount it without problems this is probably fixed. If not - you can reproduce it simply (it is 100% reproductible and occurs only on inotified kernels).
Thanks,
Grzegorz Kulewski
Quoted 2 lines · Grzegorz Kulewski
I will try that as fast as I can. I am not using -mm's since 2.6.2-mm2 because they are usually too broken for me :-(.
Okay. Please let me know how it goes.
And you don't need 2.6-mm, just grab 2.6.12 + inotify if you want.
Robert Love
Quoted 1 line · Grzegorz Kulewski
Are you aware of the following:
Yup.
Am tracking it at http://bugzilla.kernel.org/show_bug.cgi?id=4796
You are actually triggering a BUG(), which is helpful (and hopefully related).
Also, Anton fixed some NTFS-related issues that should be in the next 2.6-mm. Please do report back if that works or not.
Robert Love
Quoted 8 lines · Robert Love
Below is the latest inotify patch, against 2.6.12.
[...]
+/*
+ *fsnotify_oldname_init- save off the old filename before we change it
+ *
+ * XXX: This could be kstrdup if only we could add that tolib/string.c
+ */
I knew you were waiting for this, so I just wanted to let you know that the kstrdup function is already available in Linus tree 2.6.13-rc1. It is declared linux/string.h and implemented in mm/slab.c.
It is not implemented in lib/string.c because some architectures use lib functions in their bootloading code where the allocation functions are not available, and the linking stage then fails because of the kmalloc reference :P
Signature · 5 lines
Paulo Marques - www.grupopie.com It is a mistake to think you can solve any major problems just with potatoes. Douglas Adams