packvfs

annotate 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
rev   line source
nuclear@0 1 #include <string.h>
nuclear@0 2 #include <pthread.h>
nuclear@0 3 #include <alloca.h>
nuclear@0 4 #include "pvfs.h"
nuclear@0 5 #include "vnode.h"
nuclear@0 6
nuclear@0 7 static void add_child(struct vnode *parent, struct vnode *child);
nuclear@0 8 static struct vnode *find_child(struct vnode *node, const char *name);
nuclear@0 9
nuclear@0 10 static struct vnode *root;
nuclear@0 11 static struct vnode *cwd;
nuclear@0 12
nuclear@0 13 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
nuclear@0 14
nuclear@0 15
nuclear@0 16 struct vnode *vnode_create(const char *name)
nuclear@0 17 {
nuclear@0 18 struct vnode *n;
nuclear@0 19
nuclear@0 20 if(!(n = calloc(1, sizeof *n)) || !(n->name = strdup(name))) {
nuclear@0 21 pvfs_errno = ENOMEM;
nuclear@0 22 return 0;
nuclear@0 23 }
nuclear@0 24 return n;
nuclear@0 25 }
nuclear@0 26
nuclear@0 27 struct vnode *vnode_create_file(const char *name, PVFS_FILE *fp)
nuclear@0 28 {
nuclear@0 29 struct vnode *n;
nuclear@0 30
nuclear@0 31 if(!(n = vnode_create(name))) {
nuclear@0 32 return 0;
nuclear@0 33 }
nuclear@0 34 n->type = VNODE_FILE;
nuclear@0 35 n->obj = fp;
nuclear@0 36 return n;
nuclear@0 37 }
nuclear@0 38
nuclear@0 39 struct vnode *vnode_create_dir(const char *name, PVFS_DIR *dir)
nuclear@0 40 {
nuclear@0 41 struct vnode *n;
nuclear@0 42
nuclear@0 43 if(!(n = vnode_create(name))) {
nuclear@0 44 return 0;
nuclear@0 45 }
nuclear@0 46 n->type = VNODE_DIR;
nuclear@0 47 n->obj = dir;
nuclear@0 48 return n;
nuclear@0 49 }
nuclear@0 50
nuclear@0 51 void vnode_free(struct vnode *n)
nuclear@0 52 {
nuclear@0 53 free(n->name);
nuclear@0 54 free(n);
nuclear@0 55 }
nuclear@0 56
nuclear@0 57 static void destroy_tree_rec(struct vnode *tree)
nuclear@0 58 {
nuclear@0 59 struct vnode *c = tree->childlist;
nuclear@0 60 while(c) {
nuclear@0 61 struct vnode *tmp = c;
nuclear@0 62 c = c->next;
nuclear@0 63 vnode_destroy_tree(tmp);
nuclear@0 64 }
nuclear@0 65 vnode_free(tree);
nuclear@0 66 }
nuclear@0 67
nuclear@0 68 void vnode_destroy_tree(struct vnode *tree)
nuclear@0 69 {
nuclear@0 70 pthread_mutex_lock(&mutex);
nuclear@0 71 destroy_tree_rec(tree);
nuclear@0 72 pthread_mutex_unlock(&mutex);
nuclear@0 73 }
nuclear@0 74
nuclear@0 75 struct vnode *vnode_lookup(const char *const_path)
nuclear@0 76 {
nuclear@0 77 struct vnode *node, *res = 0;
nuclear@0 78 char *path;
nuclear@0 79
nuclear@0 80 path = alloca(strlen(const_path) + 1);
nuclear@0 81 strcpy(path, const_path);
nuclear@0 82
nuclear@0 83 pthread_mutex_lock(&mutex);
nuclear@0 84
nuclear@0 85 if(path[0] == '/') {
nuclear@0 86 node = root;
nuclear@0 87 path++;
nuclear@0 88 } else {
nuclear@0 89 node = cwd;
nuclear@0 90 }
nuclear@0 91
nuclear@0 92 while(path && *path) {
nuclear@0 93 char *slash = strchr(path + 1, '/');
nuclear@0 94 if(slash) {
nuclear@0 95 *slash = 0;
nuclear@0 96 }
nuclear@0 97
nuclear@0 98 if(!(node = find_child(node, path))) {
nuclear@0 99 pvfs_errno = ENOENT;
nuclear@0 100 goto done;
nuclear@0 101 }
nuclear@0 102 path = slash ? slash + 1 : 0;
nuclear@0 103 }
nuclear@0 104 res = node;
nuclear@0 105
nuclear@0 106 done:
nuclear@0 107 pthread_mutex_unlock(&mutex);
nuclear@0 108 return res;
nuclear@0 109 }
nuclear@0 110
nuclear@0 111 int vnode_chdir(const char *name)
nuclear@0 112 {
nuclear@0 113 struct vnode *node = vnode_lookup(name);
nuclear@0 114 if(node) {
nuclear@0 115 /* XXX race condition with delete tree, shouldn't really happen... */
nuclear@0 116 pthread_mutex_lock(&mutex);
nuclear@0 117 cwd = node;
nuclear@0 118 pthread_mutex_unlock(&mutex);
nuclear@0 119 return 0;
nuclear@0 120 }
nuclear@0 121 return -1;
nuclear@0 122 }
nuclear@0 123
nuclear@0 124 int vnode_mkdir(struct vnode *parent, const char *name)
nuclear@0 125 {
nuclear@0 126 struct vnode *n;
nuclear@0 127
nuclear@0 128 if(!parent) {
nuclear@0 129 if(root || strcmp(name, "/") != 0) {
nuclear@0 130 pvfs_errno = EEXIST;
nuclear@0 131 return -1;
nuclear@0 132 }
nuclear@0 133 }
nuclear@0 134
nuclear@0 135 if(!(n = vnode_create_dir(name, 0))) {
nuclear@0 136 return -1;
nuclear@0 137 }
nuclear@0 138 add_child(parent, n);
nuclear@0 139 return 0;
nuclear@0 140 }
nuclear@0 141
nuclear@0 142 static void add_child(struct vnode *parent, struct vnode *child)
nuclear@0 143 {
nuclear@0 144 pthread_mutex_lock(&mutex);
nuclear@0 145
nuclear@0 146 child->parent = parent;
nuclear@0 147 child->next = parent->childlist;
nuclear@0 148 parent->childlist = child;
nuclear@0 149
nuclear@0 150 pthread_mutex_unlock(&mutex);
nuclear@0 151 }
nuclear@0 152
nuclear@0 153 static struct vnode *find_child(struct vnode *node, const char *name)
nuclear@0 154 {
nuclear@0 155 struct vnode *c = node->childlist;
nuclear@0 156 while(c) {
nuclear@0 157 if(strcmp(c->name, name) == 0) {
nuclear@0 158 return c;
nuclear@0 159 }
nuclear@0 160 c = c->next;
nuclear@0 161 }
nuclear@0 162 return 0;
nuclear@0 163 }