Changeset 2c448fb in mainline for uspace/lib/libfs/libfs.c
- 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
- File:
-
- 1 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 */
Note:
See TracChangeset
for help on using the changeset viewer.