summaryrefslogtreecommitdiff
path: root/lnode.c
diff options
context:
space:
mode:
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*/
/*----------------------------------------------------------------------------*/