glusterfs

Форк
0
227 строк · 5.8 Кб
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 "io-cache.h"
12
#include "ioc-mem-types.h"
13

14
extern int ioc_log2_page_size;
15

16
/*
17
 * str_to_ptr - convert a string to pointer
18
 * @string: string
19
 *
20
 */
21
void *
22
str_to_ptr(char *string)
23
{
24
    void *ptr = NULL;
25

26
    GF_VALIDATE_OR_GOTO("io-cache", string, out);
27

28
    ptr = (void *)strtoul(string, NULL, 16);
29

30
out:
31
    return ptr;
32
}
33

34
/*
35
 * ptr_to_str - convert a pointer to string
36
 * @ptr: pointer
37
 *
38
 */
39
char *
40
ptr_to_str(void *ptr)
41
{
42
    int ret = 0;
43
    char *str = NULL;
44

45
    GF_VALIDATE_OR_GOTO("io-cache", ptr, out);
46

47
    ret = gf_asprintf(&str, "%p", ptr);
48
    if (-1 == ret) {
49
        gf_smsg("io-cache", GF_LOG_WARNING, 0,
50
                IO_CACHE_MSG_STR_COVERSION_FAILED, NULL);
51
        str = NULL;
52
        goto out;
53
    }
54

55
out:
56
    return str;
57
}
58

59
void
60
ioc_inode_wakeup(call_frame_t *frame, ioc_inode_t *ioc_inode,
61
                 struct iatt *stbuf)
62
{
63
    ioc_waitq_t *waiter = NULL, *waited = NULL;
64
    ioc_waitq_t *page_waitq = NULL;
65
    int8_t cache_still_valid = 1;
66
    ioc_local_t *local = NULL;
67
    int8_t need_fault = 0;
68
    ioc_page_t *waiter_page = NULL;
69

70
    GF_VALIDATE_OR_GOTO("io-cache", frame, out);
71

72
    local = frame->local;
73
    GF_VALIDATE_OR_GOTO(frame->this->name, local, out);
74

75
    if (ioc_inode == NULL) {
76
        local->op_ret = -1;
77
        local->op_errno = EINVAL;
78
        gf_smsg(frame->this->name, GF_LOG_WARNING, 0, IO_CACHE_MSG_INODE_NULL,
79
                NULL);
80
        goto out;
81
    }
82

83
    if (stbuf)
84
        cache_still_valid = ioc_cache_still_valid(ioc_inode, stbuf);
85
    else
86
        cache_still_valid = 0;
87

88
    ioc_inode_lock(ioc_inode);
89
    {
90
        waiter = ioc_inode->waitq;
91
        if (!waiter) {
92
            gf_smsg(frame->this->name, GF_LOG_WARNING, 0,
93
                    IO_CACHE_MSG_PAGE_WAIT_VALIDATE, NULL);
94

95
            ioc_inode_unlock(ioc_inode);
96
            goto out;
97
        }
98

99
        while (waiter) {
100
            waiter_page = waiter->data;
101
            ioc_inode->waitq = waiter->next;
102
            page_waitq = NULL;
103

104
            if (waiter_page) {
105
                if (cache_still_valid) {
106
                    /* cache valid, wake up page */
107
                    page_waitq = __ioc_page_wakeup(waiter_page,
108
                                                   waiter_page->op_errno);
109
                    if (page_waitq) {
110
                        ioc_inode_unlock(ioc_inode);
111
                        ioc_waitq_return(page_waitq);
112
                        ioc_inode_lock(ioc_inode);
113
                    }
114
                } else {
115
                    /* cache invalid, generate page fault and set
116
                     * page->ready = 0, to avoid double faults
117
                     */
118
                    if (waiter_page->ready) {
119
                        waiter_page->ready = 0;
120
                        need_fault = 1;
121
                    } else {
122
                        gf_msg_trace(frame->this->name, 0,
123
                                     "validate "
124
                                     "frame(%p) is "
125
                                     "waiting for "
126
                                     "in-transit"
127
                                     " page = %p",
128
                                     frame, waiter_page);
129
                    }
130

131
                    if (need_fault) {
132
                        need_fault = 0;
133
                        ioc_inode_unlock(ioc_inode);
134
                        ioc_page_fault(ioc_inode, frame, local->fd,
135
                                       waiter_page->offset);
136
                        ioc_inode_lock(ioc_inode);
137
                    }
138
                }
139
            }
140

141
            waited = waiter;
142
            waiter = ioc_inode->waitq;
143

144
            waited->data = NULL;
145
            GF_FREE(waited);
146
        }
147
    }
148
    ioc_inode_unlock(ioc_inode);
149

150
out:
151
    return;
152
}
153

154
/*
155
 * ioc_inode_create - create a new ioc_inode_t structure and add it to
156
 *                    the table table. fill in the fields which are derived
157
 *                    from inode_t corresponding to the file
158
 *
159
 * @table: io-table structure
160
 * @inode: inode structure
161
 *
162
 * not for external reference
163
 */
164
ioc_inode_t *
165
ioc_inode_create(ioc_table_t *table, inode_t *inode, uint32_t weight)
166
{
167
    ioc_inode_t *ioc_inode = NULL;
168

169
    GF_VALIDATE_OR_GOTO("io-cache", table, out);
170

171
    ioc_inode = GF_CALLOC(1, sizeof(ioc_inode_t), gf_ioc_mt_ioc_inode_t);
172
    if (ioc_inode == NULL) {
173
        goto out;
174
    }
175

176
    ioc_inode->inode = inode;
177
    ioc_inode->table = table;
178
    INIT_LIST_HEAD(&ioc_inode->cache.page_lru);
179
    pthread_mutex_init(&ioc_inode->inode_lock, NULL);
180
    ioc_inode->weight = weight;
181

182
    ioc_table_lock(table);
183
    {
184
        table->inode_count++;
185
        list_add(&ioc_inode->inode_list, &table->inodes);
186
        list_add_tail(&ioc_inode->inode_lru, &table->inode_lru[weight]);
187
    }
188
    ioc_table_unlock(table);
189

190
    gf_msg_trace(table->xl->name, 0, "adding to inode_lru[%d]", weight);
191

192
out:
193
    return ioc_inode;
194
}
195

196
/*
197
 * ioc_inode_destroy - destroy an ioc_inode_t object.
198
 *
199
 * @inode: inode to destroy
200
 *
201
 * to be called only from ioc_forget.
202
 */
203
void
204
ioc_inode_destroy(ioc_inode_t *ioc_inode)
205
{
206
    ioc_table_t *table = NULL;
207

208
    GF_VALIDATE_OR_GOTO("io-cache", ioc_inode, out);
209

210
    table = ioc_inode->table;
211

212
    ioc_table_lock(table);
213
    {
214
        table->inode_count--;
215
        list_del(&ioc_inode->inode_list);
216
        list_del(&ioc_inode->inode_lru);
217
    }
218
    ioc_table_unlock(table);
219

220
    ioc_inode_flush(ioc_inode);
221
    rbthash_table_destroy(ioc_inode->cache.page_table);
222

223
    pthread_mutex_destroy(&ioc_inode->inode_lock);
224
    GF_FREE(ioc_inode);
225
out:
226
    return;
227
}
228

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.