Bug Summary

File:libglusterfs/src/fd.c
Location:line 1138, column 17
Description:Value stored to 'ret' is never read

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#include "fd.h"
12#include "glusterfs.h"
13#include "inode.h"
14#include "dict.h"
15#include "statedump.h"
16
17
18#ifndef _CONFIG_H
19#define _CONFIG_H
20#include "config.h"
21#endif
22
23
24static int
25gf_fd_fdtable_expand (fdtable_t *fdtable, uint32_t nr);
26
27
28fd_t *
29__fd_ref (fd_t *fd);
30
31static int
32gf_fd_chain_fd_entries (fdentry_t *entries, uint32_t startidx,
33 uint32_t endcount)
34{
35 uint32_t i = 0;
36
37 if (!entries) {
38 gf_log_callingfn ("fd", GF_LOG_WARNING, "!entries")do { do { if (0) printf ("!entries"); } while (0); _gf_log_callingfn
("fd", "fd.c", __FUNCTION__, 38, GF_LOG_WARNING, "!entries")
; } while (0)
;
39 return -1;
40 }
41
42 /* Chain only till the second to last entry because we want to
43 * ensure that the last entry has GF_FDTABLE_END.
44 */
45 for (i = startidx; i < (endcount - 1); i++)
46 entries[i].next_free = i + 1;
47
48 /* i has already been incremented upto the last entry. */
49 entries[i].next_free = GF_FDTABLE_END-1;
50
51 return 0;
52}
53
54
55static int
56gf_fd_fdtable_expand (fdtable_t *fdtable, uint32_t nr)
57{
58 fdentry_t *oldfds = NULL((void*)0);
59 uint32_t oldmax_fds = -1;
60 int ret = -1;
61
62 if (fdtable == NULL((void*)0) || nr < 0) {
63 gf_log_callingfn ("fd", GF_LOG_ERROR, "invalid argument")do { do { if (0) printf ("invalid argument"); } while (0); _gf_log_callingfn
("fd", "fd.c", __FUNCTION__, 63, GF_LOG_ERROR, "invalid argument"
); } while (0)
;
64 ret = EINVAL22;
65 goto out;
66 }
67
68 nr /= (1024 / sizeof (fdentry_t));
69 nr = gf_roundup_next_power_of_two (nr + 1);
70 nr *= (1024 / sizeof (fdentry_t));
71
72 oldfds = fdtable->fdentries;
73 oldmax_fds = fdtable->max_fds;
74
75 fdtable->fdentries = GF_CALLOC (nr, sizeof (fdentry_t),__gf_calloc (nr, sizeof (fdentry_t), gf_common_mt_fdentry_t)
76 gf_common_mt_fdentry_t)__gf_calloc (nr, sizeof (fdentry_t), gf_common_mt_fdentry_t);
77 if (!fdtable->fdentries) {
78 ret = ENOMEM12;
79 goto out;
80 }
81 fdtable->max_fds = nr;
82
83 if (oldfds) {
84 uint32_t cpy = oldmax_fds * sizeof (fdentry_t);
85 memcpy (fdtable->fdentries, oldfds, cpy);
86 }
87
88 gf_fd_chain_fd_entries (fdtable->fdentries, oldmax_fds,
89 fdtable->max_fds);
90
91 /* Now that expansion is done, we must update the fd list
92 * head pointer so that the fd allocation functions can continue
93 * using the expanded table.
94 */
95 fdtable->first_free = oldmax_fds;
96 GF_FREE (oldfds)__gf_free (oldfds);
97 ret = 0;
98out:
99 return ret;
100}
101
102
103fdtable_t *
104gf_fd_fdtable_alloc (void)
105{
106 fdtable_t *fdtable = NULL((void*)0);
107
108 fdtable = GF_CALLOC (1, sizeof (*fdtable), gf_common_mt_fdtable_t)__gf_calloc (1, sizeof (*fdtable), gf_common_mt_fdtable_t);
109 if (!fdtable)
110 return NULL((void*)0);
111
112 pthread_mutex_init (&fdtable->lock, NULL((void*)0));
113
114 pthread_mutex_lock (&fdtable->lock);
115 {
116 gf_fd_fdtable_expand (fdtable, 0);
117 }
118 pthread_mutex_unlock (&fdtable->lock);
119
120 return fdtable;
121}
122
123
124static fdentry_t *
125__gf_fd_fdtable_get_all_fds (fdtable_t *fdtable, uint32_t *count)
126{
127 fdentry_t *fdentries = NULL((void*)0);
128
129 if (count == NULL((void*)0)) {
130 gf_log_callingfn ("fd", GF_LOG_WARNING, "!count")do { do { if (0) printf ("!count"); } while (0); _gf_log_callingfn
("fd", "fd.c", __FUNCTION__, 130, GF_LOG_WARNING, "!count");
} while (0)
;
131 goto out;
132 }
133
134 fdentries = fdtable->fdentries;
135 fdtable->fdentries = GF_CALLOC (fdtable->max_fds, sizeof (fdentry_t),__gf_calloc (fdtable->max_fds, sizeof (fdentry_t), gf_common_mt_fdentry_t
)
136 gf_common_mt_fdentry_t)__gf_calloc (fdtable->max_fds, sizeof (fdentry_t), gf_common_mt_fdentry_t
)
;
137 gf_fd_chain_fd_entries (fdtable->fdentries, 0, fdtable->max_fds);
138 *count = fdtable->max_fds;
139
140out:
141 return fdentries;
142}
143
144
145fdentry_t *
146gf_fd_fdtable_get_all_fds (fdtable_t *fdtable, uint32_t *count)
147{
148 fdentry_t *entries = NULL((void*)0);
149
150 if (fdtable) {
151 pthread_mutex_lock (&fdtable->lock);
152 {
153 entries = __gf_fd_fdtable_get_all_fds (fdtable, count);
154 }
155 pthread_mutex_unlock (&fdtable->lock);
156 }
157
158 return entries;
159}
160
161
162static fdentry_t *
163__gf_fd_fdtable_copy_all_fds (fdtable_t *fdtable, uint32_t *count)
164{
165 fdentry_t *fdentries = NULL((void*)0);
166 int i = 0;
167
168 if (count == NULL((void*)0)) {
169 gf_log_callingfn ("fd", GF_LOG_WARNING, "!count")do { do { if (0) printf ("!count"); } while (0); _gf_log_callingfn
("fd", "fd.c", __FUNCTION__, 169, GF_LOG_WARNING, "!count");
} while (0)
;
170 goto out;
171 }
172
173 fdentries = GF_CALLOC (fdtable->max_fds, sizeof (fdentry_t),__gf_calloc (fdtable->max_fds, sizeof (fdentry_t), gf_common_mt_fdentry_t
)
174 gf_common_mt_fdentry_t)__gf_calloc (fdtable->max_fds, sizeof (fdentry_t), gf_common_mt_fdentry_t
)
;
175 if (fdentries == NULL((void*)0)) {
176 goto out;
177 }
178
179 *count = fdtable->max_fds;
180
181 for (i = 0; i < fdtable->max_fds; i++) {
182 if (fdtable->fdentries[i].fd != NULL((void*)0)) {
183 fdentries[i].fd = fd_ref (fdtable->fdentries[i].fd);
184 }
185 }
186
187out:
188 return fdentries;
189}
190
191
192fdentry_t *
193gf_fd_fdtable_copy_all_fds (fdtable_t *fdtable, uint32_t *count)
194{
195 fdentry_t *entries = NULL((void*)0);
196
197 if (fdtable) {
198 pthread_mutex_lock (&fdtable->lock);
199 {
200 entries = __gf_fd_fdtable_copy_all_fds (fdtable, count);
201 }
202 pthread_mutex_unlock (&fdtable->lock);
203 }
204
205 return entries;
206}
207
208
209void
210gf_fd_fdtable_destroy (fdtable_t *fdtable)
211{
212 struct list_head list = {0, };
213 fd_t *fd = NULL((void*)0);
214 fdentry_t *fdentries = NULL((void*)0);
215 uint32_t fd_count = 0;
216 int32_t i = 0;
217
218 INIT_LIST_HEAD (&list)do { (&list)->next = (&list)->prev = &list;
} while (0)
;
219
220 if (!fdtable) {
221 gf_log_callingfn ("fd", GF_LOG_WARNING, "!fdtable")do { do { if (0) printf ("!fdtable"); } while (0); _gf_log_callingfn
("fd", "fd.c", __FUNCTION__, 221, GF_LOG_WARNING, "!fdtable"
); } while (0)
;
222 return;
223 }
224
225 pthread_mutex_lock (&fdtable->lock);
226 {
227 fdentries = __gf_fd_fdtable_get_all_fds (fdtable, &fd_count);
228 GF_FREE (fdtable->fdentries)__gf_free (fdtable->fdentries);
229 }
230 pthread_mutex_unlock (&fdtable->lock);
231
232 if (fdentries != NULL((void*)0)) {
233 for (i = 0; i < fd_count; i++) {
234 fd = fdentries[i].fd;
235 if (fd != NULL((void*)0)) {
236 fd_unref (fd);
237 }
238 }
239
240 GF_FREE (fdentries)__gf_free (fdentries);
241 pthread_mutex_destroy (&fdtable->lock);
242 GF_FREE (fdtable)__gf_free (fdtable);
243 }
244}
245
246
247int
248gf_fd_unused_get (fdtable_t *fdtable, fd_t *fdptr)
249{
250 int32_t fd = -1;
251 fdentry_t *fde = NULL((void*)0);
252 int error;
253 int alloc_attempts = 0;
254
255 if (fdtable == NULL((void*)0) || fdptr == NULL((void*)0)) {
256 gf_log_callingfn ("fd", GF_LOG_ERROR, "invalid argument")do { do { if (0) printf ("invalid argument"); } while (0); _gf_log_callingfn
("fd", "fd.c", __FUNCTION__, 256, GF_LOG_ERROR, "invalid argument"
); } while (0)
;
257 return EINVAL22;
258 }
259
260 pthread_mutex_lock (&fdtable->lock);
261 {
262 fd_alloc_try_again:
263 if (fdtable->first_free != GF_FDTABLE_END-1) {
264 fde = &fdtable->fdentries[fdtable->first_free];
265 fd = fdtable->first_free;
266 fdtable->first_free = fde->next_free;
267 fde->next_free = GF_FDENTRY_ALLOCATED-2;
268 fde->fd = fdptr;
269 } else {
270 /* If this is true, there is something
271 * seriously wrong with our data structures.
272 */
273 if (alloc_attempts >= 2) {
274 gf_log ("fd", GF_LOG_ERROR,do { do { if (0) printf ("multiple attempts to expand fd table"
" have failed."); } while (0); _gf_log ("fd", "fd.c", __FUNCTION__
, 276, GF_LOG_ERROR, "multiple attempts to expand fd table" " have failed."
); } while (0)
275 "multiple attempts to expand fd table"do { do { if (0) printf ("multiple attempts to expand fd table"
" have failed."); } while (0); _gf_log ("fd", "fd.c", __FUNCTION__
, 276, GF_LOG_ERROR, "multiple attempts to expand fd table" " have failed."
); } while (0)
276 " have failed.")do { do { if (0) printf ("multiple attempts to expand fd table"
" have failed."); } while (0); _gf_log ("fd", "fd.c", __FUNCTION__
, 276, GF_LOG_ERROR, "multiple attempts to expand fd table" " have failed."
); } while (0)
;
277 goto out;
278 }
279 error = gf_fd_fdtable_expand (fdtable,
280 fdtable->max_fds + 1);
281 if (error) {
282 gf_log ("fd", GF_LOG_ERROR,do { do { if (0) printf ("Cannot expand fdtable: %s", strerror
(error)); } while (0); _gf_log ("fd", "fd.c", __FUNCTION__, 284
, GF_LOG_ERROR, "Cannot expand fdtable: %s", strerror (error)
); } while (0)
283 "Cannot expand fdtable: %s",do { do { if (0) printf ("Cannot expand fdtable: %s", strerror
(error)); } while (0); _gf_log ("fd", "fd.c", __FUNCTION__, 284
, GF_LOG_ERROR, "Cannot expand fdtable: %s", strerror (error)
); } while (0)
284 strerror (error))do { do { if (0) printf ("Cannot expand fdtable: %s", strerror
(error)); } while (0); _gf_log ("fd", "fd.c", __FUNCTION__, 284
, GF_LOG_ERROR, "Cannot expand fdtable: %s", strerror (error)
); } while (0)
;
285 goto out;
286 }
287 ++alloc_attempts;
288 /* At this point, the table stands expanded
289 * with the first_free referring to the first
290 * free entry in the new set of fdentries that
291 * have just been allocated. That means, the
292 * above logic should just work.
293 */
294 goto fd_alloc_try_again;
295 }
296 }
297out:
298 pthread_mutex_unlock (&fdtable->lock);
299
300 return fd;
301}
302
303
304inline void
305gf_fd_put (fdtable_t *fdtable, int32_t fd)
306{
307 fd_t *fdptr = NULL((void*)0);
308 fdentry_t *fde = NULL((void*)0);
309
310 if (fd == -2)
311 /* anonymous fd */
312 return;
313
314 if (fdtable == NULL((void*)0) || fd < 0) {
315 gf_log_callingfn ("fd", GF_LOG_ERROR, "invalid argument")do { do { if (0) printf ("invalid argument"); } while (0); _gf_log_callingfn
("fd", "fd.c", __FUNCTION__, 315, GF_LOG_ERROR, "invalid argument"
); } while (0)
;
316 return;
317 }
318
319 if (!(fd < fdtable->max_fds)) {
320 gf_log_callingfn ("fd", GF_LOG_ERROR, "invalid argument")do { do { if (0) printf ("invalid argument"); } while (0); _gf_log_callingfn
("fd", "fd.c", __FUNCTION__, 320, GF_LOG_ERROR, "invalid argument"
); } while (0)
;
321 return;
322 }
323
324 pthread_mutex_lock (&fdtable->lock);
325 {
326 fde = &fdtable->fdentries[fd];
327 /* If the entry is not allocated, put operation must return
328 * without doing anything.
329 * This has the potential of masking out any bugs in a user of
330 * fd that ends up calling gf_fd_put twice for the same fd or
331 * for an unallocated fd, but it is a price we have to pay for
332 * ensuring sanity of our fd-table.
333 */
334 if (fde->next_free != GF_FDENTRY_ALLOCATED-2)
335 goto unlock_out;
336 fdptr = fde->fd;
337 fde->fd = NULL((void*)0);
338 fde->next_free = fdtable->first_free;
339 fdtable->first_free = fd;
340 }
341unlock_out:
342 pthread_mutex_unlock (&fdtable->lock);
343
344 if (fdptr) {
345 fd_unref (fdptr);
346 }
347}
348
349
350inline void
351gf_fdptr_put (fdtable_t *fdtable, fd_t *fd)
352{
353 fdentry_t *fde = NULL((void*)0);
354 int32_t i = 0;
355
356 if ((fdtable == NULL((void*)0)) || (fd == NULL((void*)0))) {
357 gf_log_callingfn ("fd", GF_LOG_ERROR, "invalid argument")do { do { if (0) printf ("invalid argument"); } while (0); _gf_log_callingfn
("fd", "fd.c", __FUNCTION__, 357, GF_LOG_ERROR, "invalid argument"
); } while (0)
;
358 return;
359 }
360
361 pthread_mutex_lock (&fdtable->lock);
362 {
363 for (i = 0; i < fdtable->max_fds; i++) {
364 if (fdtable->fdentries[i].fd == fd) {
365 fde = &fdtable->fdentries[i];
366 break;
367 }
368 }
369
370 if (fde == NULL((void*)0)) {
371 gf_log_callingfn ("fd", GF_LOG_WARNING,do { do { if (0) printf ("fd (%p) is not present in fdtable",
fd); } while (0); _gf_log_callingfn ("fd", "fd.c", __FUNCTION__
, 372, GF_LOG_WARNING, "fd (%p) is not present in fdtable", fd
); } while (0)
372 "fd (%p) is not present in fdtable", fd)do { do { if (0) printf ("fd (%p) is not present in fdtable",
fd); } while (0); _gf_log_callingfn ("fd", "fd.c", __FUNCTION__
, 372, GF_LOG_WARNING, "fd (%p) is not present in fdtable", fd
); } while (0)
;
373 goto unlock_out;
374 }
375
376 /* If the entry is not allocated, put operation must return
377 * without doing anything.
378 * This has the potential of masking out any bugs in a user of
379 * fd that ends up calling gf_fd_put twice for the same fd or
380 * for an unallocated fd, but it is a price we have to pay for
381 * ensuring sanity of our fd-table.
382 */
383 if (fde->next_free != GF_FDENTRY_ALLOCATED-2)
384 goto unlock_out;
385 fde->fd = NULL((void*)0);
386 fde->next_free = fdtable->first_free;
387 fdtable->first_free = i;
388 }
389unlock_out:
390 pthread_mutex_unlock (&fdtable->lock);
391
392 if ((fd != NULL((void*)0)) && (fde != NULL((void*)0))) {
393 fd_unref (fd);
394 }
395}
396
397
398fd_t *
399gf_fd_fdptr_get (fdtable_t *fdtable, int64_t fd)
400{
401 fd_t *fdptr = NULL((void*)0);
402
403 if (fdtable == NULL((void*)0) || fd < 0) {
404 gf_log_callingfn ("fd", GF_LOG_ERROR, "invalid argument")do { do { if (0) printf ("invalid argument"); } while (0); _gf_log_callingfn
("fd", "fd.c", __FUNCTION__, 404, GF_LOG_ERROR, "invalid argument"
); } while (0)
;
405 errno(*__errno_location ()) = EINVAL22;
406 return NULL((void*)0);
407 }
408
409 if (!(fd < fdtable->max_fds)) {
410 gf_log_callingfn ("fd", GF_LOG_ERROR, "invalid argument")do { do { if (0) printf ("invalid argument"); } while (0); _gf_log_callingfn
("fd", "fd.c", __FUNCTION__, 410, GF_LOG_ERROR, "invalid argument"
); } while (0)
;
411 errno(*__errno_location ()) = EINVAL22;
412 return NULL((void*)0);
413 }
414
415 pthread_mutex_lock (&fdtable->lock);
416 {
417 fdptr = fdtable->fdentries[fd].fd;
418 if (fdptr) {
419 fd_ref (fdptr);
420 }
421 }
422 pthread_mutex_unlock (&fdtable->lock);
423
424 return fdptr;
425}
426
427
428fd_t *
429__fd_ref (fd_t *fd)
430{
431 ++fd->refcount;
432
433 return fd;
434}
435
436
437fd_t *
438fd_ref (fd_t *fd)
439{
440 fd_t *refed_fd = NULL((void*)0);
441
442 if (!fd) {
443 gf_log_callingfn ("fd", GF_LOG_ERROR, "null fd")do { do { if (0) printf ("null fd"); } while (0); _gf_log_callingfn
("fd", "fd.c", __FUNCTION__, 443, GF_LOG_ERROR, "null fd"); }
while (0)
;
444 return NULL((void*)0);
445 }
446
447 LOCK (&fd->inode->lock)pthread_spin_lock (&fd->inode->lock);
448 refed_fd = __fd_ref (fd);
449 UNLOCK (&fd->inode->lock)pthread_spin_unlock (&fd->inode->lock);
450
451 return refed_fd;
452}
453
454
455fd_t *
456__fd_unref (fd_t *fd)
457{
458 GF_ASSERT (fd->refcount)do { if (!(fd->refcount)) { do { do { if (0) printf ("Assertion failed: "
"fd->refcount"); } while (0); _gf_log_callingfn ("", "fd.c"
, __FUNCTION__, 458, GF_LOG_ERROR, "Assertion failed: " "fd->refcount"
); } while (0); } } while (0)
;
459
460 --fd->refcount;
461
462 if (fd->refcount == 0) {
463 list_del_init (&fd->inode_list);
464 }
465
466 return fd;
467}
468
469
470static void
471fd_destroy (fd_t *fd)
472{
473 xlator_t *xl = NULL((void*)0);
474 int i = 0;
475 xlator_t *old_THIS = NULL((void*)0);
476
477 if (fd == NULL((void*)0)){
478 gf_log_callingfn ("xlator", GF_LOG_ERROR, "invalid argument")do { do { if (0) printf ("invalid argument"); } while (0); _gf_log_callingfn
("xlator", "fd.c", __FUNCTION__, 478, GF_LOG_ERROR, "invalid argument"
); } while (0)
;
479 goto out;
480 }
481
482 if (fd->inode == NULL((void*)0)){
483 gf_log_callingfn ("xlator", GF_LOG_ERROR, "fd->inode is NULL")do { do { if (0) printf ("fd->inode is NULL"); } while (0)
; _gf_log_callingfn ("xlator", "fd.c", __FUNCTION__, 483, GF_LOG_ERROR
, "fd->inode is NULL"); } while (0)
;
484 goto out;
485 }
486 if (!fd->_ctx)
487 goto out;
488
489 if (IA_ISDIR (fd->inode->ia_type)(fd->inode->ia_type == IA_IFDIR)) {
490 for (i = 0; i < fd->xl_count; i++) {
491 if (fd->_ctx[i].key) {
492 xl = fd->_ctx[i].xl_key;
493 old_THIS = THIS(*__glusterfs_this_location());
494 THIS(*__glusterfs_this_location()) = xl;
495 if (xl->cbks->releasedir)
496 xl->cbks->releasedir (xl, fd);
497 THIS(*__glusterfs_this_location()) = old_THIS;
498 }
499 }
500 } else {
501 for (i = 0; i < fd->xl_count; i++) {
502 if (fd->_ctx[i].key) {
503 xl = fd->_ctx[i].xl_key;
504 old_THIS = THIS(*__glusterfs_this_location());
505 THIS(*__glusterfs_this_location()) = xl;
506 if (xl->cbks->release)
507 xl->cbks->release (xl, fd);
508 THIS(*__glusterfs_this_location()) = old_THIS;
509 }
510 }
511 }
512
513 LOCK_DESTROY (&fd->lock)pthread_spin_destroy (&fd->lock);
514
515 GF_FREE (fd->_ctx)__gf_free (fd->_ctx);
516 LOCK (&fd->inode->lock)pthread_spin_lock (&fd->inode->lock);
517 {
518 fd->inode->fd_count--;
519 }
520 UNLOCK (&fd->inode->lock)pthread_spin_unlock (&fd->inode->lock);
521 inode_unref (fd->inode);
522 fd->inode = (inode_t *)0xaaaaaaaa;
523 fd_lk_ctx_unref (fd->lk_ctx);
524 mem_put (fd);
525out:
526 return;
527}
528
529
530void
531fd_unref (fd_t *fd)
532{
533 int32_t refcount = 0;
534
535 if (!fd) {
536 gf_log_callingfn ("fd", GF_LOG_ERROR, "fd is NULL")do { do { if (0) printf ("fd is NULL"); } while (0); _gf_log_callingfn
("fd", "fd.c", __FUNCTION__, 536, GF_LOG_ERROR, "fd is NULL"
); } while (0)
;
537 return;
538 }
539
540 LOCK (&fd->inode->lock)pthread_spin_lock (&fd->inode->lock);
541 {
542 __fd_unref (fd);
543 refcount = fd->refcount;
544 }
545 UNLOCK (&fd->inode->lock)pthread_spin_unlock (&fd->inode->lock);
546
547 if (refcount == 0) {
548 fd_destroy (fd);
549 }
550
551 return ;
552}
553
554
555fd_t *
556__fd_bind (fd_t *fd)
557{
558 list_del_init (&fd->inode_list);
559 list_add (&fd->inode_list, &fd->inode->fd_list);
560 fd->inode->fd_count++;
561
562 return fd;
563}
564
565
566fd_t *
567fd_bind (fd_t *fd)
568{
569 if (!fd || !fd->inode) {
570 gf_log_callingfn ("fd", GF_LOG_ERROR, "!fd || !fd->inode")do { do { if (0) printf ("!fd || !fd->inode"); } while (0)
; _gf_log_callingfn ("fd", "fd.c", __FUNCTION__, 570, GF_LOG_ERROR
, "!fd || !fd->inode"); } while (0)
;
571 return NULL((void*)0);
572 }
573
574 LOCK (&fd->inode->lock)pthread_spin_lock (&fd->inode->lock);
575 {
576 fd = __fd_bind (fd);
577 }
578 UNLOCK (&fd->inode->lock)pthread_spin_unlock (&fd->inode->lock);
579
580 return fd;
581}
582
583
584static fd_t *
585__fd_create (inode_t *inode, uint64_t pid)
586{
587 fd_t *fd = NULL((void*)0);
588
589 if (inode == NULL((void*)0)) {
590 gf_log_callingfn ("fd", GF_LOG_ERROR, "invalid argument")do { do { if (0) printf ("invalid argument"); } while (0); _gf_log_callingfn
("fd", "fd.c", __FUNCTION__, 590, GF_LOG_ERROR, "invalid argument"
); } while (0)
;
591 return NULL((void*)0);
592 }
593
594 fd = mem_get0 (inode->table->fd_mem_pool);
595 if (!fd)
596 goto out;
597
598 fd->xl_count = inode->table->xl->graph->xl_count + 1;
599
600 fd->_ctx = GF_CALLOC (1, (sizeof (struct _fd_ctx) * fd->xl_count),__gf_calloc (1, (sizeof (struct _fd_ctx) * fd->xl_count), gf_common_mt_fd_ctx
)
601 gf_common_mt_fd_ctx)__gf_calloc (1, (sizeof (struct _fd_ctx) * fd->xl_count), gf_common_mt_fd_ctx
)
;
602 if (!fd->_ctx)
603 goto free_fd;
604
605 fd->lk_ctx = fd_lk_ctx_create ();
606 if (!fd->lk_ctx)
607 goto free_fd_ctx;
608
609 fd->inode = inode_ref (inode);
610 fd->pid = pid;
611 INIT_LIST_HEAD (&fd->inode_list)do { (&fd->inode_list)->next = (&fd->inode_list
)->prev = &fd->inode_list; } while (0)
;
612
613 LOCK_INIT (&fd->lock)pthread_spin_init (&fd->lock, 0);
614out:
615 return fd;
616
617free_fd_ctx:
618 GF_FREE (fd->_ctx)__gf_free (fd->_ctx);
619free_fd:
620 mem_put (fd);
621
622 return NULL((void*)0);
623}
624
625
626fd_t *
627fd_create (inode_t *inode, pid_t pid)
628{
629 fd_t *fd = NULL((void*)0);
630
631 fd = __fd_create (inode, (uint64_t)pid);
632 if (!fd)
633 goto out;
634
635 fd = fd_ref (fd);
636
637out:
638 return fd;
639}
640
641fd_t *
642fd_create_uint64 (inode_t *inode, uint64_t pid)
643{
644 fd_t *fd = NULL((void*)0);
645
646 fd = __fd_create (inode, pid);
647 if (!fd)
648 goto out;
649
650 fd = fd_ref (fd);
651
652out:
653 return fd;
654}
655
656
657static fd_t *
658__fd_lookup (inode_t *inode, uint64_t pid)
659{
660 fd_t *iter_fd = NULL((void*)0);
661 fd_t *fd = NULL((void*)0);
662
663 if (list_empty (&inode->fd_list))
664 return NULL((void*)0);
665
666
667 list_for_each_entry (iter_fd, &inode->fd_list, inode_list)for (iter_fd = ((typeof(*iter_fd) *)((char *)((&inode->
fd_list)->next)-(unsigned long)(&((typeof(*iter_fd) *)
0)->inode_list))); &iter_fd->inode_list != (&inode
->fd_list); iter_fd = ((typeof(*iter_fd) *)((char *)(iter_fd
->inode_list.next)-(unsigned long)(&((typeof(*iter_fd)
*)0)->inode_list))))
{
668 if (iter_fd->anonymous)
669 /* If someone was interested in getting an
670 anonymous fd (or was OK getting an anonymous fd),
671 they can as well call fd_anonymous() directly */
672 continue;
673
674 if (!pid || iter_fd->pid == pid) {
675 fd = __fd_ref (iter_fd);
676 break;
677 }
678 }
679
680 return fd;
681}
682
683
684fd_t *
685fd_lookup (inode_t *inode, pid_t pid)
686{
687 fd_t *fd = NULL((void*)0);
688
689 if (!inode) {
690 gf_log_callingfn ("fd", GF_LOG_WARNING, "!inode")do { do { if (0) printf ("!inode"); } while (0); _gf_log_callingfn
("fd", "fd.c", __FUNCTION__, 690, GF_LOG_WARNING, "!inode");
} while (0)
;
691 return NULL((void*)0);
692 }
693
694 LOCK (&inode->lock)pthread_spin_lock (&inode->lock);
695 {
696 fd = __fd_lookup (inode, (uint64_t)pid);
697 }
698 UNLOCK (&inode->lock)pthread_spin_unlock (&inode->lock);
699
700 return fd;
701}
702
703fd_t *
704fd_lookup_uint64 (inode_t *inode, uint64_t pid)
705{
706 fd_t *fd = NULL((void*)0);
707
708 if (!inode) {
709 gf_log_callingfn ("fd", GF_LOG_WARNING, "!inode")do { do { if (0) printf ("!inode"); } while (0); _gf_log_callingfn
("fd", "fd.c", __FUNCTION__, 709, GF_LOG_WARNING, "!inode");
} while (0)
;
710 return NULL((void*)0);
711 }
712
713 LOCK (&inode->lock)pthread_spin_lock (&inode->lock);
714 {
715 fd = __fd_lookup (inode, pid);
716 }
717 UNLOCK (&inode->lock)pthread_spin_unlock (&inode->lock);
718
719 return fd;
720}
721
722static fd_t *
723__fd_lookup_anonymous (inode_t *inode)
724{
725 fd_t *iter_fd = NULL((void*)0);
726 fd_t *fd = NULL((void*)0);
727
728 if (list_empty (&inode->fd_list))
729 return NULL((void*)0);
730
731 list_for_each_entry (iter_fd, &inode->fd_list, inode_list)for (iter_fd = ((typeof(*iter_fd) *)((char *)((&inode->
fd_list)->next)-(unsigned long)(&((typeof(*iter_fd) *)
0)->inode_list))); &iter_fd->inode_list != (&inode
->fd_list); iter_fd = ((typeof(*iter_fd) *)((char *)(iter_fd
->inode_list.next)-(unsigned long)(&((typeof(*iter_fd)
*)0)->inode_list))))
{
732 if (iter_fd->anonymous) {
733 fd = __fd_ref (iter_fd);
734 break;
735 }
736 }
737
738 return fd;
739}
740
741static fd_t *
742__fd_anonymous (inode_t *inode)
743{
744 fd_t *fd = NULL((void*)0);
745
746 fd = __fd_lookup_anonymous (inode);
747
748 /* if (fd); then we already have increased the refcount in
749 __fd_lookup_anonymous(), so no need of one more fd_ref().
750 if (!fd); then both create and bind wont bump up the ref
751 count, so we have to call fd_ref() after bind. */
752 if (!fd) {
753 fd = __fd_create (inode, 0);
754
755 if (!fd)
756 return NULL((void*)0);
757
758 fd->anonymous = _gf_true;
759
760 __fd_bind (fd);
761
762 __fd_ref (fd);
763 }
764
765 return fd;
766}
767
768
769fd_t *
770fd_anonymous (inode_t *inode)
771{
772 fd_t *fd = NULL((void*)0);
773
774 LOCK (&inode->lock)pthread_spin_lock (&inode->lock);
775 {
776 fd = __fd_anonymous (inode);
777 }
778 UNLOCK (&inode->lock)pthread_spin_unlock (&inode->lock);
779
780 return fd;
781}
782
783
784gf_boolean_t
785fd_is_anonymous (fd_t *fd)
786{
787 return (fd && fd->anonymous);
788}
789
790
791uint8_t
792fd_list_empty (inode_t *inode)
793{
794 uint8_t empty = 0;
795
796 LOCK (&inode->lock)pthread_spin_lock (&inode->lock);
797 {
798 empty = list_empty (&inode->fd_list);
799 }
800 UNLOCK (&inode->lock)pthread_spin_unlock (&inode->lock);
801
802 return empty;
803}
804
805
806int
807__fd_ctx_set (fd_t *fd, xlator_t *xlator, uint64_t value)
808{
809 int index = 0, new_xl_count = 0;
810 int ret = 0;
811 int set_idx = -1;
812 void *begin = NULL((void*)0);
813 size_t diff = 0;
814 struct _fd_ctx *tmp = NULL((void*)0);
815
816 if (!fd || !xlator)
817 return -1;
818
819 for (index = 0; index < fd->xl_count; index++) {
820 if (!fd->_ctx[index].key) {
821 if (set_idx == -1)
822 set_idx = index;
823 /* dont break, to check if key already exists
824 further on */
825 }
826 if (fd->_ctx[index].xl_key == xlator) {
827 set_idx = index;
828 break;
829 }
830 }
831
832 if (set_idx == -1) {
833 set_idx = fd->xl_count;
834
835 new_xl_count = fd->xl_count + xlator->graph->xl_count;
836
837 tmp = GF_REALLOC (fd->_ctx,__gf_realloc (fd->_ctx, (sizeof (struct _fd_ctx) * new_xl_count
))
838 (sizeof (struct _fd_ctx)__gf_realloc (fd->_ctx, (sizeof (struct _fd_ctx) * new_xl_count
))
839 * new_xl_count))__gf_realloc (fd->_ctx, (sizeof (struct _fd_ctx) * new_xl_count
))
;
840 if (tmp == NULL((void*)0)) {
841 gf_log_callingfn (THIS->name, GF_LOG_WARNING,do { do { if (0) printf ("realloc of fd->_ctx for fd " "(ptr: %p) failed, cannot set the key"
, fd); } while (0); _gf_log_callingfn ((*__glusterfs_this_location
())->name, "fd.c", __FUNCTION__, 844, GF_LOG_WARNING, "realloc of fd->_ctx for fd "
"(ptr: %p) failed, cannot set the key" , fd); } while (0)
842 "realloc of fd->_ctx for fd "do { do { if (0) printf ("realloc of fd->_ctx for fd " "(ptr: %p) failed, cannot set the key"
, fd); } while (0); _gf_log_callingfn ((*__glusterfs_this_location
())->name, "fd.c", __FUNCTION__, 844, GF_LOG_WARNING, "realloc of fd->_ctx for fd "
"(ptr: %p) failed, cannot set the key" , fd); } while (0)
843 "(ptr: %p) failed, cannot set the key"do { do { if (0) printf ("realloc of fd->_ctx for fd " "(ptr: %p) failed, cannot set the key"
, fd); } while (0); _gf_log_callingfn ((*__glusterfs_this_location
())->name, "fd.c", __FUNCTION__, 844, GF_LOG_WARNING, "realloc of fd->_ctx for fd "
"(ptr: %p) failed, cannot set the key" , fd); } while (0)
844 , fd)do { do { if (0) printf ("realloc of fd->_ctx for fd " "(ptr: %p) failed, cannot set the key"
, fd); } while (0); _gf_log_callingfn ((*__glusterfs_this_location
())->name, "fd.c", __FUNCTION__, 844, GF_LOG_WARNING, "realloc of fd->_ctx for fd "
"(ptr: %p) failed, cannot set the key" , fd); } while (0)
;
845 ret = -1;
846 goto out;
847 }
848
849 fd->_ctx = tmp;
850
851 begin = fd->_ctx;
852 begin += (fd->xl_count * sizeof (struct _fd_ctx));
853
854 diff = (new_xl_count - fd->xl_count )
855 * sizeof (struct _fd_ctx);
856
857 memset (begin, 0, diff);
858
859 fd->xl_count = new_xl_count;
860 }
861
862 fd->_ctx[set_idx].xl_key = xlator;
863 fd->_ctx[set_idx].value1 = value;
864
865out:
866 return ret;
867}
868
869
870int
871fd_ctx_set (fd_t *fd, xlator_t *xlator, uint64_t value)
872{
873 int ret = 0;
874
875 if (!fd || !xlator) {
876 gf_log_callingfn ("", GF_LOG_WARNING, "%p %p", fd, xlator)do { do { if (0) printf ("%p %p", fd, xlator); } while (0); _gf_log_callingfn
("", "fd.c", __FUNCTION__, 876, GF_LOG_WARNING, "%p %p", fd,
xlator); } while (0)
;
877 return -1;
878 }
879
880 LOCK (&fd->lock)pthread_spin_lock (&fd->lock);
881 {
882 ret = __fd_ctx_set (fd, xlator, value);
883 }
884 UNLOCK (&fd->lock)pthread_spin_unlock (&fd->lock);
885
886 return ret;
887}
888
889
890int
891__fd_ctx_get (fd_t *fd, xlator_t *xlator, uint64_t *value)
892{
893 int index = 0;
894 int ret = 0;
895
896 if (!fd || !xlator)
897 return -1;
898
899 for (index = 0; index < fd->xl_count; index++) {
900 if (fd->_ctx[index].xl_key == xlator)
901 break;
902 }
903
904 if (index == fd->xl_count) {
905 ret = -1;
906 goto out;
907 }
908
909 if (value)
910 *value = fd->_ctx[index].value1;
911
912out:
913 return ret;
914}
915
916
917int
918fd_ctx_get (fd_t *fd, xlator_t *xlator, uint64_t *value)
919{
920 int ret = 0;
921
922 if (!fd || !xlator)
923 return -1;
924
925 LOCK (&fd->lock)pthread_spin_lock (&fd->lock);
926 {
927 ret = __fd_ctx_get (fd, xlator, value);
928 }
929 UNLOCK (&fd->lock)pthread_spin_unlock (&fd->lock);
930
931 return ret;
932}
933
934
935int
936__fd_ctx_del (fd_t *fd, xlator_t *xlator, uint64_t *value)
937{
938 int index = 0;
939 int ret = 0;
940
941 if (!fd || !xlator)
942 return -1;
943
944 for (index = 0; index < fd->xl_count; index++) {
945 if (fd->_ctx[index].xl_key == xlator)
946 break;
947 }
948
949 if (index == fd->xl_count) {
950 ret = -1;
951 goto out;
952 }
953
954 if (value)
955 *value = fd->_ctx[index].value1;
956
957 fd->_ctx[index].key = 0;
958 fd->_ctx[index].value1 = 0;
959
960out:
961 return ret;
962}
963
964
965int
966fd_ctx_del (fd_t *fd, xlator_t *xlator, uint64_t *value)
967{
968 int ret = 0;
969
970 if (!fd || !xlator)
971 return -1;
972
973 LOCK (&fd->lock)pthread_spin_lock (&fd->lock);
974 {
975 ret = __fd_ctx_del (fd, xlator, value);
976 }
977 UNLOCK (&fd->lock)pthread_spin_unlock (&fd->lock);
978
979 return ret;
980}
981
982
983void
984fd_dump (fd_t *fd, char *prefix)
985{
986 char key[GF_DUMP_MAX_BUF_LEN4096];
987
988 if (!fd)
989 return;
990
991 memset(key, 0, sizeof(key));
992 gf_proc_dump_write("pid", "%llu", fd->pid);
993 gf_proc_dump_write("refcount", "%d", fd->refcount);
994 gf_proc_dump_write("flags", "%d", fd->flags);
995
996 if (fd->inode) {
997 gf_proc_dump_build_key (key, "inode", NULL){ _gf_proc_dump_build_key(key, "inode", ((void*)0)); };
998 gf_proc_dump_add_section(key);
999 inode_dump (fd->inode, key);
1000 }
1001
1002}
1003
1004
1005void
1006fdentry_dump (fdentry_t *fdentry, char *prefix)
1007{
1008 if (!fdentry)
1009 return;
1010
1011 if (GF_FDENTRY_ALLOCATED-2 != fdentry->next_free)
1012 return;
1013
1014 if (fdentry->fd)
1015 fd_dump(fdentry->fd, prefix);
1016}
1017
1018
1019void
1020fdtable_dump (fdtable_t *fdtable, char *prefix)
1021{
1022 char key[GF_DUMP_MAX_BUF_LEN4096];
1023 int i = 0;
1024 int ret = -1;
1025
1026 if (!fdtable)
1027 return;
1028
1029 ret = pthread_mutex_trylock (&fdtable->lock);
1030
1031 if (ret)
1032 goto out;
1033
1034 memset(key, 0, sizeof(key));
1035 gf_proc_dump_build_key(key, prefix, "refcount"){ _gf_proc_dump_build_key(key, prefix, "refcount"); };
1036 gf_proc_dump_write(key, "%d", fdtable->refcount);
1037 gf_proc_dump_build_key(key, prefix, "maxfds"){ _gf_proc_dump_build_key(key, prefix, "maxfds"); };
1038 gf_proc_dump_write(key, "%d", fdtable->max_fds);
1039 gf_proc_dump_build_key(key, prefix, "first_free"){ _gf_proc_dump_build_key(key, prefix, "first_free"); };
1040 gf_proc_dump_write(key, "%d", fdtable->first_free);
1041
1042 for ( i = 0 ; i < fdtable->max_fds; i++) {
1043 if (GF_FDENTRY_ALLOCATED-2 ==
1044 fdtable->fdentries[i].next_free) {
1045 gf_proc_dump_build_key(key, prefix, "fdentry[%d]", i){ _gf_proc_dump_build_key(key, prefix, "fdentry[%d]", i); };
1046 gf_proc_dump_add_section(key);
1047 fdentry_dump(&fdtable->fdentries[i], key);
1048 }
1049 }
1050
1051 pthread_mutex_unlock(&fdtable->lock);
1052
1053out:
1054 if (ret != 0)
1055 gf_proc_dump_write ("Unable to dump the fdtable",
1056 "(Lock acquistion failed) %p", fdtable);
1057 return;
1058}
1059
1060
1061void
1062fd_ctx_dump (fd_t *fd, char *prefix)
1063{
1064 struct _fd_ctx *fd_ctx = NULL((void*)0);
1065 xlator_t *xl = NULL((void*)0);
1066 int i = 0;
1067
1068
1069 if ((fd == NULL((void*)0)) || (fd->_ctx == NULL((void*)0))) {
1070 goto out;
1071 }
1072
1073 LOCK (&fd->lock)pthread_spin_lock (&fd->lock);
1074 {
1075 if (fd->_ctx != NULL((void*)0)) {
1076 fd_ctx = GF_CALLOC (fd->xl_count, sizeof (*fd_ctx),__gf_calloc (fd->xl_count, sizeof (*fd_ctx), gf_common_mt_fd_ctx
)
1077 gf_common_mt_fd_ctx)__gf_calloc (fd->xl_count, sizeof (*fd_ctx), gf_common_mt_fd_ctx
)
;
1078 if (fd_ctx == NULL((void*)0)) {
1079 goto unlock;
1080 }
1081
1082 for (i = 0; i < fd->xl_count; i++) {
1083 fd_ctx[i] = fd->_ctx[i];
1084 }
1085 }
1086 }
1087unlock:
1088 UNLOCK (&fd->lock)pthread_spin_unlock (&fd->lock);
1089
1090 if (fd_ctx == NULL((void*)0)) {
1091 goto out;
1092 }
1093
1094 for (i = 0; i < fd->xl_count; i++) {
1095 if (fd_ctx[i].xl_key) {
1096 xl = (xlator_t *)(long)fd_ctx[i].xl_key;
1097 if (xl->dumpops && xl->dumpops->fdctx)
1098 xl->dumpops->fdctx (xl, fd);
1099 }
1100 }
1101
1102out:
1103 GF_FREE (fd_ctx)__gf_free (fd_ctx);
1104
1105 return;
1106}
1107
1108void
1109fdentry_dump_to_dict (fdentry_t *fdentry, char *prefix, dict_t *dict,
1110 int *openfds)
1111{
1112 char key[GF_DUMP_MAX_BUF_LEN4096] = {0,};
1113 int ret = -1;
1114
1115 if (!fdentry)
1116 return;
1117 if (!dict)
1118 return;
1119
1120 if (GF_FDENTRY_ALLOCATED-2 != fdentry->next_free)
1121 return;
1122
1123 if (fdentry->fd) {
1124 memset (key, 0, sizeof (key));
1125 snprintf (key, sizeof (key), "%s.pid", prefix);
1126 ret = dict_set_int32 (dict, key, fdentry->fd->pid);
1127 if (ret)
1128 return;
1129
1130 memset (key, 0, sizeof (key));
1131 snprintf (key, sizeof (key), "%s.refcount", prefix);
1132 ret = dict_set_int32 (dict, key, fdentry->fd->refcount);
1133 if (ret)
1134 return;
1135
1136 memset (key, 0, sizeof (key));
1137 snprintf (key, sizeof (key), "%s.flags", prefix);
1138 ret = dict_set_int32 (dict, key, fdentry->fd->flags);
Value stored to 'ret' is never read
1139
1140 (*openfds)++;
1141 }
1142 return;
1143}
1144
1145void
1146fdtable_dump_to_dict (fdtable_t *fdtable, char *prefix, dict_t *dict)
1147{
1148 char key[GF_DUMP_MAX_BUF_LEN4096] = {0,};
1149 int i = 0;
1150 int openfds = 0;
1151 int ret = -1;
1152
1153 if (!fdtable)
1154 return;
1155 if (!dict)
1156 return;
1157
1158 ret = pthread_mutex_trylock (&fdtable->lock);
1159 if (ret)
1160 goto out;
1161
1162 memset (key, 0, sizeof (key));
1163 snprintf (key, sizeof (key), "%s.fdtable.refcount", prefix);
1164 ret = dict_set_int32 (dict, key, fdtable->refcount);
1165 if (ret)
1166 goto out;
1167
1168 memset (key, 0, sizeof (key));
1169 snprintf (key, sizeof (key), "%s.fdtable.maxfds", prefix);
1170 ret = dict_set_uint32 (dict, key, fdtable->max_fds);
1171 if (ret)
1172 goto out;
1173
1174 memset (key, 0, sizeof (key));
1175 snprintf (key, sizeof (key), "%s.fdtable.firstfree", prefix);
1176 ret = dict_set_int32 (dict, key, fdtable->first_free);
1177 if (ret)
1178 goto out;
1179
1180 for (i = 0; i < fdtable->max_fds; i++) {
1181 if (GF_FDENTRY_ALLOCATED-2 ==
1182 fdtable->fdentries[i].next_free) {
1183 memset (key, 0, sizeof (key));
1184 snprintf (key, sizeof (key), "%s.fdtable.fdentry%d",
1185 prefix, i);
1186 fdentry_dump_to_dict (&fdtable->fdentries[i], key,
1187 dict, &openfds);
1188 }
1189 }
1190
1191 memset (key, 0, sizeof (key));
1192 snprintf (key, sizeof (key), "%s.fdtable.openfds", prefix);
1193 ret = dict_set_int32 (dict, key, openfds);
1194
1195out:
1196 pthread_mutex_unlock (&fdtable->lock);
1197 return;
1198}