Rev 2542 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2542 | Rev 2544 | ||
---|---|---|---|
Line 43... | Line 43... | ||
43 | #include <bool.h> |
43 | #include <bool.h> |
44 | #include <futex.h> |
44 | #include <futex.h> |
45 | #include <libadt/list.h> |
45 | #include <libadt/list.h> |
46 | #include "vfs.h" |
46 | #include "vfs.h" |
47 | 47 | ||
- | 48 | #define min(a, b) ((a) < (b) ? (a) : (b)) |
|
- | 49 | ||
48 | atomic_t plb_futex = FUTEX_INITIALIZER; |
50 | atomic_t plb_futex = FUTEX_INITIALIZER; |
49 | link_t plb_head; |
51 | link_t plb_head; /**< PLB entry ring buffer. */ |
50 | uint8_t *plb = NULL; |
52 | uint8_t *plb = NULL; |
51 | 53 | ||
52 | void vfs_lookup(ipc_callid_t rid, ipc_call_t *request) |
54 | int vfs_lookup_internal(char *path, size_t len, vfs_node_t *result) |
53 | { |
55 | { |
- | 56 | if (!len) |
|
- | 57 | return EINVAL; |
|
- | 58 | ||
54 | if (!rootfs) |
59 | if (!rootfs) |
- | 60 | return ENOENT; |
|
- | 61 | ||
- | 62 | futex_down(&plb_futex); |
|
- | 63 | ||
- | 64 | plb_entry_t entry; |
|
- | 65 | link_initialize(&entry.plb_link); |
|
- | 66 | entry.len = len; |
|
- | 67 | ||
- | 68 | off_t first; /* the first free index */ |
|
- | 69 | off_t last; /* the last free index */ |
|
- | 70 | ||
- | 71 | if (list_empty(&plb_head)) { |
|
- | 72 | first = 0; |
|
- | 73 | last = PLB_SIZE - 1; |
|
- | 74 | } else { |
|
- | 75 | plb_entry_t *oldest = list_get_instance(plb_head.next, |
|
- | 76 | plb_entry_t, plb_link); |
|
- | 77 | plb_entry_t *newest = list_get_instance(plb_head.prev, |
|
- | 78 | plb_entry_t, plb_link); |
|
- | 79 | ||
- | 80 | first = (newest->index + newest->len) % PLB_SIZE; |
|
- | 81 | last = (oldest->index - 1) % PLB_SIZE; |
|
- | 82 | } |
|
- | 83 | ||
- | 84 | if (first <= last) { |
|
- | 85 | if ((last - first) + 1 < len) { |
|
- | 86 | /* |
|
- | 87 | * The buffer cannot absorb the path. |
|
- | 88 | */ |
|
- | 89 | futex_up(&plb_futex); |
|
- | 90 | return ELIMIT; |
|
- | 91 | } |
|
- | 92 | } else { |
|
- | 93 | if (PLB_SIZE - ((first - last) + 1) < len) { |
|
- | 94 | /* |
|
- | 95 | * The buffer cannot absorb the path. |
|
- | 96 | */ |
|
- | 97 | futex_up(&plb_futex); |
|
- | 98 | return ELIMIT; |
|
- | 99 | } |
|
- | 100 | } |
|
- | 101 | ||
- | 102 | /* |
|
- | 103 | * We know the first free index in PLB and we also know that there is |
|
- | 104 | * enough space in the buffer to hold our path. |
|
- | 105 | */ |
|
- | 106 | ||
- | 107 | entry.index = first; |
|
- | 108 | entry.len = len; |
|
- | 109 | ||
- | 110 | /* |
|
- | 111 | * Claim PLB space by inserting the entry into the PLB entry ring |
|
- | 112 | * buffer. |
|
- | 113 | */ |
|
- | 114 | list_append(&entry.plb_link, &plb_head); |
|
- | 115 | ||
- | 116 | futex_up(&plb_futex); |
|
- | 117 | ||
- | 118 | /* |
|
- | 119 | * Copy the path into PLB. |
|
- | 120 | */ |
|
- | 121 | size_t cnt1 = min(len, (PLB_SIZE - first) + 1); |
|
- | 122 | size_t cnt2 = len - cnt1; |
|
- | 123 | ||
55 | ipc_answer_fast(rid, ENOENT, 0, 0); |
124 | memcpy(&plb[first], path, cnt1); |
- | 125 | memcpy(plb, &path[cnt1], cnt2); |
|
- | 126 | ||
- | 127 | ipc_call_t answer; |
|
- | 128 | int phone = 0; /* TODO */ |
|
- | 129 | aid_t req = async_send_2(phone, VFS_LOOKUP, (ipcarg_t) first, |
|
- | 130 | (ipcarg_t) last, &answer); |
|
- | 131 | ||
- | 132 | ipcarg_t rc; |
|
- | 133 | async_wait_for(req, &rc); |
|
- | 134 | ||
- | 135 | futex_down(&plb_futex); |
|
- | 136 | list_remove(&entry.plb_link); |
|
- | 137 | futex_up(&plb_futex); |
|
- | 138 | ||
- | 139 | if (rc == EOK) { |
|
- | 140 | result->fs_handle = (int) IPC_GET_ARG1(answer); |
|
- | 141 | result->dev_handle = (int) IPC_GET_ARG2(answer); |
|
- | 142 | result->index = (int) IPC_GET_ARG3(answer); |
|
- | 143 | } |
|
- | 144 | ||
- | 145 | return rc; |
|
56 | } |
146 | } |
57 | 147 | ||
58 | /** |
148 | /** |
59 | * @} |
149 | * @} |
60 | */ |
150 | */ |