[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
- netfs part of a console server with server-client model, Marcus Brinkmann, 2002/06/01
- Re: netfs part of a console server with server-client model, Niels Möller, 2002/06/02
- Re: netfs part of a console server with server-client model, Marcus Brinkmann, 2002/06/02
- Re: netfs part of a console server with server-client model, Niels Möller, 2002/06/02
- Re: netfs part of a console server with server-client model, Marcus Brinkmann, 2002/06/02
- Re: netfs part of a console server with server-client model, Niels Möller, 2002/06/02
- Re: netfs part of a console server with server-client model, Marcus Brinkmann, 2002/06/02
- Re: netfs part of a console server with server-client model, Niels Möller, 2002/06/03
Re: netfs part of a console server with server-client model, Marcus Brinkmann, 2002/06/02
- Re: netfs part of a console server with server-client model,
Marcus Brinkmann <=