Index: oldkernel/linux/fs/nfs/inode.c diff -u linux/fs/nfs/inode.c:1.2 linux/fs/nfs/inode.c:1.3 --- linux/fs/nfs/inode.c:1.2 Thu Jun 1 15:03:08 2000 +++ linux/fs/nfs/inode.c Thu Jun 1 15:37:13 2000 @@ -212,7 +212,12 @@ if (!data) goto out_miss_args; - if (data->version != NFS_MOUNT_VERSION) { + /* No NFS V3. */ + if (data->flags & NFS_MOUNT_VER3) + goto out_fail; + + /* Don't complain if "mount" is newer. */ + if (data->version < NFS_MOUNT_VERSION) { printk("nfs warning: mount version %s than kernel\n", data->version < NFS_MOUNT_VERSION ? "older" : "newer"); if (data->version < 2) Index: oldkernel/linux/fs/nfsd/nfsfh.c diff -u linux/fs/nfsd/nfsfh.c:1.1.1.1 linux/fs/nfsd/nfsfh.c:1.2 --- linux/fs/nfsd/nfsfh.c:1.1.1.1 Wed May 31 12:33:48 2000 +++ linux/fs/nfsd/nfsfh.c Thu Jun 1 15:37:13 2000 @@ -455,13 +455,27 @@ break; } - result = ERR_PTR(-ENOENT); - dir = iget_in_use(sb, dirino); - if (!dir) - goto out_root; - dentry = d_alloc_root(dir, NULL); - if (!dentry) - goto out_iput; + /* + * Fix for /// bad export bug: if dirino is the root, + * get the real root dentry rather than creating a temporary + * "root" dentry. XXX We could extend this to use + * any existing dentry for the located 'dir', but all + * of this code is going to be completely rewritten soon, + * so I won't bother. + */ + + if (dirino == root_ino) { + dentry = dget(root); + } + else { + result = ERR_PTR(-ENOENT); + dir = iget_in_use(sb, dirino); + if (!dir) + goto out_root; + dentry = d_alloc_root(dir, NULL); + if (!dentry) + goto out_iput; + } /* * Get the name for this inode and the next parent inode. @@ -847,12 +861,12 @@ dirent.ino = ino; error = get_parent_ino(parent, &dirent); if (error) { -#ifdef NFSD_PARANOIA +#ifdef NFSD_PARANOIA_EXTREME printk("lookup_by_inode: ino %ld not found in %s\n", ino, parent->d_name.name); #endif goto no_entry; } -#ifdef NFSD_PARANOIA +#ifdef NFSD_PARANOIA_EXTREME printk("lookup_by_inode: found %s\n", dirent.name); #endif @@ -860,13 +874,13 @@ if (!IS_ERR(dentry)) { if (dentry->d_inode && dentry->d_inode->i_ino == ino) goto out; -#ifdef NFSD_PARANOIA +#ifdef NFSD_PARANOIA_EXTREME printk("lookup_by_inode: %s/%s inode mismatch??\n", parent->d_name.name, dentry->d_name.name); #endif dput(dentry); } else { -#ifdef NFSD_PARANOIA +#ifdef NFSD_PARANOIA_EXTREME printk("lookup_by_inode: %s lookup failed, error=%ld\n", dirent.name, PTR_ERR(dentry)); #endif @@ -1077,7 +1091,7 @@ /* * Stage 5: Search the whole volume, Yea Right. */ -#ifdef NFSD_PARANOIA +#ifdef NFSD_PARANOIA_EXTREME printk("find_fh_dentry: %s/%u dir/%u not found!\n", kdevname(u32_to_kdev_t(fh->fh_dev)), fh->fh_ino, fh->fh_dirino); #endif @@ -1330,7 +1344,7 @@ fhp->fh_handle.fh_ino = ino_t_to_u32(inode->i_ino); fhp->fh_handle.fh_generation = inode->i_generation; fhp->fh_handle.fh_dcookie = (struct dentry *)0xfeebbaca; - out: +out: return; out_bad: Index: oldkernel/linux/fs/nfsd/nfsproc.c diff -u linux/fs/nfsd/nfsproc.c:1.1.1.1 linux/fs/nfsd/nfsproc.c:1.2 --- linux/fs/nfsd/nfsproc.c:1.1.1.1 Wed May 31 12:33:48 2000 +++ linux/fs/nfsd/nfsproc.c Thu Jun 1 15:37:13 2000 @@ -237,6 +237,9 @@ if (nfserr) goto done; inode = newfhp->fh_dentry->d_inode; + if (inode && newfhp->fh_handle.fh_ino == 0) + /* inode might have been instantiated while we slept */ + fh_update(newfhp); /* Unfudge the mode bits */ if (attr->ia_valid & ATTR_MODE) {