Index: fs/super.c =================================================================== RCS file: /cvsroot/nfs/kernel/linux-2.2/fs/super.c,v retrieving revision 1.2 diff -u -w -r1.2 super.c --- fs/super.c 1999/10/15 23:56:25 1.2 +++ fs/super.c 1999/12/31 07:39:05 @@ -90,6 +90,43 @@ /* NOTREACHED */ } +/*CBLAKE XXX maybe replace mount point dentry with passed in dentry */ +int vfsmnt_replace_mt_de(struct inode *i, struct dentry *de_new) +{ + struct vfsmount *vmt; + struct dentry *de = NULL, *cov; + int rv = 0; + +#if 0 +printk("vfsmnt_replace_mt_de(0x%p(%d), 0x%p(\"%s\"))\n", i, i->i_ino, de_new, de_new->d_name.name); +#endif + for (vmt = vfsmntlist; vmt; vmt = vmt->mnt_next) { + if (!vmt->mnt_sb || + !(de = vmt->mnt_sb->s_root) || + !de->d_covers) + continue; +#if 0 +printk(" %s: 0x%p ==? 0x%p\tcovers = 0x%p\n", de->d_covers->d_name.name, i, de->d_covers->d_inode, de->d_covers); +#endif + if (de->d_covers->d_inode == i && de->d_covers != de_new) { + cov = de->d_covers; + printk("VFS: Replacing %s with %s in mount table -- new ref ct = ", + cov->d_name.name, de_new->d_name.name, de_new->d_count + 1); + rv = 1; + de->d_covers = dget(de_new); + printk("%d, old ref ct = ", de_new->d_count); + de_new->d_mounts = de; + cov->d_mounts = cov; + d_drop(cov); + dput(cov); + d_delete(cov); + printk("%d\n", cov->d_count); + } + } + return rv; +} +/*CBLAKE*/ + static struct vfsmount *add_vfsmnt(struct super_block *sb, const char *dev_name, const char *dir_name) { @@ -616,11 +653,17 @@ struct dentry * root = sb->s_root; struct dentry * covered = root->d_covers; - if (root->d_count != 1) + if (root->d_count != 1) { + printk("VFS: %s has refcount %d\n", root->d_covers->d_name.name, + root->d_count); return -EBUSY; + } - if (root->d_inode->i_state) + if (root->d_inode->i_state) { + printk("VFS: %s has i_state %d\n", root->d_covers->d_name.name, + root->d_inode->i_state); return -EBUSY; + } sb->s_root = NULL; Index: fs/nfs/dir.c =================================================================== RCS file: /cvsroot/nfs/kernel/linux-2.2/fs/nfs/dir.c,v retrieving revision 1.16 diff -u -w -r1.16 dir.c --- fs/nfs/dir.c 1999/12/20 12:42:01 1.16 +++ fs/nfs/dir.c 1999/12/31 07:39:05 @@ -38,6 +38,8 @@ #include /* for fs functions */ +int vfsmnt_replace_mt_de(struct inode *e, struct dentry *dentry); + #define NFS_PARANOIA 1 /* #define NFS_DEBUG_VERBOSE 1 */ @@ -595,6 +597,8 @@ nfs_refresh_inode(inode, &fattr); nfs_refresh_inode(dir_i, &dir_attr); + vfsmnt_replace_mt_de(inode, dentry); /* XXX cblake */ + out_valid_renew: nfs_renew_times(dentry); out_valid: @@ -687,7 +691,7 @@ static struct dentry *nfs_lookup(struct inode *dir_i, struct dentry * dentry) { - struct dentry *dir = dentry->d_parent; + struct dentry *dir = dentry->d_parent, *tmp; struct inode *inode; int error; struct nfs_fh fhandle; @@ -716,9 +720,9 @@ if (inode) goto no_entry; #endif - error = NFS_CALL(lookup, dir_i, (dir, &dir_attr, - &dentry->d_name, &fhandle, &fattr)); + &dentry->d_name, + &fhandle, &fattr)); nfs_refresh_inode(dir_i, &dir_attr); inode = NULL; if (error == -ENOENT) Index: fs/nfs/inode.c =================================================================== RCS file: /cvsroot/nfs/kernel/linux-2.2/fs/nfs/inode.c,v retrieving revision 1.12 diff -u -w -r1.12 inode.c --- fs/nfs/inode.c 1999/12/13 14:48:36 1.12 +++ fs/nfs/inode.c 1999/12/31 07:39:05 @@ -1097,6 +1097,9 @@ goto out; } + /* printk("NFS: checking if need to swap mt pt\n"); */ + vfsmnt_replace_mt_de(inode, dentry); /* XXX cblake */ + dfprintk(PAGECACHE, "NFS: %s/%s revalidation complete\n", dentry->d_parent->d_name.name, dentry->d_name.name); out: Index: kernel/ksyms.c =================================================================== RCS file: /cvsroot/nfs/kernel/linux-2.2/kernel/ksyms.c,v retrieving revision 1.8 diff -u -w -r1.8 ksyms.c --- kernel/ksyms.c 1999/12/13 14:48:37 1.8 +++ kernel/ksyms.c 1999/12/31 07:39:13 @@ -82,6 +82,9 @@ #endif EXPORT_SYMBOL(get_options); +int vfsmnt_replace_mt_de(struct inode *e, struct dentry *dentry); +EXPORT_SYMBOL(vfsmnt_replace_mt_de); + /* process memory management */ EXPORT_SYMBOL(do_mmap); EXPORT_SYMBOL(do_munmap);