}
// insert readdir results too
- request->readdir_result.clear();
+ assert(request->readdir_result.empty());
// the rest?
p = reply->get_extra_bl().begin();
insert_dentry_inode(dir, dname, &dlease, in, from, mds);
// add to cached result list
- struct stat st;
- int stmask = fill_stat(in, &st);
- request->readdir_result.push_back(DirEntry(dname, st, stmask));
+ in->get();
+ request->readdir_result.push_back(pair<string,Inode*>(dname, in));
dout(15) << " '" << dname << "' -> " << in->ino << dendl;
put_inode(dirp->inode);
dirp->inode = 0;
}
+ _readdir_drop_dirp_buffer(dirp);
delete dirp;
}
}
}
+void Client::_readdir_drop_dirp_buffer(DirResult *dirp)
+{
+ dout(10) << "_readdir_drop_dirp_buffer " << dirp << dendl;
+ if (dirp->buffer) {
+ for (unsigned i = 0; i < dirp->buffer->size(); i++)
+ put_inode((*dirp->buffer)[i].second);
+ delete dirp->buffer;
+ }
+}
+
int Client::_readdir_get_frag(DirResult *dirp)
{
// get the current frag.
// stuff dir contents to cache, DirResult
assert(diri);
- delete dirp->buffer;
- dirp->buffer = new vector<DirEntry>;
+ _readdir_drop_dirp_buffer(dirp);
+
+ dirp->buffer = new vector<pair<string,Inode*> >;
dirp->buffer->swap(req->readdir_result);
dirp->buffer_frag = fg;
fill_dirent(&de, ".", S_IFDIR, diri->ino, next_off);
- struct stat st;
fill_stat(diri, &st);
int r = cb(p, &de, &st, -1, next_off);
Inode *in = diri->dn->inode;
fill_dirent(&de, "..", S_IFDIR, in->ino, 2);
- struct stat st;
fill_stat(in, &st);
int r = cb(p, &de, &st, -1, 2);
while (off - dirp->this_offset >= 0 &&
off - dirp->this_offset < dirp->buffer->size()) {
uint64_t pos = DirResult::make_fpos(fg, off);
- DirEntry& ent = (*dirp->buffer)[off - dirp->this_offset];
+ pair<string,Inode*>& ent = (*dirp->buffer)[off - dirp->this_offset];
- fill_dirent(&de, ent.d_name.c_str(), ent.st.st_mode, ent.st.st_ino, dirp->offset + 1);
+ int stmask = fill_stat(ent.second, &st);
+ fill_dirent(&de, ent.first.c_str(), st.st_mode, st.st_ino, dirp->offset + 1);
- int r = cb(p, &de, &ent.st, ent.stmask, dirp->offset + 1); // _next_ offset
+ int r = cb(p, &de, &st, stmask, dirp->offset + 1); // _next_ offset
dout(15) << " de " << de.d_name << " off " << dirp->offset
<< " = " << r
<< dendl;
if (dirp->last_name.length()) {
dout(10) << " fetching next chunk of this frag" << dendl;
- delete dirp->buffer;
- dirp->buffer = NULL;
+ _readdir_drop_dirp_buffer(dirp);
continue; // more!
}
bool kick;
// readdir result
- vector<DirEntry> readdir_result;
+ vector<pair<string,Inode*> > readdir_result;
bool readdir_end;
int readdir_num;
string readdir_last_name;
uint64_t release_count;
frag_t buffer_frag;
- vector<DirEntry> *buffer;
+ vector<pair<string,Inode*> > *buffer;
DirResult(Inode *in) : inode(in), offset(0), next_offset(2),
release_count(0),
// some helpers
int _opendir(Inode *in, DirResult **dirpp, int uid=-1, int gid=-1);
+ void _readdir_drop_dirp_buffer(DirResult *dirp);
bool _readdir_have_frag(DirResult *dirp);
void _readdir_next_frag(DirResult *dirp);
void _readdir_rechoose_frag(DirResult *dirp);