{
public:
RGWFileHandle* rgw_fh;
- std::string uri;
uint64_t* offset;
void* cb_arg;
rgw_readdir_cb rcb;
int operator()(const std::string& name, const std::string& marker,
bool add_marker) {
+ /* hash offset of name in parent (short name) for NFS readdir cookie */
uint64_t off = XXH64(name.c_str(), name.length(), fh_key::seed);
*offset = off;
/* update traversal cache */
}
virtual void send_response() {
+ struct req_state* s = get_state();
size_t size = objs.size();for (const auto& iter : objs) {
size_t last_del = iter.key.name.find_last_of('/');
boost::string_ref sref;
sref = boost::string_ref{iter.key.name.substr(last_del+1)};
else
sref = boost::string_ref{iter.key.name};
+
+ /* if we find a trailing slash in a -listing- the parent is an
+ * empty directory */
+ if (sref=="")
+ continue;
std::cout << "RGWListBucketRequest "
- << __func__ << " " << "list uri=" << uri << " "
+ << __func__ << " " << "list uri=" << s->relative_uri << " "
<< " prefix=" << prefix << " "
<< " obj path=" << iter.key.name
<< " (" << sref << ")" << ""
sref = boost::string_ref{iter.first};
std::cout << "RGWListBucketRequest "
- << __func__ << " " << "list uri=" << uri << " "
+ << __func__ << " " << "list uri=" << s->relative_uri << " "
<< " prefix=" << prefix << " "
<< " cpref=" << sref << " (not chomped)"
<< std::endl;
RGWFileHandle* rgw_fh;
std::string path;
bool matched;
+ bool is_dir;
RGWStatLeafRequest(CephContext* _cct, RGWUserInfo *_user,
RGWFileHandle* _rgw_fh, const std::string& _path)
: RGWLibRequest(_cct, _user), rgw_fh(_rgw_fh), path(_path),
- matched(false) {
+ matched(false), is_dir(false) {
default_max = 1000; // logical max {"foo", "foo/"}
magic = 80;
op = this;
s->user = user;
prefix = rgw_fh->full_object_name();
+ if (prefix.length() > 0)
+ prefix += "/";
+ prefix += path;
delimiter = '/';
return 0;
struct req_state* s = get_state();
// try objects
for (const auto& iter : objs) {
- path = iter.key.name;
+ auto& name = iter.key.name;
std::cout << "RGWStatLeafRequest "
<< __func__ << " " << "list uri=" << s->relative_uri << " "
<< " prefix=" << prefix << " "
- << " obj path=" << path << ""
+ << " obj path=" << name << ""
<< std::endl;
+ /* XXX is there a missing match-dir case (trailing '/')? */
matched = true;
return;
}
// try prefixes
for (auto& iter : common_prefixes) {
- path = iter.first;
+ auto& name = iter.first;
std::cout << "RGWStatLeafRequest "
<< __func__ << " " << "list uri=" << s->relative_uri << " "
<< " prefix=" << prefix << " "
- << " pref path=" << path << " (not chomped)"
+ << " pref path=" << name << " (not chomped)"
<< std::endl;
matched = true;
+ is_dir = true;
break;
}
}
RGWFileHandle* rgw_fh = rec.rgw_fh;
if (rgw_fh) {
const char* type = rgw_fh->is_dir() ? "DIR " : "FILE ";
- os << rec.name << ": "
+ os << rec.rgw_fh->full_object_name()
+ << " (" << rec.rgw_fh->object_name() << ", "
+ << " " << rec.name << "): "
<< type;
}
return os;
static bool r1_cb(const char* name, void *arg, uint64_t offset) {
struct rgw_file_handle* parent_fh
= static_cast<struct rgw_file_handle*>(arg);
+ RGWFileHandle* rgw_fh = get_rgwfh(parent_fh);
+ std::cout << __func__
+ << " bucket=" << rgw_fh->bucket_name()
+ << " dir=" << rgw_fh->full_object_name()
+ << " called back name=" << name
+ << std::endl;
obj_stack.push(
obj_rec{name, nullptr, parent_fh, nullptr});
return true; /* XXX */
std::cout << "readdir in"
<< " bucket: " << elt.rgw_fh->bucket_name()
<< " object_name: " << elt.rgw_fh->object_name()
- << " full name: " << elt.rgw_fh->full_object_name()
+ << " full_name: " << elt.rgw_fh->full_object_name()
<< std::endl;
rc = rgw_readdir(fs, elt.fh, &offset, r1_cb, elt.fh, &eof);
elt.state.readdir = true;