glusterfs

Форк
0
/
server-common.c 
369 строк · 11.2 Кб
1
#include "server.h"
2
#include "glusterfs3.h"
3
#include <glusterfs/compat-errno.h>
4
#include "server-messages.h"
5
#include "server-helpers.h"
6

7
#ifdef BUILD_GNFS
8
#include "xdr-nfs3.h"
9
#endif
10

11
/* Version 4 helpers */
12

13
void
14
server4_post_readlink(gfx_readlink_rsp *rsp, struct iatt *stbuf,
15
                      const char *buf)
16
{
17
    gfx_stat_from_iattx(&rsp->buf, stbuf);
18
    rsp->path = (char *)buf;
19
}
20

21
void
22
server4_post_common_3iatt(server_state_t *state, gfx_common_3iatt_rsp *rsp,
23
                          inode_t *inode, struct iatt *stbuf,
24
                          struct iatt *preparent, struct iatt *postparent)
25
{
26
    inode_t *link_inode = NULL;
27

28
    gfx_stat_from_iattx(&rsp->stat, stbuf);
29
    if (state->client->subdir_mount &&
30
        !gf_uuid_compare(preparent->ia_gfid, state->client->subdir_gfid)) {
31
        /* This is very important as when we send iatt of
32
           root-inode, fuse/client expect the gfid to be 1,
33
           along with inode number. As for subdirectory mount,
34
           we use inode table which is shared by everyone, but
35
           make sure we send fops only from subdir and below,
36
           we have to alter inode gfid and send it to client */
37
        static uuid_t gfid = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
38

39
        preparent->ia_ino = 1;
40
        postparent->ia_ino = 1;
41
        gf_uuid_copy(preparent->ia_gfid, gfid);
42
        gf_uuid_copy(postparent->ia_gfid, gfid);
43
    }
44

45
    gfx_stat_from_iattx(&rsp->preparent, preparent);
46
    gfx_stat_from_iattx(&rsp->postparent, postparent);
47

48
    link_inode = inode_link(inode, state->loc.parent, state->loc.name, stbuf);
49
    inode_lookup(link_inode);
50
    inode_unref(link_inode);
51
}
52

53
void
54
server4_post_common_3iatt_noinode(gfx_common_3iatt_rsp *rsp, struct iatt *stbuf,
55
                                  struct iatt *prebuf_dst,
56
                                  struct iatt *postbuf_dst)
57
{
58
    gfx_stat_from_iattx(&rsp->stat, stbuf);
59
    gfx_stat_from_iattx(&rsp->preparent, prebuf_dst);
60
    gfx_stat_from_iattx(&rsp->postparent, postbuf_dst);
61
}
62

63
void
64
server4_post_common_2iatt(gfx_common_2iatt_rsp *rsp, struct iatt *prebuf,
65
                          struct iatt *postbuf)
66
{
67
    gfx_stat_from_iattx(&rsp->prestat, prebuf);
68
    gfx_stat_from_iattx(&rsp->poststat, postbuf);
69
}
70

71
void
72
server4_post_entry_remove(server_state_t *state, gfx_common_2iatt_rsp *rsp,
73
                          struct iatt *prebuf, struct iatt *postbuf)
74
{
75
    inode_unlink(state->loc.inode, state->loc.parent, state->loc.name);
76
    /* parent should not be found for directories after
77
     * inode_unlink, since directories cannot have
78
     * hardlinks.
79
     */
80
    forget_inode_if_no_dentry(state->loc.inode);
81

82
    gfx_stat_from_iattx(&rsp->prestat, prebuf);
83
    gfx_stat_from_iattx(&rsp->poststat, postbuf);
84
}
85

86
void
87
server4_post_statfs(gfx_statfs_rsp *rsp, struct statvfs *stbuf)
88
{
89
    gf_statfs_from_statfs(&rsp->statfs, stbuf);
90
}
91

92
void
93
server4_post_common_iatt(server_state_t *state, gfx_common_iatt_rsp *rsp,
94
                         struct iatt *stbuf)
95
{
96
    if (state->client->subdir_mount &&
97
        !gf_uuid_compare(stbuf->ia_gfid, state->client->subdir_gfid)) {
98
        /* This is very important as when we send iatt of
99
           root-inode, fuse/client expect the gfid to be 1,
100
           along with inode number. As for subdirectory mount,
101
           we use inode table which is shared by everyone, but
102
           make sure we send fops only from subdir and below,
103
           we have to alter inode gfid and send it to client */
104
        static uuid_t gfid = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
105

106
        stbuf->ia_ino = 1;
107
        gf_uuid_copy(stbuf->ia_gfid, gfid);
108
    }
109

110
    gfx_stat_from_iattx(&rsp->stat, stbuf);
111
}
112

