mirror of
https://github.com/ceph/ceph
synced 2024-12-21 10:54:42 +00:00
librgw: conditionally send '.' and '..' (rgw_readdir)
Ganesha traditionally does not expect them, but they may be needed when bypassing the MDCACHE (2.4). Signed-off-by: Matt Benjamin <mbenjamin@redhat.com>
This commit is contained in:
parent
5e75c1834a
commit
b7730c0a6b
@ -152,9 +152,13 @@ int rgw_unlink(struct rgw_fs *rgw_fs,
|
||||
*/
|
||||
typedef bool (*rgw_readdir_cb)(const char *name, void *arg, uint64_t offset);
|
||||
|
||||
#define RGW_READDIR_FLAG_NONE 0x0000
|
||||
#define RGW_READDIR_FLAG_DOTDOT 0x0001 /* send dot names */
|
||||
|
||||
int rgw_readdir(struct rgw_fs *rgw_fs,
|
||||
struct rgw_file_handle *parent_fh, uint64_t *offset,
|
||||
rgw_readdir_cb rcb, void *cb_arg, bool *eof);
|
||||
rgw_readdir_cb rcb, void *cb_arg, bool *eof,
|
||||
uint32_t flags);
|
||||
|
||||
/* XXX (get|set)attr mask bits */
|
||||
#define RGW_SETATTR_MODE 1
|
||||
|
@ -210,7 +210,7 @@ namespace rgw {
|
||||
} /* RGWFileHandle::reclaim */
|
||||
|
||||
int RGWFileHandle::readdir(rgw_readdir_cb rcb, void *cb_arg, uint64_t *offset,
|
||||
bool *eof)
|
||||
bool *eof, uint32_t flags)
|
||||
{
|
||||
using event = RGWLibFS::event;
|
||||
int rc = 0;
|
||||
@ -220,6 +220,12 @@ namespace rgw {
|
||||
|
||||
(void) clock_gettime(CLOCK_MONOTONIC_COARSE, &now); /* !LOCKED */
|
||||
|
||||
if (flags & RGW_READDIR_FLAG_DOTDOT) {
|
||||
/* send '.' and '..' with their NFS-defined offsets */
|
||||
rcb(".", cb_arg, 1);
|
||||
rcb("..", cb_arg, 2);
|
||||
}
|
||||
|
||||
if (is_root()) {
|
||||
RGWListBucketsRequest req(cct, fs->get_user(), this, rcb, cb_arg,
|
||||
offset);
|
||||
@ -957,14 +963,15 @@ int rgw_close(struct rgw_fs *rgw_fs,
|
||||
|
||||
int rgw_readdir(struct rgw_fs *rgw_fs,
|
||||
struct rgw_file_handle *parent_fh, uint64_t *offset,
|
||||
rgw_readdir_cb rcb, void *cb_arg, bool *eof)
|
||||
rgw_readdir_cb rcb, void *cb_arg, bool *eof,
|
||||
uint32_t flags)
|
||||
{
|
||||
RGWFileHandle* parent = get_rgwfh(parent_fh);
|
||||
if (! parent) {
|
||||
/* bad parent */
|
||||
return -EINVAL;
|
||||
}
|
||||
int rc = parent->readdir(rcb, cb_arg, offset, eof);
|
||||
int rc = parent->readdir(rcb, cb_arg, offset, eof, flags);
|
||||
return -rc;
|
||||
}
|
||||
|
||||
|
@ -417,7 +417,8 @@ namespace rgw {
|
||||
return EPERM;
|
||||
}
|
||||
|
||||
int readdir(rgw_readdir_cb rcb, void *cb_arg, uint64_t *offset, bool *eof);
|
||||
int readdir(rgw_readdir_cb rcb, void *cb_arg, uint64_t *offset, bool *eof,
|
||||
uint32_t flags);
|
||||
int write(uint64_t off, size_t len, size_t *nbytes, void *buffer);
|
||||
int write_finish();
|
||||
int close();
|
||||
|
@ -97,7 +97,8 @@ TEST(LibRGW, LIST_BUCKETS) {
|
||||
|
||||
bool eof = false;
|
||||
uint64_t offset = 0;
|
||||
int ret = rgw_readdir(fs, fs->root_fh, &offset, r1_cb, &fids1, &eof);
|
||||
int ret = rgw_readdir(fs, fs->root_fh, &offset, r1_cb, &fids1, &eof,
|
||||
RGW_READDIR_FLAG_NONE);
|
||||
for (auto& fid : fids1) {
|
||||
std::cout << "fname: " << get<0>(fid) << " fid: " << get<1>(fid)
|
||||
<< std::endl;
|
||||
@ -170,7 +171,8 @@ TEST(LibRGW, LIST_OBJECTS) {
|
||||
|
||||
bool eof = false;
|
||||
uint64_t offset = 0;
|
||||
int ret = rgw_readdir(fs, bucket_fh, &offset, r2_cb, &obj_vector, &eof);
|
||||
int ret = rgw_readdir(fs, bucket_fh, &offset, r2_cb, &obj_vector, &eof,
|
||||
RGW_READDIR_FLAG_NONE);
|
||||
for (auto& obj : obj_vector) {
|
||||
std::cout << "fname: " << get<0>(obj) << " fid: " << get<1>(obj)
|
||||
<< std::endl;
|
||||
|
@ -208,7 +208,7 @@ TEST(LibRGW, LIST_OBJECTS) {
|
||||
bool eof = false;
|
||||
uint64_t offset = 0;
|
||||
int ret = rgw_readdir(fs, bucket_fh, &offset, r2_cb, &fids,
|
||||
&eof);
|
||||
&eof, RGW_READDIR_FLAG_NONE);
|
||||
for (auto& fid : fids) {
|
||||
std::cout << "fname: " << get<0>(fid) << " fid: " << get<1>(fid)
|
||||
<< std::endl;
|
||||
|
@ -167,8 +167,12 @@ extern "C" {
|
||||
<< " dir=" << rgw_fh->full_object_name()
|
||||
<< " called back name=" << name
|
||||
<< dendl;
|
||||
obj_stack.push(
|
||||
obj_rec{name, nullptr, parent_fh, nullptr});
|
||||
string name_str{name};
|
||||
if (! ((name_str == ".") ||
|
||||
(name_str == ".."))) {
|
||||
obj_stack.push(
|
||||
obj_rec{std::move(name_str), nullptr, parent_fh, nullptr});
|
||||
}
|
||||
return true; /* XXX */
|
||||
}
|
||||
}
|
||||
@ -222,7 +226,8 @@ TEST(LibRGW, ENUMERATE1) {
|
||||
<< " object_name: " << elt.rgw_fh->object_name()
|
||||
<< " full_name: " << elt.rgw_fh->full_object_name()
|
||||
<< dendl;
|
||||
rc = rgw_readdir(fs, elt.fh, &offset, r1_cb, elt.fh, &eof);
|
||||
rc = rgw_readdir(fs, elt.fh, &offset, r1_cb, elt.fh, &eof,
|
||||
RGW_READDIR_FLAG_DOTDOT);
|
||||
elt.state.readdir = true;
|
||||
ASSERT_EQ(rc, 0);
|
||||
// ASSERT_TRUE(eof); // XXXX working incorrectly w/single readdir
|
||||
@ -324,7 +329,11 @@ extern "C" {
|
||||
<< " iv count=" << dvec.count
|
||||
<< " called back name=" << name
|
||||
<< dendl;
|
||||
dvec.obj_names.push_back(dirent_t{name, offset});
|
||||
string name_str{name};
|
||||
if (! ((name_str == ".") ||
|
||||
(name_str == ".."))) {
|
||||
dvec.obj_names.push_back(dirent_t{std::move(name_str), offset});
|
||||
}
|
||||
return true; /* XXX */
|
||||
}
|
||||
}
|
||||
@ -347,7 +356,8 @@ TEST(LibRGW, MARKER1_READDIR)
|
||||
|
||||
do {
|
||||
ASSERT_TRUE(dvec.count <= max_iterations);
|
||||
int ret = rgw_readdir(fs, marker_fh, &offset, r2_cb, &dvec, &eof);
|
||||
int ret = rgw_readdir(fs, marker_fh, &offset, r2_cb, &dvec, &eof,
|
||||
RGW_READDIR_FLAG_DOTDOT);
|
||||
ASSERT_EQ(ret, 0);
|
||||
ASSERT_EQ(offset, get<1>(dvec.obj_names.back())); // cookie check
|
||||
++dvec.count;
|
||||
|
Loading…
Reference in New Issue
Block a user