packvfs
diff src/vnode.c @ 0:df5e9ee65a50
packvfs initial commit
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Fri, 02 Aug 2013 06:03:38 +0300 |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/vnode.c Fri Aug 02 06:03:38 2013 +0300 1.3 @@ -0,0 +1,163 @@ 1.4 +#include <string.h> 1.5 +#include <pthread.h> 1.6 +#include <alloca.h> 1.7 +#include "pvfs.h" 1.8 +#include "vnode.h" 1.9 + 1.10 +static void add_child(struct vnode *parent, struct vnode *child); 1.11 +static struct vnode *find_child(struct vnode *node, const char *name); 1.12 + 1.13 +static struct vnode *root; 1.14 +static struct vnode *cwd; 1.15 + 1.16 +static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 1.17 + 1.18 + 1.19 +struct vnode *vnode_create(const char *name) 1.20 +{ 1.21 + struct vnode *n; 1.22 + 1.23 + if(!(n = calloc(1, sizeof *n)) || !(n->name = strdup(name))) { 1.24 + pvfs_errno = ENOMEM; 1.25 + return 0; 1.26 + } 1.27 + return n; 1.28 +} 1.29 + 1.30 +struct vnode *vnode_create_file(const char *name, PVFS_FILE *fp) 1.31 +{ 1.32 + struct vnode *n; 1.33 + 1.34 + if(!(n = vnode_create(name))) { 1.35 + return 0; 1.36 + } 1.37 + n->type = VNODE_FILE; 1.38 + n->obj = fp; 1.39 + return n; 1.40 +} 1.41 + 1.42 +struct vnode *vnode_create_dir(const char *name, PVFS_DIR *dir) 1.43 +{ 1.44 + struct vnode *n; 1.45 + 1.46 + if(!(n = vnode_create(name))) { 1.47 + return 0; 1.48 + } 1.49 + n->type = VNODE_DIR; 1.50 + n->obj = dir; 1.51 + return n; 1.52 +} 1.53 + 1.54 +void vnode_free(struct vnode *n) 1.55 +{ 1.56 + free(n->name); 1.57 + free(n); 1.58 +} 1.59 + 1.60 +static void destroy_tree_rec(struct vnode *tree) 1.61 +{ 1.62 + struct vnode *c = tree->childlist; 1.63 + while(c) { 1.64 + struct vnode *tmp = c; 1.65 + c = c->next; 1.66 + vnode_destroy_tree(tmp); 1.67 + } 1.68 + vnode_free(tree); 1.69 +} 1.70 + 1.71 +void vnode_destroy_tree(struct vnode *tree) 1.72 +{ 1.73 + pthread_mutex_lock(&mutex); 1.74 + destroy_tree_rec(tree); 1.75 + pthread_mutex_unlock(&mutex); 1.76 +} 1.77 + 1.78 +struct vnode *vnode_lookup(const char *const_path) 1.79 +{ 1.80 + struct vnode *node, *res = 0; 1.81 + char *path; 1.82 + 1.83 + path = alloca(strlen(const_path) + 1); 1.84 + strcpy(path, const_path); 1.85 + 1.86 + pthread_mutex_lock(&mutex); 1.87 + 1.88 + if(path[0] == '/') { 1.89 + node = root; 1.90 + path++; 1.91 + } else { 1.92 + node = cwd; 1.93 + } 1.94 + 1.95 + while(path && *path) { 1.96 + char *slash = strchr(path + 1, '/'); 1.97 + if(slash) { 1.98 + *slash = 0; 1.99 + } 1.100 + 1.101 + if(!(node = find_child(node, path))) { 1.102 + pvfs_errno = ENOENT; 1.103 + goto done; 1.104 + } 1.105 + path = slash ? slash + 1 : 0; 1.106 + } 1.107 + res = node; 1.108 + 1.109 +done: 1.110 + pthread_mutex_unlock(&mutex); 1.111 + return res; 1.112 +} 1.113 + 1.114 +int vnode_chdir(const char *name) 1.115 +{ 1.116 + struct vnode *node = vnode_lookup(name); 1.117 + if(node) { 1.118 + /* XXX race condition with delete tree, shouldn't really happen... */ 1.119 + pthread_mutex_lock(&mutex); 1.120 + cwd = node; 1.121 + pthread_mutex_unlock(&mutex); 1.122 + return 0; 1.123 + } 1.124 + return -1; 1.125 +} 1.126 + 1.127 +int vnode_mkdir(struct vnode *parent, const char *name) 1.128 +{ 1.129 + struct vnode *n; 1.130 + 1.131 + if(!parent) { 1.132 + if(root || strcmp(name, "/") != 0) { 1.133 + pvfs_errno = EEXIST; 1.134 + return -1; 1.135 + } 1.136 + } 1.137 + 1.138 + if(!(n = vnode_create_dir(name, 0))) { 1.139 + return -1; 1.140 + } 1.141 + add_child(parent, n); 1.142 + return 0; 1.143 +} 1.144 + 1.145 +static void add_child(struct vnode *parent, struct vnode *child) 1.146 +{ 1.147 + pthread_mutex_lock(&mutex); 1.148 + 1.149 + child->parent = parent; 1.150 + child->next = parent->childlist; 1.151 + parent->childlist = child; 1.152 + 1.153 + pthread_mutex_unlock(&mutex); 1.154 +} 1.155 + 1.156 +static struct vnode *find_child(struct vnode *node, const char *name) 1.157 +{ 1.158 + struct vnode *c = node->childlist; 1.159 + while(c) { 1.160 + if(strcmp(c->name, name) == 0) { 1.161 + return c; 1.162 + } 1.163 + c = c->next; 1.164 + } 1.165 + return 0; 1.166 +}