Rev 3150 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3150 | Rev 3403 | ||
---|---|---|---|
Line 79... | Line 79... | ||
79 | { |
79 | { |
80 | ipc_callid_t callid; |
80 | ipc_callid_t callid; |
81 | ipc_call_t call; |
81 | ipc_call_t call; |
82 | int retval; |
82 | int retval; |
83 | void *fs_va = NULL; |
83 | void *fs_va = NULL; |
84 | ipcarg_t offset; |
84 | off_t offset; |
- | 85 | size_t block_size; |
|
- | 86 | size_t maxblock_size; |
|
85 | 87 | ||
86 | /* |
88 | /* |
87 | * We allocate VA for communication per connection. |
89 | * Answer the first IPC_M_CONNECT_ME_TO call. |
88 | * This allows us to potentionally have more clients and work |
- | |
89 | * concurrently. |
- | |
90 | */ |
90 | */ |
91 | fs_va = as_get_mappable_page(ALIGN_UP(BLOCK_SIZE, PAGE_SIZE)); |
- | |
92 | if (!fs_va) { |
- | |
93 | /* |
- | |
94 | * Hang up the phone if we cannot proceed any further. |
- | |
95 | * This is the answer to the call that opened the connection. |
- | |
96 | */ |
- | |
97 | ipc_answer_0(iid, EHANGUP); |
91 | ipc_answer_0(iid, EOK); |
98 | return; |
- | |
99 | } else { |
- | |
100 | /* |
- | |
101 | * Answer the first IPC_M_CONNECT_ME_TO call. |
- | |
102 | * Return supported block size as ARG1. |
- | |
103 | */ |
- | |
104 | ipc_answer_1(iid, EOK, BLOCK_SIZE); |
- | |
105 | } |
- | |
106 | 92 | ||
107 | /* |
93 | /* |
108 | * Now we wait for the client to send us its communication as_area. |
94 | * Now we wait for the client to send us its communication as_area. |
109 | */ |
95 | */ |
110 | size_t size; |
- | |
111 | int flags; |
96 | int flags; |
112 | if (ipc_share_out_receive(&callid, &size, &flags)) { |
97 | if (ipc_share_out_receive(&callid, &maxblock_size, &flags)) { |
113 | if (size >= BLOCK_SIZE) { |
- | |
114 | /* |
- | |
115 | * The client sends an as_area that can absorb the whole |
98 | fs_va = as_get_mappable_page(maxblock_size); |
116 | * block. |
99 | if (fs_va) { |
117 | */ |
- | |
118 | (void) ipc_share_out_finalize(callid, fs_va); |
100 | (void) ipc_share_out_finalize(callid, fs_va); |
119 | } else { |
101 | } else { |
120 | /* |
- | |
121 | * The client offered as_area too small. |
- | |
122 | * Close the connection. |
- | |
123 | */ |
- | |
124 | ipc_answer_0(callid, EHANGUP); |
102 | ipc_answer_0(callid, EHANGUP); |
125 | return; |
103 | return; |
126 | } |
104 | } |
127 | } else { |
105 | } else { |
128 | /* |
106 | /* |
Line 144... | Line 122... | ||
144 | */ |
122 | */ |
145 | ipc_answer_0(callid, EOK); |
123 | ipc_answer_0(callid, EOK); |
146 | return; |
124 | return; |
147 | case RD_READ_BLOCK: |
125 | case RD_READ_BLOCK: |
148 | offset = IPC_GET_ARG1(call); |
126 | offset = IPC_GET_ARG1(call); |
- | 127 | block_size = IPC_GET_ARG2(call); |
|
- | 128 | if (block_size > maxblock_size) { |
|
- | 129 | /* |
|
- | 130 | * Maximum block size exceeded. |
|
- | 131 | */ |
|
- | 132 | retval = ELIMIT; |
|
- | 133 | break; |
|
- | 134 | } |
|
149 | if (offset * BLOCK_SIZE > rd_size - BLOCK_SIZE) { |
135 | if (offset * block_size > rd_size - block_size) { |
150 | /* |
136 | /* |
151 | * Reading past the end of the device. |
137 | * Reading past the end of the device. |
152 | */ |
138 | */ |
153 | retval = ELIMIT; |
139 | retval = ELIMIT; |
154 | break; |
140 | break; |
155 | } |
141 | } |
156 | futex_down(&rd_futex); |
142 | futex_down(&rd_futex); |
157 | memcpy(fs_va, rd_addr + offset * BLOCK_SIZE, BLOCK_SIZE); |
143 | memcpy(fs_va, rd_addr + offset * block_size, block_size); |
158 | futex_up(&rd_futex); |
144 | futex_up(&rd_futex); |
159 | retval = EOK; |
145 | retval = EOK; |
160 | break; |
146 | break; |
161 | case RD_WRITE_BLOCK: |
147 | case RD_WRITE_BLOCK: |
162 | offset = IPC_GET_ARG1(call); |
148 | offset = IPC_GET_ARG1(call); |
- | 149 | block_size = IPC_GET_ARG2(call); |
|
- | 150 | if (block_size > maxblock_size) { |
|
- | 151 | /* |
|
- | 152 | * Maximum block size exceeded. |
|
- | 153 | */ |
|
- | 154 | retval = ELIMIT; |
|
- | 155 | break; |
|
- | 156 | } |
|
163 | if (offset * BLOCK_SIZE > rd_size - BLOCK_SIZE) { |
157 | if (offset * block_size > rd_size - block_size) { |
164 | /* |
158 | /* |
165 | * Writing past the end of the device. |
159 | * Writing past the end of the device. |
166 | */ |
160 | */ |
167 | retval = ELIMIT; |
161 | retval = ELIMIT; |
168 | break; |
162 | break; |
169 | } |
163 | } |
170 | futex_up(&rd_futex); |
164 | futex_up(&rd_futex); |
171 | memcpy(rd_addr + offset * BLOCK_SIZE, fs_va, BLOCK_SIZE); |
165 | memcpy(rd_addr + offset * block_size, fs_va, block_size); |
172 | futex_down(&rd_futex); |
166 | futex_down(&rd_futex); |
173 | retval = EOK; |
167 | retval = EOK; |
174 | break; |
168 | break; |
175 | default: |
169 | default: |
176 | /* |
170 | /* |