Bug Summary

File:xlators/performance/io-cache/src/page.c
Location:line 434, column 17
Description:Access to field 'table' results in a dereference of a null pointer (loaded from variable 'ioc_inode')

Annotated Source Code

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 "io-cache.h"
21#include "ioc-mem-types.h"
22#include <assert.h>
23#include <sys/time.h>
24
25char
26ioc_empty (struct ioc_cache *cache)
27{
28 char is_empty = -1;
29
30 GF_VALIDATE_OR_GOTO ("io-cache", cache, out)do { if (!cache) { (*__errno_location ()) = 22; do { do { if (
0) printf ("invalid argument: " "cache"); } while (0); _gf_log_callingfn
("io-cache", "page.c", __FUNCTION__, 30, GF_LOG_ERROR, "invalid argument: "
"cache"); } while (0); goto out; } } while (0)
;
31
32 is_empty = list_empty (&cache->page_lru);
33
34out:
35 return is_empty;
36}
37
38
39ioc_page_t *
40__ioc_page_get (ioc_inode_t *ioc_inode, off_t offset)
41{
42 ioc_page_t *page = NULL((void*)0);
43 ioc_table_t *table = NULL((void*)0);
44 off_t rounded_offset = 0;
45
46 GF_VALIDATE_OR_GOTO ("io-cache", ioc_inode, out)do { if (!ioc_inode) { (*__errno_location ()) = 22; do { do {
if (0) printf ("invalid argument: " "ioc_inode"); } while (0
); _gf_log_callingfn ("io-cache", "page.c", __FUNCTION__, 46,
GF_LOG_ERROR, "invalid argument: " "ioc_inode"); } while (0)
; goto out; } } while (0)
;
47
48 table = ioc_inode->table;
49 GF_VALIDATE_OR_GOTO ("io-cache", ioc_inode, out)do { if (!ioc_inode) { (*__errno_location ()) = 22; do { do {
if (0) printf ("invalid argument: " "ioc_inode"); } while (0
); _gf_log_callingfn ("io-cache", "page.c", __FUNCTION__, 49,
GF_LOG_ERROR, "invalid argument: " "ioc_inode"); } while (0)
; goto out; } } while (0)
;
50
51 rounded_offset = floor (offset, table->page_size)(((offset)/((table->page_size)?(table->page_size):1))*(
table->page_size))
;
52
53 page = rbthash_get (ioc_inode->cache.page_table, &rounded_offset,
54 sizeof (rounded_offset));
55
56 if (page != NULL((void*)0)) {
57 /* push the page to the end of the lru list */
58 list_move_tail (&page->page_lru, &ioc_inode->cache.page_lru);
59 }
60
61out:
62 return page;
63}
64
65
66ioc_page_t *
67ioc_page_get (ioc_inode_t *ioc_inode, off_t offset)
68{
69 ioc_page_t *page = NULL((void*)0);
70
71 if (ioc_inode == NULL((void*)0)) {
72 goto out;
73 }
74
75 ioc_inode_lock (ioc_inode)do { do { do { if (0) printf ("locked inode(%p)", ioc_inode);
} while (0); _gf_log (ioc_inode->table->xl->name, "page.c"
, __FUNCTION__, 75, GF_LOG_TRACE, "locked inode(%p)", ioc_inode
); } while (0); pthread_mutex_lock (&ioc_inode->inode_lock
); } while (0)
;
76 {
77 page = __ioc_page_get (ioc_inode, offset);
78 }
79 ioc_inode_unlock (ioc_inode)do { do { do { if (0) printf ("unlocked inode(%p)", ioc_inode
); } while (0); _gf_log (ioc_inode->table->xl->name,
"page.c", __FUNCTION__, 79, GF_LOG_TRACE, "unlocked inode(%p)"
, ioc_inode); } while (0); pthread_mutex_unlock (&ioc_inode
->inode_lock); } while (0)
;
80
81out:
82 return page;
83}
84
85
86/*
87 * __ioc_page_destroy -
88 *
89 * @page:
90 *
91 */
92int64_t
93__ioc_page_destroy (ioc_page_t *page)
94{
95 int64_t page_size = 0;
96
97 GF_VALIDATE_OR_GOTO ("io-cache", page, out)do { if (!page) { (*__errno_location ()) = 22; do { do { if (
0) printf ("invalid argument: " "page"); } while (0); _gf_log_callingfn
("io-cache", "page.c", __FUNCTION__, 97, GF_LOG_ERROR, "invalid argument: "
"page"); } while (0); goto out; } } while (0)
;
98
99 if (page->iobref)
100 page_size = iobref_size (page->iobref);
101
102 if (page->waitq) {
103 /* frames waiting on this page, do not destroy this page */
104 page_size = -1;
105 page->stale = 1;
106 } else {
107 rbthash_remove (page->inode->cache.page_table, &page->offset,
108 sizeof (page->offset));
109 list_del (&page->page_lru);
110
111 gf_log (page->inode->table->xl->name, GF_LOG_TRACE,do { do { if (0) printf ("destroying page = %p, offset = %""ll"
"d"" " "&& inode = %p", page, page->offset, page->
inode); } while (0); _gf_log (page->inode->table->xl
->name, "page.c", __FUNCTION__, 114, GF_LOG_TRACE, "destroying page = %p, offset = %"
"ll" "d"" " "&& inode = %p", page, page->offset, page
->inode); } while (0)
112 "destroying page = %p, offset = %"PRId64" "do { do { if (0) printf ("destroying page = %p, offset = %""ll"
"d"" " "&& inode = %p", page, page->offset, page->
inode); } while (0); _gf_log (page->inode->table->xl
->name, "page.c", __FUNCTION__, 114, GF_LOG_TRACE, "destroying page = %p, offset = %"
"ll" "d"" " "&& inode = %p", page, page->offset, page
->inode); } while (0)
113 "&& inode = %p",do { do { if (0) printf ("destroying page = %p, offset = %""ll"
"d"" " "&& inode = %p", page, page->offset, page->
inode); } while (0); _gf_log (page->inode->table->xl
->name, "page.c", __FUNCTION__, 114, GF_LOG_TRACE, "destroying page = %p, offset = %"
"ll" "d"" " "&& inode = %p", page, page->offset, page
->inode); } while (0)
114 page, page->offset, page->inode)do { do { if (0) printf ("destroying page = %p, offset = %""ll"
"d"" " "&& inode = %p", page, page->offset, page->
inode); } while (0); _gf_log (page->inode->table->xl
->name, "page.c", __FUNCTION__, 114, GF_LOG_TRACE, "destroying page = %p, offset = %"
"ll" "d"" " "&& inode = %p", page, page->offset, page
->inode); } while (0)
;
115
116 if (page->vector){
117 iobref_unref (page->iobref);
118 GF_FREE (page->vector)__gf_free (page->vector);
119 page->vector = NULL((void*)0);
120 }
121
122 page->inode = NULL((void*)0);
123 }
124
125 if (page_size != -1) {
126 pthread_mutex_destroy (&page->page_lock);
127 GF_FREE (page)__gf_free (page);
128 }
129
130out:
131 return page_size;
132}
133
134
135int64_t
136ioc_page_destroy (ioc_page_t *page)
137{
138 int64_t ret = 0;
139
140 if (page == NULL((void*)0)) {
141 goto out;
142 }
143
144 ioc_inode_lock (page->inode)do { do { do { if (0) printf ("locked inode(%p)", page->inode
); } while (0); _gf_log (page->inode->table->xl->
name, "page.c", __FUNCTION__, 144, GF_LOG_TRACE, "locked inode(%p)"
, page->inode); } while (0); pthread_mutex_lock (&page
->inode->inode_lock); } while (0)
;
145 {
146 ret = __ioc_page_destroy (page);
147 }
148 ioc_inode_unlock (page->inode)do { do { do { if (0) printf ("unlocked inode(%p)", page->
inode); } while (0); _gf_log (page->inode->table->xl
->name, "page.c", __FUNCTION__, 148, GF_LOG_TRACE, "unlocked inode(%p)"
, page->inode); } while (0); pthread_mutex_unlock (&page
->inode->inode_lock); } while (0)
;
149
150out:
151 return ret;
152}
153
154int32_t
155__ioc_inode_prune (ioc_inode_t *curr, uint64_t *size_pruned,
156 uint64_t size_to_prune, uint32_t index)
157{
158 ioc_page_t *page = NULL((void*)0), *next = NULL((void*)0);
159 int32_t ret = 0;
160 ioc_table_t *table = NULL((void*)0);
161
162 if (curr == NULL((void*)0)) {
163 goto out;
164 }
165
166 table = curr->table;
167
168 list_for_each_entry_safe (page, next, &curr->cache.page_lru, page_lru)for (page = ((typeof(*page) *)((char *)((&curr->cache.
page_lru)->next)-(unsigned long)(&((typeof(*page) *)0)
->page_lru))), next = ((typeof(*page) *)((char *)(page->
page_lru.next)-(unsigned long)(&((typeof(*page) *)0)->
page_lru))); &page->page_lru != (&curr->cache.page_lru
); page = next, next = ((typeof(*next) *)((char *)(next->page_lru
.next)-(unsigned long)(&((typeof(*next) *)0)->page_lru
))))
{
169 *size_pruned += page->size;
170 ret = __ioc_page_destroy (page);
171
172 if (ret != -1)
173 table->cache_used -= ret;
174
175 gf_log (table->xl->name, GF_LOG_TRACE,do { do { if (0) printf ("index = %d && table->cache_used = %"
"ll" "u"" && table->" "cache_size = %""ll" "u", index
, table->cache_used, table->cache_size); } while (0); _gf_log
(table->xl->name, "page.c", __FUNCTION__, 178, GF_LOG_TRACE
, "index = %d && table->cache_used = %""ll" "u"" && table->"
"cache_size = %""ll" "u", index, table->cache_used, table
->cache_size); } while (0)
176 "index = %d && table->cache_used = %"PRIu64" && table->"do { do { if (0) printf ("index = %d && table->cache_used = %"
"ll" "u"" && table->" "cache_size = %""ll" "u", index
, table->cache_used, table->cache_size); } while (0); _gf_log
(table->xl->name, "page.c", __FUNCTION__, 178, GF_LOG_TRACE
, "index = %d && table->cache_used = %""ll" "u"" && table->"
"cache_size = %""ll" "u", index, table->cache_used, table
->cache_size); } while (0)
177 "cache_size = %"PRIu64, index, table->cache_used,do { do { if (0) printf ("index = %d && table->cache_used = %"
"ll" "u"" && table->" "cache_size = %""ll" "u", index
, table->cache_used, table->cache_size); } while (0); _gf_log
(table->xl->name, "page.c", __FUNCTION__, 178, GF_LOG_TRACE
, "index = %d && table->cache_used = %""ll" "u"" && table->"
"cache_size = %""ll" "u", index, table->cache_used, table
->cache_size); } while (0)
178 table->cache_size)do { do { if (0) printf ("index = %d && table->cache_used = %"
"ll" "u"" && table->" "cache_size = %""ll" "u", index
, table->cache_used, table->cache_size); } while (0); _gf_log
(table->xl->name, "page.c", __FUNCTION__, 178, GF_LOG_TRACE
, "index = %d && table->cache_used = %""ll" "u"" && table->"
"cache_size = %""ll" "u", index, table->cache_used, table
->cache_size); } while (0)
;
179
180 if ((*size_pruned) >= size_to_prune)
181 break;
182 }
183
184 if (ioc_empty (&curr->cache)) {
185 list_del_init (&curr->inode_lru);
186 }
187
188out:
189 return 0;
190}
191/*
192 * ioc_prune - prune the cache. we have a limit to the number of pages we
193 * can have in-memory.
194 *
195 * @table: ioc_table_t of this translator
196 *
197 */
198int32_t
199ioc_prune (ioc_table_t *table)
200{
201 ioc_inode_t *curr = NULL((void*)0), *next_ioc_inode = NULL((void*)0);
202 int32_t index = 0;
203 uint64_t size_to_prune = 0;
204 uint64_t size_pruned = 0;
205
206 GF_VALIDATE_OR_GOTO ("io-cache", table, out)do { if (!table) { (*__errno_location ()) = 22; do { do { if (
0) printf ("invalid argument: " "table"); } while (0); _gf_log_callingfn
("io-cache", "page.c", __FUNCTION__, 206, GF_LOG_ERROR, "invalid argument: "
"table"); } while (0); goto out; } } while (0)
;
207
208 ioc_table_lock (table)do { do { do { if (0) printf ("locked table(%p)", table); } while
(0); _gf_log (table->xl->name, "page.c", __FUNCTION__,
208, GF_LOG_TRACE, "locked table(%p)", table); } while (0); pthread_mutex_lock
(&table->table_lock); } while (0)
;
209 {
210 size_to_prune = table->cache_used - table->cache_size;
211 /* take out the least recently used inode */
212 for (index=0; index < table->max_pri; index++) {
213 list_for_each_entry_safe (curr, next_ioc_inode,for (curr = ((typeof(*curr) *)((char *)((&table->inode_lru
[index])->next)-(unsigned long)(&((typeof(*curr) *)0)->
inode_lru))), next_ioc_inode = ((typeof(*curr) *)((char *)(curr
->inode_lru.next)-(unsigned long)(&((typeof(*curr) *)0
)->inode_lru))); &curr->inode_lru != (&table->
inode_lru[index]); curr = next_ioc_inode, next_ioc_inode = ((
typeof(*next_ioc_inode) *)((char *)(next_ioc_inode->inode_lru
.next)-(unsigned long)(&((typeof(*next_ioc_inode) *)0)->
inode_lru))))
214 &table->inode_lru[index],for (curr = ((typeof(*curr) *)((char *)((&table->inode_lru
[index])->next)-(unsigned long)(&((typeof(*curr) *)0)->
inode_lru))), next_ioc_inode = ((typeof(*curr) *)((char *)(curr
->inode_lru.next)-(unsigned long)(&((typeof(*curr) *)0
)->inode_lru))); &curr->inode_lru != (&table->
inode_lru[index]); curr = next_ioc_inode, next_ioc_inode = ((
typeof(*next_ioc_inode) *)((char *)(next_ioc_inode->inode_lru
.next)-(unsigned long)(&((typeof(*next_ioc_inode) *)0)->
inode_lru))))
215 inode_lru)for (curr = ((typeof(*curr) *)((char *)((&table->inode_lru
[index])->next)-(unsigned long)(&((typeof(*curr) *)0)->
inode_lru))), next_ioc_inode = ((typeof(*curr) *)((char *)(curr
->inode_lru.next)-(unsigned long)(&((typeof(*curr) *)0
)->inode_lru))); &curr->inode_lru != (&table->
inode_lru[index]); curr = next_ioc_inode, next_ioc_inode = ((
typeof(*next_ioc_inode) *)((char *)(next_ioc_inode->inode_lru
.next)-(unsigned long)(&((typeof(*next_ioc_inode) *)0)->
inode_lru))))
{
216 /* prune page-by-page for this inode, till
217 * we reach the equilibrium */
218 ioc_inode_lock (curr)do { do { do { if (0) printf ("locked inode(%p)", curr); } while
(0); _gf_log (curr->table->xl->name, "page.c", __FUNCTION__
, 218, GF_LOG_TRACE, "locked inode(%p)", curr); } while (0); pthread_mutex_lock
(&curr->inode_lock); } while (0)
;
219 {
220 __ioc_inode_prune (curr, &size_pruned,
221 size_to_prune,
222 index);
223 }
224 ioc_inode_unlock (curr)do { do { do { if (0) printf ("unlocked inode(%p)", curr); } while
(0); _gf_log (curr->table->xl->name, "page.c", __FUNCTION__
, 224, GF_LOG_TRACE, "unlocked inode(%p)", curr); } while (0)
; pthread_mutex_unlock (&curr->inode_lock); } while (0
)
;
225
226 if (size_pruned >= size_to_prune)
227 break;
228 } /* list_for_each_entry_safe (curr...) */
229
230 if (size_pruned >= size_to_prune)
231 break;
232 } /* for(index=0;...) */
233
234 } /* ioc_inode_table locked region end */
235 ioc_table_unlock (table)do { do { do { if (0) printf ("unlocked table(%p)", table); }
while (0); _gf_log (table->xl->name, "page.c", __FUNCTION__
, 235, GF_LOG_TRACE, "unlocked table(%p)", table); } while (0
); pthread_mutex_unlock (&table->table_lock); } while (
0)
;
236
237out:
238 return 0;
239}
240
241/*
242 * __ioc_page_create - create a new page.
243 *
244 * @ioc_inode:
245 * @offset:
246 *
247 */
248ioc_page_t *
249__ioc_page_create (ioc_inode_t *ioc_inode, off_t offset)
250{
251 ioc_table_t *table = NULL((void*)0);
252 ioc_page_t *page = NULL((void*)0);
253 off_t rounded_offset = 0;
254 ioc_page_t *newpage = NULL((void*)0);
255
256 GF_VALIDATE_OR_GOTO ("io-cache", ioc_inode, out)do { if (!ioc_inode) { (*__errno_location ()) = 22; do { do {
if (0) printf ("invalid argument: " "ioc_inode"); } while (0
); _gf_log_callingfn ("io-cache", "page.c", __FUNCTION__, 256
, GF_LOG_ERROR, "invalid argument: " "ioc_inode"); } while (0
); goto out; } } while (0)
;
257
258 table = ioc_inode->table;
259 GF_VALIDATE_OR_GOTO ("io-cache", table, out)do { if (!table) { (*__errno_location ()) = 22; do { do { if (
0) printf ("invalid argument: " "table"); } while (0); _gf_log_callingfn
("io-cache", "page.c", __FUNCTION__, 259, GF_LOG_ERROR, "invalid argument: "
"table"); } while (0); goto out; } } while (0)
;
260
261 rounded_offset = floor (offset, table->page_size)(((offset)/((table->page_size)?(table->page_size):1))*(
table->page_size))
;
262
263 newpage = GF_CALLOC (1, sizeof (*newpage), gf_ioc_mt_ioc_newpage_t)__gf_calloc (1, sizeof (*newpage), gf_ioc_mt_ioc_newpage_t);
264 if (newpage == NULL((void*)0)) {
265 goto out;
266 }
267
268 if (!ioc_inode) {
269 GF_FREE (newpage)__gf_free (newpage);
270 newpage = NULL((void*)0);
271 goto out;
272 }
273
274 newpage->offset = rounded_offset;
275 newpage->inode = ioc_inode;
276 pthread_mutex_init (&newpage->page_lock, NULL((void*)0));
277
278 rbthash_insert (ioc_inode->cache.page_table, newpage, &rounded_offset,
279 sizeof (rounded_offset));
280
281 list_add_tail (&newpage->page_lru, &ioc_inode->cache.page_lru);
282
283 page = newpage;
284
285 gf_log ("io-cache", GF_LOG_TRACE,do { do { if (0) printf ("returning new page %p", page); } while
(0); _gf_log ("io-cache", "page.c", __FUNCTION__, 286, GF_LOG_TRACE
, "returning new page %p", page); } while (0)
286 "returning new page %p", page)do { do { if (0) printf ("returning new page %p", page); } while
(0); _gf_log ("io-cache", "page.c", __FUNCTION__, 286, GF_LOG_TRACE
, "returning new page %p", page); } while (0)
;
287
288out:
289 return page;
290}
291
292/*
293 * ioc_wait_on_page - pause a frame to wait till the arrival of a page.
294 * here we need to handle the case when the frame who calls wait_on_page
295 * himself has caused page_fault
296 *
297 * @page: page to wait on
298 * @frame: call frame who is waiting on page
299 *
300 */
301void
302__ioc_wait_on_page (ioc_page_t *page, call_frame_t *frame, off_t offset,
303 size_t size)
304{
305 ioc_waitq_t *waitq = NULL((void*)0);
306 ioc_local_t *local = NULL((void*)0);
307
308 GF_VALIDATE_OR_GOTO ("io-cache", frame, out)do { if (!frame) { (*__errno_location ()) = 22; do { do { if (
0) printf ("invalid argument: " "frame"); } while (0); _gf_log_callingfn
("io-cache", "page.c", __FUNCTION__, 308, GF_LOG_ERROR, "invalid argument: "
"frame"); } while (0); goto out; } } while (0)
;
309 local = frame->local;
310
311 GF_VALIDATE_OR_GOTO (frame->this->name, local, out)do { if (!local) { (*__errno_location ()) = 22; do { do { if (
0) printf ("invalid argument: " "local"); } while (0); _gf_log_callingfn
(frame->this->name, "page.c", __FUNCTION__, 311, GF_LOG_ERROR
, "invalid argument: " "local"); } while (0); goto out; } } while
(0)
;
312
313 if (page == NULL((void*)0)) {
314 local->op_ret = -1;
315 local->op_errno = ENOMEM12;
316 gf_log (frame->this->name, GF_LOG_WARNING,do { do { if (0) printf ("asked to wait on a NULL page"); } while
(0); _gf_log (frame->this->name, "page.c", __FUNCTION__
, 317, GF_LOG_WARNING, "asked to wait on a NULL page"); } while
(0)
317 "asked to wait on a NULL page")do { do { if (0) printf ("asked to wait on a NULL page"); } while
(0); _gf_log (frame->this->name, "page.c", __FUNCTION__
, 317, GF_LOG_WARNING, "asked to wait on a NULL page"); } while
(0)
;
318 }
319
320 waitq = GF_CALLOC (1, sizeof (*waitq), gf_ioc_mt_ioc_waitq_t)__gf_calloc (1, sizeof (*waitq), gf_ioc_mt_ioc_waitq_t);
321 if (waitq == NULL((void*)0)) {
322 local->op_ret = -1;
323 local->op_errno = ENOMEM12;
324 goto out;
325 }
326
327 gf_log (frame->this->name, GF_LOG_TRACE,do { do { if (0) printf ("frame(%p) waiting on page = %p, offset=%"
"ll" "d"", " "size=%""zu""", frame, page, offset, size); } while
(0); _gf_log (frame->this->name, "page.c", __FUNCTION__
, 330, GF_LOG_TRACE, "frame(%p) waiting on page = %p, offset=%"
"ll" "d"", " "size=%""zu""", frame, page, offset, size); } while
(0)
328 "frame(%p) waiting on page = %p, offset=%"PRId64", "do { do { if (0) printf ("frame(%p) waiting on page = %p, offset=%"
"ll" "d"", " "size=%""zu""", frame, page, offset, size); } while
(0); _gf_log (frame->this->name, "page.c", __FUNCTION__
, 330, GF_LOG_TRACE, "frame(%p) waiting on page = %p, offset=%"
"ll" "d"", " "size=%""zu""", frame, page, offset, size); } while
(0)
329 "size=%"GF_PRI_SIZET"",do { do { if (0) printf ("frame(%p) waiting on page = %p, offset=%"
"ll" "d"", " "size=%""zu""", frame, page, offset, size); } while
(0); _gf_log (frame->this->name, "page.c", __FUNCTION__
, 330, GF_LOG_TRACE, "frame(%p) waiting on page = %p, offset=%"
"ll" "d"", " "size=%""zu""", frame, page, offset, size); } while
(0)
330 frame, page, offset, size)do { do { if (0) printf ("frame(%p) waiting on page = %p, offset=%"
"ll" "d"", " "size=%""zu""", frame, page, offset, size); } while
(0); _gf_log (frame->this->name, "page.c", __FUNCTION__
, 330, GF_LOG_TRACE, "frame(%p) waiting on page = %p, offset=%"
"ll" "d"", " "size=%""zu""", frame, page, offset, size); } while
(0)
;
331
332 waitq->data = frame;
333 waitq->next = page->waitq;
334 waitq->pending_offset = offset;
335 waitq->pending_size = size;
336 page->waitq = waitq;
337 /* one frame can wait only once on a given page,
338 * local->wait_count is number of pages a frame is waiting on */
339 ioc_local_lock (local)do { do { do { if (0) printf ("locked local(%p)", local); } while
(0); _gf_log (local->inode->table->xl->name, "page.c"
, __FUNCTION__, 339, GF_LOG_TRACE, "locked local(%p)", local)
; } while (0); pthread_mutex_lock (&local->local_lock)
; } while (0)
;
340 {
341 local->wait_count++;
342 }
343 ioc_local_unlock (local)do { do { do { if (0) printf ("unlocked local(%p)", local); }
while (0); _gf_log (local->inode->table->xl->name
, "page.c", __FUNCTION__, 343, GF_LOG_TRACE, "unlocked local(%p)"
, local); } while (0); pthread_mutex_unlock (&local->local_lock
); } while (0)
;
344
345out:
346 return;
347}
348
349
350/*
351 * ioc_cache_still_valid - see if cached pages ioc_inode are still valid
352 * against given stbuf
353 *
354 * @ioc_inode:
355 * @stbuf:
356 *
357 * assumes ioc_inode is locked
358 */
359int8_t
360ioc_cache_still_valid (ioc_inode_t *ioc_inode, struct iatt *stbuf)
361{
362 int8_t cache_still_valid = 1;
363
364 GF_VALIDATE_OR_GOTO ("io-cache", ioc_inode, out)do { if (!ioc_inode) { (*__errno_location ()) = 22; do { do {
if (0) printf ("invalid argument: " "ioc_inode"); } while (0
); _gf_log_callingfn ("io-cache", "page.c", __FUNCTION__, 364
, GF_LOG_ERROR, "invalid argument: " "ioc_inode"); } while (0
); goto out; } } while (0)
;
365
366#if 0
367 if (!stbuf || (stbuf->ia_mtime != ioc_inode->cache.mtime) ||
368 (stbuf->st_mtim.tv_nsec != ioc_inode->stbuf.st_mtim.tv_nsec))
369 cache_still_valid = 0;
370
371#else
372 if (!stbuf || (stbuf->ia_mtime != ioc_inode->cache.mtime)
373 || (stbuf->ia_mtime_nsec != ioc_inode->cache.mtime_nsec))
374 cache_still_valid = 0;
375
376#endif
377
378#if 0
379 /* talk with avati@gluster.com to enable this section */
380 if (!ioc_inode->mtime && stbuf) {
381 cache_still_valid = 1;
382 ioc_inode->mtime = stbuf->ia_mtime;
383 }
384#endif
385
386out:
387 return cache_still_valid;
388}
389
390
391void
392ioc_waitq_return (ioc_waitq_t *waitq)
393{
394 ioc_waitq_t *trav = NULL((void*)0);
395 ioc_waitq_t *next = NULL((void*)0);
396 call_frame_t *frame = NULL((void*)0);
397
398 for (trav = waitq; trav; trav = next) {
399 next = trav->next;
400
401 frame = trav->data;
402 ioc_frame_return (frame);
403 GF_FREE (trav)__gf_free (trav);
404 }
405}
406
407
408int
409ioc_fault_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
410 int32_t op_ret, int32_t op_errno, struct iovec *vector,
411 int32_t count, struct iatt *stbuf, struct iobref *iobref,
412 dict_t *xdata)
413{
414 ioc_local_t *local = NULL((void*)0);
415 off_t offset = 0;
416 ioc_inode_t *ioc_inode = NULL((void*)0);
417 ioc_table_t *table = NULL((void*)0);
418 ioc_page_t *page = NULL((void*)0);
419 int32_t destroy_size = 0;
420 size_t page_size = 0;
421 ioc_waitq_t *waitq = NULL((void*)0);
422 size_t iobref_page_size = 0;
423 char zero_filled = 0;
424
425 GF_ASSERT (frame)do { if (!(frame)) { do { do { if (0) printf ("Assertion failed: "
"frame"); } while (0); _gf_log_callingfn ("", "page.c", __FUNCTION__
, 425, GF_LOG_ERROR, "Assertion failed: " "frame"); } while (
0); } } while (0)
;
426
427 local = frame->local;
428 GF_ASSERT (local)do { if (!(local)) { do { do { if (0) printf ("Assertion failed: "
"local"); } while (0); _gf_log_callingfn ("", "page.c", __FUNCTION__
, 428, GF_LOG_ERROR, "Assertion failed: " "local"); } while (
0); } } while (0)
;
429
430 offset = local->pending_offset;
431 ioc_inode = local->inode;
1
Value assigned to 'ioc_inode'
432 GF_ASSERT (ioc_inode)do { if (!(ioc_inode)) { do { do { if (0) printf ("Assertion failed: "
"ioc_inode"); } while (0); _gf_log_callingfn ("", "page.c", __FUNCTION__
, 432, GF_LOG_ERROR, "Assertion failed: " "ioc_inode"); } while
(0); } } while (0)
;
2
Within the expansion of the macro 'GF_ASSERT':
a
Assuming 'ioc_inode' is null
433
434 table = ioc_inode->table;
3
Access to field 'table' results in a dereference of a null pointer (loaded from variable 'ioc_inode')
435 GF_ASSERT (table)do { if (!(table)) { do { do { if (0) printf ("Assertion failed: "
"table"); } while (0); _gf_log_callingfn ("", "page.c", __FUNCTION__
, 435, GF_LOG_ERROR, "Assertion failed: " "table"); } while (
0); } } while (0)
;
436
437 zero_filled = ((op_ret >=0) && (stbuf->ia_mtime == 0));
438
439 ioc_inode_lock (ioc_inode)do { do { do { if (0) printf ("locked inode(%p)", ioc_inode);
} while (0); _gf_log (ioc_inode->table->xl->name, "page.c"
, __FUNCTION__, 439, GF_LOG_TRACE, "locked inode(%p)", ioc_inode
); } while (0); pthread_mutex_lock (&ioc_inode->inode_lock
); } while (0)
;
440 {
441 if (op_ret == -1 || !(zero_filled ||
442 ioc_cache_still_valid(ioc_inode,
443 stbuf))) {
444 gf_log (ioc_inode->table->xl->name, GF_LOG_TRACE,do { do { if (0) printf ("cache for inode(%p) is invalid. flushing "
"all pages", ioc_inode); } while (0); _gf_log (ioc_inode->
table->xl->name, "page.c", __FUNCTION__, 446, GF_LOG_TRACE
, "cache for inode(%p) is invalid. flushing " "all pages", ioc_inode
); } while (0)
445 "cache for inode(%p) is invalid. flushing "do { do { if (0) printf ("cache for inode(%p) is invalid. flushing "
"all pages", ioc_inode); } while (0); _gf_log (ioc_inode->
table->xl->name, "page.c", __FUNCTION__, 446, GF_LOG_TRACE
, "cache for inode(%p) is invalid. flushing " "all pages", ioc_inode
); } while (0)
446 "all pages", ioc_inode)do { do { if (0) printf ("cache for inode(%p) is invalid. flushing "
"all pages", ioc_inode); } while (0); _gf_log (ioc_inode->
table->xl->name, "page.c", __FUNCTION__, 446, GF_LOG_TRACE
, "cache for inode(%p) is invalid. flushing " "all pages", ioc_inode
); } while (0)
;
447 destroy_size = __ioc_inode_flush (ioc_inode);
448 }
449
450 if ((op_ret >= 0) && !zero_filled) {
451 ioc_inode->cache.mtime = stbuf->ia_mtime;
452 ioc_inode->cache.mtime_nsec = stbuf->ia_mtime_nsec;
453 }
454
455 gettimeofday (&ioc_inode->cache.tv, NULL((void*)0));
456
457 if (op_ret < 0) {
458 /* error, readv returned -1 */
459 page = __ioc_page_get (ioc_inode, offset);
460 if (page)
461 waitq = __ioc_page_error (page, op_ret,
462 op_errno);
463 } else {
464 gf_log (ioc_inode->table->xl->name, GF_LOG_TRACE,do { do { if (0) printf ("op_ret = %d", op_ret); } while (0);
_gf_log (ioc_inode->table->xl->name, "page.c", __FUNCTION__
, 465, GF_LOG_TRACE, "op_ret = %d", op_ret); } while (0)
465 "op_ret = %d", op_ret)do { do { if (0) printf ("op_ret = %d", op_ret); } while (0);
_gf_log (ioc_inode->table->xl->name, "page.c", __FUNCTION__
, 465, GF_LOG_TRACE, "op_ret = %d", op_ret); } while (0)
;
466 page = __ioc_page_get (ioc_inode, offset);
467 if (!page) {
468 /* page was flushed */
469 /* some serious bug ? */
470 gf_log (frame->this->name, GF_LOG_WARNING,do { do { if (0) printf ("wasted copy: %""ll" "d""[+%""ll" "d"
"] " "ioc_inode=%p", offset, table->page_size, ioc_inode);
} while (0); _gf_log (frame->this->name, "page.c", __FUNCTION__
, 473, GF_LOG_WARNING, "wasted copy: %""ll" "d""[+%""ll" "d""] "
"ioc_inode=%p", offset, table->page_size, ioc_inode); } while
(0)
471 "wasted copy: %"PRId64"[+%"PRId64"] "do { do { if (0) printf ("wasted copy: %""ll" "d""[+%""ll" "d"
"] " "ioc_inode=%p", offset, table->page_size, ioc_inode);
} while (0); _gf_log (frame->this->name, "page.c", __FUNCTION__
, 473, GF_LOG_WARNING, "wasted copy: %""ll" "d""[+%""ll" "d""] "
"ioc_inode=%p", offset, table->page_size, ioc_inode); } while
(0)
472 "ioc_inode=%p", offset,do { do { if (0) printf ("wasted copy: %""ll" "d""[+%""ll" "d"
"] " "ioc_inode=%p", offset, table->page_size, ioc_inode);
} while (0); _gf_log (frame->this->name, "page.c", __FUNCTION__
, 473, GF_LOG_WARNING, "wasted copy: %""ll" "d""[+%""ll" "d""] "
"ioc_inode=%p", offset, table->page_size, ioc_inode); } while
(0)
473 table->page_size, ioc_inode)do { do { if (0) printf ("wasted copy: %""ll" "d""[+%""ll" "d"
"] " "ioc_inode=%p", offset, table->page_size, ioc_inode);
} while (0); _gf_log (frame->this->name, "page.c", __FUNCTION__
, 473, GF_LOG_WARNING, "wasted copy: %""ll" "d""[+%""ll" "d""] "
"ioc_inode=%p", offset, table->page_size, ioc_inode); } while
(0)
;
474 } else {
475 if (page->vector) {
476 iobref_unref (page->iobref);
477 GF_FREE (page->vector)__gf_free (page->vector);
478 page->vector = NULL((void*)0);
479 }
480
481 /* keep a copy of the page for our cache */
482 page->vector = iov_dup (vector, count);
483 if (page->vector == NULL((void*)0)) {
484 page = __ioc_page_get (ioc_inode,
485 offset);
486 if (page != NULL((void*)0))
487 waitq = __ioc_page_error (page,
488 -1,
489 ENOMEM12);
490 goto unlock;
491 }
492
493 page->count = count;
494 if (iobref) {
495 page->iobref = iobref_ref (iobref);
496 } else {
497 /* TODO: we have got a response to
498 * our request and no data */
499 gf_log (frame->this->name,do { do { if (0) printf ("frame>root>rsp_refs is null")
; } while (0); _gf_log (frame->this->name, "page.c", __FUNCTION__
, 501, GF_LOG_CRITICAL, "frame>root>rsp_refs is null");
} while (0)
500 GF_LOG_CRITICAL,do { do { if (0) printf ("frame>root>rsp_refs is null")
; } while (0); _gf_log (frame->this->name, "page.c", __FUNCTION__
, 501, GF_LOG_CRITICAL, "frame>root>rsp_refs is null");
} while (0)
501 "frame>root>rsp_refs is null")do { do { if (0) printf ("frame>root>rsp_refs is null")
; } while (0); _gf_log (frame->this->name, "page.c", __FUNCTION__
, 501, GF_LOG_CRITICAL, "frame>root>rsp_refs is null");
} while (0)
;
502 } /* if(frame->root->rsp_refs) */
503
504 /* page->size should indicate exactly how
505 * much the readv call to the child
506 * translator returned. earlier op_ret
507 * from child translator was used, which
508 * gave rise to a bug where reads from
509 * io-cached volume were resulting in 0
510 * byte replies */
511 page_size = iov_length(vector, count);
512 page->size = page_size;
513 page->op_errno = op_errno;
514
515 iobref_page_size = iobref_size (page->iobref);
516
517 if (page->waitq) {
518 /* wake up all the frames waiting on
519 * this page, including
520 * the frame which triggered fault */
521 waitq = __ioc_page_wakeup (page,
522 op_errno);
523 } /* if(page->waitq) */
524 } /* if(!page)...else */
525 } /* if(op_ret < 0)...else */
526 } /* ioc_inode locked region end */
527unlock:
528 ioc_inode_unlock (ioc_inode)do { do { do { if (0) printf ("unlocked inode(%p)", ioc_inode
); } while (0); _gf_log (ioc_inode->table->xl->name,
"page.c", __FUNCTION__, 528, GF_LOG_TRACE, "unlocked inode(%p)"
, ioc_inode); } while (0); pthread_mutex_unlock (&ioc_inode
->inode_lock); } while (0)
;
529
530 ioc_waitq_return (waitq);
531
532 if (iobref_page_size) {
533 ioc_table_lock (table)do { do { do { if (0) printf ("locked table(%p)", table); } while
(0); _gf_log (table->xl->name, "page.c", __FUNCTION__,
533, GF_LOG_TRACE, "locked table(%p)", table); } while (0); pthread_mutex_lock
(&table->table_lock); } while (0)
;
534 {
535 table->cache_used += iobref_page_size;
536 }
537 ioc_table_unlock (table)do { do { do { if (0) printf ("unlocked table(%p)", table); }
while (0); _gf_log (table->xl->name, "page.c", __FUNCTION__
, 537, GF_LOG_TRACE, "unlocked table(%p)", table); } while (0
); pthread_mutex_unlock (&table->table_lock); } while (
0)
;
538 }
539
540 if (destroy_size) {
541 ioc_table_lock (table)do { do { do { if (0) printf ("locked table(%p)", table); } while
(0); _gf_log (table->xl->name, "page.c", __FUNCTION__,
541, GF_LOG_TRACE, "locked table(%p)", table); } while (0); pthread_mutex_lock
(&table->table_lock); } while (0)
;
542 {
543 table->cache_used -= destroy_size;
544 }
545 ioc_table_unlock (table)do { do { do { if (0) printf ("unlocked table(%p)", table); }
while (0); _gf_log (table->xl->name, "page.c", __FUNCTION__
, 545, GF_LOG_TRACE, "unlocked table(%p)", table); } while (0
); pthread_mutex_unlock (&table->table_lock); } while (
0)
;
546 }
547
548 if (ioc_need_prune (ioc_inode->table)) {
549 ioc_prune (ioc_inode->table);
550 }
551
552 gf_log (frame->this->name, GF_LOG_TRACE, "fault frame %p returned",do { do { if (0) printf ("fault frame %p returned", frame); }
while (0); _gf_log (frame->this->name, "page.c", __FUNCTION__
, 553, GF_LOG_TRACE, "fault frame %p returned", frame); } while
(0)
553 frame)do { do { if (0) printf ("fault frame %p returned", frame); }
while (0); _gf_log (frame->this->name, "page.c", __FUNCTION__
, 553, GF_LOG_TRACE, "fault frame %p returned", frame); } while
(0)
;
554 pthread_mutex_destroy (&local->local_lock);
555
556 fd_unref (local->fd);
557
558 STACK_DESTROY (frame->root);
559 return 0;
560}
561
562
563/*
564 * ioc_page_fault -
565 *
566 * @ioc_inode:
567 * @frame:
568 * @fd:
569 * @offset:
570 *
571 */
572void
573ioc_page_fault (ioc_inode_t *ioc_inode, call_frame_t *frame, fd_t *fd,
574 off_t offset)
575{
576 ioc_table_t *table = NULL((void*)0);
577 call_frame_t *fault_frame = NULL((void*)0);
578 ioc_local_t *fault_local = NULL((void*)0);
579 int32_t op_ret = -1, op_errno = -1;
580 ioc_waitq_t *waitq = NULL((void*)0);
581 ioc_page_t *page = NULL((void*)0);
582
583 GF_ASSERT (ioc_inode)do { if (!(ioc_inode)) { do { do { if (0) printf ("Assertion failed: "
"ioc_inode"); } while (0); _gf_log_callingfn ("", "page.c", __FUNCTION__
, 583, GF_LOG_ERROR, "Assertion failed: " "ioc_inode"); } while
(0); } } while (0)
;
584 if (frame == NULL((void*)0)) {
585 op_ret = -1;
586 op_errno = EINVAL22;
587 gf_log ("io-cache", GF_LOG_WARNING,do { do { if (0) printf ("page fault on a NULL frame"); } while
(0); _gf_log ("io-cache", "page.c", __FUNCTION__, 588, GF_LOG_WARNING
, "page fault on a NULL frame"); } while (0)
588 "page fault on a NULL frame")do { do { if (0) printf ("page fault on a NULL frame"); } while
(0); _gf_log ("io-cache", "page.c", __FUNCTION__, 588, GF_LOG_WARNING
, "page fault on a NULL frame"); } while (0)
;
589 goto err;
590 }
591
592 table = ioc_inode->table;
593 fault_frame = copy_frame (frame);
594 if (fault_frame == NULL((void*)0)) {
595 op_ret = -1;
596 op_errno = ENOMEM12;
597 goto err;
598 }
599
600 fault_local = mem_get0 (THIS(*__glusterfs_this_location())->local_pool);
601 if (fault_local == NULL((void*)0)) {
602 op_ret = -1;
603 op_errno = ENOMEM12;
604 STACK_DESTROY (fault_frame->root);
605 goto err;
606 }
607
608 /* NOTE: copy_frame() means, the frame the fop whose fd_ref we
609 * are using till now won't be valid till we get reply from server.
610 * we unref this fd, in fault_cbk */
611 fault_local->fd = fd_ref (fd);
612
613 fault_frame->local = fault_local;
614 pthread_mutex_init (&fault_local->local_lock, NULL((void*)0));
615
616 INIT_LIST_HEAD (&fault_local->fill_list)do { (&fault_local->fill_list)->next = (&fault_local
->fill_list)->prev = &fault_local->fill_list; } while
(0)
;
617 fault_local->pending_offset = offset;
618 fault_local->pending_size = table->page_size;
619 fault_local->inode = ioc_inode;
620
621 gf_log (frame->this->name, GF_LOG_TRACE,do { do { if (0) printf ("stack winding page fault for offset = %"
"ll" "d"" with " "frame %p", offset, fault_frame); } while (0
); _gf_log (frame->this->name, "page.c", __FUNCTION__, 623
, GF_LOG_TRACE, "stack winding page fault for offset = %""ll"
"d"" with " "frame %p", offset, fault_frame); } while (0)
622 "stack winding page fault for offset = %"PRId64" with "do { do { if (0) printf ("stack winding page fault for offset = %"
"ll" "d"" with " "frame %p", offset, fault_frame); } while (0
); _gf_log (frame->this->name, "page.c", __FUNCTION__, 623
, GF_LOG_TRACE, "stack winding page fault for offset = %""ll"
"d"" with " "frame %p", offset, fault_frame); } while (0)
623 "frame %p", offset, fault_frame)do { do { if (0) printf ("stack winding page fault for offset = %"
"ll" "d"" with " "frame %p", offset, fault_frame); } while (0
); _gf_log (frame->this->name, "page.c", __FUNCTION__, 623
, GF_LOG_TRACE, "stack winding page fault for offset = %""ll"
"d"" with " "frame %p", offset, fault_frame); } while (0)
;
624
625 STACK_WIND (fault_frame, ioc_fault_cbk, 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__, 627
, GF_LOG_ERROR, "alloc failed"); } while (0); break; } typeof
( (fault_frame->this->children->xlator)->fops->
readv_cbk) tmp_cbk = ioc_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 = "ioc_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), fd, table->page_size, offset, 0, ((void
*)0)); (*__glusterfs_this_location()) = old_THIS; } while (0)
626 FIRST_CHILD(fault_frame->this)->fops->readv, fd,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__, 627
, GF_LOG_ERROR, "alloc failed"); } while (0); break; } typeof
( (fault_frame->this->children->xlator)->fops->
readv_cbk) tmp_cbk = ioc_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 = "ioc_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), fd, table->page_size, offset, 0, ((void
*)0)); (*__glusterfs_this_location()) = old_THIS; } while (0)
627 table->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__, 627
, GF_LOG_ERROR, "alloc failed"); } while (0); break; } typeof
( (fault_frame->this->children->xlator)->fops->
readv_cbk) tmp_cbk = ioc_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 = "ioc_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), fd, table->page_size, offset, 0, ((void
*)0)); (*__glusterfs_this_location()) = old_THIS; } while (0)
;
628 return;
629
630err:
631 ioc_inode_lock (ioc_inode)do { do { do { if (0) printf ("locked inode(%p)", ioc_inode);
} while (0); _gf_log (ioc_inode->table->xl->name, "page.c"
, __FUNCTION__, 631, GF_LOG_TRACE, "locked inode(%p)", ioc_inode
); } while (0); pthread_mutex_lock (&ioc_inode->inode_lock
); } while (0)
;
632 {
633 page = __ioc_page_get (ioc_inode, offset);
634 if (page != NULL((void*)0)) {
635 waitq = __ioc_page_error (page, op_ret, op_errno);
636 }
637 }
638 ioc_inode_unlock (ioc_inode)do { do { do { if (0) printf ("unlocked inode(%p)", ioc_inode
); } while (0); _gf_log (ioc_inode->table->xl->name,
"page.c", __FUNCTION__, 638, GF_LOG_TRACE, "unlocked inode(%p)"
, ioc_inode); } while (0); pthread_mutex_unlock (&ioc_inode
->inode_lock); } while (0)
;
639
640 if (waitq != NULL((void*)0)) {
641 ioc_waitq_return (waitq);
642 }
643}
644
645
646int32_t
647__ioc_frame_fill (ioc_page_t *page, call_frame_t *frame, off_t offset,
648 size_t size, int32_t op_errno)
649{
650 ioc_local_t *local = NULL((void*)0);
651 ioc_fill_t *fill = NULL((void*)0);
652 off_t src_offset = 0;
653 off_t dst_offset = 0;
654 ssize_t copy_size = 0;
655 ioc_inode_t *ioc_inode = NULL((void*)0);
656 ioc_fill_t *new = NULL((void*)0);
657 int8_t found = 0;
658 int32_t ret = -1;
659
660 GF_VALIDATE_OR_GOTO ("io-cache", frame, out)do { if (!frame) { (*__errno_location ()) = 22; do { do { if (
0) printf ("invalid argument: " "frame"); } while (0); _gf_log_callingfn
("io-cache", "page.c", __FUNCTION__, 660, GF_LOG_ERROR, "invalid argument: "
"frame"); } while (0); goto out; } } while (0)
;
661
662 local = frame->local;
663 GF_VALIDATE_OR_GOTO (frame->this->name, local, out)do { if (!local) { (*__errno_location ()) = 22; do { do { if (
0) printf ("invalid argument: " "local"); } while (0); _gf_log_callingfn
(frame->this->name, "page.c", __FUNCTION__, 663, GF_LOG_ERROR
, "invalid argument: " "local"); } while (0); goto out; } } while
(0)
;
664
665 if (page == NULL((void*)0)) {
666 gf_log (frame->this->name, GF_LOG_WARNING,do { do { if (0) printf ("NULL page has been provided to serve read request"
); } while (0); _gf_log (frame->this->name, "page.c", __FUNCTION__
, 667, GF_LOG_WARNING, "NULL page has been provided to serve read request"
); } while (0)
667 "NULL page has been provided to serve read request")do { do { if (0) printf ("NULL page has been provided to serve read request"
); } while (0); _gf_log (frame->this->name, "page.c", __FUNCTION__
, 667, GF_LOG_WARNING, "NULL page has been provided to serve read request"
); } while (0)
;
668 local->op_ret = -1;
669 local->op_errno = EINVAL22;
670 goto out;
671 }
672
673 ioc_inode = page->inode;
674
675 gf_log (frame->this->name, GF_LOG_TRACE,do { do { if (0) printf ("frame (%p) offset = %""ll" "d"" && size = %"
"zu"" " "&& page->size = %""zu"" && wait_count = %d"
, frame, offset, size, page->size, local->wait_count); }
while (0); _gf_log (frame->this->name, "page.c", __FUNCTION__
, 678, GF_LOG_TRACE, "frame (%p) offset = %""ll" "d"" && size = %"
"zu"" " "&& page->size = %""zu"" && wait_count = %d"
, frame, offset, size, page->size, local->wait_count); }
while (0)
676 "frame (%p) offset = %"PRId64" && size = %"GF_PRI_SIZET" "do { do { if (0) printf ("frame (%p) offset = %""ll" "d"" && size = %"
"zu"" " "&& page->size = %""zu"" && wait_count = %d"
, frame, offset, size, page->size, local->wait_count); }
while (0); _gf_log (frame->this->name, "page.c", __FUNCTION__
, 678, GF_LOG_TRACE, "frame (%p) offset = %""ll" "d"" && size = %"
"zu"" " "&& page->size = %""zu"" && wait_count = %d"
, frame, offset, size, page->size, local->wait_count); }
while (0)
677 "&& page->size = %"GF_PRI_SIZET" && wait_count = %d",do { do { if (0) printf ("frame (%p) offset = %""ll" "d"" && size = %"
"zu"" " "&& page->size = %""zu"" && wait_count = %d"
, frame, offset, size, page->size, local->wait_count); }
while (0); _gf_log (frame->this->name, "page.c", __FUNCTION__
, 678, GF_LOG_TRACE, "frame (%p) offset = %""ll" "d"" && size = %"
"zu"" " "&& page->size = %""zu"" && wait_count = %d"
, frame, offset, size, page->size, local->wait_count); }
while (0)
678 frame, offset, size, page->size, local->wait_count)do { do { if (0) printf ("frame (%p) offset = %""ll" "d"" && size = %"
"zu"" " "&& page->size = %""zu"" && wait_count = %d"
, frame, offset, size, page->size, local->wait_count); }
while (0); _gf_log (frame->this->name, "page.c", __FUNCTION__
, 678, GF_LOG_TRACE, "frame (%p) offset = %""ll" "d"" && size = %"
"zu"" " "&& page->size = %""zu"" && wait_count = %d"
, frame, offset, size, page->size, local->wait_count); }
while (0)
;
679
680 /* immediately move this page to the end of the page_lru list */
681 list_move_tail (&page->page_lru, &ioc_inode->cache.page_lru);
682 /* fill local->pending_size bytes from local->pending_offset */
683 if (local->op_ret != -1) {
684 local->op_errno = op_errno;
685
686 if (page->size == 0) {
687 goto done;
688 }
689
690 if (offset > page->offset)
691 /* offset is offset in file, convert it to offset in
692 * page */
693 src_offset = offset - page->offset;
694 /*FIXME: since offset is the offset within page is the
695 * else case valid? */
696 else
697 /* local->pending_offset is in previous page. do not
698 * fill until we have filled all previous pages */
699 dst_offset = page->offset - offset;
700
701 /* we have to copy from offset to either end of this page
702 * or till the requested size */
703 copy_size = min (page->size - src_offset,((page->size - src_offset)<(size - dst_offset)?(page->
size - src_offset):(size - dst_offset))
704 size - dst_offset)((page->size - src_offset)<(size - dst_offset)?(page->
size - src_offset):(size - dst_offset))
;
705
706 if (copy_size < 0) {
707 /* if page contains fewer bytes and the required offset
708 is beyond the page size in the page */
709 copy_size = src_offset = 0;
710 }
711
712 gf_log (page->inode->table->xl->name, GF_LOG_TRACE,do { do { if (0) printf ("copy_size = %""zu"" && src_offset = "
"%""ll" "d"" && dst_offset = %""ll" "d""", copy_size
, src_offset, dst_offset); } while (0); _gf_log (page->inode
->table->xl->name, "page.c", __FUNCTION__, 715, GF_LOG_TRACE
, "copy_size = %""zu"" && src_offset = " "%""ll" "d"" && dst_offset = %"
"ll" "d""", copy_size, src_offset, dst_offset); } while (0)
713 "copy_size = %"GF_PRI_SIZET" && src_offset = "do { do { if (0) printf ("copy_size = %""zu"" && src_offset = "
"%""ll" "d"" && dst_offset = %""ll" "d""", copy_size
, src_offset, dst_offset); } while (0); _gf_log (page->inode
->table->xl->name, "page.c", __FUNCTION__, 715, GF_LOG_TRACE
, "copy_size = %""zu"" && src_offset = " "%""ll" "d"" && dst_offset = %"
"ll" "d""", copy_size, src_offset, dst_offset); } while (0)
714 "%"PRId64" && dst_offset = %"PRId64"",do { do { if (0) printf ("copy_size = %""zu"" && src_offset = "
"%""ll" "d"" && dst_offset = %""ll" "d""", copy_size
, src_offset, dst_offset); } while (0); _gf_log (page->inode
->table->xl->name, "page.c", __FUNCTION__, 715, GF_LOG_TRACE
, "copy_size = %""zu"" && src_offset = " "%""ll" "d"" && dst_offset = %"
"ll" "d""", copy_size, src_offset, dst_offset); } while (0)
715 copy_size, src_offset, dst_offset)do { do { if (0) printf ("copy_size = %""zu"" && src_offset = "
"%""ll" "d"" && dst_offset = %""ll" "d""", copy_size
, src_offset, dst_offset); } while (0); _gf_log (page->inode
->table->xl->name, "page.c", __FUNCTION__, 715, GF_LOG_TRACE
, "copy_size = %""zu"" && src_offset = " "%""ll" "d"" && dst_offset = %"
"ll" "d""", copy_size, src_offset, dst_offset); } while (0)
;
716
717 {
718 new = GF_CALLOC (1, sizeof (*new),__gf_calloc (1, sizeof (*new), gf_ioc_mt_ioc_fill_t)
719 gf_ioc_mt_ioc_fill_t)__gf_calloc (1, sizeof (*new), gf_ioc_mt_ioc_fill_t);
720 if (new == NULL((void*)0)) {
721 local->op_ret = -1;
722 local->op_errno = ENOMEM12;
723 goto out;
724 }
725
726 new->offset = page->offset;
727 new->size = copy_size;
728 new->iobref = iobref_ref (page->iobref);
729 new->count = iov_subset (page->vector, page->count,
730 src_offset,
731 src_offset + copy_size,
732 NULL((void*)0));
733
734 new->vector = GF_CALLOC (new->count,__gf_calloc (new->count, sizeof (struct iovec), gf_ioc_mt_iovec
)
735 sizeof (struct iovec),__gf_calloc (new->count, sizeof (struct iovec), gf_ioc_mt_iovec
)
736 gf_ioc_mt_iovec)__gf_calloc (new->count, sizeof (struct iovec), gf_ioc_mt_iovec
)
;
737 if (new->vector == NULL((void*)0)) {
738 local->op_ret = -1;
739 local->op_errno = ENOMEM12;
740
741 iobref_unref (new->iobref);
742 GF_FREE (new)__gf_free (new);
743 goto out;
744 }
745
746 new->count = iov_subset (page->vector, page->count,
747 src_offset,
748 src_offset + copy_size,
749 new->vector);
750
751 /* add the ioc_fill to fill_list for this frame */
752 if (list_empty (&local->fill_list)) {
753 /* if list is empty, then this is the first
754 * time we are filling frame, add the
755 * ioc_fill_t to the end of list */
756 list_add_tail (&new->list, &local->fill_list);
757 } else {
758 found = 0;
759 /* list is not empty, we need to look for
760 * where this offset fits in list */
761 list_for_each_entry (fill, &local->fill_list,for (fill = ((typeof(*fill) *)((char *)((&local->fill_list
)->next)-(unsigned long)(&((typeof(*fill) *)0)->list
))); &fill->list != (&local->fill_list); fill =
((typeof(*fill) *)((char *)(fill->list.next)-(unsigned long
)(&((typeof(*fill) *)0)->list))))
762 list)for (fill = ((typeof(*fill) *)((char *)((&local->fill_list
)->next)-(unsigned long)(&((typeof(*fill) *)0)->list
))); &fill->list != (&local->fill_list); fill =
((typeof(*fill) *)((char *)(fill->list.next)-(unsigned long
)(&((typeof(*fill) *)0)->list))))
{
763 if (fill->offset > new->offset) {
764 found = 1;
765 break;
766 }
767 }
768
769 if (found) {
770 list_add_tail (&new->list,
771 &fill->list);
772 } else {
773 list_add_tail (&new->list,
774 &local->fill_list);
775 }
776 }
777 }
778
779 local->op_ret += copy_size;
780 }
781
782done:
783 ret = 0;
784out:
785 return ret;
786}
787
788/*
789 * ioc_frame_unwind - frame unwinds only from here
790 *
791 * @frame: call frame to unwind
792 *
793 * to be used only by ioc_frame_return(), when a frame has
794 * finished waiting on all pages, required
795 *
796 */
797static void
798ioc_frame_unwind (call_frame_t *frame)
799{
800 ioc_local_t *local = NULL((void*)0);
801 ioc_fill_t *fill = NULL((void*)0), *next = NULL((void*)0);
802 int32_t count = 0;
803 struct iovec *vector = NULL((void*)0);
804 int32_t copied = 0;
805 struct iobref *iobref = NULL((void*)0);
806 struct iatt stbuf = {0,};
807 int32_t op_ret = 0, op_errno = 0;
808
809 GF_ASSERT (frame)do { if (!(frame)) { do { do { if (0) printf ("Assertion failed: "
"frame"); } while (0); _gf_log_callingfn ("", "page.c", __FUNCTION__
, 809, GF_LOG_ERROR, "Assertion failed: " "frame"); } while (
0); } } while (0)
;
810
811 local = frame->local;
812 if (local == NULL((void*)0)) {
813 gf_log (frame->this->name, GF_LOG_WARNING,do { do { if (0) printf ("local is NULL"); } while (0); _gf_log
(frame->this->name, "page.c", __FUNCTION__, 814, GF_LOG_WARNING
, "local is NULL"); } while (0)
814 "local is NULL")do { do { if (0) printf ("local is NULL"); } while (0); _gf_log
(frame->this->name, "page.c", __FUNCTION__, 814, GF_LOG_WARNING
, "local is NULL"); } while (0)
;
815 op_ret = -1;
816 op_errno = ENOMEM12;
817 goto unwind;
818 }
819
820 if (local->op_ret < 0) {
821 op_ret = local->op_ret;
822 op_errno = local->op_errno;
823 goto unwind;
824 }
825
826 // ioc_local_lock (local);
827 iobref = iobref_new ();
828 if (iobref == NULL((void*)0)) {
829 op_ret = -1;
830 op_errno = ENOMEM12;
831 }
832
833 if (list_empty (&local->fill_list)) {
834 gf_log (frame->this->name, GF_LOG_TRACE,do { do { if (0) printf ("frame(%p) has 0 entries in local->fill_list "
"(offset = %""ll" "d"" && size = %""zu"")", frame, local
->offset, local->size); } while (0); _gf_log (frame->
this->name, "page.c", __FUNCTION__, 837, GF_LOG_TRACE, "frame(%p) has 0 entries in local->fill_list "
"(offset = %""ll" "d"" && size = %""zu"")", frame, local
->offset, local->size); } while (0)
835 "frame(%p) has 0 entries in local->fill_list "do { do { if (0) printf ("frame(%p) has 0 entries in local->fill_list "
"(offset = %""ll" "d"" && size = %""zu"")", frame, local
->offset, local->size); } while (0); _gf_log (frame->
this->name, "page.c", __FUNCTION__, 837, GF_LOG_TRACE, "frame(%p) has 0 entries in local->fill_list "
"(offset = %""ll" "d"" && size = %""zu"")", frame, local
->offset, local->size); } while (0)
836 "(offset = %"PRId64" && size = %"GF_PRI_SIZET")",do { do { if (0) printf ("frame(%p) has 0 entries in local->fill_list "
"(offset = %""ll" "d"" && size = %""zu"")", frame, local
->offset, local->size); } while (0); _gf_log (frame->
this->name, "page.c", __FUNCTION__, 837, GF_LOG_TRACE, "frame(%p) has 0 entries in local->fill_list "
"(offset = %""ll" "d"" && size = %""zu"")", frame, local
->offset, local->size); } while (0)
837 frame, local->offset, local->size)do { do { if (0) printf ("frame(%p) has 0 entries in local->fill_list "
"(offset = %""ll" "d"" && size = %""zu"")", frame, local
->offset, local->size); } while (0); _gf_log (frame->
this->name, "page.c", __FUNCTION__, 837, GF_LOG_TRACE, "frame(%p) has 0 entries in local->fill_list "
"(offset = %""ll" "d"" && size = %""zu"")", frame, local
->offset, local->size); } while (0)
;
838 }
839
840 list_for_each_entry (fill, &local->fill_list, list)for (fill = ((typeof(*fill) *)((char *)((&local->fill_list
)->next)-(unsigned long)(&((typeof(*fill) *)0)->list
))); &fill->list != (&local->fill_list); fill =
((typeof(*fill) *)((char *)(fill->list.next)-(unsigned long
)(&((typeof(*fill) *)0)->list))))
{
841 count += fill->count;
842 }
843
844 vector = GF_CALLOC (count, sizeof (*vector), gf_ioc_mt_iovec)__gf_calloc (count, sizeof (*vector), gf_ioc_mt_iovec);
845 if (vector == NULL((void*)0)) {
846 op_ret = -1;
847 op_errno = ENOMEM12;
848 }
849
850 list_for_each_entry_safe (fill, next, &local->fill_list, list)for (fill = ((typeof(*fill) *)((char *)((&local->fill_list
)->next)-(unsigned long)(&((typeof(*fill) *)0)->list
))), next = ((typeof(*fill) *)((char *)(fill->list.next)-(
unsigned long)(&((typeof(*fill) *)0)->list))); &fill
->list != (&local->fill_list); fill = next, next = (
(typeof(*next) *)((char *)(next->list.next)-(unsigned long
)(&((typeof(*next) *)0)->list))))
{
851 if ((vector != NULL((void*)0)) && (iobref != NULL((void*)0))) {
852 memcpy (((char *)vector) + copied,
853 fill->vector,
854 fill->count * sizeof (*vector));
855
856 copied += (fill->count * sizeof (*vector));
857
858 iobref_merge (iobref, fill->iobref);
859 }
860
861 list_del (&fill->list);
862 iobref_unref (fill->iobref);
863 GF_FREE (fill->vector)__gf_free (fill->vector);
864 GF_FREE (fill)__gf_free (fill);
865 }
866
867 if (op_ret != -1) {
868 op_ret = iov_length (vector, count);
869 }
870
871unwind:
872 gf_log (frame->this->name, GF_LOG_TRACE,do { do { if (0) printf ("frame(%p) unwinding with op_ret=%d"
, frame, op_ret); } while (0); _gf_log (frame->this->name
, "page.c", __FUNCTION__, 873, GF_LOG_TRACE, "frame(%p) unwinding with op_ret=%d"
, frame, op_ret); } while (0)
873 "frame(%p) unwinding with op_ret=%d", frame, op_ret)do { do { if (0) printf ("frame(%p) unwinding with op_ret=%d"
, frame, op_ret); } while (0); _gf_log (frame->this->name
, "page.c", __FUNCTION__, 873, GF_LOG_TRACE, "frame(%p) unwinding with op_ret=%d"
, frame, op_ret); } while (0)
;
874
875 // ioc_local_unlock (local);
876
877 frame->local = NULL((void*)0);
878 STACK_UNWIND_STRICT (readv, frame, op_ret, op_errno, vector,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__, 879, 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, op_ret
, op_errno, vector, count, &stbuf, iobref, ((void*)0)); (
*__glusterfs_this_location()) = old_THIS; } while (0)
879 count, &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__, 879, 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, op_ret
, op_errno, vector, count, &stbuf, iobref, ((void*)0)); (
*__glusterfs_this_location()) = old_THIS; } while (0)
;
880
881 if (iobref != NULL((void*)0)) {
882 iobref_unref (iobref);
883 }
884
885 if (vector != NULL((void*)0)) {
886 GF_FREE (vector)__gf_free (vector);
887 vector = NULL((void*)0);
888 }
889
890 pthread_mutex_destroy (&local->local_lock);
891 if (local)
892 mem_put (local);
893
894 return;
895}
896
897/*
898 * ioc_frame_return -
899 * @frame:
900 *
901 * to be called only when a frame is waiting on an in-transit page
902 */
903void
904ioc_frame_return (call_frame_t *frame)
905{
906 ioc_local_t *local = NULL((void*)0);
907 int32_t wait_count = 0;
908
909 GF_ASSERT (frame)do { if (!(frame)) { do { do { if (0) printf ("Assertion failed: "
"frame"); } while (0); _gf_log_callingfn ("", "page.c", __FUNCTION__
, 909, GF_LOG_ERROR, "Assertion failed: " "frame"); } while (
0); } } while (0)
;
910
911 local = frame->local;
912 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__, 912, GF_LOG_ERROR
, "Assertion failed: " "local->wait_count > 0"); } while
(0); } } while (0)
;
913
914 ioc_local_lock (local)do { do { do { if (0) printf ("locked local(%p)", local); } while
(0); _gf_log (local->inode->table->xl->name, "page.c"
, __FUNCTION__, 914, GF_LOG_TRACE, "locked local(%p)", local)
; } while (0); pthread_mutex_lock (&local->local_lock)
; } while (0)
;
915 {
916 wait_count = --local->wait_count;
917 }
918 ioc_local_unlock (local)do { do { do { if (0) printf ("unlocked local(%p)", local); }
while (0); _gf_log (local->inode->table->xl->name
, "page.c", __FUNCTION__, 918, GF_LOG_TRACE, "unlocked local(%p)"
, local); } while (0); pthread_mutex_unlock (&local->local_lock
); } while (0)
;
919
920 if (!wait_count) {
921 ioc_frame_unwind (frame);
922 }
923
924 return;
925}
926
927/*
928 * ioc_page_wakeup -
929 * @page:
930 *
931 * to be called only when a frame is waiting on an in-transit page
932 */
933ioc_waitq_t *
934__ioc_page_wakeup (ioc_page_t *page, int32_t op_errno)
935{
936 ioc_waitq_t *waitq = NULL((void*)0), *trav = NULL((void*)0);
937 call_frame_t *frame = NULL((void*)0);
938 int32_t ret = -1;
939
940 GF_VALIDATE_OR_GOTO ("io-cache", page, out)do { if (!page) { (*__errno_location ()) = 22; do { do { if (
0) printf ("invalid argument: " "page"); } while (0); _gf_log_callingfn
("io-cache", "page.c", __FUNCTION__, 940, GF_LOG_ERROR, "invalid argument: "
"page"); } while (0); goto out; } } while (0)
;
941
942 waitq = page->waitq;
943 page->waitq = NULL((void*)0);
944
945 page->ready = 1;
946
947 gf_log (page->inode->table->xl->name, GF_LOG_TRACE,do { do { if (0) printf ("page is %p && waitq = %p", page
, waitq); } while (0); _gf_log (page->inode->table->
xl->name, "page.c", __FUNCTION__, 948, GF_LOG_TRACE, "page is %p && waitq = %p"
, page, waitq); } while (0)
948 "page is %p && waitq = %p", page, waitq)do { do { if (0) printf ("page is %p && waitq = %p", page
, waitq); } while (0); _gf_log (page->inode->table->
xl->name, "page.c", __FUNCTION__, 948, GF_LOG_TRACE, "page is %p && waitq = %p"
, page, waitq); } while (0)
;
949
950 for (trav = waitq; trav; trav = trav->next) {
951 frame = trav->data;
952 ret = __ioc_frame_fill (page, frame, trav->pending_offset,
953 trav->pending_size, op_errno);
954 if (ret == -1) {
955 break;
956 }
957 }
958
959 if (page->stale) {
960 __ioc_page_destroy (page);
961 }
962
963out:
964 return waitq;
965}
966
967
968
969/*
970 * ioc_page_error -
971 * @page:
972 * @op_ret:
973 * @op_errno:
974 *
975 */
976ioc_waitq_t *
977__ioc_page_error (ioc_page_t *page, int32_t op_ret, int32_t op_errno)
978{
979 ioc_waitq_t *waitq = NULL((void*)0), *trav = NULL((void*)0);
980 call_frame_t *frame = NULL((void*)0);
981 int64_t ret = 0;
982 ioc_table_t *table = NULL((void*)0);
983 ioc_local_t *local = NULL((void*)0);
984
985 GF_VALIDATE_OR_GOTO ("io-cache", page, out)do { if (!page) { (*__errno_location ()) = 22; do { do { if (
0) printf ("invalid argument: " "page"); } while (0); _gf_log_callingfn
("io-cache", "page.c", __FUNCTION__, 985, GF_LOG_ERROR, "invalid argument: "
"page"); } while (0); goto out; } } while (0)
;
986
987 waitq = page->waitq;
988 page->waitq = NULL((void*)0);
989
990 gf_log (page->inode->table->xl->name, GF_LOG_WARNING,do { do { if (0) printf ("page error for page = %p & waitq = %p"
, page, waitq); } while (0); _gf_log (page->inode->table
->xl->name, "page.c", __FUNCTION__, 991, GF_LOG_WARNING
, "page error for page = %p & waitq = %p", page, waitq); }
while (0)
991 "page error for page = %p & waitq = %p", page, waitq)do { do { if (0) printf ("page error for page = %p & waitq = %p"
, page, waitq); } while (0); _gf_log (page->inode->table
->xl->name, "page.c", __FUNCTION__, 991, GF_LOG_WARNING
, "page error for page = %p & waitq = %p", page, waitq); }
while (0)
;
992
993 for (trav = waitq; trav; trav = trav->next) {
994
995 frame = trav->data;
996
997 local = frame->local;
998 ioc_local_lock (local)do { do { do { if (0) printf ("locked local(%p)", local); } while
(0); _gf_log (local->inode->table->xl->name, "page.c"
, __FUNCTION__, 998, GF_LOG_TRACE, "locked local(%p)", local)
; } while (0); pthread_mutex_lock (&local->local_lock)
; } while (0)
;
999 {
1000 if (local->op_ret != -1) {
1001 local->op_ret = op_ret;
1002 local->op_errno = op_errno;
1003 }
1004 }
1005 ioc_local_unlock (local)do { do { do { if (0) printf ("unlocked local(%p)", local); }
while (0); _gf_log (local->inode->table->xl->name
, "page.c", __FUNCTION__, 1005, GF_LOG_TRACE, "unlocked local(%p)"
, local); } while (0); pthread_mutex_unlock (&local->local_lock
); } while (0)
;
1006 }
1007
1008 table = page->inode->table;
1009 ret = __ioc_page_destroy (page);
1010
1011 if (ret != -1) {
1012 table->cache_used -= ret;
1013 }
1014
1015out:
1016 return waitq;
1017}
1018
1019/*
1020 * ioc_page_error -
1021 * @page:
1022 * @op_ret:
1023 * @op_errno:
1024 *
1025 */
1026ioc_waitq_t *
1027ioc_page_error (ioc_page_t *page, int32_t op_ret, int32_t op_errno)
1028{
1029 ioc_waitq_t *waitq = NULL((void*)0);
1030
1031 if (page == NULL((void*)0)) {
1032 goto out;
1033 }
1034
1035 ioc_inode_lock (page->inode)do { do { do { if (0) printf ("locked inode(%p)", page->inode
); } while (0); _gf_log (page->inode->table->xl->
name, "page.c", __FUNCTION__, 1035, GF_LOG_TRACE, "locked inode(%p)"
, page->inode); } while (0); pthread_mutex_lock (&page
->inode->inode_lock); } while (0)
;
1036 {
1037 waitq = __ioc_page_error (page, op_ret, op_errno);
1038 }
1039 ioc_inode_unlock (page->inode)do { do { do { if (0) printf ("unlocked inode(%p)", page->
inode); } while (0); _gf_log (page->inode->table->xl
->name, "page.c", __FUNCTION__, 1039, GF_LOG_TRACE, "unlocked inode(%p)"
, page->inode); } while (0); pthread_mutex_unlock (&page
->inode->inode_lock); } while (0)
;
1040
1041out:
1042 return waitq;
1043}