bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: netfs part of a console server with server-client model


From: Marcus Brinkmann
Subject: Re: netfs part of a console server with server-client model
Date: Mon, 3 Jun 2002 03:51:50 +0200
User-agent: Mutt/1.3.28i

On Mon, Jun 03, 2002 at 03:42:44AM +0200, Marcus Brinkmann wrote:
> Below is a diff

and here it is

--- console-old.c       Mon Jun  3 03:29:50 2002
+++ console.c   Mon Jun  3 03:32:12 2002
@@ -67,6 +67,7 @@
   struct node *dir_node;
   struct node *cons_node;
   struct node *disp_node;
+  struct node *inpt_node;
 
   /* The output queue holds the characters that are to be outputted.
      The display driver might refuse to handle some incomplete
@@ -178,14 +179,15 @@
         }
       previous_vcons->next = vcons;
     }
-  else {
-    if (cons->vcons_list)
-      {
-       cons->vcons_list->prev = vcons;
-       vcons->next = cons->vcons_list;
-      }
-    cons->vcons_list = vcons;
-  }
+  else
+    {
+      if (cons->vcons_list)
+       {
+         cons->vcons_list->prev = vcons;
+         vcons->next = cons->vcons_list;
+       }
+      cons->vcons_list = vcons;
+    }
   mutex_unlock (&cons->lock);
   *r_vcons = vcons;
   return 0;
@@ -217,25 +219,35 @@
          we know that without references, this virtual console is
          neither active nor used by any input group.  */
 
-      /* XXX Destroy the state.  */
-      free (vcons->name);
       if (vcons->prev)
         vcons->prev->next = vcons->next;
+      else
+       cons->vcons_list = vcons->next;
       if (vcons->next)
         vcons->next->prev = vcons->prev;
-      if (!vcons->prev && !vcons->next)
-       vcons->cons->vcons_list = NULL;
+
+      /* XXX Destroy the state.  */
+      free (vcons->name);
       free (vcons);
     }
   mutex_unlock (&cons->lock);
 }
 
-
+struct netnode
+{
+  /* The root node points to the console object.  */
+  cons_t cons;
+
+  /* All other nodes point to the virtual console object.  */
+  vcons_t vcons;
+};
+
 typedef enum
   {
     VCONS_NODE_DIR = 0,
     VCONS_NODE_CONSOLE,
-    VCONS_NODE_DISPLAY
+    VCONS_NODE_DISPLAY,
+    VCONS_NODE_INPUT
   } vcons_node_type;
 
 /* Make a new virtual node.  Always consumes the ports.  */
@@ -254,6 +266,7 @@
       return ENOMEM;
     }
   (*np)->nn_stat = cons->stat_template;
+  (*np)->nn_translated = 0;
 
   switch (type)
     {
@@ -265,13 +278,21 @@
     case VCONS_NODE_CONSOLE:
       (*np)->nn_stat.st_ino = (vcons->id << 2) + 1;
       (*np)->nn_stat.st_mode |= S_IFCHR;       /* Don't set nn_translated! */
+      (*np)->nn_stat.st_mode &= ~(S_IXUSR | S_IXGRP | S_IXOTH);
       (*np)->nn_stat.st_size = 0;
       break;
     case VCONS_NODE_DISPLAY:
       (*np)->nn_stat.st_ino = (vcons->id << 2) + 2;
       (*np)->nn_stat.st_mode |= S_IFREG;
+      (*np)->nn_stat.st_mode &= ~(S_IXUSR | S_IXGRP | S_IXOTH);
       (*np)->nn_stat.st_size = 2000; /* XXX */
       break;
+    case VCONS_NODE_INPUT:
+      (*np)->nn_stat.st_ino = (vcons->id << 2) + 3;
+      (*np)->nn_stat.st_mode |= S_IFIFO;
+      (*np)->nn_stat.st_mode &= ~(S_IXUSR | S_IXGRP | S_IXOTH);
+      (*np)->nn_stat.st_size = 0;
+      break;
     }
 
   /* If the underlying node isn't a directory, propagate read permission to
@@ -306,17 +327,32 @@
   /* The root node does never go away.  */
   assert (!np->nn->cons && np->nn->vcons);
 
+  /* Avoid deadlock.  */
+  spin_unlock (&netfs_node_refcnt_lock);
+
   /* Find the back reference to ourself in the virtual console
      structure, and delete it.  */
   mutex_lock (&vcons->lock);
+  spin_lock (&netfs_node_refcnt_lock);
+  if (np->references)
+    {
+      /* Someone else got a reference while we were attempting to go
+        away.  This can happen in netfs_attempt_lookup.  In this
+        case, just unlock the node and do nothing else.  */
+      mutex_unlock (&vcons->lock);
+      mutex_unlock (&np->lock);
+      return;
+    }
   if (np == vcons->dir_node)
     vcons->dir_node = 0;
   else if (np == vcons->cons_node)
     vcons->cons_node = 0;
