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) */
 };
 
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to