glusterfs

Форк
0
/
quota-common-utils.c 
255 строк · 6.0 Кб
1
/*
2
   Copyright (c) 2015 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 "glusterfs/dict.h"
12
#include "glusterfs/logging.h"
13
#include "glusterfs/quota-common-utils.h"
14
#include "glusterfs/libglusterfs-messages.h"
15
#include <glusterfs/syscall.h>
16

17
gf_boolean_t
18
quota_meta_is_null(const quota_meta_t *meta)
19
{
20
    if (meta->size == 0 && meta->file_count == 0 && meta->dir_count == 0)
21
        return _gf_true;
22

23
    return _gf_false;
24
}
25

26
int32_t
27
quota_data_to_meta(data_t *data, quota_meta_t *meta)
28
{
29
    int32_t ret = -1;
30
    quota_meta_t *value = NULL;
31
    int64_t *size = NULL;
32

33
    if (!data || !meta)
34
        goto out;
35

36
    if (data->len > sizeof(int64_t)) {
37
        value = (quota_meta_t *)data->data;
38
        meta->size = be64toh(value->size);
39
        meta->file_count = be64toh(value->file_count);
40
        if (data->len > (sizeof(int64_t)) * 2)
41
            meta->dir_count = be64toh(value->dir_count);
42
        else
43
            meta->dir_count = 0;
44
    } else {
45
        size = (int64_t *)data->data;
46
        meta->size = be64toh(*size);
47
        meta->file_count = 0;
48
        meta->dir_count = 0;
49
        /* This can happen during software upgrade.
50
         * Older version of glusterfs will not have inode count.
51
         * Return failure, this will be healed as part of lookup
52
         */
53
        gf_msg_callingfn("quota", GF_LOG_DEBUG, 0, LG_MSG_QUOTA_XATTRS_MISSING,
54
                         "Object quota "
55
                         "xattrs missing: len = %d",
56
                         data->len);
57
        ret = -2;
58
        goto out;
59
    }
60

61
    ret = 0;
62
out:
63

64
    return ret;
65
}
66

67
int32_t
68
quota_dict_get_inode_meta(dict_t *dict, char *key, const int keylen,
69
                          quota_meta_t *meta)
70
{
71
    int32_t ret = -1;
72
    data_t *data = NULL;
73

74
    if (!dict || !key || !meta)
75
        goto out;
76

77
    data = dict_getn(dict, key, keylen);
78
    if (!data || !data->data)
79
        goto out;
80

81
    ret = quota_data_to_meta(data, meta);
82

83
out:
84

85
    return ret;
86
}
87

88
int32_t
89
quota_dict_get_meta(dict_t *dict, char *key, const int keylen,
90
                    quota_meta_t *meta)
91
{
92
    int32_t ret = -1;
93

94
    ret = quota_dict_get_inode_meta(dict, key, keylen, meta);
95
    if (ret == -2)
96
        ret = 0;
97

98
    return ret;
99
}
100

101
int32_t
102
quota_dict_set_meta(dict_t *dict, char *key, const quota_meta_t *meta,
103
                    ia_type_t ia_type)
104
{
105
    int32_t ret = -ENOMEM;
106
    quota_meta_t *value = NULL;
107

108
    value = GF_MALLOC(sizeof(quota_meta_t), gf_common_quota_meta_t);
109
    if (value == NULL) {
110
        goto out;
111
    }
112

113
    value->size = htobe64(meta->size);
114
    value->file_count = htobe64(meta->file_count);
115
    value->dir_count = htobe64(meta->dir_count);
116

117
    if (ia_type == IA_IFDIR) {
118
        ret = dict_set_bin(dict, key, value, sizeof(*value));
119
    } else {
120
        /* For a file we don't need to store dir_count in the
121
         * quota size xattr, so we set the len of the data in the dict
122
         * as 128bits, so when the posix xattrop reads the dict, it only
123
         * performs operations on size and file_count
124
         */
125
        ret = dict_set_bin(dict, key, value, sizeof(*value) - sizeof(int64_t));
126
    }
127

128
    if (ret < 0) {
129
        gf_msg_callingfn("quota", GF_LOG_ERROR, 0, LG_MSG_DICT_SET_FAILED,
130
                         "dict set failed");
131
        GF_FREE(value);
132
    }
133

134
out:
135
    return ret;
136
}
137

