ConnectionRef con = request->reply->get_connection();
uint64_t features = con->get_features();
- assert(request->readdir_result.empty());
+ dir_result_t *dirp = request->dirp;
+ assert(dirp);
// the extra buffer list is only set for readdir and lssnap replies
bufferlist::iterator p = reply->get_extra_bl().begin();
::decode(end, p);
::decode(complete, p);
- frag_t fg = request->readdir_frag;
- uint64_t readdir_offset = request->readdir_offset;
- string readdir_start = request->readdir_start;
+ frag_t fg = (unsigned)request->head.args.readdir.frag;
+ uint64_t readdir_offset = dirp->next_offset;
+ string readdir_start = dirp->last_name;
+
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();
+ dirp->offset = dir_result_t::make_fpos(fg, readdir_offset);
}
ldout(cct, 10) << __func__ << " " << numdn << " readdir items, end=" << (int)end
<< ", offset " << readdir_offset
<< ", readdir_start " << readdir_start << dendl;
- request->readdir_reply_frag = fg;
- request->readdir_end = end;
- request->readdir_num = numdn;
+ dirp->buffer_frag = fg;
+ dirp->this_offset = readdir_offset;
+
+ _readdir_drop_dirp_buffer(dirp);
+ dirp->buffer.reserve(numdn);
string dname;
LeaseStat dlease;
dn = link(dir, dname, in, NULL);
}
update_dentry_lease(dn, &dlease, request->sent_stamp, session);
- dn->offset = dir_result_t::make_fpos(fg, i + readdir_offset);
+ dn->offset = dir_result_t::make_fpos(fg, readdir_offset++);
// add to cached result list
- request->readdir_result.push_back(pair<string,InodeRef>(dname, in));
+ dirp->buffer.push_back(pair<string,InodeRef>(dname, in));
ldout(cct, 15) << __func__ << " " << hex << dn->offset << dec << ": '" << dname << "' -> " << in->ino << dendl;
}
- request->readdir_last_name = dname;
+
+ if (end) {
+ dirp->last_name.clear();
+ dirp->next_offset = 2;
+ } else {
+ dirp->last_name = dname;
+ dirp->next_offset = readdir_offset;
+ }
if (dir->is_empty())
close_dir(dir);
req->head.args.readdir.frag = fg;
if (dirp->last_name.length()) {
req->path2.set_path(dirp->last_name.c_str());
- req->readdir_start = dirp->last_name;
}
- req->readdir_offset = dirp->next_offset;
- req->readdir_frag = fg;
-
+ req->dirp = dirp;
bufferlist dirbl;
int res = make_request(req, dirp->owner_uid, dirp->owner_gid, NULL, NULL, -1, &dirbl);
}
if (res == 0) {
- // stuff dir contents to cache, dir_result_t
- assert(diri);
-
- _readdir_drop_dirp_buffer(dirp);
-
- dirp->buffer.swap(req->readdir_result);
-
- if (fg != req->readdir_reply_frag) {
- fg = req->readdir_reply_frag;
- dirp->next_offset = 2;
- dirp->offset = dir_result_t::make_fpos(fg, dirp->next_offset);
- }
- dirp->buffer_frag = fg;
- dirp->this_offset = dirp->next_offset;
ldout(cct, 10) << "_readdir_get_frag " << dirp << " got frag " << dirp->buffer_frag
<< " this_offset " << dirp->this_offset
<< " size " << dirp->buffer.size() << dendl;
-
- if (req->readdir_end) {
- dirp->last_name.clear();
- dirp->next_offset = 2;
- } else {
- dirp->last_name = req->readdir_last_name;
- dirp->next_offset += req->readdir_num;
- }
} else {
ldout(cct, 10) << "_readdir_get_frag got error " << res << ", setting end flag" << dendl;
dirp->set_end();
ldout(cct, 10) << "off " << off << " this_offset " << hex << dirp->this_offset << dec << " size " << dirp->buffer.size()
<< " frag " << fg << dendl;
- dirp->offset = dir_result_t::make_fpos(fg, off);
while (off >= dirp->this_offset &&
off - dirp->this_offset < dirp->buffer.size()) {
pair<string,InodeRef>& ent = dirp->buffer[off - dirp->this_offset];
return r;
}
- if (dirp->last_name.length()) {
+ if (!dirp->last_name.empty()) {
ldout(cct, 10) << " fetching next chunk of this frag" << dendl;
_readdir_drop_dirp_buffer(dirp);
continue; // more!
class MClientReply;
class Dentry;
+class dir_result_t;
struct MetaRequest {
private:
bool success;
// readdir result
- frag_t readdir_frag;
- string readdir_start; // starting _after_ this name
- uint64_t readdir_offset;
-
- frag_t readdir_reply_frag;
- vector<pair<string,InodeRef> > readdir_result;
- bool readdir_end;
- int readdir_num;
- string readdir_last_name;
+ dir_result_t *dirp;
//possible responses
bool got_unsafe;
num_fwd(0), retry_attempt(0),
ref(1), reply(0),
kick(false), success(false),
- readdir_offset(0), readdir_end(false), readdir_num(0),
got_unsafe(false), item(this), unsafe_item(this),
unsafe_dir_item(this), unsafe_target_item(this),
caller_cond(0), dispatch_cond(0) {