>From 82f635e6ecafe74c70269babfb0e0bb0e7db99db Mon Sep 17 00:00:00 2001 From: Sergiu Ivanov <unlimitedscol...@gmail.com> Date: Mon, 10 Aug 2009 20:13:26 +0300 Subject: [PATCH] Add the .MASTER node to the eth-multiplexer.
* eth-multiplexer/device_impl.c (ds_device_open): Handle the .MASTER node specially. * eth-multiplexer/multiplexer.c (main): Create the .MASTER node. * eth-multiplexer/netfs_impl.c (master_node): New variable. (lookup): Handle the lookups for .MASTER specially. (netfs_add_dirents): Add the .MASTER node. * eth-multiplexer/netfs_impl.h (MASTER_NODE_NAME): New definition. (master_node): New variable. --- eth-multiplexer/device_impl.c | 21 ++++++++++++++++++++- eth-multiplexer/multiplexer.c | 6 +++++- eth-multiplexer/netfs_impl.c | 21 ++++++++++++++++++++- eth-multiplexer/netfs_impl.h | 8 ++++++++ 4 files changed, 53 insertions(+), 3 deletions(-) diff --git a/eth-multiplexer/device_impl.c b/eth-multiplexer/device_impl.c index abbd146..6aa27dd 100644 --- a/eth-multiplexer/device_impl.c +++ b/eth-multiplexer/device_impl.c @@ -116,7 +116,26 @@ ds_device_open (mach_port_t master_port, mach_port_t reply_port, ln->st = ln->n->nn_stat; } - dev = (struct vether_device *) pi->po->np->nn->ln; + if (pi->po->np == master_node) + { + /* This device_open RPC was invoked on a port the .MASTER node, + so we don't care about light nodes (because the .MASTER node + does not have one). */ + extern struct port_bucket *port_bucket; + extern struct port_class *vdev_portclass; + + /* Create a new virtual device. */ + dev = (struct lnode *) add_vdev (name, sizeof (*dev), vdev_portclass, + port_bucket); + if (dev == NULL) + { + ports_port_deref (pi); + return D_NO_MEMORY; + } + } + else + dev = (struct vether_device *) pi->po->np->nn->ln; + /* check the mode */ openstat = pi->po->openstat; if ((openstat & O_READ) && !(mode & D_READ)) diff --git a/eth-multiplexer/multiplexer.c b/eth-multiplexer/multiplexer.c index 173a8f9..a87c9c4 100644 --- a/eth-multiplexer/multiplexer.c +++ b/eth-multiplexer/multiplexer.c @@ -162,9 +162,13 @@ main (int argc, char *argv[]) if (err) error (5, err, "Cannot create root node"); + err = new_node (NULL, &master_node); + if (err) + error (6, err, "Cannot create the .MASTER node"); + err = io_stat (root_file, &underlying_node_stat); if (err) - error (6, err, "Cannot stat underlying node"); + error (7, err, "Cannot stat underlying node"); struct stat stat = underlying_node_stat; /* If the underlying node is not a directory, increase its permissions */ diff --git a/eth-multiplexer/netfs_impl.c b/eth-multiplexer/netfs_impl.c index c70701b..875ff48 100644 --- a/eth-multiplexer/netfs_impl.c +++ b/eth-multiplexer/netfs_impl.c @@ -31,6 +31,10 @@ #include "vdev.h" #include "util.h" +/* The .MASTER node which will be used by static instances of + devnode. */ +struct node * master_node; + #define DIRENTS_CHUNK_SIZE (8*1024) /* Returned directory entries are aligned to blocks this many bytes long. * Must be a power of two. */ @@ -85,6 +89,18 @@ new_node (struct lnode *ln, struct node **np) struct node * lookup (char *name) { + if (strcmp(name, MASTER_NODE_NAME) == 0) + { + netfs_nref (master_node); + + /* netfs_attempt_lookup expects the returned node not to be + locked, while `master_node` might have been locked in the + previous lookups. */ + mutex_unlock (&master_node->lock); + + return master_node; + } + struct lnode *ln = (struct lnode *) lookup_dev_by_name (name); char *copied_name = malloc (strlen (name) + 1); @@ -276,10 +292,13 @@ netfs_get_dirents (struct iouser *cred, struct node *dir, if (!err) { data_p = *data; - if (first_entry < 2 + get_dev_num ()) + /* Count the .MASTER node, too. */ + if (first_entry < 2 + get_dev_num () + 1) { add_dirent (".", 2, DT_DIR); add_dirent ("..", 2, DT_DIR); + add_dirent (MASTER_NODE_NAME, 2, DT_CHR); + foreach_dev_do (add_each_dev); } diff --git a/eth-multiplexer/netfs_impl.h b/eth-multiplexer/netfs_impl.h index ec3b389..1c9662a 100644 --- a/eth-multiplexer/netfs_impl.h +++ b/eth-multiplexer/netfs_impl.h @@ -29,6 +29,10 @@ /* Shows the stat information in the node is invalid. */ #define NODE_STAT_INVALID 0x0001 +/* The name of the node which provides the pseudo master device port + functionality for static instances of devnode. */ +#define MASTER_NODE_NAME ".MASTER" + struct netnode { struct lnode *ln; @@ -47,6 +51,10 @@ struct lnode extern file_t root_file; volatile struct mapped_time_value *multiplexer_maptime; +/* The .MASTER node which will be used by static instances of + devnode. */ +extern struct node * master_node; + error_t new_node (struct lnode *ln, struct node **np); #endif -- 1.5.2.4