Rev 2847 | Rev 2857 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 2847 | Rev 2852 | ||
|---|---|---|---|
| Line 148... | Line 148... | ||
| 148 | if (last < next) |
148 | if (last < next) |
| 149 | last += PLB_SIZE; |
149 | last += PLB_SIZE; |
| 150 | 150 | ||
| 151 | void *par = NULL; |
151 | void *par = NULL; |
| 152 | void *cur = ops->root_get(dev_handle); |
152 | void *cur = ops->root_get(dev_handle); |
| - | 153 | void *tmp = NULL; |
|
| 153 | 154 | ||
| 154 | if (ops->plb_get_char(next) == '/') |
155 | if (ops->plb_get_char(next) == '/') |
| 155 | next++; /* eat slash */ |
156 | next++; /* eat slash */ |
| 156 | 157 | ||
| 157 | while (ops->has_children(cur) && next <= last) { |
158 | while (ops->has_children(cur) && next <= last) { |
| 158 | void *tmp; |
- | |
| 159 | - | ||
| 160 | /* collect the component */ |
159 | /* collect the component */ |
| 161 | len = 0; |
160 | len = 0; |
| 162 | while ((ops->plb_get_char(next) != '/') && (next <= last)) { |
161 | while ((ops->plb_get_char(next) != '/') && (next <= last)) { |
| 163 | if (len + 1 == NAME_MAX) { |
162 | if (len + 1 == NAME_MAX) { |
| 164 | /* comopnent length overflow */ |
163 | /* comopnent length overflow */ |
| 165 | ipc_answer_0(rid, ENAMETOOLONG); |
164 | ipc_answer_0(rid, ENAMETOOLONG); |
| 166 | return; |
165 | goto out; |
| 167 | } |
166 | } |
| 168 | component[len++] = ops->plb_get_char(next); |
167 | component[len++] = ops->plb_get_char(next); |
| 169 | next++; /* process next character */ |
168 | next++; /* process next character */ |
| 170 | } |
169 | } |
| 171 | 170 | ||
| Line 179... | Line 178... | ||
| 179 | /* handle miss: match amongst siblings */ |
178 | /* handle miss: match amongst siblings */ |
| 180 | if (!tmp) { |
179 | if (!tmp) { |
| 181 | if (next <= last) { |
180 | if (next <= last) { |
| 182 | /* there are unprocessed components */ |
181 | /* there are unprocessed components */ |
| 183 | ipc_answer_0(rid, ENOENT); |
182 | ipc_answer_0(rid, ENOENT); |
| 184 | return; |
183 | goto out; |
| 185 | } |
184 | } |
| 186 | /* miss in the last component */ |
185 | /* miss in the last component */ |
| 187 | if (lflag & (L_CREATE | L_LINK)) { |
186 | if (lflag & (L_CREATE | L_LINK)) { |
| 188 | /* request to create a new link */ |
187 | /* request to create a new link */ |
| 189 | if (!ops->is_directory(cur)) { |
188 | if (!ops->is_directory(cur)) { |
| 190 | ipc_answer_0(rid, ENOTDIR); |
189 | ipc_answer_0(rid, ENOTDIR); |
| 191 | return; |
190 | goto out; |
| 192 | } |
191 | } |
| 193 | void *nodep; |
192 | void *nodep; |
| 194 | if (lflag & L_CREATE) |
193 | if (lflag & L_CREATE) |
| 195 | nodep = ops->create(lflag); |
194 | nodep = ops->create(lflag); |
| 196 | else |
195 | else |
| Line 205... | Line 204... | ||
| 205 | ipc_answer_5(rid, EOK, |
204 | ipc_answer_5(rid, EOK, |
| 206 | fs_handle, dev_handle, |
205 | fs_handle, dev_handle, |
| 207 | ops->index_get(nodep), |
206 | ops->index_get(nodep), |
| 208 | ops->size_get(nodep), |
207 | ops->size_get(nodep), |
| 209 | ops->lnkcnt_get(nodep)); |
208 | ops->lnkcnt_get(nodep)); |
| - | 209 | ops->node_put(nodep); |
|
| 210 | } |
210 | } |
| 211 | } else { |
211 | } else { |
| 212 | ipc_answer_0(rid, ENOSPC); |
212 | ipc_answer_0(rid, ENOSPC); |
| 213 | } |
213 | } |
| 214 | return; |
214 | goto out; |
| 215 | } else if (lflag & L_PARENT) { |
215 | } else if (lflag & L_PARENT) { |
| 216 | /* return parent */ |
216 | /* return parent */ |
| 217 | ipc_answer_5(rid, EOK, fs_handle, dev_handle, |
217 | ipc_answer_5(rid, EOK, fs_handle, dev_handle, |
| 218 | ops->index_get(cur), ops->size_get(cur), |
218 | ops->index_get(cur), ops->size_get(cur), |
| 219 | ops->lnkcnt_get(cur)); |
219 | ops->lnkcnt_get(cur)); |
| 220 | } |
220 | } |
| 221 | ipc_answer_0(rid, ENOENT); |
221 | ipc_answer_0(rid, ENOENT); |
| 222 | return; |
222 | goto out; |
| 223 | } |
223 | } |
| 224 | 224 | ||
| - | 225 | if (par) |
|
| - | 226 | ops->node_put(par); |
|
| - | 227 | ||
| 225 | /* descend one level */ |
228 | /* descend one level */ |
| 226 | par = cur; |
229 | par = cur; |
| 227 | cur = tmp; |
230 | cur = tmp; |
| - | 231 | tmp = NULL; |
|
| 228 | } |
232 | } |
| 229 | 233 | ||
| 230 | /* handle miss: excessive components */ |
234 | /* handle miss: excessive components */ |
| 231 | if (!ops->has_children(cur) && next <= last) { |
235 | if (!ops->has_children(cur) && next <= last) { |
| 232 | if (lflag & (L_CREATE | L_LINK)) { |
236 | if (lflag & (L_CREATE | L_LINK)) { |
| 233 | if (!ops->is_directory(cur)) { |
237 | if (!ops->is_directory(cur)) { |
| 234 | ipc_answer_0(rid, ENOTDIR); |
238 | ipc_answer_0(rid, ENOTDIR); |
| 235 | return; |
239 | goto out; |
| 236 | } |
240 | } |
| 237 | 241 | ||
| 238 | /* collect next component */ |
242 | /* collect next component */ |
| 239 | len = 0; |
243 | len = 0; |
| 240 | while (next <= last) { |
244 | while (next <= last) { |
| 241 | if (ops->plb_get_char(next) == '/') { |
245 | if (ops->plb_get_char(next) == '/') { |
| 242 | /* more than one component */ |
246 | /* more than one component */ |
| 243 | ipc_answer_0(rid, ENOENT); |
247 | ipc_answer_0(rid, ENOENT); |
| 244 | return; |
248 | goto out; |
| 245 | } |
249 | } |
| 246 | if (len + 1 == NAME_MAX) { |
250 | if (len + 1 == NAME_MAX) { |
| 247 | /* component length overflow */ |
251 | /* component length overflow */ |
| 248 | ipc_answer_0(rid, ENAMETOOLONG); |
252 | ipc_answer_0(rid, ENAMETOOLONG); |
| 249 | return; |
253 | goto out; |
| 250 | } |
254 | } |
| 251 | component[len++] = ops->plb_get_char(next); |
255 | component[len++] = ops->plb_get_char(next); |
| 252 | next++; /* process next character */ |
256 | next++; /* process next character */ |
| 253 | } |
257 | } |
| 254 | assert(len); |
258 | assert(len); |
| Line 269... | Line 273... | ||
| 269 | ipc_answer_5(rid, EOK, |
273 | ipc_answer_5(rid, EOK, |
| 270 | fs_handle, dev_handle, |
274 | fs_handle, dev_handle, |
| 271 | ops->index_get(nodep), |
275 | ops->index_get(nodep), |
| 272 | ops->size_get(nodep), |
276 | ops->size_get(nodep), |
| 273 | ops->lnkcnt_get(nodep)); |
277 | ops->lnkcnt_get(nodep)); |
| - | 278 | ops->node_put(nodep); |
|
| 274 | } |
279 | } |
| 275 | } else { |
280 | } else { |
| 276 | ipc_answer_0(rid, ENOSPC); |
281 | ipc_answer_0(rid, ENOSPC); |
| 277 | } |
282 | } |
| 278 | return; |
283 | goto out; |
| 279 | } |
284 | } |
| 280 | ipc_answer_0(rid, ENOENT); |
285 | ipc_answer_0(rid, ENOENT); |
| 281 | return; |
286 | goto out; |
| 282 | } |
287 | } |
| 283 | 288 | ||
| 284 | /* handle hit */ |
289 | /* handle hit */ |
| 285 | if (lflag & L_PARENT) { |
290 | if (lflag & L_PARENT) { |
| - | 291 | ops->node_put(cur); |
|
| 286 | cur = par; |
292 | cur = par; |
| - | 293 | par = NULL; |
|
| 287 | if (!cur) { |
294 | if (!cur) { |
| 288 | ipc_answer_0(rid, ENOENT); |
295 | ipc_answer_0(rid, ENOENT); |
| 289 | return; |
296 | goto out; |
| 290 | } |
297 | } |
| 291 | } |
298 | } |
| 292 | if (lflag & L_UNLINK) { |
299 | if (lflag & L_UNLINK) { |
| 293 | unsigned old_lnkcnt = ops->lnkcnt_get(cur); |
300 | unsigned old_lnkcnt = ops->lnkcnt_get(cur); |
| 294 | int res = ops->unlink(par, cur); |
301 | int res = ops->unlink(par, cur); |
| 295 | ipc_answer_5(rid, (ipcarg_t)res, fs_handle, dev_handle, |
302 | ipc_answer_5(rid, (ipcarg_t)res, fs_handle, dev_handle, |
| 296 | ops->index_get(cur), ops->size_get(cur), old_lnkcnt); |
303 | ops->index_get(cur), ops->size_get(cur), old_lnkcnt); |
| 297 | return; |
304 | goto out; |
| 298 | } |
305 | } |
| 299 | if (((lflag & (L_CREATE | L_EXCLUSIVE)) == (L_CREATE | L_EXCLUSIVE)) || |
306 | if (((lflag & (L_CREATE | L_EXCLUSIVE)) == (L_CREATE | L_EXCLUSIVE)) || |
| 300 | (lflag & L_LINK)) { |
307 | (lflag & L_LINK)) { |
| 301 | ipc_answer_0(rid, EEXIST); |
308 | ipc_answer_0(rid, EEXIST); |
| 302 | return; |
309 | goto out; |
| 303 | } |
310 | } |
| 304 | if ((lflag & L_FILE) && (ops->is_directory(cur))) { |
311 | if ((lflag & L_FILE) && (ops->is_directory(cur))) { |
| 305 | ipc_answer_0(rid, EISDIR); |
312 | ipc_answer_0(rid, EISDIR); |
| 306 | return; |
313 | goto out; |
| 307 | } |
314 | } |
| 308 | if ((lflag & L_DIRECTORY) && (ops->is_file(cur))) { |
315 | if ((lflag & L_DIRECTORY) && (ops->is_file(cur))) { |
| 309 | ipc_answer_0(rid, ENOTDIR); |
316 | ipc_answer_0(rid, ENOTDIR); |
| 310 | return; |
317 | goto out; |
| 311 | } |
318 | } |
| 312 | 319 | ||
| 313 | ipc_answer_5(rid, EOK, fs_handle, dev_handle, ops->index_get(cur), |
320 | ipc_answer_5(rid, EOK, fs_handle, dev_handle, ops->index_get(cur), |
| 314 | ops->size_get(cur), ops->lnkcnt_get(cur)); |
321 | ops->size_get(cur), ops->lnkcnt_get(cur)); |
| - | 322 | ||
| - | 323 | out: |
|
| - | 324 | if (par) |
|
| - | 325 | ops->node_put(par); |
|
| - | 326 | if (cur) |
|
| - | 327 | ops->node_put(cur); |
|
| - | 328 | if (tmp) |
|
| - | 329 | ops->node_put(tmp); |
|
| 315 | } |
330 | } |
| 316 | 331 | ||
| 317 | /** @} |
332 | /** @} |
| 318 | */ |
333 | */ |