summaryrefslogtreecommitdiff
path: root/unionfs/node.h
blob: 41ae43adb31750786cb0f720d50ba3a6ec52a5b1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/* Hurd unionfs
   Copyright (C) 2001, 2002 Free Software Foundation, Inc.
   Written by Moritz Schulte <moritz@duesseldorf.ccc.de>.

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License as
   published by the Free Software Foundation; either version 2 of the
   License, or * (at your option) any later version.
 
   This program is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.
 
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
   USA.  */

/* node management.  */

#ifndef INCLUDED_NODE_H
#define INCLUDED_NODE_H

#include <error.h>
#include <sys/stat.h>
#include <hurd/netfs.h>

typedef struct node node_t;

#include "lnode.h"

/* per-ulfs data for each node.  */
struct node_ulfs
{
  int flags;			/* Flags associated for this
				   underlying filesystem.  */
  file_t port;			/* A port to the underlying
				   filesystem.  */
};
typedef struct node_ulfs node_ulfs_t;

/* Flags.  */

/* The according port should not be updated.  */
#define FLAG_NODE_ULFS_FIXED 0x00000001

struct netnode
{
  lnode_t *lnode;		/* A reference to the according light
				   node.  */
  int flags;			/* Associated flags.  */
  node_ulfs_t *ulfs;		/* Array holding data for each
				   underlying filesystem.  */
  int ulfs_num;			/* Number of entries in ULFS.  */
  node_t *ncache_next;
  node_t *ncache_prev;
};
typedef struct netnode netnode_t;

/* Flags.  */
#define FLAG_NODE_INVALIDATE    0x00000001
#define FLAG_NODE_ULFS_UPTODATE 0x00000002

typedef struct node_dirent
{
  struct dirent *dirent;
  struct node_dirent *next;
} node_dirent_t;

/* Create a new node, derived from a light node, add a reference to
   the light node.  */
error_t node_create (lnode_t *lnode, node_t **node);

/* Destroy a node, remove one reference from the associated light
   node.  */
void node_destroy (node_t *node);

/* Make sure that all ports to the underlying filesystems of NODE,
   which must be locked, are uptodate.  */
error_t node_update (node_t *node);

/* Create a directory named NAME beneath DIR on all the (writable) underlying
   filesystems.  */
error_t node_dir_create (node_t *dir, char *name, mode_t mode);

/* Remove all directory named NAME beneath DIR on all underlying filesystems.
   Fails if we cannot remove all the directories.  */
error_t node_dir_remove (node_t *dir, char *name);

/* Remove all files named NAME beneath DIR on the underlying filesystems
   with FLAGS as openflags.  */
error_t node_unlink_file (node_t *dir, char *name);

/* Lookup a file named NAME beneath DIR on the underlying filesystems
   with FLAGS as openflags.  Return the first port successfully looked
   up in *PORT and according stat information in *STAT.  */
error_t node_lookup_file (node_t *dir, char *name, int flags,
			  file_t *port, struct stat *stat);

/* Initialize per-ulfs data structures for NODE.  The ulfs_lock must
   be held by the caller.  */
error_t node_ulfs_init (node_t *node);

/* Read the merged directory entries from NODE, which must be
   locked, into *DIRENTS.  */
error_t node_entries_get (node_t *node, node_dirent_t **dirents);

/* Free DIRENTS.  */
void node_entries_free (node_dirent_t *dirents);

/* Create the root node (and it's according lnode) and store it in
   *ROOT_NODE.  */
error_t node_create_root (node_t **root_node);

/* Initialize the ports to the underlying filesystems for the root
   node.  */
error_t node_init_root (node_t *node);

/* Return non-zero, if NODE is the root node.  */
#define node_is_root(node) (node)->nn->lnode->dir ? 0 : 1

/* Iterate over the per-ulfs data in NODE, which must be locked by the
   caller.  */
#define node_ulfs_iterate_unlocked(node)              \
  for (node_ulfs_t *node_ulfs = (node)->nn->ulfs;     \
       node_ulfs < (node)->nn->ulfs + (node)->nn->ulfs_num;  \
       node_ulfs++)

#define node_ulfs_iterate_reverse_unlocked(node)			\
  for (node_ulfs_t *node_ulfs = (node)->nn->ulfs + (node)->nn->ulfs_num - 1;\
       node_ulfs >= (node)->nn->ulfs;					\
       node_ulfs--)

#endif