Messages in this thread Patch in this message | | | Date | Thu, 17 Sep 1998 16:20:13 -0400 | From | Bill Hawes <> | Subject | diagnostic patch for busy inodes |
| |
A number of people have mentioned having problems unmounting because of mysterious files remaining in use. The attached patch is very helpful for tracking down this kind of problem, as it gives a report of busy inode names and numbers whenever you unmount a volume.
Not all of the busy inodes reported are necessarily open for writing, so it's normal to have some inodes in use on the root.
Anyway, hope this is helpful ...
Regards, Bill--- linux-2.1.121/fs/inode.c.old Thu Sep 10 08:07:04 1998 +++ linux-2.1.121/fs/inode.c Thu Sep 10 08:22:06 1998 @@ -281,6 +281,8 @@ inode = list_entry(tmp, struct inode, i_list); if (inode->i_sb != sb) continue; + if (sb->s_root && inode == sb->s_root->d_inode) + continue; if (!inode->i_count) { list_del(&inode->i_hash); INIT_LIST_HEAD(&inode->i_hash); @@ -290,6 +292,40 @@ } busy = 1; } + +#ifdef INODE_PARANOIA + /* + * Display the busy inodes + */ + if (busy) { + struct list_head * tmp; + struct inode * inode; + char *pname, *fname; + + printk("Busy Inodes for Device %s:\n", kdevname(sb->s_dev)); + for (tmp = head->next; tmp != head; tmp = tmp->next) { + inode = list_entry(tmp, struct inode, i_list); + if (inode->i_sb != sb) + continue; + if (sb->s_root && inode == sb->s_root->d_inode) + continue; + if (!inode->i_count) + continue; + pname = ""; + fname = ""; + if (!list_empty(&inode->i_dentry)) { + struct dentry * dentry; + dentry = list_entry(inode->i_dentry.next, + struct dentry, d_alias); + pname = (char *) dentry->d_parent->d_name.name; + fname = (char *) dentry->d_name.name; + } + printk("inode %s/%s(%ld): count=%d, state=%lx\n", + pname, fname, inode->i_ino, inode->i_count, + inode->i_state); + } + } +#endif return busy; } --- linux-2.1.121/fs/super.c.old Tue Sep 1 21:40:19 1998 +++ linux-2.1.121/fs/super.c Thu Sep 10 08:22:06 1998 @@ -623,11 +657,15 @@ struct dentry * root = sb->s_root; struct dentry * covered = root->d_covers; - if (root->d_count != 1) + if (root->d_count != 1) { + printk("d_umount: root d_count=%d\n", root->d_count); return -EBUSY; + } - if (root->d_inode->i_state) + if (root->d_inode->i_state) { + printk("d_umount: root inode busy\n"); return -EBUSY; + } sb->s_root = NULL; @@ -702,9 +740,10 @@ retval = 0; if (!(sb->s_flags & MS_RDONLY)) retval = do_remount_sb(sb, MS_RDONLY, 0); - return retval; + goto out; } + invalidate_inodes(sb); retval = d_umount(sb); if (retval) goto out;
| |