From 60b950f6675580beed86c21197a457fdf39d176b Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 1 Apr 2009 10:54:48 -0700 Subject: [PATCH] mds: include 'last', 'complete' flags in readdir reply --- src/include/ceph_fs.h | 3 ++- src/kernel/dir.c | 9 +++++++-- src/kernel/mds_client.c | 5 ++++- src/kernel/mds_client.h | 1 + src/mds/Server.cc | 25 ++++++++++++++++++++++--- 5 files changed, 36 insertions(+), 7 deletions(-) diff --git a/src/include/ceph_fs.h b/src/include/ceph_fs.h index 744feaba938ac..37f7b5ddbc2af 100644 --- a/src/include/ceph_fs.h +++ b/src/include/ceph_fs.h @@ -44,7 +44,7 @@ #define CEPH_MDS_PROTOCOL 7 /* cluster internal */ #define CEPH_MON_PROTOCOL 4 /* cluster internal */ #define CEPH_OSDC_PROTOCOL 6 /* public/client */ -#define CEPH_MDSC_PROTOCOL 15 /* public/client */ +#define CEPH_MDSC_PROTOCOL 16 /* public/client */ #define CEPH_MONC_PROTOCOL 11 /* public/client */ @@ -769,6 +769,7 @@ union ceph_mds_request_args { } __attribute__ ((packed)) fstat; struct { __le32 frag; + __le32 max_entries; } __attribute__ ((packed)) readdir; struct { __le32 mode; diff --git a/src/kernel/dir.c b/src/kernel/dir.c index 029682e4f651e..7fffac050dd2d 100644 --- a/src/kernel/dir.c +++ b/src/kernel/dir.c @@ -58,6 +58,7 @@ static int ceph_readdir(struct file *filp, void *dirent, filldir_t filldir) int err; u32 ftype; struct ceph_mds_reply_info_parsed *rinfo; + int complete = 0; /* set I_READDIR at start of readdir */ if (filp->f_pos == 0) @@ -97,7 +98,11 @@ nextfrag: return err; } dout(10, "readdir got and parsed readdir result=%d" - " on frag %x\n", err, frag); + " on frag %x, end=%d, complete=%d\n", err, frag, + (int)req->r_reply_info.dir_complete, + (int)req->r_reply_info.dir_end); + if (req->r_reply_info.dir_complete) + complete = 1; fi->last_readdir = req; } @@ -163,7 +168,7 @@ nextfrag: * dir contents in our cache. */ spin_lock(&inode->i_lock); - if (ci->i_ceph_flags & CEPH_I_READDIR) { + if (complete && (ci->i_ceph_flags & CEPH_I_READDIR)) { dout(10, " marking %p complete\n", inode); ci->i_ceph_flags |= CEPH_I_COMPLETE; ci->i_ceph_flags &= ~CEPH_I_READDIR; diff --git a/src/kernel/mds_client.c b/src/kernel/mds_client.c index 3426cc185293b..2164e03e5f903 100644 --- a/src/kernel/mds_client.c +++ b/src/kernel/mds_client.c @@ -124,7 +124,10 @@ static int parse_reply_info_dir(void **p, void *end, if (*p > end) goto bad; - ceph_decode_32_safe(p, end, num, bad); + ceph_decode_need(p, end, sizeof(num) + 2, bad); + ceph_decode_32(p, num); + ceph_decode_8(p, info->dir_end); + ceph_decode_8(p, info->dir_complete); if (num == 0) goto done; diff --git a/src/kernel/mds_client.h b/src/kernel/mds_client.h index d7f8b7d2c599a..143aa10b3be61 100644 --- a/src/kernel/mds_client.h +++ b/src/kernel/mds_client.h @@ -86,6 +86,7 @@ struct ceph_mds_reply_info_parsed { u32 *dir_dname_len; struct ceph_mds_reply_lease **dir_dlease; struct ceph_mds_reply_info_in *dir_in; + u8 dir_complete, dir_end; /* encoded blob describing snapshot contexts for certain operations (e.g., open) */ diff --git a/src/mds/Server.cc b/src/mds/Server.cc index 0f48fb550833a..da746305cf72a 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -2152,12 +2152,23 @@ void Server::handle_client_readdir(MDRequest *mdr) bufferlist dirbl, dnbl; dir->encode_dirstat(dirbl, mds->get_nodeid()); - __u32 numfiles = 0; CDir::map_t::iterator it = dir->begin(); - while (it != dir->end()) { + + unsigned max = req->head.args.readdir.max_entries; + if (!max) + max = dir->get_num_any(); // whatever, something big. + + nstring offset_str = req->get_path2(); + const char *offset = offset_str.length() ? offset_str.c_str() : 0; + + __u32 numfiles = 0; + while (it != dir->end() && numfiles < max) { CDentry *dn = it->second; it++; + if (offset && strcmp(dn->get_name().c_str(), offset) <= 0) + continue; + bool dnp = dn->use_projected(client, mdr); CDentry::linkage_t *dnl = dnp ? dn->get_projected_linkage() : dn->get_linkage(); @@ -2212,7 +2223,14 @@ void Server::handle_client_readdir(MDRequest *mdr) // touch dn mdcache->lru.lru_touch(dn); } + + __u8 end = (it == dir->end()); + __u8 complete = (end && !offset); + + // final blob ::encode(numfiles, dirbl); + ::encode(end, dirbl); + ::encode(complete, dirbl); dirbl.claim_append(dnbl); if (snaps) @@ -2221,7 +2239,8 @@ void Server::handle_client_readdir(MDRequest *mdr) // yay, reply MClientReply *reply = new MClientReply(req, 0); reply->set_dir_bl(dirbl); - dout(10) << "reply to " << *req << " readdir " << numfiles << " files" << dendl; + dout(10) << "reply to " << *req << " readdir num=" << numfiles << " end=" << (int)end + << " complete=" << (int)complete << dendl; // bump popularity. NOTE: this doesn't quite capture it. mds->balancer->hit_dir(g_clock.now(), dir, META_POP_IRD, -1, numfiles); -- 2.39.5