Subversion Repositories HelenOS

Rev

Rev 2760 | Rev 2770 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2760 Rev 2763
Line 139... Line 139...
139
{
139
{
140
    unsigned next = IPC_GET_ARG1(*request);
140
    unsigned next = IPC_GET_ARG1(*request);
141
    unsigned last = IPC_GET_ARG2(*request);
141
    unsigned last = IPC_GET_ARG2(*request);
142
    int dev_handle = IPC_GET_ARG3(*request);
142
    int dev_handle = IPC_GET_ARG3(*request);
143
    int lflag = IPC_GET_ARG4(*request);
143
    int lflag = IPC_GET_ARG4(*request);
-
 
144
    int index = IPC_GET_ARG5(*request); /* when L_LINK specified */
144
 
145
 
145
    if (last < next)
146
    if (last < next)
146
        last += PLB_SIZE;
147
        last += PLB_SIZE;
147
 
148
 
148
    void *par = NULL;
149
    void *par = NULL;
Line 178... Line 179...
178
        while (tmp && !ops->match(cur, tmp, component))
179
        while (tmp && !ops->match(cur, tmp, component))
179
            tmp = ops->sibling_get(tmp);
180
            tmp = ops->sibling_get(tmp);
180
 
181
 
181
        /* handle miss: match amongst siblings */
182
        /* handle miss: match amongst siblings */
182
        if (!tmp) {
183
        if (!tmp) {
-
 
184
            if (next <= last) {
-
 
185
                /* there are unprocessed components */
-
 
186
                ipc_answer_0(rid, ENOENT);
-
 
187
                return;
-
 
188
            }
-
 
189
            /* miss in the last component */
183
            if ((next > last) && (lflag & L_CREATE)) {
190
            if (lflag & (L_CREATE | L_LINK)) {
184
                /* no components left and L_CREATE specified */
191
                /* request to create a new link */
185
                if (!ops->is_directory(cur)) {
192
                if (!ops->is_directory(cur)) {
186
                    ipc_answer_0(rid, ENOTDIR);
193
                    ipc_answer_0(rid, ENOTDIR);
187
                    return;
194
                    return;
188
                }
195
                }
-
 
196
                void *nodep;
-
 
197
                if (lflag & L_CREATE)
189
                void *nodep = ops->create(lflag);
198
                    nodep = ops->create(lflag);
-
 
199
                else
-
 
200
                    nodep = ops->node_get(fs_handle,
-
 
201
                        dev_handle, index);
190
                if (nodep) {
202
                if (nodep) {
191
                    if (!ops->link(cur, nodep, component)) {
203
                    if (!ops->link(cur, nodep, component)) {
-
 
204
                        if (lflag & L_CREATE)
192
                        ops->destroy(nodep);
205
                            ops->destroy(nodep);
193
                        ipc_answer_0(rid, ENOSPC);
206
                        ipc_answer_0(rid, ENOSPC);
194
                    } else {
207
                    } else {
195
                        ipc_answer_5(rid, EOK,
208
                        ipc_answer_5(rid, EOK,
196
                            fs_handle, dev_handle,
209
                            fs_handle, dev_handle,
197
                            ops->index_get(nodep), 0,
210
                            ops->index_get(nodep),
-
 
211
                            ops->size_get(nodep),
198
                            ops->lnkcnt_get(nodep));
212
                            ops->lnkcnt_get(nodep));
199
                    }
213
                    }
200
                } else {
214
                } else {
201
                    ipc_answer_0(rid, ENOSPC);
215
                    ipc_answer_0(rid, ENOSPC);
202
                }
216
                }
203
                return;
217
                return;
-
 
218
            } else if (lflag & L_PARENT) {
-
 
219
                /* return parent */
-
 
220
                ipc_answer_5(rid, EOK, fs_handle, dev_handle,
-
 
221
                    ops->index_get(cur), ops->size_get(cur),
-
 
222
                    ops->lnkcnt_get(cur));
204
            }
223
            }
205
            ipc_answer_0(rid, ENOENT);
224
            ipc_answer_0(rid, ENOENT);
206
            return;
225
            return;
207
        }
226
        }
208
 
227
 
209
        /* descend one level */
228
        /* descend one level */
Line 212... Line 231...
212
        tmp = ops->child_get(tmp);
231
        tmp = ops->child_get(tmp);
213
    }
232
    }