113
void
114
server4_post_lk(xlator_t *this, gfx_lk_rsp *rsp, struct gf_flock *lock)
115
{
116
    switch (lock->l_type) {
117
        case F_RDLCK:
118
            lock->l_type = GF_LK_F_RDLCK;
119
            break;
120
        case F_WRLCK:
121
            lock->l_type = GF_LK_F_WRLCK;
122
            break;
123
        case F_UNLCK:
124
            lock->l_type = GF_LK_F_UNLCK;
125
            break;
126
        default:
127
            gf_msg(this->name, GF_LOG_ERROR, 0, PS_MSG_LOCK_ERROR,
128
                   "Unknown lock type: %" PRId32 "!", lock->l_type);
129
            break;
130
    }
131

132
    gf_proto_flock_from_flock(&rsp->flock, lock);
133
}
134

135
int
136
server4_post_readdir(gfx_readdir_rsp *rsp, gf_dirent_t *entries)
137
{
138
    int ret = 0;
139

140
    ret = serialize_rsp_dirent_v2(entries, rsp);
141

142
    return ret;
143
}
144

145
void
146
server4_post_seek(gfx_seek_rsp *rsp, off_t offset)
147
{
148
    rsp->offset = offset;
149
}
150

151
int
152
server4_post_readdirp(gfx_readdirp_rsp *rsp, gf_dirent_t *entries)
153
{
154
    int ret = 0;
155

156
    ret = serialize_rsp_direntp_v2(entries, rsp);
157

158
    return ret;
159
}
160

161
void
162
server4_post_rchecksum(gfx_rchecksum_rsp *rsp, uint32_t weak_checksum,
163
                       uint8_t *strong_checksum)
164
{
165
    rsp->weak_checksum = weak_checksum;
166
    /* When the length encoding changes, update the change
167
       in posix code also. */
168
    rsp->strong_checksum.strong_checksum_val = (char *)strong_checksum;
169
    rsp->strong_checksum.strong_checksum_len = SHA256_DIGEST_LENGTH;
170
    rsp->flags = 1; /* Indicates SHA256 TYPE */
171
}
172

173
void
174
server4_post_rename(call_frame_t *frame, server_state_t *state,
175
                    gfx_rename_rsp *rsp, struct iatt *stbuf,
176
                    struct iatt *preoldparent, struct iatt *postoldparent,
177
                    struct iatt *prenewparent, struct iatt *postnewparent)
178
{
179
    inode_t *tmp_inode = NULL;
180

181
    stbuf->ia_type = state->loc.inode->ia_type;
182

183
    /* TODO: log gfid of the inodes */
184
    gf_msg_trace(frame->root->client->bound_xl->name, 0,
185
                 "%" PRId64
186
                 ": "
187
                 "RENAME_CBK %s ==> %s",
188
                 frame->root->unique, state->loc.name, state->loc2.name);
189

190
    /* Before renaming the inode, we have to get the inode for the
191
     * destination entry (i.e. inode with state->loc2.parent as
192
     * parent and state->loc2.name as name). If it exists, then
193
     * unlink that inode, and send forget on that inode if the
194
     * unlinked entry is the last entry. In case of fuse client
195
     * the fuse kernel module itself sends the forget on the
196
     * unlinked inode.
197
     */
198
    tmp_inode = inode_grep(state->loc.inode->table, state->loc2.parent,
199
                           state->loc2.name);
200
    if (tmp_inode) {
201
        inode_unlink(tmp_inode, state->loc2.parent, state->loc2.name);
202
        forget_inode_if_no_dentry(tmp_inode);
203
        inode_unref(tmp_inode);
204
    }
205

206
    inode_rename(state->itable, state->loc.parent, state->loc.name,
207
                 state->loc2.parent, state->loc2.name, state->loc.inode, stbuf);
208
    gfx_stat_from_iattx(&rsp->stat, stbuf);
209

210
    gfx_stat_from_iattx(&rsp->preoldparent, preoldparent);
211
    gfx_stat_from_iattx(&rsp->postoldparent, postoldparent);
212

213
    gfx_stat_from_iattx(&rsp->prenewparent, prenewparent);
214
    gfx_stat_from_iattx(&rsp->postnewparent, postnewparent);
215
}
216

217
int
218
server4_post_open(call_frame_t *frame, xlator_t *this, gfx_open_rsp *rsp,
219
                  fd_t *fd)
220
{
221
    server_ctx_t *serv_ctx = NULL;
222
    uint64_t fd_no = 0;
223

224
    serv_ctx = server_ctx_get(frame->root->client, this);
225
    if (serv_ctx == NULL) {
226
        gf_msg(this->name, GF_LOG_INFO, 0, PS_MSG_SERVER_CTX_GET_FAILED,
227
               "server_ctx_get() "
228
               "failed");
229
        return -1;
230
    }
231

232
    fd_bind(fd);
233
    fd_ref(fd);
234
    fd_no = gf_fd_unused_get(serv_ctx->fdtable, fd);
235
    rsp->fd = fd_no;
236

237
    return 0;
238
}
239

240
void
241
server4_post_readv(gfx_read_rsp *rsp, struct iatt *stbuf, int op_ret)
242
{
243
    gfx_stat_from_iattx(&rsp->stat, stbuf);
244
    rsp->size = op_ret;
245
}
246

