svn commit: r352334 - head/sys/fs/pseudofs

Edward Tomasz Napierala trasz at FreeBSD.org
Sat Sep 14 19:16:08 UTC 2019


Author: trasz
Date: Sat Sep 14 19:16:07 2019
New Revision: 352334
URL: https://svnweb.freebsd.org/changeset/base/352334

Log:
  Make pseudofs(9) create directory entries in order, instead
  of the reverse.
  
  This fixes Linux sysctl(8) binary - it assumes the first two
  directory entries are always "." and "..". There might be other
  Linux apps affected by this.
  
  NB it might be a good idea to rewrite it using queue(3).
  
  Reviewed by:	kib
  MFC after:	2 weeks
  Sponsored by:	The FreeBSD Foundation
  Differential Revision:	https://reviews.freebsd.org/D21550

Modified:
  head/sys/fs/pseudofs/pseudofs.c
  head/sys/fs/pseudofs/pseudofs.h

Modified: head/sys/fs/pseudofs/pseudofs.c
==============================================================================
--- head/sys/fs/pseudofs/pseudofs.c	Sat Sep 14 18:20:14 2019	(r352333)
+++ head/sys/fs/pseudofs/pseudofs.c	Sat Sep 14 19:16:07 2019	(r352334)
@@ -135,10 +135,21 @@ pfs_add_node(struct pfs_node *parent, struct pfs_node 
 	pfs_fileno_alloc(pn);
 
 	pfs_lock(parent);
-	pn->pn_next = parent->pn_nodes;
 	if ((parent->pn_flags & PFS_PROCDEP) != 0)
 		pn->pn_flags |= PFS_PROCDEP;
-	parent->pn_nodes = pn;
+	if (parent->pn_nodes == NULL) {
+		KASSERT(parent->pn_last_node == NULL,
+		    ("%s(): pn_last_node not NULL", __func__));
+		parent->pn_nodes = pn;
+		parent->pn_last_node = pn;
+	} else {
+		KASSERT(parent->pn_last_node != NULL,
+		    ("%s(): pn_last_node is NULL", __func__));
+		KASSERT(parent->pn_last_node->pn_next == NULL,
+		    ("%s(): pn_last_node->pn_next not NULL", __func__));
+		parent->pn_last_node->pn_next = pn;
+		parent->pn_last_node = pn;
+	}
 	pfs_unlock(parent);
 }
 
@@ -148,7 +159,7 @@ pfs_add_node(struct pfs_node *parent, struct pfs_node 
 static void
 pfs_detach_node(struct pfs_node *pn)
 {
-	struct pfs_node *parent = pn->pn_parent;
+	struct pfs_node *node, *parent = pn->pn_parent;
 	struct pfs_node **iter;
 
 	KASSERT(parent != NULL, ("%s(): node has no parent", __func__));
@@ -156,6 +167,16 @@ pfs_detach_node(struct pfs_node *pn)
 	    ("%s(): parent has different pn_info", __func__));
 
 	pfs_lock(parent);
+	if (pn == parent->pn_last_node) {
+		if (pn == pn->pn_nodes) {
+			parent->pn_last_node = NULL;
+		} else {
+			for (node = parent->pn_nodes;
+			    node->pn_next != pn; node = node->pn_next)
+				continue;
+			parent->pn_last_node = node;
+		}
+	}
 	iter = &parent->pn_nodes;
 	while (*iter != NULL) {
 		if (*iter == pn) {

Modified: head/sys/fs/pseudofs/pseudofs.h
==============================================================================
--- head/sys/fs/pseudofs/pseudofs.h	Sat Sep 14 18:20:14 2019	(r352333)
+++ head/sys/fs/pseudofs/pseudofs.h	Sat Sep 14 19:16:07 2019	(r352334)
@@ -237,6 +237,7 @@ struct pfs_node {
 
 	struct pfs_node		*pn_parent;		/* (o) */
 	struct pfs_node		*pn_nodes;		/* (o) */
+	struct pfs_node		*pn_last_node;		/* (o) */
 	struct pfs_node		*pn_next;		/* (p) */
 };
 


More information about the svn-src-head mailing list