214
 
233
 
215
    /* handle miss: excessive components */
234
    /* handle miss: excessive components */
216
    if (!tmp && next <= last) {
235
    if (!tmp && next <= last) {
217
        if (lflag & L_CREATE) {
236
        if (lflag & (L_CREATE | L_LINK)) {
218
            if (!ops->is_directory(cur)) {
237
            if (!ops->is_directory(cur)) {
219
                ipc_answer_0(rid, ENOTDIR);
238
                ipc_answer_0(rid, ENOTDIR);
220
                return;
239
                return;
221
            }
240
            }
222
 
241
 
Line 237... Line 256...
237
            }
256
            }
238
            assert(len);
257
            assert(len);
239
            component[len] = '\0';
258
            component[len] = '\0';
240
            len = 0;
259
            len = 0;
241
               
260
               
-
 
261
            void *nodep;
-
 
262
            if (lflag & L_CREATE)
242
            void *nodep = ops->create(lflag);
263
                nodep = ops->create(lflag);
-
 
264
            else
-
 
265
                nodep = ops->node_get(fs_handle, dev_handle,
-
 
266
                    index);
243
            if (nodep) {
267
            if (nodep) {
244
                if (!ops->link(cur, nodep, component)) {
268
                if (!ops->link(cur, nodep, component)) {
-
 
269
                    if (lflag & L_CREATE)
245
                    ops->destroy(nodep);
270
                        ops->destroy(nodep);
246
                    ipc_answer_0(rid, ENOSPC);
271
                    ipc_answer_0(rid, ENOSPC);
247
                } else {
272
                } else {
248
                    ipc_answer_5(rid, EOK,
273
                    ipc_answer_5(rid, EOK,
249
                        fs_handle, dev_handle,
274
                        fs_handle, dev_handle,
250
                        ops->index_get(nodep), 0,
275
                        ops->index_get(nodep),
-
 
276
                        ops->size_get(nodep),
251
                        ops->lnkcnt_get(nodep));
277
                        ops->lnkcnt_get(nodep));
252
                }
278
                }
253
            } else {
279
            } else {
254
                ipc_answer_0(rid, ENOSPC);
280
                ipc_answer_0(rid, ENOSPC);
255
            }
281
            }
Line 258... Line 284...
258
        ipc_answer_0(rid, ENOENT);
284
        ipc_answer_0(rid, ENOENT);
259
        return;
285
        return;
260
    }
286
    }
261
 
287
 
262
    /* handle hit */
288
    /* handle hit */
263
    if (lflag & L_DESTROY) {
289
    if (lflag & L_PARENT) {
-
 
290
        cur = par;
-
 
291
        if (!cur) {
-
 
292
            ipc_answer_0(rid, ENOENT);
-
 
293
            return;
-
 
294
        }
-
 
295
    }
-
 
296
    if (lflag & L_UNLINK) {
264
        unsigned old_lnkcnt = ops->lnkcnt_get(cur);
297
        unsigned old_lnkcnt = ops->lnkcnt_get(cur);
265
        int res = ops->unlink(par, cur);
298
        int res = ops->unlink(par, cur);
266
        ipc_answer_5(rid, (ipcarg_t)res, fs_handle, dev_handle,
299
        ipc_answer_5(rid, (ipcarg_t)res, fs_handle, dev_handle,
267
            ops->index_get(cur), ops->size_get(cur), old_lnkcnt);
300
            ops->index_get(cur), ops->size_get(cur), old_lnkcnt);
268
        return;
301
        return;
269
    }
302
    }
270
    if ((lflag & (L_CREATE | L_EXCLUSIVE)) == (L_CREATE | L_EXCLUSIVE)) {
303
    if (((lflag & (L_CREATE | L_EXCLUSIVE)) == (L_CREATE | L_EXCLUSIVE)) ||
-
 
304
        (lflag & L_LINK)) {
271
        ipc_answer_0(rid, EEXIST);
305
        ipc_answer_0(rid, EEXIST);
272
        return;
306
        return;
273
    }
307
    }
274
    if ((lflag & L_FILE) && (ops->is_directory(cur))) {
308
    if ((lflag & L_FILE) && (ops->is_directory(cur))) {
275
        ipc_answer_0(rid, EISDIR);
309
        ipc_answer_0(rid, EISDIR);