]> xenbits.xensource.com Git - freebsd.git/commitdiff
Make pseudofs(9) create directory entries in order, instead
authortrasz <trasz@FreeBSD.org>
Sat, 14 Sep 2019 19:16:07 +0000 (19:16 +0000)
committertrasz <trasz@FreeBSD.org>
Sat, 14 Sep 2019 19:16:07 +0000 (19:16 +0000)
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

sys/fs/pseudofs/pseudofs.c
sys/fs/pseudofs/pseudofs.h

index 73d3c7cbdd9dfecdbabf9677c0719548c92f3bbe..c013de14771902a700ce2f0d4081500295e736d3 100644 (file)
@@ -135,10 +135,21 @@ pfs_add_node(struct pfs_node *parent, struct pfs_node *pn)
        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 *pn)
 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) {
index 602e1fbfa377ce2c78725c6e249a9427c8da7677..3dbd5435f04d21a5098a8b1cc338e72718228685 100644 (file)
@@ -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) */
 };