summaryrefslogtreecommitdiff
path: root/lnode.c
diff options
context:
space:
mode:
authorSergiu Ivanov <unlimitedscolobb@gmail.com>2008-09-07 22:36:45 +0300
committerSergiu Ivanov <unlimitedscolobb@gmail.com>2008-09-07 22:36:45 +0300
commitdd5f567d830707ca1530e8e3c2ef7b1c6b4b3862 (patch)
tree0b468f7df0a4aaba9a4c09762825932ac530a4f5 /lnode.c
parent13fa6563250dcd4b2d1a54f15aba1bb7d8aace28 (diff)
Added proxy nodes, optimized node management policy
Now, when 'file,,x' is requested, nsmux will create a proxy node and will set the translator 'x' on this node, not on the real filesystem node. Also, nsmux will not create nodes for simple file looks, instead it will simply return the port to the required file, thus avoiding the necessity to handle IO operations inside itself.
Diffstat (limited to 'lnode.c')
-rw-r--r--lnode.c168
1 files changed, 110 insertions, 58 deletions
diff --git a/lnode.c b/lnode.c
index aed83a0f5..2e6d34eb5 100644
--- a/lnode.c
+++ b/lnode.c
@@ -5,7 +5,7 @@
/*----------------------------------------------------------------------------*/
/*Based on the code of unionfs translator.*/
/*----------------------------------------------------------------------------*/
-/*Copyright (C) 2001, 2002, 2005 Free Software Foundation, Inc.
+/*Copyright (C) 2001, 2002, 2005, 2008 Free Software Foundation, Inc.
Written by Sergiu Ivanov <unlimitedscolobb@gmail.com>.
This program is free software; you can redistribute it and/or
@@ -29,6 +29,7 @@
/*----------------------------------------------------------------------------*/
#include "lnode.h"
#include "debug.h"
+#include "node.h"
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
@@ -138,9 +139,19 @@ lnode_destroy
/*Destroy the name of the node*/
free(node->name);
- /*If there is a list of translators*/
- if(node->trans)
- free(node->trans);
+ /*While the list of proxies has not been freed*/
+ node_list_t p;
+ for(p = node->proxies; p;)
+ {
+ /*shift the pointer to the head of the list forward*/
+ node->proxies = node->proxies->next;
+
+ /*drop the current cell in the list*/
+ free(p);
+
+ /*store the current proxy*/
+ p = node->proxies;
+ }
/*Destroy the node itself*/
free(node);
@@ -307,70 +318,111 @@ lnode_uninstall
node->next->prevp = &node->next;
}/*lnode_uninstall*/
/*----------------------------------------------------------------------------*/
-/*Constructs a list of translators that were set on the ancestors of `node`*/
+/*Makes the specified lnode aware of another proxy. Both `node` and `proxy`
+ must be locked*/
error_t
-lnode_list_translators
+lnode_add_proxy
(
lnode_t * node,
- char ** trans, /*the malloced list of 0-separated strings*/
- size_t * ntrans /*the number of elements in `trans`*/
+ node_t * proxy
)
{
- /*The size of block of memory for the list of translators*/
- size_t sz = 0;
-
- /*Used for tracing the lineage of `node`*/
- lnode_t * ln = node;
-
- /*Used in computing the lengths of lists of translators in every node
- we will go through and for constructing the final list of translators*/
- char * p;
-
- /*The current position in *data (used in filling out the list of
- translators)*/
- char * transp;
-
- /*The length of the current translator name*/
- size_t complen;
-
- size_t i;
-
- /*Trace the lineage of the `node` (including itself) and compute the
- total length of the list of translators*/
- for(; ln; sz += ln->translen, ln = ln->dir);
-
- /*Try to allocate a block of memory sufficient for storing the list of
- translators*/
- *trans = malloc(sz);
- if(!*trans)
+ /*TODO: Make the list of proxies finite*/
+
+ /*Create an new cell in the list of proxies*/
+ node_list_t p = malloc(sizeof(node_list_t));
+ if(!p)
return ENOMEM;
+
+ /*If the supplied node references an lnode already
+ (this should always happen, though)*/
+ if(proxy->nn->lnode)
+ /*remove the reference held by the node to that lnode*/
+ lnode_ref_remove(proxy->nn->lnode);
+
+ /*Connect the proxy to the lnode*/
+ proxy->nn->lnode = node;
+
+ /*Store the pointer to the proxy in the new cell*/
+ p->node = proxy;
+
+ /*Add the new cell to the list of proxies*/
+ p->next = node->proxies;
+ node->proxies = p;
- /*No translators at first*/
- *ntrans = 0;
+ /*Count a new reference to this lnode*/
+ lnode_ref_add(node);
- /*Again trace the lineage of the `node` (including itself)*/
- for(transp = *trans + sz, ln = node; ln; ln = ln->dir)
+ /*Everything is OK here*/
+ return 0;
+ }/*lnode_add_proxy*/
+/*----------------------------------------------------------------------------*/
+/*Removes the specified proxy from the list of proxies of the supplied lnode.
+ `proxy` must not be locked*/
+void
+lnode_remove_proxy
+ (
+ lnode_t * node,
+ node_t * proxy
+ )
+ {
+ /*A pointer to a cell in the list of proxies*/
+ node_list_t p;
+
+ /*Lock the lnode*/
+ mutex_lock(&node->lock);
+
+ /*If the first cell in the list contains a reference to `proxy`*/
+ if(node->proxies->node == proxy)
{
- /*Go through each translator name in the list of names*/
- for(i = 0, p = ln->trans + ln->translen - 2; i < ln->ntrans; ++i)
- {
- /*position p at the beginning of the current component and
- compute its length at the same time*/
- for(complen = 0; *p; --p, ++complen);
- --p;
-
- /*move the current position backwards*/
- transp -= complen + 1;
+ /*store a pointer to the head of the list*/
+ p = node->proxies;
+
+ /*shift the head of the list forward*/
+ node->proxies = node->proxies->next;
+
+ /*destroy the former head*/
+ free(p);
+
+ /*remove a reference from the supplied lnode*/
+ lnode_ref_remove(node);
+
+ /*stop right here*/
+ mutex_unlock(&node->lock);
+ return;
+ }
- /*copy the current translator name into the list*/
- strcpy(transp, p + 2);
-
- /*we've got another translator*/
- ++*ntrans;
- }
+ /*Another pointer to a cell in the list*/
+ node_list_t q;
+
+ /*Go through the list of proxy nodes of the given lnode*/
+ for(p = node->proxies; p->next; p = p->next)
+ {
+ /*If the next cell does not contain a reference to the same node,
+ as specified in the parameter, skip this entry*/
+ if(p->next->node != proxy)
+ continue;
+
+ /*store a copy of the next element*/
+ q = p->next;
+
+ /*unregister the next element from the list*/
+ p->next = q->next;
+
+ /*remove the unregistered element*/
+ free(q);
+
+ /*stop looping*/
+ break;
}
+
+ /*Remove a reference from the supplied lnode*/
+ lnode_ref_remove(node);
- /*Everything OK*/
- return 0;
- }/*lnode_list_translators*/
+
+ /*Unlock the node*/
+ mutex_unlock(&node->lock);
+
+ return;
+ }/*lnode_remove_proxy*/
/*----------------------------------------------------------------------------*/