if (fg != dst.frag) {
ldout(cct, 10) << "insert_trace got new frag " << fg << " -> " << dst.frag << dendl;
fg = dst.frag;
- readdir_offset = 2;
- readdir_start.clear();
- if (!hash_order)
+ if (!hash_order) {
+ readdir_offset = 2;
+ readdir_start.clear();
dirp->offset = dir_result_t::make_fpos(fg, readdir_offset, false);
+ }
}
ldout(cct, 10) << __func__ << " " << numdn << " readdir items, end=" << end
ldout(cct, 15) << __func__ << " " << hex << dn->offset << dec << ": '" << dname << "' -> " << in->ino << dendl;
}
- if (end) {
- dirp->last_name.clear();
- dirp->next_offset = 2;
- } else {
+ if (numdn > 0)
dirp->last_name = dname;
+ if (end)
+ dirp->next_offset = 2;
+ else
dirp->next_offset = readdir_offset;
- }
if (dir->is_empty())
close_dir(dir);
ldout(cct, 10) << "_readdir_next_frag advance from " << dirp->buffer_frag << " to " << fg << dendl;
if (dirp->hash_order()) {
+ // keep last_name
int64_t new_offset = dir_result_t::make_fpos(fg.value(), 2, true);
if (dirp->offset < new_offset) // don't decrease offset
dirp->offset = new_offset;
} else {
+ dirp->last_name.clear();
dirp->offset = dir_result_t::make_fpos(fg, 2, false);
_readdir_rechoose_frag(dirp);
}
return r;
}
- if (!dirp->last_name.empty()) {
+ if (dirp->next_offset > 2) {
ldout(cct, 10) << " fetching next chunk of this frag" << dendl;
_readdir_drop_dirp_buffer(dirp);
continue; // more!
frag_t fg = (__u32)req->head.args.readdir.frag;
unsigned req_flags = (__u32)req->head.args.readdir.flags;
string offset_str = req->get_path2();
- dout(10) << " frag " << fg << " offset '" << offset_str << "'" << dendl;
+ dout(10) << " frag " << fg << " offset '" << offset_str << "'"
+ << " flags " << req_flags << dendl;
__u32 offset_hash = 0;
if (!offset_str.empty())
// does the frag exist?
if (diri->dirfragtree[fg.value()] != fg) {
- frag_t newfg = diri->dirfragtree[fg.value()];
+ frag_t newfg;
+ if (req_flags & CEPH_READDIR_REPLY_BITFLAGS) {
+ if (fg.contains((unsigned)offset_hash)) {
+ newfg = diri->dirfragtree[offset_hash];
+ } else {
+ // client actually wants next frag
+ newfg = diri->dirfragtree[fg.value()];
+ }
+ } else {
+ offset_str.clear();
+ newfg = diri->dirfragtree[fg.value()];
+ }
dout(10) << " adjust frag " << fg << " -> " << newfg << " " << diri->dirfragtree << dendl;
fg = newfg;
- offset_str.clear();
}
CDir *dir = try_open_auth_dirfrag(diri, fg, mdr);