}
-int Client::fill_stat(Inode *in, struct stat *st)
+int Client::fill_stat(Inode *in, struct stat *st, frag_info_t *dirstat)
{
dout(10) << "fill_stat on " << in->inode.ino << " mode 0" << oct << in->inode.mode << dec
<< " mtime " << in->inode.mtime << " ctime " << in->inode.ctime << dendl;
st->st_blocks = (in->inode.size + 511) >> 9;
}
st->st_blksize = MAX(ceph_file_layout_su(in->inode.layout), 4096);
+
+ if (dirstat)
+ *dirstat = in->inode.dirstat;
+
return in->lease_mask;
}
-int Client::lstat(const char *relpath, struct stat *stbuf)
+int Client::lstat(const char *relpath, struct stat *stbuf, frag_info_t *dirstat)
{
Mutex::Locker lock(client_lock);
tout << "lstat" << std::endl;
tout << relpath << std::endl;
filepath path = mkpath(relpath);
- return _lstat(path, stbuf);
+ return _lstat(path, stbuf, -1, -1, dirstat);
}
-int Client::_lstat(const filepath &path, struct stat *stbuf, int uid, int gid)
+int Client::_lstat(const filepath &path, struct stat *stbuf, int uid, int gid, frag_info_t *dirstat)
{
Inode *in = 0;
int res = _do_lstat(path, CEPH_STAT_MASK_INODE_ALL, &in);
if (res == 0) {
assert(in);
- fill_stat(in, stbuf);
+ fill_stat(in, stbuf, dirstat);
dout(10) << "stat sez size = " << in->inode.size
<< " mode = 0" << oct << stbuf->st_mode << dec
<< " ino = " << stbuf->st_ino << dendl;
// find dentry based on filepath
Dentry *lookup(const filepath& path);
- int fill_stat(Inode *in, struct stat *st);
+ int fill_stat(Inode *in, struct stat *st, frag_info_t *dirstat=0);
// trace generation
int _rmdir(const filepath &path, int uid=-1, int gid=-1);
int _readlink(const filepath &path, char *buf, off_t size, int uid=-1, int gid=-1);
int _symlink(const filepath &path, const char *target, int uid=-1, int gid=-1);
- int _lstat(const filepath &path, struct stat *stbuf, int uid=-1, int gid=-1);
+ int _lstat(const filepath &path, struct stat *stbuf, int uid=-1, int gid=-1, frag_info_t *dirstat=0);
int _chmod(const filepath &path, mode_t mode, bool followsym, int uid=-1, int gid=-1);
int _chown(const filepath &path, uid_t uid, gid_t gid, bool followsym, int cuid=-1, int cgid=-1);
int _getxattr(const filepath &path, const char *name, void *value, size_t len, bool followsym, int uid=-1, int gid=-1);
int symlink(const char *existing, const char *newname);
// inode stuff
- int lstat(const char *path, struct stat *stbuf);
+ int lstat(const char *path, struct stat *stbuf, frag_info_t *dirstat=0);
int lstatlite(const char *path, struct statlite *buf);
int chmod(const char *path, mode_t mode);
if (time_to_stop()) return -1;
list<string> dirq;
+ list<frag_info_t> statq;
dirq.push_back(basedir);
+ frag_info_t empty;
+ memset(&empty, 0, sizeof(empty));
+ statq.push_back(empty);
while (!dirq.empty()) {
string dir = dirq.front();
+ frag_info_t expect = statq.front();
dirq.pop_front();
+ statq.pop_front();
+
+ frag_info_t actual = empty;
// read dir
list<string> contents;
string file = dir + "/" + *it;
struct stat st;
- int r = client->lstat(file.c_str(), &st);
+ frag_info_t dirstat;
+ int r = client->lstat(file.c_str(), &st, &dirstat);
if (r < 0) {
dout(1) << "stat error on " << file << " r=" << r << dendl;
continue;
}
+
+ if (S_ISDIR(st.st_mode))
+ actual.nsubdirs++;
+ else
+ actual.nfiles++;
// print
char *tm = ctime(&st.st_mtime);
if ((st.st_mode & S_IFMT) == S_IFDIR) {
dirq.push_back(file);
+ statq.push_back(dirstat);
}
}
+
+ if (actual.nsubdirs != expect.nsubdirs ||
+ actual.nfiles != expect.nfiles) {
+ dout(0) << dir << ": expected " << expect << dendl;
+ dout(0) << dir << ": got " << actual << dendl;
+ }
}
return 0;