1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
#include "metadisp.h"
/**
* With a change to the posix xlator, readdir and readdirp are shockingly
* simple.
*
* The issue with separating the backend data of the files
* with the metadata is that readdirs must now read from multiple sources
* to coalesce the directory entries.
*
* The way we do this is to tell the METADATA_CHILD that when it's
* running readdirp, each file entry should have a stat wound to
* 'stat-source-of-truth'.
*
* see metadisp_stat for how it handles winds _from_posix.
*/
int32_t
metadisp_readdir(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
off_t off, dict_t *xdata)
{
METADISP_TRACE(".");
/*
* Always use readdirp, even if the original was readdir. Why? Because NFS.
* There are multiple translations between Gluster, UNIX, and NFS stat
* structures in that path. One of them uses the type etc. from the stat
* structure, which is only filled in by readdirp. If we use readdir, the
* entries do actually go all the way back to the client and are visible in
* getdents, but then the readdir throws them away because of the
* uninitialized type.
*/
GF_UNUSED int32_t ret;
if (!xdata) {
xdata = dict_new();
}
// ret = dict_set_int32 (xdata, "list-xattr", 1);
// I'm my own source of truth!
ret = dict_set_static_ptr(xdata, "stat-source-of-truth", (void *)this);
STACK_WIND(frame, default_readdirp_cbk, METADATA_CHILD(this),
METADATA_CHILD(this)->fops->readdirp, fd, size, off, xdata);
return 0;
}
int32_t
metadisp_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
off_t off, dict_t *xdata)
{
METADISP_TRACE(".");
if (!xdata) {
xdata = dict_new();
}
GF_UNUSED int32_t ret;
// ret = dict_set_int32 (xdata, "list-xattr", 1);
// I'm my own source of truth!
ret = dict_set_static_ptr(xdata, "stat-source-of-truth", (void *)this);
STACK_WIND(frame, default_readdirp_cbk, METADATA_CHILD(this),
METADATA_CHILD(this)->fops->readdirp, fd, size, off, xdata);
return 0;
}
|