changeset 3640:8d28349677cb

6462361 Cannot make hardlinks to device nodes on lofs Contributed by Richard Lowe <richlowe@richlowe.net> 5105488 ufs_dirremove() should not panic in face of NULL name passed in Contributed by John Sonnenschein <johnsonnenschein@gmail.com>
author batschul
date Tue, 13 Feb 2007 07:18:09 -0800
parents 77dd70fd4e7b
children 4488c321dec8
files usr/src/uts/common/fs/lofs/lofs_vnops.c usr/src/uts/common/fs/ufs/ufs_dir.c
diffstat 2 files changed, 25 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/fs/lofs/lofs_vnops.c	Tue Feb 13 01:45:18 2007 -0800
+++ b/usr/src/uts/common/fs/lofs/lofs_vnops.c	Tue Feb 13 07:18:09 2007 -0800
@@ -699,6 +699,8 @@
 static int
 lo_link(vnode_t *tdvp, vnode_t *vp, char *tnm, struct cred *cr)
 {
+	vnode_t *realvp;
+
 #ifdef LODEBUG
 	lo_dprint(4, "lo_link vp %p realvp %p\n", vp, realvp(vp));
 #endif
@@ -726,6 +728,17 @@
 	while (vn_matchops(vp, lo_vnodeops)) {
 		vp = realvp(vp);
 	}
+
+	/*
+	 * In the case where the source vnode is on another stacking
+	 * filesystem (such as specfs), the loop above will
+	 * terminate before finding the true underlying vnode.
+	 *
+	 * We use VOP_REALVP here to continue the search.
+	 */
+	if (VOP_REALVP(vp, &realvp) == 0)
+		vp = realvp;
+
 	while (vn_matchops(tdvp, lo_vnodeops)) {
 		tdvp = realvp(tdvp);
 	}
--- a/usr/src/uts/common/fs/ufs/ufs_dir.c	Tue Feb 13 01:45:18 2007 -0800
+++ b/usr/src/uts/common/fs/ufs/ufs_dir.c	Tue Feb 13 07:18:09 2007 -0800
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -2445,8 +2445,17 @@
 	ushort_t extra;
 
 	namlen = (int)strlen(namep);
-	if (namlen == 0)
-		return (ufs_fault(ITOV(dp), "ufs_dirremove: namlen == 0"));
+	if (namlen == 0) {
+		struct fs	*fs = dp->i_fs;
+
+		cmn_err(CE_WARN, "%s: ufs_dirremove: attempted to remove"
+		    " nameless file in directory (directory inode %llu)",
+		    fs->fs_fsmnt, (u_longlong_t)dp->i_number);
+		ASSERT(namlen != 0);
+
+		return (ENOENT);
+	}
+
 	/*
 	 * return error when removing . and ..
 	 */