packvfs
view src/vnode.c @ 3:ef6c1472607f
jesus fucking christ that was easy... written a test prog "zipcat" to try out
zlib's contrib library "minizip", to list and read files out of zip archives
directly...
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Mon, 04 Nov 2013 06:46:17 +0200 |
parents | |
children |
line source
1 #include <string.h>
2 #include <pthread.h>
3 #include <alloca.h>
4 #include "pvfs.h"
5 #include "vnode.h"
7 static void add_child(struct vnode *parent, struct vnode *child);
8 static struct vnode *find_child(struct vnode *node, const char *name);
10 static struct vnode *root;
11 static struct vnode *cwd;
13 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
16 struct vnode *vnode_create(const char *name)
17 {
18 struct vnode *n;
20 if(!(n = calloc(1, sizeof *n)) || !(n->name = strdup(name))) {
21 pvfs_errno = ENOMEM;
22 return 0;
23 }
24 return n;
25 }
27 struct vnode *vnode_create_file(const char *name, PVFS_FILE *fp)
28 {
29 struct vnode *n;
31 if(!(n = vnode_create(name))) {
32 return 0;
33 }
34 n->type = VNODE_FILE;
35 n->obj = fp;
36 return n;
37 }
39 struct vnode *vnode_create_dir(const char *name, PVFS_DIR *dir)
40 {
41 struct vnode *n;
43 if(!(n = vnode_create(name))) {
44 return 0;
45 }
46 n->type = VNODE_DIR;
47 n->obj = dir;
48 return n;
49 }
51 void vnode_free(struct vnode *n)
52 {
53 free(n->name);
54 free(n);
55 }
57 static void destroy_tree_rec(struct vnode *tree)
58 {
59 struct vnode *c = tree->childlist;
60 while(c) {
61 struct vnode *tmp = c;
62 c = c->next;
63 vnode_destroy_tree(tmp);
64 }
65 vnode_free(tree);
66 }
68 void vnode_destroy_tree(struct vnode *tree)
69 {
70 pthread_mutex_lock(&mutex);
71 destroy_tree_rec(tree);
72 pthread_mutex_unlock(&mutex);
73 }
75 struct vnode *vnode_lookup(const char *const_path)
76 {
77 struct vnode *node, *res = 0;
78 char *path;
80 path = alloca(strlen(const_path) + 1);
81 strcpy(path, const_path);
83 pthread_mutex_lock(&mutex);
85 if(path[0] == '/') {
86 node = root;
87 path++;
88 } else {
89 node = cwd;
90 }
92 while(path && *path) {
93 char *slash = strchr(path + 1, '/');
94 if(slash) {
95 *slash = 0;
96 }
98 if(!(node = find_child(node, path))) {
99 pvfs_errno = ENOENT;
100 goto done;
101 }
102 path = slash ? slash + 1 : 0;
103 }
104 res = node;
106 done:
107 pthread_mutex_unlock(&mutex);
108 return res;
109 }
111 int vnode_chdir(const char *name)
112 {
113 struct vnode *node = vnode_lookup(name);
114 if(node) {
115 /* XXX race condition with delete tree, shouldn't really happen... */
116 pthread_mutex_lock(&mutex);
117 cwd = node;
118 pthread_mutex_unlock(&mutex);
119 return 0;
120 }
121 return -1;
122 }
124 int vnode_mkdir(struct vnode *parent, const char *name)
125 {
126 struct vnode *n;
128 if(!parent) {
129 if(root || strcmp(name, "/") != 0) {
130 pvfs_errno = EEXIST;
131 return -1;
132 }
133 }
135 if(!(n = vnode_create_dir(name, 0))) {
136 return -1;
137 }
138 add_child(parent, n);
139 return 0;
140 }
142 static void add_child(struct vnode *parent, struct vnode *child)
143 {
144 pthread_mutex_lock(&mutex);
146 child->parent = parent;
147 child->next = parent->childlist;
148 parent->childlist = child;
150 pthread_mutex_unlock(&mutex);
151 }
153 static struct vnode *find_child(struct vnode *node, const char *name)
154 {
155 struct vnode *c = node->childlist;
156 while(c) {
157 if(strcmp(c->name, name) == 0) {
158 return c;
159 }
160 c = c->next;
161 }
162 return 0;
163 }