138
int32_t
139
quota_conf_read_header(int fd, char *buf)
140
{
141
    int ret = 0;
142
    const int header_len = SLEN(QUOTA_CONF_HEADER);
143

144
    ret = gf_nread(fd, buf, header_len);
145
    if (ret <= 0) {
146
        goto out;
147
    } else if (ret > 0 && ret != header_len) {
148
        ret = -1;
149
        goto out;
150
    }
151

152
    buf[header_len - 1] = 0;
153

154
out:
155
    if (ret < 0)
156
        gf_msg_callingfn("quota", GF_LOG_ERROR, 0, LG_MSG_QUOTA_CONF_ERROR,
157
                         "failed to read "
158
                         "header from a quota conf");
159

160
    return ret;
161
}
162

163
int32_t
164
quota_conf_read_version(int fd, float *version)
165
{
166
    int ret = 0;
167
    char buf[PATH_MAX] = "";
168
    char *tail = NULL;
169
    float value = 0.0f;
170

171
    ret = quota_conf_read_header(fd, buf);
172
    if (ret == 0) {
173
        /* quota.conf is empty */
174
        value = GF_QUOTA_CONF_VERSION;
175
        goto out;
176
    } else if (ret < 0) {
177
        goto out;
178
    }
179

180
    value = strtof((buf + strlen(buf) - 3), &tail);
181
    if (tail[0] != '\0') {
182
        ret = -1;
183
        gf_msg_callingfn("quota", GF_LOG_ERROR, 0, LG_MSG_QUOTA_CONF_ERROR,
184
                         "invalid quota conf"
185
                         " version");
186
        goto out;
187
    }
188

189
    ret = 0;
190

191
out:
192
    if (ret >= 0)
193
        *version = value;
194
    else
195
        gf_msg_callingfn("quota", GF_LOG_ERROR, 0, LG_MSG_QUOTA_CONF_ERROR,
196
                         "failed to "
197
                         "read version from a quota conf header");
198

199
    return ret;
200
}
201

202
int32_t
203
quota_conf_read_gfid(int fd, void *buf, char *type, float version)
204
{
205
    int ret = 0;
206

207
    ret = gf_nread(fd, buf, 16);
208
    if (ret <= 0)
209
        goto out;
210

211
    if (ret != 16) {
212
        ret = -1;
213
        goto out;
214
    }
215

216
    if (version >= 1.2f) {
217
        ret = gf_nread(fd, type, 1);
218
        if (ret != 1) {
219
            ret = -1;
220
            goto out;
221
        }
222
        ret = 17;
223
    } else {
224
        *type = GF_QUOTA_CONF_TYPE_USAGE;
225
    }
226

227
out:
228
    if (ret < 0)
229
        gf_msg_callingfn("quota", GF_LOG_ERROR, 0, LG_MSG_QUOTA_CONF_ERROR,
230
                         "failed to "
231
                         "read gfid from a quota conf");
232

233
    return ret;
234
}
235

236
static int
237
gf_skip_header_section(int fd, int header_len)
238
{
239
    int ret = -1;
240

241
    ret = sys_lseek(fd, header_len, SEEK_SET);
242
    if (ret == (off_t)-1) {
243
        gf_smsg("", GF_LOG_ERROR, 0, LG_MSG_SKIP_HEADER_FAILED, NULL);
244
    } else {
245
        ret = 0;
246
    }
247

248
    return ret;
249
}
250

251
int32_t
252
quota_conf_skip_header(int fd)
253
{
254
    return gf_skip_header_section(fd, strlen(QUOTA_CONF_HEADER));
255
}
256

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

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

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

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