patch-2.2.15 linux/fs/nfsd/nfsfh.c

Next file: linux/fs/nfsd/nfsproc.c
Previous file: linux/fs/nfsd/nfsctl.c
Back to the patch index
Back to the overall index

diff -u --new-file --recursive --exclude-from ../../exclude v2.2.14/fs/nfsd/nfsfh.c linux/fs/nfsd/nfsfh.c
@@ -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.
@@ -676,6 +690,15 @@
 		return 1;
 	}
 
+	/* if nfsd_server is zero, NFSD_MAXFH will be zero too, so
+	 * find_fhe() will NEVER find the file handle NOR an empty space,
+	 * and expire_slot will not be able to expire any file handle,
+	 * because NFSD_MAXFH is zero ... */
+
+	if (nfsd_nservers <= 0) {
+		return 0;
+	}
+
 	expire_slot(cache);
 	goto repeat;
 }
@@ -847,12 +870,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 +883,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 +1100,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 +1353,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:

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)