Changeset 2c448fb in mainline
- Timestamp:
- 2008-02-27T22:49:48Z (17 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 7fe1f75
- Parents:
- 56976a17
- Location:
- uspace
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/libfs/libfs.c
r56976a17 r2c448fb 1 1 /* 2 * Copyright (c) 200 7Jakub Jermar2 * Copyright (c) 2008 Jakub Jermar 3 3 * All rights reserved. 4 4 * … … 41 41 #include <ipc/ipc.h> 42 42 #include <as.h> 43 #include <assert.h> 44 #include <dirent.h> 43 45 44 46 /** Register file system server. … … 121 123 } 122 124 125 void libfs_lookup(libfs_ops_t *ops, int fs_handle, ipc_callid_t rid, 126 ipc_call_t *request) 127 { 128 unsigned next = IPC_GET_ARG1(*request); 129 unsigned last = IPC_GET_ARG2(*request); 130 int dev_handle = IPC_GET_ARG3(*request); 131 int lflag = IPC_GET_ARG4(*request); 132 133 if (last < next) 134 last += PLB_SIZE; 135 136 void *cur = ops->root_get(); 137 void *tmp = ops->child_get(cur); 138 139 if (ops->plb_get_char(next) == '/') 140 next++; /* eat slash */ 141 142 char component[NAME_MAX + 1]; 143 int len = 0; 144 while (tmp && next <= last) { 145 146 /* collect the component */ 147 if (ops->plb_get_char(next) != '/') { 148 if (len + 1 == NAME_MAX) { 149 /* comopnent length overflow */ 150 ipc_answer_0(rid, ENAMETOOLONG); 151 return; 152 } 153 component[len++] = ops->plb_get_char(next); 154 next++; /* process next character */ 155 if (next <= last) 156 continue; 157 } 158 159 assert(len); 160 component[len] = '\0'; 161 next++; /* eat slash */ 162 len = 0; 163 164 /* match the component */ 165 while (tmp && !ops->match(tmp, component)) 166 tmp = ops->sibling_get(tmp); 167 168 /* handle miss: match amongst siblings */ 169 if (!tmp) { 170 if ((next > last) && (lflag & L_CREATE)) { 171 /* no components left and L_CREATE specified */ 172 if (!ops->is_directory(cur)) { 173 ipc_answer_0(rid, ENOTDIR); 174 return; 175 } 176 void *nodep = ops->create(lflag); 177 if (nodep) { 178 if (!ops->link(cur, nodep, component)) { 179 ops->destroy(nodep); 180 ipc_answer_0(rid, ENOSPC); 181 } else { 182 ipc_answer_5(rid, EOK, 183 fs_handle, dev_handle, 184 ops->index_get(nodep), 0, 185 ops->lnkcnt_get(nodep)); 186 } 187 } else { 188 ipc_answer_0(rid, ENOSPC); 189 } 190 return; 191 } 192 ipc_answer_0(rid, ENOENT); 193 return; 194 } 195 196 /* descend one level */ 197 cur = tmp; 198 tmp = ops->child_get(tmp); 199 } 200 201 /* handle miss: excessive components */ 202 if (!tmp && next <= last) { 203 if (lflag & L_CREATE) { 204 if (!ops->is_directory(cur)) { 205 ipc_answer_0(rid, ENOTDIR); 206 return; 207 } 208 209 /* collect next component */ 210 while (next <= last) { 211 if (ops->plb_get_char(next) == '/') { 212 /* more than one component */ 213 ipc_answer_0(rid, ENOENT); 214 return; 215 } 216 if (len + 1 == NAME_MAX) { 217 /* component length overflow */ 218 ipc_answer_0(rid, ENAMETOOLONG); 219 return; 220 } 221 component[len++] = ops->plb_get_char(next); 222 next++; /* process next character */ 223 } 224 assert(len); 225 component[len] = '\0'; 226 len = 0; 227 228 void *nodep = ops->create(lflag); 229 if (nodep) { 230 if (!ops->link(cur, nodep, component)) { 231 ops->destroy(nodep); 232 ipc_answer_0(rid, ENOSPC); 233 } else { 234 ipc_answer_5(rid, EOK, 235 fs_handle, dev_handle, 236 ops->index_get(nodep), 0, 237 ops->lnkcnt_get(nodep)); 238 } 239 } else { 240 ipc_answer_0(rid, ENOSPC); 241 } 242 return; 243 } 244 ipc_answer_0(rid, ENOENT); 245 return; 246 } 247 248 /* handle hit */ 249 if (lflag & L_DESTROY) { 250 unsigned old_lnkcnt = ops->lnkcnt_get(cur); 251 int res = ops->unlink(cur); 252 ipc_answer_5(rid, (ipcarg_t)res, fs_handle, dev_handle, 253 ops->index_get(cur), ops->size_get(cur), old_lnkcnt); 254 return; 255 } 256 if ((lflag & (L_CREATE | L_EXCLUSIVE)) == (L_CREATE | L_EXCLUSIVE)) { 257 ipc_answer_0(rid, EEXIST); 258 return; 259 } 260 if ((lflag & L_FILE) && (ops->is_directory(cur))) { 261 ipc_answer_0(rid, EISDIR); 262 return; 263 } 264 if ((lflag & L_DIRECTORY) && (ops->is_file(cur))) { 265 ipc_answer_0(rid, ENOTDIR); 266 return; 267 } 268 269 ipc_answer_5(rid, EOK, fs_handle, dev_handle, ops->index_get(cur), 270 ops->size_get(cur), ops->lnkcnt_get(cur)); 271 } 272 123 273 /** @} 124 274 */ -
uspace/lib/libfs/libfs.h
r56976a17 r2c448fb 43 43 44 44 typedef struct { 45 bool (* match)(void *, const char *); 46 void * (* create)(int); 47 void (* destroy)(void *); 48 bool (* link)(void *, void *, const char *); 49 int (* unlink)(void *); 50 unsigned long (* index_get)(void *); 51 unsigned long (* size_get)(void *); 52 unsigned (* lnkcnt_get)(void *); 53 void *(* child_get)(void *); 54 void *(* sibling_get)(void *); 55 void *(* root_get)(void); 56 char (* plb_get_char)(unsigned pos); 57 bool (* is_directory)(void *); 58 bool (* is_file)(void *); 59 } libfs_ops_t; 60 61 typedef struct { 45 62 int fs_handle; /**< File system handle. */ 46 63 ipcarg_t vfs_phonehash; /**< Initial VFS phonehash. */ … … 56 73 extern void node_del_mp(int, unsigned long); 57 74 extern bool node_is_mp(int, unsigned long); 75 76 extern void libfs_lookup(libfs_ops_t *, int, ipc_callid_t, ipc_call_t *); 77 58 78 #endif 59 79 -
uspace/srv/fs/tmpfs/tmpfs_ops.c
r56976a17 r2c448fb 46 46 #include <string.h> 47 47 #include <stdio.h> 48 #include <dirent.h>49 48 #include <assert.h> 50 49 #include <sys/types.h> 51 50 #include <libadt/hash_table.h> 52 51 #include <as.h> 52 #include <libfs.h> 53 53 54 54 #define min(a, b) ((a) < (b) ? (a) : (b)) 55 55 #define max(a, b) ((a) > (b) ? (a) : (b)) 56 56 57 #define PLB_GET_CHAR(i) (tmpfs_reg.plb_ro[(i) % PLB_SIZE])58 59 57 #define DENTRIES_BUCKETS 256 60 58 61 #define TMPFS_GET_INDEX(x) (((tmpfs_dentry_t *)(x))->index) 62 #define TMPFS_GET_LNKCNT(x) 1 59 /* 60 * For now, we don't distinguish between different dev_handles/instances. All 61 * requests resolve to the only instance, rooted in the following variable. 62 */ 63 static tmpfs_dentry_t *root; 64 65 /* 66 * Implementation of the libfs interface. 67 */ 63 68 64 69 /* Forward declarations of static functions. */ 65 static void *create_node(int); 66 static bool link_node(void *, void *, const char *); 67 static int unlink_node(void *); 68 static void destroy_node(void *); 70 static bool tmpfs_match(void *, const char *); 71 static void *tmpfs_create_node(int); 72 static bool tmpfs_link_node(void *, void *, const char *); 73 static int tmpfs_unlink_node(void *); 74 static void tmpfs_destroy_node(void *); 75 76 /* Implementation of helper functions. */ 77 static unsigned long tmpfs_index_get(void *nodep) 78 { 79 return ((tmpfs_dentry_t *) nodep)->index; 80 } 81 82 static unsigned long tmpfs_size_get(void *nodep) 83 { 84 return ((tmpfs_dentry_t *) nodep)->size; 85 } 86 87 static unsigned tmpfs_lnkcnt_get(void *nodep) 88 { 89 return 1; 90 } 91 92 static void *tmpfs_child_get(void *nodep) 93 { 94 return ((tmpfs_dentry_t *) nodep)->child; 95 } 96 97 static void *tmpfs_sibling_get(void *nodep) 98 { 99 return ((tmpfs_dentry_t *) nodep)->sibling; 100 } 101 102 static void *tmpfs_root_get(void) 103 { 104 return root; 105 } 106 107 static char tmpfs_plb_get_char(unsigned pos) 108 { 109 return tmpfs_reg.plb_ro[pos % PLB_SIZE]; 110 } 111 112 static bool tmpfs_is_directory(void *nodep) 113 { 114 return ((tmpfs_dentry_t *) nodep)->type == TMPFS_DIRECTORY; 115 } 116 117 static bool tmpfs_is_file(void *nodep) 118 { 119 return ((tmpfs_dentry_t *) nodep)->type == TMPFS_FILE; 120 } 121 122 /** libfs operations */ 123 libfs_ops_t tmpfs_libfs_ops = { 124 .match = tmpfs_match, 125 .create = tmpfs_create_node, 126 .destroy = tmpfs_destroy_node, 127 .link = tmpfs_link_node, 128 .unlink = tmpfs_unlink_node, 129 .index_get = tmpfs_index_get, 130 .size_get = tmpfs_size_get, 131 .lnkcnt_get = tmpfs_lnkcnt_get, 132 .child_get = tmpfs_child_get, 133 .sibling_get = tmpfs_sibling_get, 134 .root_get = tmpfs_root_get, 135 .plb_get_char = tmpfs_plb_get_char, 136 .is_directory = tmpfs_is_directory, 137 .is_file = tmpfs_is_file 138 }; 69 139 70 140 /** Hash table of all directory entries. */ 71 141 hash_table_t dentries; 72 142 143 /* Implementation of hash table interface. */ 73 144 static hash_index_t dentries_hash(unsigned long *key) 74 145 { … … 110 181 } 111 182 112 /*113 * For now, we don't distinguish between different dev_handles/instances. All114 * requests resolve to the only instance, rooted in the following variable.115 */116 static tmpfs_dentry_t *root;117 118 183 static bool tmpfs_init(void) 119 184 { 120 185 if (!hash_table_create(&dentries, DENTRIES_BUCKETS, 1, &dentries_ops)) 121 186 return false; 122 root = (tmpfs_dentry_t *) create_node(L_DIRECTORY);187 root = (tmpfs_dentry_t *) tmpfs_create_node(L_DIRECTORY); 123 188 return root != NULL; 124 189 } … … 131 196 * @return True on match, false otherwise. 132 197 */ 133 static bool match_component(void *nodep, const char *component)198 bool tmpfs_match(void *nodep, const char *component) 134 199 { 135 200 tmpfs_dentry_t *dentry = (tmpfs_dentry_t *) nodep; … … 138 203 } 139 204 140 void * create_node(int lflag)205 void *tmpfs_create_node(int lflag) 141 206 { 142 207 assert((lflag & L_FILE) ^ (lflag & L_DIRECTORY)); … … 158 223 } 159 224 160 bool link_node(void *prnt, void *chld, const char *nm)225 bool tmpfs_link_node(void *prnt, void *chld, const char *nm) 161 226 { 162 227 tmpfs_dentry_t *parentp = (tmpfs_dentry_t *) prnt; … … 186 251 } 187 252 188 int unlink_node(void *nodeptr)253 int tmpfs_unlink_node(void *nodeptr) 189 254 { 190 255 tmpfs_dentry_t *dentry = (tmpfs_dentry_t *)nodeptr; … … 214 279 } 215 280 216 void destroy_node(void *nodep)281 void tmpfs_destroy_node(void *nodep) 217 282 { 218 283 tmpfs_dentry_t *dentry = (tmpfs_dentry_t *) nodep; … … 231 296 void tmpfs_lookup(ipc_callid_t rid, ipc_call_t *request) 232 297 { 233 unsigned next = IPC_GET_ARG1(*request); 234 unsigned last = IPC_GET_ARG2(*request); 235 int dev_handle = IPC_GET_ARG3(*request); 236 int lflag = IPC_GET_ARG4(*request); 237 238 if (last < next) 239 last += PLB_SIZE; 240 241 /* 242 * Initialize TMPFS. 243 */ 298 /* Initialize TMPFS. */ 244 299 if (!root && !tmpfs_init()) { 245 300 ipc_answer_0(rid, ENOMEM); 246 301 return; 247 302 } 248 249 tmpfs_dentry_t *dtmp = root->child; 250 tmpfs_dentry_t *dcur = root; 251 252 if (PLB_GET_CHAR(next) == '/') 253 next++; /* eat slash */ 254 255 char component[NAME_MAX + 1]; 256 int len = 0; 257 while (dtmp && next <= last) { 258 259 /* collect the component */ 260 if (PLB_GET_CHAR(next) != '/') { 261 if (len + 1 == NAME_MAX) { 262 /* comopnent length overflow */ 263 ipc_answer_0(rid, ENAMETOOLONG); 264 return; 265 } 266 component[len++] = PLB_GET_CHAR(next); 267 next++; /* process next character */ 268 if (next <= last) 269 continue; 270 } 271 272 assert(len); 273 component[len] = '\0'; 274 next++; /* eat slash */ 275 len = 0; 276 277 /* match the component */ 278 while (dtmp && !match_component(dtmp, component)) 279 dtmp = dtmp->sibling; 280 281 /* handle miss: match amongst siblings */ 282 if (!dtmp) { 283 if ((next > last) && (lflag & L_CREATE)) { 284 /* no components left and L_CREATE specified */ 285 if (dcur->type != TMPFS_DIRECTORY) { 286 ipc_answer_0(rid, ENOTDIR); 287 return; 288 } 289 void *nodep = create_node(lflag); 290 if (nodep) { 291 if (!link_node(dcur, nodep, 292 component)) { 293 destroy_node(nodep); 294 ipc_answer_0(rid, ENOSPC); 295 } else { 296 ipc_answer_5(rid, EOK, 297 tmpfs_reg.fs_handle, 298 dev_handle, 299 TMPFS_GET_INDEX(nodep), 0, 300 TMPFS_GET_LNKCNT(nodep)); 301 } 302 } else { 303 ipc_answer_0(rid, ENOSPC); 304 } 305 return; 306 } 307 ipc_answer_0(rid, ENOENT); 308 return; 309 } 310 311 /* descend one level */ 312 dcur = dtmp; 313 dtmp = dtmp->child; 314 } 315 316 /* handle miss: excessive components */ 317 if (!dtmp && next <= last) { 318 if (lflag & L_CREATE) { 319 if (dcur->type != TMPFS_DIRECTORY) { 320 ipc_answer_0(rid, ENOTDIR); 321 return; 322 } 323 324 /* collect next component */ 325 while (next <= last) { 326 if (PLB_GET_CHAR(next) == '/') { 327 /* more than one component */ 328 ipc_answer_0(rid, ENOENT); 329 return; 330 } 331 if (len + 1 == NAME_MAX) { 332 /* component length overflow */ 333 ipc_answer_0(rid, ENAMETOOLONG); 334 return; 335 } 336 component[len++] = PLB_GET_CHAR(next); 337 next++; /* process next character */ 338 } 339 assert(len); 340 component[len] = '\0'; 341 len = 0; 342 343 void *nodep = create_node(lflag); 344 if (nodep) { 345 if (!link_node(dcur, nodep, component)) { 346 destroy_node(nodep); 347 ipc_answer_0(rid, ENOSPC); 348 } else { 349 ipc_answer_5(rid, EOK, 350 tmpfs_reg.fs_handle, 351 dev_handle, TMPFS_GET_INDEX(nodep), 352 0, TMPFS_GET_LNKCNT(nodep)); 353 } 354 } else { 355 ipc_answer_0(rid, ENOSPC); 356 } 357 return; 358 } 359 ipc_answer_0(rid, ENOENT); 360 return; 361 } 362 363 /* handle hit */ 364 if (lflag & L_DESTROY) { 365 unsigned old_lnkcnt = TMPFS_GET_LNKCNT(dcur); 366 int res = unlink_node(dcur); 367 ipc_answer_5(rid, (ipcarg_t)res, tmpfs_reg.fs_handle, 368 dev_handle, dcur->index, dcur->size, old_lnkcnt); 369 return; 370 } 371 if ((lflag & (L_CREATE | L_EXCLUSIVE)) == (L_CREATE | L_EXCLUSIVE)) { 372 ipc_answer_0(rid, EEXIST); 373 return; 374 } 375 if ((lflag & L_FILE) && (dcur->type != TMPFS_FILE)) { 376 ipc_answer_0(rid, EISDIR); 377 return; 378 } 379 if ((lflag & L_DIRECTORY) && (dcur->type != TMPFS_DIRECTORY)) { 380 ipc_answer_0(rid, ENOTDIR); 381 return; 382 } 383 384 ipc_answer_5(rid, EOK, tmpfs_reg.fs_handle, dev_handle, dcur->index, 385 dcur->size, TMPFS_GET_LNKCNT(dcur)); 303 libfs_lookup(&tmpfs_libfs_ops, tmpfs_reg.fs_handle, rid, request); 386 304 } 387 305 … … 562 480 tmpfs_dentry_t *dentry = hash_table_get_instance(hlp, tmpfs_dentry_t, 563 481 dh_link); 564 destroy_node(dentry);482 tmpfs_destroy_node(dentry); 565 483 ipc_answer_0(rid, EOK); 566 484 }
Note:
See TracChangeset
for help on using the changeset viewer.