+  else if (np == vcons->disp_node)
+    vcons->disp_node = 0;
   else
     {
-      assert (np == vcons->disp_node);
-      vcons->disp_node = 0;
+      assert (np == vcons->inpt_node);
+      vcons->inpt_node = 0;
     }
   mutex_unlock (&vcons->lock);
 
@@ -559,6 +595,25 @@
            }
          mutex_unlock (&vcons->lock);
        }
+      else if (!strcmp (name, "input"))
+       {
+         mutex_lock (&vcons->lock);
+         if (vcons->inpt_node)
+           {
+             *node = vcons->inpt_node;
+             netfs_nref (*node);
+           }
+         else
+           {
+             err = new_node (node, vcons, VCONS_NODE_INPUT);
+             if (!err)
+               {
+                 vcons->inpt_node = *node;
+                 ref_vcons = 1;
+               }
+           }
+         mutex_unlock (&vcons->lock);
+       }
       else
        err = ENOENT;
 
@@ -646,13 +701,8 @@
     {
       /* See how much space we need for the result.  */
       for (vcons = first_vcons; vcons; vcons = vcons->next)
-#if 0
-       if (vcons->dir_node /* XXX see above */
-           && !bump_size (vcons->name))
-#else
-         if (!bump_size (vcons->name))
-#endif
-           break;
+       if (!bump_size (vcons->name))
+         break;
     }
   else
     {
@@ -660,6 +710,8 @@
        bump_size ("console");
       if (first_entry <= 3)
        bump_size ("display");
+      if (first_entry <= 4)
+       bump_size ("input");
     }
 
   /* Allocate it.  */
@@ -716,11 +768,7 @@
 
          /* Fill in the real directory entries.  */
          for (vcons = first_vcons; vcons; vcons = vcons->next)
-           if (
-#if 0 
-               /* XXX see above */ vcons->dir_node &&
-#endif
-               !add_dir_entry (vcons->name,
+           if (!add_dir_entry (vcons->name,
                                vcons->id << 2, DT_DIR))
              break;
          mutex_unlock (&dir->nn->cons->lock);
@@ -734,9 +782,11 @@
            add_dir_entry ("..", 2, DT_DIR);
 
          if (first_entry <= 2)
-           add_dir_entry ("console", (vcons->id << 2) + 1, DT_REG);
+           add_dir_entry ("console", (dir->nn->vcons->id << 2) + 1, DT_REG);
          if (first_entry <= 3)
-           add_dir_entry ("display", (vcons->id << 2) + 2, DT_REG);
+           add_dir_entry ("display", (dir->nn->vcons->id << 2) + 2, DT_REG);
+         if (first_entry <= 4)
+           add_dir_entry ("input", (dir->nn->vcons->id << 3) + 2, DT_FIFO);
        }         
     }
       
@@ -795,6 +845,11 @@
          vcons->disp_node->nn_stat.st_uid = uid;
          vcons->disp_node->nn_stat.st_gid = gid;
        }
+      if (vcons->inpt_node)
+       {
+         vcons->inpt_node->nn_stat.st_uid = uid;
+         vcons->inpt_node->nn_stat.st_gid = gid;
+       }
     }
   mutex_unlock (&cons->lock);
   fshelp_touch (&node->nn_stat, TOUCH_CTIME, console_maptime);
@@ -832,6 +887,8 @@
        vcons->cons_node->nn_stat.st_author = author;
       if (vcons->disp_node)
        vcons->disp_node->nn_stat.st_author = author;
+      if (vcons->inpt_node)
+       vcons->inpt_node->nn_stat.st_author = author;
     }
   mutex_unlock (&cons->lock);
   fshelp_touch (&node->nn_stat, TOUCH_CTIME, console_maptime);
@@ -956,9 +1013,11 @@
 
   if (np == vcons->cons_node)
     *len = 0; /* Pass input queue content to caller.  */
+  else if (np == vcons->disp_node)
+    *len = 0; /* Pass input queue content to caller.  */
   else
     {
-      assert (np == vcons->disp_node);
+      assert (np == vcons->inpt_node);
       *len = 0; /* Pass display content to caller.  */
     }
   return 0;
@@ -974,6 +1033,8 @@
 
   if (np == vcons->cons_node)
     *len = 0; /* Write input to text matrix.  */
+  else if (np == vcons->disp_node)
+    *len = 0; /* Put input into input queue.  */
   else
     {
       assert (np == vcons->disp_node);

-- 
`Rhubarb is no Egyptian god.' Debian http://www.debian.org brinkmd@debian.org
Marcus Brinkmann              GNU    http://www.gnu.org    marcus@gnu.org
Marcus.Brinkmann@ruhr-uni-bochum.de
http://www.marcus-brinkmann.de



reply via email to

[Prev in Thread] Current Thread [Next in Thread]