247
int
248
server4_post_create(call_frame_t *frame, gfx_create_rsp *rsp,
249
                    server_state_t *state, xlator_t *this, fd_t *fd,
250
                    inode_t *inode, struct iatt *stbuf, struct iatt *preparent,
251
                    struct iatt *postparent)
252
{
253
    server_ctx_t *serv_ctx = NULL;
254
    inode_t *link_inode = NULL;
255
    uint64_t fd_no = 0;
256
    int op_errno = 0;
257

258
    link_inode = inode_link(inode, state->loc.parent, state->loc.name, stbuf);
259

260
    if (!link_inode) {
261
        op_errno = ENOENT;
262
        goto out;
263
    }
264

265
    if (link_inode != inode) {
266
        /*
267
          VERY racy code (if used anywhere else)
268
          -- don't do this without understanding
269
        */
270

271
        inode_ctx_merge(fd, fd->inode, link_inode);
272
        inode_unref(fd->inode);
273
        fd->inode = inode_ref(link_inode);
274
    }
275

276
    inode_lookup(link_inode);
277
    inode_unref(link_inode);
278

279
    serv_ctx = server_ctx_get(frame->root->client, this);
280
    if (serv_ctx == NULL) {
281
        gf_msg(this->name, GF_LOG_INFO, 0, PS_MSG_SERVER_CTX_GET_FAILED,
282
               "server_ctx_get() "
283
               "failed");
284
        goto out;
285
    }
286

287
    fd_bind(fd);
288
    fd_ref(fd);
289
    fd_no = gf_fd_unused_get(serv_ctx->fdtable, fd);
290

291
    if ((fd_no > UINT64_MAX) || (fd == 0)) {
292
        op_errno = errno;
293
    }
294

295
    rsp->fd = fd_no;
296
    gfx_stat_from_iattx(&rsp->stat, stbuf);
297
    gfx_stat_from_iattx(&rsp->preparent, preparent);
298
    gfx_stat_from_iattx(&rsp->postparent, postparent);
299

300
    return 0;
301
out:
302
    return -op_errno;
303
}
304

305
/*TODO: Handle revalidate path */
306
void
307
server4_post_lookup(gfx_common_2iatt_rsp *rsp, call_frame_t *frame,
308
                    server_state_t *state, inode_t *inode, struct iatt *stbuf,
309
                    dict_t *xdata)
310
{
311
    inode_t *root_inode = NULL;
312
    inode_t *link_inode = NULL;
313
    static uuid_t rootgfid = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
314

315
    root_inode = frame->root->client->bound_xl->itable->root;
316

317
    if (!__is_root_gfid(inode->gfid)) {
318
        link_inode = inode_link(inode, state->loc.parent, state->loc.name,
319
                                stbuf);
320
        if (link_inode) {
321
            if (dict_get_sizen(xdata, GF_NAMESPACE_KEY)) {
322
                inode_set_namespace_inode(link_inode, link_inode);
323
            }
324

325
            inode_lookup(link_inode);
326
            inode_unref(link_inode);
327
        }
328
    }
329

330
    if ((inode == root_inode) || (state->client->subdir_mount &&
331
                                  (inode == state->client->subdir_inode))) {
332
        /* we just looked up root ("/") OR
333
           subdir mount directory, which is root ('/') in client */
334
        /* This is very important as when we send iatt of
335
           root-inode, fuse/client expect the gfid to be 1,
336
           along with inode number. As for subdirectory mount,
337
           we use inode table which is shared by everyone, but
338
           make sure we send fops only from subdir and below,
339
           we have to alter inode gfid and send it to client */
340
        stbuf->ia_ino = 1;
341
        gf_uuid_copy(stbuf->ia_gfid, rootgfid);
342
        if (inode->ia_type == 0)
343
            inode->ia_type = stbuf->ia_type;
344
    }
345

346
    gfx_stat_from_iattx(&rsp->prestat, stbuf);
347
}
348

349
void
350
server4_post_lease(gfx_lease_rsp *rsp, struct gf_lease *lease)
351
{
352
    gf_proto_lease_from_lease(&rsp->lease, lease);
353
}
354

355
void
356
server4_post_link(server_state_t *state, gfx_common_3iatt_rsp *rsp,
357
                  inode_t *inode, struct iatt *stbuf, struct iatt *preparent,
358
                  struct iatt *postparent)
359
{
360
    inode_t *link_inode = NULL;
361

362
    gfx_stat_from_iattx(&rsp->stat, stbuf);
363
    gfx_stat_from_iattx(&rsp->preparent, preparent);
364
    gfx_stat_from_iattx(&rsp->postparent, postparent);
365

366
    link_inode = inode_link(inode, state->loc2.parent, state->loc2.name, stbuf);
367
    inode_lookup(link_inode);
368
    inode_unref(link_inode);
369
}
370

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

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

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

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