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') |
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 | ||||
25 | char | |||
26 | ioc_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 | ||||
34 | out: | |||
35 | return is_empty; | |||
36 | } | |||
37 | ||||
38 | ||||
39 | ioc_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 | ||||
61 | out: | |||
62 | return page; | |||
63 | } | |||
64 | ||||
65 | ||||
66 | ioc_page_t * | |||
67 | ioc_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 | ||||
81 | out: | |||
82 | return page; | |||
83 | } | |||
84 | ||||
85 | ||||
86 | /* | |||
87 | * __ioc_page_destroy - | |||
88 | * | |||
89 | * @page: | |||
90 | * | |||
91 | */ | |||
92 | int64_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 | ||||
130 | out: | |||
131 | return page_size; | |||
132 | } | |||
133 | ||||
134 | ||||
135 | int64_t | |||
136 | ioc_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 | ||||
150 | out: | |||
151 | return ret; | |||
152 | } | |||
153 | ||||
154 | int32_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 | ||||
188 | out: | |||
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 | */ | |||
198 | int32_t | |||
199 | ioc_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 | ||||
237 | out: | |||
238 | return 0; | |||
239 | } | |||
240 | ||||
241 | /* | |||
242 | * __ioc_page_create - create a new page. | |||
243 | * | |||
244 | * @ioc_inode: | |||
245 | * @offset: | |||
246 | * | |||
247 | */ | |||
248 | ioc_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 | ||||
288 | out: | |||
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 | */ | |||
301 | void | |||
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 | ||||
345 | out: | |||
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 | */ | |||
359 | int8_t | |||
360 | ioc_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 | ||||
386 | out: | |||
387 | return cache_still_valid; | |||
388 | } | |||
389 | ||||
390 | ||||
391 | void | |||
392 | ioc_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 | ||||
408 | int | |||
409 | ioc_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; | |||
| ||||
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); | |||
433 | ||||
434 | table = ioc_inode->table; | |||
| ||||
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 */ | |||
527 | unlock: | |||
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 | */ | |||
572 | void | |||
573 | ioc_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 | ||||
630 | err: | |||
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 | ||||
646 | int32_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 | ||||
782 | done: | |||
783 | ret = 0; | |||
784 | out: | |||
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 | */ | |||
797 | static void | |||
798 | ioc_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 | ||||
871 | unwind: | |||
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 | */ | |||
903 | void | |||
904 | ioc_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 | */ | |||
933 | ioc_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 | ||||
963 | out: | |||
964 | return waitq; | |||
965 | } | |||
966 | ||||
967 | ||||
968 | ||||
969 | /* | |||
970 | * ioc_page_error - | |||
971 | * @page: | |||
972 | * @op_ret: | |||
973 | * @op_errno: | |||
974 | * | |||
975 | */ | |||
976 | ioc_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 | ||||
1015 | out: | |||
1016 | return waitq; | |||
1017 | } | |||
1018 | ||||
1019 | /* | |||
1020 | * ioc_page_error - | |||
1021 | * @page: | |||
1022 | * @op_ret: | |||
1023 | * @op_errno: | |||
1024 | * | |||
1025 | */ | |||
1026 | ioc_waitq_t * | |||
1027 | ioc_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 | ||||
1041 | out: | |||
1042 | return waitq; | |||
1043 | } |