File: | xlators/performance/read-ahead/src/page.c |
Location: | line 160, column 17 |
Description: | Value stored to 'op_ret' is never read |
1 | /* |
2 | Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com> |
3 | This file is part of GlusterFS. |
4 | |
5 | This file is licensed to you under your choice of the GNU Lesser |
6 | General Public License, version 3 or any later version (LGPLv3 or |
7 | later), or the GNU General Public License, version 2 (GPLv2), in all |
8 | cases as published by the Free Software Foundation. |
9 | */ |
10 | |
11 | #ifndef _CONFIG_H |
12 | #define _CONFIG_H |
13 | #include "config.h" |
14 | #endif |
15 | |
16 | #include "glusterfs.h" |
17 | #include "logging.h" |
18 | #include "dict.h" |
19 | #include "xlator.h" |
20 | #include "read-ahead.h" |
21 | #include <assert.h> |
22 | |
23 | ra_page_t * |
24 | ra_page_get (ra_file_t *file, off_t offset) |
25 | { |
26 | ra_page_t *page = NULL((void*)0); |
27 | off_t rounded_offset = 0; |
28 | |
29 | GF_VALIDATE_OR_GOTO ("read-ahead", file, out)do { if (!file) { (*__errno_location ()) = 22; do { do { if ( 0) printf ("invalid argument: " "file"); } while (0); _gf_log_callingfn ("read-ahead", "page.c", __FUNCTION__, 29, GF_LOG_ERROR, "invalid argument: " "file"); } while (0); goto out; } } while (0); |
30 | |
31 | page = file->pages.next; |
32 | rounded_offset = floor (offset, file->page_size)(((offset)/((file->page_size)?(file->page_size):1))*(file ->page_size)); |
33 | |
34 | while (page != &file->pages && page->offset < rounded_offset) |
35 | page = page->next; |
36 | |
37 | if (page == &file->pages || page->offset != rounded_offset) |
38 | page = NULL((void*)0); |
39 | |
40 | out: |
41 | return page; |
42 | } |
43 | |
44 | |
45 | ra_page_t * |
46 | ra_page_create (ra_file_t *file, off_t offset) |
47 | { |
48 | ra_page_t *page = NULL((void*)0); |
49 | off_t rounded_offset = 0; |
50 | ra_page_t *newpage = NULL((void*)0); |
51 | |
52 | GF_VALIDATE_OR_GOTO ("read-ahead", file, out)do { if (!file) { (*__errno_location ()) = 22; do { do { if ( 0) printf ("invalid argument: " "file"); } while (0); _gf_log_callingfn ("read-ahead", "page.c", __FUNCTION__, 52, GF_LOG_ERROR, "invalid argument: " "file"); } while (0); goto out; } } while (0); |
53 | |
54 | page = file->pages.next; |
55 | rounded_offset = floor (offset, file->page_size)(((offset)/((file->page_size)?(file->page_size):1))*(file ->page_size)); |
56 | |
57 | while (page != &file->pages && page->offset < rounded_offset) |
58 | page = page->next; |
59 | |
60 | if (page == &file->pages || page->offset != rounded_offset) { |
61 | newpage = GF_CALLOC (1, sizeof (*newpage), gf_ra_mt_ra_page_t)__gf_calloc (1, sizeof (*newpage), gf_ra_mt_ra_page_t); |
62 | if (!newpage) { |
63 | goto out; |
64 | } |
65 | |
66 | newpage->offset = rounded_offset; |
67 | newpage->prev = page->prev; |
68 | newpage->next = page; |
69 | newpage->file = file; |
70 | page->prev->next = newpage; |
71 | page->prev = newpage; |
72 | |
73 | page = newpage; |
74 | } |
75 | |
76 | out: |
77 | return page; |
78 | } |
79 | |
80 | |
81 | void |
82 | ra_wait_on_page (ra_page_t *page, call_frame_t *frame) |
83 | { |
84 | ra_waitq_t *waitq = NULL((void*)0); |
85 | ra_local_t *local = NULL((void*)0); |
86 | |
87 | GF_VALIDATE_OR_GOTO ("read-ahead", frame, out)do { if (!frame) { (*__errno_location ()) = 22; do { do { if ( 0) printf ("invalid argument: " "frame"); } while (0); _gf_log_callingfn ("read-ahead", "page.c", __FUNCTION__, 87, GF_LOG_ERROR, "invalid argument: " "frame"); } while (0); goto out; } } while (0); |
88 | GF_VALIDATE_OR_GOTO (frame->this->name, page, out)do { if (!page) { (*__errno_location ()) = 22; do { do { if ( 0) printf ("invalid argument: " "page"); } while (0); _gf_log_callingfn (frame->this->name, "page.c", __FUNCTION__, 88, GF_LOG_ERROR , "invalid argument: " "page"); } while (0); goto out; } } while (0); |
89 | |
90 | local = frame->local; |
91 | |
92 | waitq = GF_CALLOC (1, sizeof (*waitq), gf_ra_mt_ra_waitq_t)__gf_calloc (1, sizeof (*waitq), gf_ra_mt_ra_waitq_t); |
93 | if (!waitq) { |
94 | local->op_ret = -1; |
95 | local->op_errno = ENOMEM12; |
96 | goto out; |
97 | } |
98 | |
99 | waitq->data = frame; |
100 | waitq->next = page->waitq; |
101 | page->waitq = waitq; |
102 | |
103 | ra_local_lock (local); |
104 | { |
105 | local->wait_count++; |
106 | } |
107 | ra_local_unlock (local); |
108 | |
109 | out: |
110 | return; |
111 | } |
112 | |
113 | |
114 | void |
115 | ra_waitq_return (ra_waitq_t *waitq) |
116 | { |
117 | ra_waitq_t *trav = NULL((void*)0); |
118 | ra_waitq_t *next = NULL((void*)0); |
119 | call_frame_t *frame = NULL((void*)0); |
120 | |
121 | for (trav = waitq; trav; trav = next) { |
122 | next = trav->next; |
123 | |
124 | frame = trav->data; |
125 | ra_frame_return (frame); |
126 | GF_FREE (trav)__gf_free (trav); |
127 | } |
128 | |
129 | return; |
130 | } |
131 | |
132 | |
133 | int |
134 | ra_fault_cbk (call_frame_t *frame, void *cookie, xlator_t *this, |
135 | int32_t op_ret, int32_t op_errno, struct iovec *vector, |
136 | int32_t count, struct iatt *stbuf, struct iobref *iobref, |
137 | dict_t *xdata) |
138 | { |
139 | ra_local_t *local = NULL((void*)0); |
140 | off_t pending_offset = 0; |
141 | ra_file_t *file = NULL((void*)0); |
142 | ra_page_t *page = NULL((void*)0); |
143 | ra_waitq_t *waitq = NULL((void*)0); |
144 | fd_t *fd = NULL((void*)0); |
145 | uint64_t tmp_file = 0; |
146 | |
147 | GF_ASSERT (frame)do { if (!(frame)) { do { do { if (0) printf ("Assertion failed: " "frame"); } while (0); _gf_log_callingfn ("", "page.c", __FUNCTION__ , 147, GF_LOG_ERROR, "Assertion failed: " "frame"); } while ( 0); } } while (0); |
148 | |
149 | local = frame->local; |
150 | fd = local->fd; |
151 | |
152 | fd_ctx_get (fd, this, &tmp_file); |
153 | |
154 | file = (ra_file_t *)(long)tmp_file; |
155 | pending_offset = local->pending_offset; |
156 | |
157 | if (file == NULL((void*)0)) { |
158 | gf_log (this->name, GF_LOG_WARNING,do { do { if (0) printf ("read-ahead context not set in fd (%p)" , fd); } while (0); _gf_log (this->name, "page.c", __FUNCTION__ , 159, GF_LOG_WARNING, "read-ahead context not set in fd (%p)" , fd); } while (0) |
159 | "read-ahead context not set in fd (%p)", fd)do { do { if (0) printf ("read-ahead context not set in fd (%p)" , fd); } while (0); _gf_log (this->name, "page.c", __FUNCTION__ , 159, GF_LOG_WARNING, "read-ahead context not set in fd (%p)" , fd); } while (0); |
160 | op_ret = -1; |
Value stored to 'op_ret' is never read | |
161 | op_errno = EBADF9; |
162 | goto out; |
163 | } |
164 | |
165 | ra_file_lock (file); |
166 | { |
167 | if (op_ret >= 0) |
168 | file->stbuf = *stbuf; |
169 | |
170 | page = ra_page_get (file, pending_offset); |
171 | |
172 | if (!page) { |
173 | gf_log (this->name, GF_LOG_TRACE,do { do { if (0) printf ("wasted copy: %""ll" "d""[+%""ll" "d" "] file=%p", pending_offset, file->page_size, file); } while (0); _gf_log (this->name, "page.c", __FUNCTION__, 175, GF_LOG_TRACE , "wasted copy: %""ll" "d""[+%""ll" "d""] file=%p", pending_offset , file->page_size, file); } while (0) |
174 | "wasted copy: %"PRId64"[+%"PRId64"] file=%p",do { do { if (0) printf ("wasted copy: %""ll" "d""[+%""ll" "d" "] file=%p", pending_offset, file->page_size, file); } while (0); _gf_log (this->name, "page.c", __FUNCTION__, 175, GF_LOG_TRACE , "wasted copy: %""ll" "d""[+%""ll" "d""] file=%p", pending_offset , file->page_size, file); } while (0) |
175 | pending_offset, file->page_size, file)do { do { if (0) printf ("wasted copy: %""ll" "d""[+%""ll" "d" "] file=%p", pending_offset, file->page_size, file); } while (0); _gf_log (this->name, "page.c", __FUNCTION__, 175, GF_LOG_TRACE , "wasted copy: %""ll" "d""[+%""ll" "d""] file=%p", pending_offset , file->page_size, file); } while (0); |
176 | goto unlock; |
177 | } |
178 | |
179 | /* |
180 | * "Dirty" means that the request was a pure read-ahead; it's |
181 | * set for requests we issue ourselves, and cleared when user |
182 | * requests are issued or put on the waitq. "Poisoned" means |
183 | * that we got a write while a read was still in flight, and we |
184 | * couldn't stop it so we marked it instead. If it's both |
185 | * dirty and poisoned by the time we get here, we cancel its |
186 | * effect so that a subsequent user read doesn't get data that |
187 | * we know is stale (because we made it stale ourselves). We |
188 | * can't use ESTALE because that has special significance. |
189 | * ECANCELED has no such special meaning, and is close to what |
190 | * we're trying to indicate. |
191 | */ |
192 | if (page->dirty && page->poisoned) { |
193 | op_ret = -1; |
194 | op_errno = ECANCELED125; |
195 | } |
196 | |
197 | if (op_ret < 0) { |
198 | waitq = ra_page_error (page, op_ret, op_errno); |
199 | goto unlock; |
200 | } |
201 | |
202 | if (page->vector) { |
203 | iobref_unref (page->iobref); |
204 | GF_FREE (page->vector)__gf_free (page->vector); |
205 | } |
206 | |
207 | page->vector = iov_dup (vector, count); |
208 | if (page->vector == NULL((void*)0)) { |
209 | waitq = ra_page_error (page, -1, ENOMEM12); |
210 | goto unlock; |
211 | } |
212 | |
213 | page->count = count; |
214 | page->iobref = iobref_ref (iobref); |
215 | page->ready = 1; |
216 | |
217 | page->size = iov_length (vector, count); |
218 | |
219 | waitq = ra_page_wakeup (page); |
220 | } |
221 | unlock: |
222 | ra_file_unlock (file); |
223 | |
224 | ra_waitq_return (waitq); |
225 | |
226 | fd_unref (local->fd); |
227 | |
228 | mem_put (frame->local); |
229 | frame->local = NULL((void*)0); |
230 | |
231 | out: |
232 | STACK_DESTROY (frame->root); |
233 | return 0; |
234 | } |
235 | |
236 | |
237 | void |
238 | ra_page_fault (ra_file_t *file, call_frame_t *frame, off_t offset) |
239 | { |
240 | call_frame_t *fault_frame = NULL((void*)0); |
241 | ra_local_t *fault_local = NULL((void*)0); |
242 | ra_page_t *page = NULL((void*)0); |
243 | ra_waitq_t *waitq = NULL((void*)0); |
244 | int32_t op_ret = -1, op_errno = -1; |
245 | |
246 | GF_VALIDATE_OR_GOTO ("read-ahead", frame, out)do { if (!frame) { (*__errno_location ()) = 22; do { do { if ( 0) printf ("invalid argument: " "frame"); } while (0); _gf_log_callingfn ("read-ahead", "page.c", __FUNCTION__, 246, GF_LOG_ERROR, "invalid argument: " "frame"); } while (0); goto out; } } while (0); |
247 | GF_VALIDATE_OR_GOTO (frame->this->name, file, out)do { if (!file) { (*__errno_location ()) = 22; do { do { if ( 0) printf ("invalid argument: " "file"); } while (0); _gf_log_callingfn (frame->this->name, "page.c", __FUNCTION__, 247, GF_LOG_ERROR , "invalid argument: " "file"); } while (0); goto out; } } while (0); |
248 | |
249 | fault_frame = copy_frame (frame); |
250 | if (fault_frame == NULL((void*)0)) { |
251 | op_ret = -1; |
252 | op_errno = ENOMEM12; |
253 | goto err; |
254 | } |
255 | |
256 | fault_local = mem_get0 (THIS(*__glusterfs_this_location())->local_pool); |
257 | if (fault_local == NULL((void*)0)) { |
258 | STACK_DESTROY (fault_frame->root); |
259 | op_ret = -1; |
260 | op_errno = ENOMEM12; |
261 | goto err; |
262 | } |
263 | |
264 | fault_frame->local = fault_local; |
265 | fault_local->pending_offset = offset; |
266 | fault_local->pending_size = file->page_size; |
267 | |
268 | fault_local->fd = fd_ref (file->fd); |
269 | |
270 | STACK_WIND (fault_frame, ra_fault_cbk,do { call_frame_t *_new = ((void*)0); xlator_t *old_THIS = (( void*)0); _new = mem_get0 (fault_frame->root->pool-> frame_mem_pool); if (!_new) { do { do { if (0) printf ("alloc failed" ); } while (0); _gf_log ("stack", "page.c", __FUNCTION__, 273 , GF_LOG_ERROR, "alloc failed"); } while (0); break; } typeof ( (fault_frame->this->children->xlator)->fops-> readv_cbk) tmp_cbk = ra_fault_cbk; _new->root = fault_frame ->root; _new->this = (fault_frame->this->children ->xlator); _new->ret = (ret_fn_t) tmp_cbk; _new->parent = fault_frame; _new->cookie = _new; _new->wind_from = __FUNCTION__ ; _new->wind_to = "FIRST_CHILD (fault_frame->this)->fops->readv" ; _new->unwind_to = "ra_fault_cbk"; pthread_spin_init (& _new->lock, 0); pthread_spin_lock (&fault_frame->root ->stack_lock); { _new->next = fault_frame->root-> frames.next; _new->prev = &fault_frame->root->frames ; if (fault_frame->root->frames.next) fault_frame->root ->frames.next->prev = _new; fault_frame->root->frames .next = _new; fault_frame->ref_count++; } pthread_spin_unlock (&fault_frame->root->stack_lock); old_THIS = (*__glusterfs_this_location ()); (*__glusterfs_this_location()) = (fault_frame->this-> children->xlator); if (fault_frame->this->ctx->measure_latency ) gf_latency_begin (_new, (fault_frame->this->children-> xlator)->fops->readv); (fault_frame->this->children ->xlator)->fops->readv (_new, (fault_frame->this-> children->xlator), file->fd, file->page_size, offset , 0, ((void*)0)); (*__glusterfs_this_location()) = old_THIS; } while (0) |
271 | FIRST_CHILD (fault_frame->this),do { call_frame_t *_new = ((void*)0); xlator_t *old_THIS = (( void*)0); _new = mem_get0 (fault_frame->root->pool-> frame_mem_pool); if (!_new) { do { do { if (0) printf ("alloc failed" ); } while (0); _gf_log ("stack", "page.c", __FUNCTION__, 273 , GF_LOG_ERROR, "alloc failed"); } while (0); break; } typeof ( (fault_frame->this->children->xlator)->fops-> readv_cbk) tmp_cbk = ra_fault_cbk; _new->root = fault_frame ->root; _new->this = (fault_frame->this->children ->xlator); _new->ret = (ret_fn_t) tmp_cbk; _new->parent = fault_frame; _new->cookie = _new; _new->wind_from = __FUNCTION__ ; _new->wind_to = "FIRST_CHILD (fault_frame->this)->fops->readv" ; _new->unwind_to = "ra_fault_cbk"; pthread_spin_init (& _new->lock, 0); pthread_spin_lock (&fault_frame->root ->stack_lock); { _new->next = fault_frame->root-> frames.next; _new->prev = &fault_frame->root->frames ; if (fault_frame->root->frames.next) fault_frame->root ->frames.next->prev = _new; fault_frame->root->frames .next = _new; fault_frame->ref_count++; } pthread_spin_unlock (&fault_frame->root->stack_lock); old_THIS = (*__glusterfs_this_location ()); (*__glusterfs_this_location()) = (fault_frame->this-> children->xlator); if (fault_frame->this->ctx->measure_latency ) gf_latency_begin (_new, (fault_frame->this->children-> xlator)->fops->readv); (fault_frame->this->children ->xlator)->fops->readv (_new, (fault_frame->this-> children->xlator), file->fd, file->page_size, offset , 0, ((void*)0)); (*__glusterfs_this_location()) = old_THIS; } while (0) |
272 | FIRST_CHILD (fault_frame->this)->fops->readv,do { call_frame_t *_new = ((void*)0); xlator_t *old_THIS = (( void*)0); _new = mem_get0 (fault_frame->root->pool-> frame_mem_pool); if (!_new) { do { do { if (0) printf ("alloc failed" ); } while (0); _gf_log ("stack", "page.c", __FUNCTION__, 273 , GF_LOG_ERROR, "alloc failed"); } while (0); break; } typeof ( (fault_frame->this->children->xlator)->fops-> readv_cbk) tmp_cbk = ra_fault_cbk; _new->root = fault_frame ->root; _new->this = (fault_frame->this->children ->xlator); _new->ret = (ret_fn_t) tmp_cbk; _new->parent = fault_frame; _new->cookie = _new; _new->wind_from = __FUNCTION__ ; _new->wind_to = "FIRST_CHILD (fault_frame->this)->fops->readv" ; _new->unwind_to = "ra_fault_cbk"; pthread_spin_init (& _new->lock, 0); pthread_spin_lock (&fault_frame->root ->stack_lock); { _new->next = fault_frame->root-> frames.next; _new->prev = &fault_frame->root->frames ; if (fault_frame->root->frames.next) fault_frame->root ->frames.next->prev = _new; fault_frame->root->frames .next = _new; fault_frame->ref_count++; } pthread_spin_unlock (&fault_frame->root->stack_lock); old_THIS = (*__glusterfs_this_location ()); (*__glusterfs_this_location()) = (fault_frame->this-> children->xlator); if (fault_frame->this->ctx->measure_latency ) gf_latency_begin (_new, (fault_frame->this->children-> xlator)->fops->readv); (fault_frame->this->children ->xlator)->fops->readv (_new, (fault_frame->this-> children->xlator), file->fd, file->page_size, offset , 0, ((void*)0)); (*__glusterfs_this_location()) = old_THIS; } while (0) |
273 | file->fd, file->page_size, offset, 0, NULL)do { call_frame_t *_new = ((void*)0); xlator_t *old_THIS = (( void*)0); _new = mem_get0 (fault_frame->root->pool-> frame_mem_pool); if (!_new) { do { do { if (0) printf ("alloc failed" ); } while (0); _gf_log ("stack", "page.c", __FUNCTION__, 273 , GF_LOG_ERROR, "alloc failed"); } while (0); break; } typeof ( (fault_frame->this->children->xlator)->fops-> readv_cbk) tmp_cbk = ra_fault_cbk; _new->root = fault_frame ->root; _new->this = (fault_frame->this->children ->xlator); _new->ret = (ret_fn_t) tmp_cbk; _new->parent = fault_frame; _new->cookie = _new; _new->wind_from = __FUNCTION__ ; _new->wind_to = "FIRST_CHILD (fault_frame->this)->fops->readv" ; _new->unwind_to = "ra_fault_cbk"; pthread_spin_init (& _new->lock, 0); pthread_spin_lock (&fault_frame->root ->stack_lock); { _new->next = fault_frame->root-> frames.next; _new->prev = &fault_frame->root->frames ; if (fault_frame->root->frames.next) fault_frame->root ->frames.next->prev = _new; fault_frame->root->frames .next = _new; fault_frame->ref_count++; } pthread_spin_unlock (&fault_frame->root->stack_lock); old_THIS = (*__glusterfs_this_location ()); (*__glusterfs_this_location()) = (fault_frame->this-> children->xlator); if (fault_frame->this->ctx->measure_latency ) gf_latency_begin (_new, (fault_frame->this->children-> xlator)->fops->readv); (fault_frame->this->children ->xlator)->fops->readv (_new, (fault_frame->this-> children->xlator), file->fd, file->page_size, offset , 0, ((void*)0)); (*__glusterfs_this_location()) = old_THIS; } while (0); |
274 | |
275 | return; |
276 | |
277 | err: |
278 | ra_file_lock (file); |
279 | { |
280 | page = ra_page_get (file, offset); |
281 | if (page) |
282 | waitq = ra_page_error (page, op_ret, |
283 | op_errno); |
284 | } |
285 | ra_file_unlock (file); |
286 | |
287 | if (waitq != NULL((void*)0)) { |
288 | ra_waitq_return (waitq); |
289 | } |
290 | |
291 | out: |
292 | return; |
293 | } |
294 | |
295 | |
296 | void |
297 | ra_frame_fill (ra_page_t *page, call_frame_t *frame) |
298 | { |
299 | ra_local_t *local = NULL((void*)0); |
300 | ra_fill_t *fill = NULL((void*)0); |
301 | off_t src_offset = 0; |
302 | off_t dst_offset = 0; |
303 | ssize_t copy_size = 0; |
304 | ra_fill_t *new = NULL((void*)0); |
305 | |
306 | GF_VALIDATE_OR_GOTO ("read-ahead", frame, out)do { if (!frame) { (*__errno_location ()) = 22; do { do { if ( 0) printf ("invalid argument: " "frame"); } while (0); _gf_log_callingfn ("read-ahead", "page.c", __FUNCTION__, 306, GF_LOG_ERROR, "invalid argument: " "frame"); } while (0); goto out; } } while (0); |
307 | GF_VALIDATE_OR_GOTO (frame->this->name, page, out)do { if (!page) { (*__errno_location ()) = 22; do { do { if ( 0) printf ("invalid argument: " "page"); } while (0); _gf_log_callingfn (frame->this->name, "page.c", __FUNCTION__, 307, GF_LOG_ERROR , "invalid argument: " "page"); } while (0); goto out; } } while (0); |
308 | |
309 | local = frame->local; |
310 | fill = &local->fill; |
311 | |
312 | if (local->op_ret != -1 && page->size) { |
313 | if (local->offset > page->offset) |
314 | src_offset = local->offset - page->offset; |
315 | else |
316 | dst_offset = page->offset - local->offset; |
317 | |
318 | copy_size = min (page->size - src_offset,((page->size - src_offset)<(local->size - dst_offset )?(page->size - src_offset):(local->size - dst_offset)) |
319 | local->size - dst_offset)((page->size - src_offset)<(local->size - dst_offset )?(page->size - src_offset):(local->size - dst_offset)); |
320 | |
321 | if (copy_size < 0) { |
322 | /* if page contains fewer bytes and the required offset |
323 | is beyond the page size in the page */ |
324 | copy_size = src_offset = 0; |
325 | } |
326 | |
327 | fill = fill->next; |
328 | while (fill != &local->fill) { |
329 | if (fill->offset > page->offset) { |
330 | break; |
331 | } |
332 | fill = fill->next; |
333 | } |
334 | |
335 | new = GF_CALLOC (1, sizeof (*new), gf_ra_mt_ra_fill_t)__gf_calloc (1, sizeof (*new), gf_ra_mt_ra_fill_t); |
336 | if (new == NULL((void*)0)) { |
337 | local->op_ret = -1; |
338 | local->op_errno = ENOMEM12; |
339 | goto out; |
340 | } |
341 | |
342 | new->offset = page->offset; |
343 | new->size = copy_size; |
344 | new->iobref = iobref_ref (page->iobref); |
345 | new->count = iov_subset (page->vector, page->count, |
346 | src_offset, src_offset+copy_size, |
347 | NULL((void*)0)); |
348 | new->vector = GF_CALLOC (new->count, sizeof (struct iovec),__gf_calloc (new->count, sizeof (struct iovec), gf_ra_mt_iovec ) |
349 | gf_ra_mt_iovec)__gf_calloc (new->count, sizeof (struct iovec), gf_ra_mt_iovec ); |
350 | if (new->vector == NULL((void*)0)) { |
351 | local->op_ret = -1; |
352 | local->op_errno = ENOMEM12; |
353 | GF_FREE (new)__gf_free (new); |
354 | goto out; |
355 | } |
356 | |
357 | new->count = iov_subset (page->vector, page->count, |
358 | src_offset, src_offset+copy_size, |
359 | new->vector); |
360 | |
361 | new->next = fill; |
362 | new->prev = new->next->prev; |
363 | new->next->prev = new; |
364 | new->prev->next = new; |
365 | |
366 | local->op_ret += copy_size; |
367 | } |
368 | |
369 | out: |
370 | return; |
371 | } |
372 | |
373 | |
374 | void |
375 | ra_frame_unwind (call_frame_t *frame) |
376 | { |
377 | ra_local_t *local = NULL((void*)0); |
378 | ra_fill_t *fill = NULL((void*)0); |
379 | int32_t count = 0; |
380 | struct iovec *vector = NULL((void*)0); |
381 | int32_t copied = 0; |
382 | struct iobref *iobref = NULL((void*)0); |
383 | ra_fill_t *next = NULL((void*)0); |
384 | fd_t *fd = NULL((void*)0); |
385 | ra_file_t *file = NULL((void*)0); |
386 | uint64_t tmp_file = 0; |
387 | |
388 | GF_VALIDATE_OR_GOTO ("read-ahead", frame, out)do { if (!frame) { (*__errno_location ()) = 22; do { do { if ( 0) printf ("invalid argument: " "frame"); } while (0); _gf_log_callingfn ("read-ahead", "page.c", __FUNCTION__, 388, GF_LOG_ERROR, "invalid argument: " "frame"); } while (0); goto out; } } while (0); |
389 | |
390 | local = frame->local; |
391 | fill = local->fill.next; |
392 | |
393 | iobref = iobref_new (); |
394 | if (iobref == NULL((void*)0)) { |
395 | local->op_ret = -1; |
396 | local->op_errno = ENOMEM12; |
397 | } |
398 | |
399 | frame->local = NULL((void*)0); |
400 | |
401 | while (fill != &local->fill) { |
402 | count += fill->count; |
403 | fill = fill->next; |
404 | } |
405 | |
406 | vector = GF_CALLOC (count, sizeof (*vector), gf_ra_mt_iovec)__gf_calloc (count, sizeof (*vector), gf_ra_mt_iovec); |
407 | if (vector == NULL((void*)0)) { |
408 | local->op_ret = -1; |
409 | local->op_errno = ENOMEM12; |
410 | iobref_unref (iobref); |
411 | iobref = NULL((void*)0); |
412 | } |
413 | |
414 | fill = local->fill.next; |
415 | |
416 | while (fill != &local->fill) { |
417 | next = fill->next; |
418 | |
419 | if ((vector != NULL((void*)0)) && (iobref != NULL((void*)0))) { |
420 | memcpy (((char *)vector) + copied, fill->vector, |
421 | fill->count * sizeof (*vector)); |
422 | |
423 | copied += (fill->count * sizeof (*vector)); |
424 | iobref_merge (iobref, fill->iobref); |
425 | } |
426 | |
427 | fill->next->prev = fill->prev; |
428 | fill->prev->next = fill->prev; |
429 | |
430 | iobref_unref (fill->iobref); |
431 | GF_FREE (fill->vector)__gf_free (fill->vector); |
432 | GF_FREE (fill)__gf_free (fill); |
433 | |
434 | fill = next; |
435 | } |
436 | |
437 | fd = local->fd; |
438 | fd_ctx_get (fd, frame->this, &tmp_file); |
439 | file = (ra_file_t *)(long)tmp_file; |
440 | |
441 | STACK_UNWIND_STRICT (readv, frame, local->op_ret, local->op_errno,do { fop_readv_cbk_t fn = ((void*)0); call_frame_t *_parent = ((void*)0); xlator_t *old_THIS = ((void*)0); if (!frame) { do { do { if (0) printf ("!frame"); } while (0); _gf_log ("stack" , "page.c", __FUNCTION__, 442, GF_LOG_CRITICAL, "!frame"); } while (0); break; } fn = (fop_readv_cbk_t )frame->ret; _parent = frame->parent; pthread_spin_lock (&frame->root-> stack_lock); { _parent->ref_count--; } pthread_spin_unlock (&frame->root->stack_lock); old_THIS = (*__glusterfs_this_location ()); (*__glusterfs_this_location()) = _parent->this; frame ->complete = _gf_true; frame->unwind_from = __FUNCTION__ ; if (frame->this->ctx->measure_latency) gf_latency_end (frame); fn (_parent, frame->cookie, _parent->this, local ->op_ret, local->op_errno, vector, count, &file-> stbuf, iobref, ((void*)0)); (*__glusterfs_this_location()) = old_THIS ; } while (0) |
442 | vector, count, &file->stbuf, iobref, NULL)do { fop_readv_cbk_t fn = ((void*)0); call_frame_t *_parent = ((void*)0); xlator_t *old_THIS = ((void*)0); if (!frame) { do { do { if (0) printf ("!frame"); } while (0); _gf_log ("stack" , "page.c", __FUNCTION__, 442, GF_LOG_CRITICAL, "!frame"); } while (0); break; } fn = (fop_readv_cbk_t )frame->ret; _parent = frame->parent; pthread_spin_lock (&frame->root-> stack_lock); { _parent->ref_count--; } pthread_spin_unlock (&frame->root->stack_lock); old_THIS = (*__glusterfs_this_location ()); (*__glusterfs_this_location()) = _parent->this; frame ->complete = _gf_true; frame->unwind_from = __FUNCTION__ ; if (frame->this->ctx->measure_latency) gf_latency_end (frame); fn (_parent, frame->cookie, _parent->this, local ->op_ret, local->op_errno, vector, count, &file-> stbuf, iobref, ((void*)0)); (*__glusterfs_this_location()) = old_THIS ; } while (0); |
443 | |
444 | iobref_unref (iobref); |
445 | pthread_mutex_destroy (&local->local_lock); |
446 | mem_put (local); |
447 | GF_FREE (vector)__gf_free (vector); |
448 | |
449 | out: |
450 | return; |
451 | } |
452 | |
453 | /* |
454 | * ra_frame_return - |
455 | * @frame: |
456 | * |
457 | */ |
458 | void |
459 | ra_frame_return (call_frame_t *frame) |
460 | { |
461 | ra_local_t *local = NULL((void*)0); |
462 | int32_t wait_count = 0; |
463 | |
464 | GF_VALIDATE_OR_GOTO ("read-ahead", frame, out)do { if (!frame) { (*__errno_location ()) = 22; do { do { if ( 0) printf ("invalid argument: " "frame"); } while (0); _gf_log_callingfn ("read-ahead", "page.c", __FUNCTION__, 464, GF_LOG_ERROR, "invalid argument: " "frame"); } while (0); goto out; } } while (0); |
465 | |
466 | local = frame->local; |
467 | GF_ASSERT (local->wait_count > 0)do { if (!(local->wait_count > 0)) { do { do { if (0) printf ("Assertion failed: " "local->wait_count > 0"); } while (0); _gf_log_callingfn ("", "page.c", __FUNCTION__, 467, GF_LOG_ERROR , "Assertion failed: " "local->wait_count > 0"); } while (0); } } while (0); |
468 | |
469 | ra_local_lock (local); |
470 | { |
471 | wait_count = --local->wait_count; |
472 | } |
473 | ra_local_unlock (local); |
474 | |
475 | if (!wait_count) |
476 | ra_frame_unwind (frame); |
477 | |
478 | out: |
479 | return; |
480 | } |
481 | |
482 | /* |
483 | * ra_page_wakeup - |
484 | * @page: |
485 | * |
486 | */ |
487 | ra_waitq_t * |
488 | ra_page_wakeup (ra_page_t *page) |
489 | { |
490 | ra_waitq_t *waitq = NULL((void*)0), *trav = NULL((void*)0); |
491 | call_frame_t *frame = NULL((void*)0); |
492 | |
493 | GF_VALIDATE_OR_GOTO ("read-ahead", page, out)do { if (!page) { (*__errno_location ()) = 22; do { do { if ( 0) printf ("invalid argument: " "page"); } while (0); _gf_log_callingfn ("read-ahead", "page.c", __FUNCTION__, 493, GF_LOG_ERROR, "invalid argument: " "page"); } while (0); goto out; } } while (0); |
494 | |
495 | waitq = page->waitq; |
496 | page->waitq = NULL((void*)0); |
497 | |
498 | for (trav = waitq; trav; trav = trav->next) { |
499 | frame = trav->data; |
500 | ra_frame_fill (page, frame); |
501 | } |
502 | |
503 | if (page->stale) { |
504 | ra_page_purge (page); |
505 | } |
506 | out: |
507 | return waitq; |
508 | } |
509 | |
510 | /* |
511 | * ra_page_purge - |
512 | * @page: |
513 | * |
514 | */ |
515 | void |
516 | ra_page_purge (ra_page_t *page) |
517 | { |
518 | GF_VALIDATE_OR_GOTO ("read-ahead", page, out)do { if (!page) { (*__errno_location ()) = 22; do { do { if ( 0) printf ("invalid argument: " "page"); } while (0); _gf_log_callingfn ("read-ahead", "page.c", __FUNCTION__, 518, GF_LOG_ERROR, "invalid argument: " "page"); } while (0); goto out; } } while (0); |
519 | |
520 | page->prev->next = page->next; |
521 | page->next->prev = page->prev; |
522 | |
523 | if (page->iobref) { |
524 | iobref_unref (page->iobref); |
525 | } |
526 | |
527 | GF_FREE (page->vector)__gf_free (page->vector); |
528 | GF_FREE (page)__gf_free (page); |
529 | |
530 | out: |
531 | return; |
532 | } |
533 | |
534 | /* |
535 | * ra_page_error - |
536 | * @page: |
537 | * @op_ret: |
538 | * @op_errno: |
539 | * |
540 | */ |
541 | ra_waitq_t * |
542 | ra_page_error (ra_page_t *page, int32_t op_ret, int32_t op_errno) |
543 | { |
544 | ra_waitq_t *waitq = NULL((void*)0); |
545 | ra_waitq_t *trav = NULL((void*)0); |
546 | call_frame_t *frame = NULL((void*)0); |
547 | ra_local_t *local = NULL((void*)0); |
548 | |
549 | GF_VALIDATE_OR_GOTO ("read-ahead", page, out)do { if (!page) { (*__errno_location ()) = 22; do { do { if ( 0) printf ("invalid argument: " "page"); } while (0); _gf_log_callingfn ("read-ahead", "page.c", __FUNCTION__, 549, GF_LOG_ERROR, "invalid argument: " "page"); } while (0); goto out; } } while (0); |
550 | |
551 | waitq = page->waitq; |
552 | page->waitq = NULL((void*)0); |
553 | |
554 | for (trav = waitq; trav; trav = trav->next) { |
555 | frame = trav->data; |
556 | |
557 | local = frame->local; |
558 | if (local->op_ret != -1) { |
559 | local->op_ret = op_ret; |
560 | local->op_errno = op_errno; |
561 | } |
562 | } |
563 | |
564 | ra_page_purge (page); |
565 | |
566 | out: |
567 | return waitq; |
568 | } |
569 | |
570 | /* |
571 | * ra_file_destroy - |
572 | * @file: |
573 | * |
574 | */ |
575 | void |
576 | ra_file_destroy (ra_file_t *file) |
577 | { |
578 | ra_conf_t *conf = NULL((void*)0); |
579 | ra_page_t *trav = NULL((void*)0); |
580 | |
581 | GF_VALIDATE_OR_GOTO ("read-ahead", file, out)do { if (!file) { (*__errno_location ()) = 22; do { do { if ( 0) printf ("invalid argument: " "file"); } while (0); _gf_log_callingfn ("read-ahead", "page.c", __FUNCTION__, 581, GF_LOG_ERROR, "invalid argument: " "file"); } while (0); goto out; } } while (0); |
582 | |
583 | conf = file->conf; |
584 | |
585 | ra_conf_lock (conf); |
586 | { |
587 | file->prev->next = file->next; |
588 | file->next->prev = file->prev; |
589 | } |
590 | ra_conf_unlock (conf); |
591 | |
592 | trav = file->pages.next; |
593 | while (trav != &file->pages) { |
594 | ra_page_error (trav, -1, EINVAL22); |
595 | trav = file->pages.next; |
596 | } |
597 | |
598 | pthread_mutex_destroy (&file->file_lock); |
599 | GF_FREE (file)__gf_free (file); |
600 | |
601 | out: |
602 | return; |
603 | } |