From 3c571d46fbc74c77f0ccdc01e5d793e47d17c2ed Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 2 Jan 2009 15:29:29 -0800 Subject: [PATCH] mds: put a cap in each inode stat in trace; simplify snaprealm trace encoding --- src/include/ceph_fs.h | 13 +++++--- src/mds/CInode.cc | 20 +++++++++++- src/mds/CInode.h | 2 +- src/mds/Capability.h | 5 --- src/mds/MDCache.h | 1 - src/mds/Server.cc | 62 ++++++++++--------------------------- src/mds/Server.h | 1 - src/mds/snap.cc | 7 ++++- src/mds/snap.h | 3 ++ src/messages/MClientCaps.h | 2 ++ src/messages/MClientReply.h | 11 ++----- 11 files changed, 57 insertions(+), 70 deletions(-) diff --git a/src/include/ceph_fs.h b/src/include/ceph_fs.h index da46971ef9efb..af8d73b33b4f7 100644 --- a/src/include/ceph_fs.h +++ b/src/include/ceph_fs.h @@ -803,9 +803,6 @@ struct ceph_mds_reply_head { ceph_tid_t tid; __le32 op; __le32 result; - __le32 file_caps; - __le32 file_caps_seq; - __le32 file_caps_mseq; __le32 mdsmap_epoch; __u8 safe; } __attribute__ ((packed)); @@ -821,17 +818,23 @@ struct ceph_frag_tree_head { struct ceph_frag_tree_split splits[]; } __attribute__ ((packed)); +struct ceph_mds_reply_cap { + __le32 caps; + __le32 seq, mseq; +} __attribute__ ((packed)); + struct ceph_mds_reply_inode { __le64 ino; __le64 snapid; + __le32 rdev; __le64 version; + struct ceph_mds_reply_cap cap; struct ceph_file_layout layout; struct ceph_timespec ctime, mtime, atime; __le64 time_warp_seq; - __le32 rdev; + __le64 size, max_size, truncate_seq; __le32 mode, uid, gid; __le32 nlink; - __le64 size, max_size, truncate_seq; __le64 files, subdirs, rbytes, rfiles, rsubdirs; /* dir stats */ struct ceph_timespec rctime; struct ceph_frag_tree_head fragtree; diff --git a/src/mds/CInode.cc b/src/mds/CInode.cc index a1e42fb3d2721..d9716077d495f 100644 --- a/src/mds/CInode.cc +++ b/src/mds/CInode.cc @@ -1277,7 +1277,7 @@ void CInode::decode_snap_blob(bufferlist& snapbl) } -bool CInode::encode_inodestat(bufferlist& bl, snapid_t snapid, bool projected) +bool CInode::encode_inodestat(bufferlist& bl, Capability *cap, snapid_t snapid, bool projected) { bool valid = true; @@ -1349,6 +1349,24 @@ bool CInode::encode_inodestat(bufferlist& bl, snapid_t snapid, bool projected) ::encode(xattrs, xbl); ::encode(xbl, bl); + + // include capability? + if (snapid != CEPH_NOSNAP) { + e.cap.caps = valid ? get_caps_allowed(false) : CEPH_STAT_CAP_INODE; + e.cap.seq = 0; + e.cap.mseq = 0; + } else { + if (cap && valid) { + e.cap.caps = cap->pending(); + e.cap.seq = cap->get_last_seq(); + e.cap.mseq = cap->get_mseq(); + } else { + e.cap.caps = 0; + e.cap.seq = 0; + e.cap.mseq = 0; + } + } + return valid; } diff --git a/src/mds/CInode.h b/src/mds/CInode.h index 92c7ce1809303..a014c5e152fdf 100644 --- a/src/mds/CInode.h +++ b/src/mds/CInode.h @@ -419,7 +419,7 @@ private: // for giving to clients - bool encode_inodestat(bufferlist& bl, snapid_t snapid=CEPH_NOSNAP, bool projected=false); + bool encode_inodestat(bufferlist& bl, Capability *cap, snapid_t snapid=CEPH_NOSNAP, bool projected=false); // -- locks -- diff --git a/src/mds/Capability.h b/src/mds/Capability.h index b9a56ae61da6f..0cdb1d7a60e52 100644 --- a/src/mds/Capability.h +++ b/src/mds/Capability.h @@ -24,11 +24,6 @@ using namespace std; #include "config.h" - -// heuristics -//#define CEPH_CAP_DELAYFLUSH 32 - - class CInode; class Capability { diff --git a/src/mds/MDCache.h b/src/mds/MDCache.h index 0c5b8aa2e50ac..056f61972f764 100644 --- a/src/mds/MDCache.h +++ b/src/mds/MDCache.h @@ -260,7 +260,6 @@ struct MDRequest : public Mutation { Capability *cap; int snap_caps; - bufferlist snapbl; bool did_early_reply; // -- i am a slave request diff --git a/src/mds/Server.cc b/src/mds/Server.cc index faa05214bade4..ae14f5e89fb67 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -516,23 +516,6 @@ void Server::reply_request(MDRequest *mdr, int r, CInode *tracei, CDentry *trace reply_request(mdr, new MClientReply(mdr->client_request, r), tracei, tracedn); } -void Server::include_cap_in_reply(MDRequest *mdr, MClientReply *reply) -{ - // include cap / snapbl? - // (only once!) - if (mdr->snapbl.length()) - reply->snapbl.claim(mdr->snapbl); - if (mdr->cap) { - reply->set_file_caps(mdr->cap->pending()); - reply->set_file_caps_seq(mdr->cap->get_last_seq()); - reply->set_file_caps_mseq(mdr->cap->get_mseq()); - mdr->cap = 0; - } - if (mdr->snap_caps) - reply->set_file_caps(mdr->snap_caps); -} - - void Server::early_reply(MDRequest *mdr, CInode *tracei, CDentry *tracedn) { if (!g_conf.mds_early_reply) @@ -560,9 +543,6 @@ void Server::early_reply(MDRequest *mdr, CInode *tracei, CDentry *tracedn) if (tracei || tracedn) set_trace_dist(mdr->session, reply, tracei, tracedn, snapid, snapdiri, true); - // include cap info? - include_cap_in_reply(mdr, reply); - mdr->did_early_reply = true; messenger->send_message(reply, client_inst); @@ -607,9 +587,6 @@ void Server::reply_request(MDRequest *mdr, MClientReply *reply, CInode *tracei, reply->set_mdsmap_epoch(mds->mdsmap->get_epoch()); - // include cap info? - include_cap_in_reply(mdr, reply); - // infer tracei/tracedn from mdr? snapid_t snapid = CEPH_NOSNAP; CInode *snapdiri = 0; @@ -700,6 +677,11 @@ void Server::set_trace_dist(Session *session, MClientReply *reply, CInode *in, C utime_t now = g_clock.now(); int lmask = 0; + // snapbl + SnapRealm *realm = in->find_snaprealm(); + reply->snapbl = realm->get_snap_trace(); + dout(10) << "set_trace_dist snaprealm " << *realm << dendl; + // start with dentry or inode? if (!in) { assert(dn); @@ -709,18 +691,13 @@ void Server::set_trace_dist(Session *session, MClientReply *reply, CInode *in, C inode: numi++; - if (in->encode_inodestat(bl, snapid, projected)) - lmask = mds->locker->issue_client_lease(in, client, bl, now, session); - else { - lmask = CEPH_STAT_CAP_INODE; // immutable bits - encode_null_lease(bl); - } - dout(20) << " trace added " << lmask << " snapid " << snapid << " " << *in << dendl; + in->encode_inodestat(bl, in->get_client_cap(client), snapid, projected); + dout(20) << "set_trace_dist added snapid " << snapid << " " << *in << dendl; if (snapid != CEPH_NOSNAP && in == snapdiri) { // do the snap name dentry const string& snapname = in->find_snaprealm()->get_snapname(snapid, in->ino()); - dout(10) << " snapname " << snapname << dendl; + dout(10) << "set_trace_dist snapname " << snapname << dendl; ::encode(snapname, bl); encode_infinite_lease(bl); numdn++; @@ -728,13 +705,12 @@ void Server::set_trace_dist(Session *session, MClientReply *reply, CInode *in, C // back to the live tree snapid = CEPH_NOSNAP; - in->encode_inodestat(bl, snapid); - lmask = mds->locker->issue_client_lease(in, client, bl, now, session); + in->encode_inodestat(bl, in->get_client_cap(client), snapid, false); numi++; - dout(20) << " trace added " << lmask << " snapid " << snapid << " " << *in << dendl; + dout(20) << "set_trace_dist added snapid " << snapid << " " << *in << dendl; snapdirpos = numi; - dout(10) << " snapdiri at pos " << snapdirpos << dendl; + dout(10) << "set_trace_dist snapdiri at pos " << snapdirpos << dendl; } if (!dn) { @@ -755,7 +731,7 @@ void Server::set_trace_dist(Session *session, MClientReply *reply, CInode *in, C else encode_null_lease(bl); numdn++; - dout(20) << " trace added " << lmask << " snapid " << snapid << " " << *dn << dendl; + dout(20) << "set_trace_dist added " << lmask << " snapid " << snapid << " " << *dn << dendl; // dir #ifdef MDS_VERIFY_FRAGSTAT @@ -764,7 +740,7 @@ void Server::set_trace_dist(Session *session, MClientReply *reply, CInode *in, C #endif dn->get_dir()->encode_dirstat(bl, whoami); - dout(20) << " trace added " << *dn->get_dir() << dendl; + dout(20) << "set_trace_dist added " << *dn->get_dir() << dendl; in = dn->get_dir()->get_inode(); dn = 0; @@ -2254,9 +2230,8 @@ void Server::handle_client_readdir(MDRequest *mdr) // inode dout(12) << "including inode " << *in << dendl; - bool valid = in->encode_inodestat(dnbl, snapid); + bool valid = in->encode_inodestat(dnbl, in->get_client_cap(client), snapid); assert(valid); - mds->locker->issue_client_lease(in, client, dnbl, mdr->now, mdr->session); numfiles++; // touch dn @@ -4914,10 +4889,6 @@ void Server::_do_open(MDRequest *mdr, CInode *cur) mds->balancer->hit_inode(mdr->now, cur, META_POP_IRD, mdr->client_request->get_orig_source().num()); - SnapRealm *realm = cur->find_snaprealm(); - realm->build_snap_trace(mdr->snapbl); - dout(10) << " snaprealm is " << *realm << " on " << *realm->inode << dendl; - reply_request(mdr, 0); } @@ -5108,7 +5079,6 @@ void Server::handle_client_openc(MDRequest *mdr) // stick cap, snapbl info in mdr mdr->cap = cap; - realm->build_snap_trace(mdr->snapbl); // make sure this inode gets into the journal le->metablob.add_opened_ino(in->ino()); @@ -5197,7 +5167,7 @@ void Server::handle_client_lssnap(MDRequest *mdr) else ::encode(p->second->get_long_name(), dnbl); encode_infinite_lease(dnbl); - diri->encode_inodestat(dnbl, p->first); + diri->encode_inodestat(dnbl, NULL, p->first); mds->locker->issue_client_lease(diri, client, dnbl, now, mdr->session); num++; } @@ -5387,7 +5357,7 @@ void Server::_mksnap_finish(MDRequest *mdr, CInode *diri, SnapInfo &info) mdr->ref_snapid = snapid; mdr->ref_snapdiri = diri; MClientReply *reply = new MClientReply(mdr->client_request, 0); - diri->snaprealm->build_snap_trace(reply->snapbl); + reply->snapbl = diri->snaprealm->get_snap_trace(); reply_request(mdr, reply); } diff --git a/src/mds/Server.h b/src/mds/Server.h index 6a83d52d5c37c..4f5619dbd930d 100644 --- a/src/mds/Server.h +++ b/src/mds/Server.h @@ -81,7 +81,6 @@ public: void set_trace_dist(Session *session, MClientReply *reply, CInode *in, CDentry *dn, snapid_t snapid, CInode *snapdiri, bool projected = false); - void include_cap_in_reply(MDRequest *mdr, MClientReply *reply); void encode_empty_dirstat(bufferlist& bl); void encode_infinite_lease(bufferlist& bl); diff --git a/src/mds/snap.cc b/src/mds/snap.cc index 13eddd35f45e7..7a041751fccdf 100644 --- a/src/mds/snap.cc +++ b/src/mds/snap.cc @@ -192,6 +192,7 @@ void SnapRealm::check_cache() cached_seq = seq; build_snap_set(cached_snaps, cached_seq, cached_last_created, cached_last_destroyed, 0, CEPH_NOSNAP); + build_snap_trace(cached_snap_trace); dout(10) << "check_cache rebuilt " << cached_snaps << " seq " << seq @@ -404,7 +405,11 @@ void SnapRealm::split_at(SnapRealm *child) } - +const bufferlist& SnapRealm::get_snap_trace() +{ + check_cache(); + return cached_snap_trace; +} void SnapRealm::build_snap_trace(bufferlist& snapbl) { diff --git a/src/mds/snap.h b/src/mds/snap.h index 2e701b412598b..743cc73fb6bcb 100644 --- a/src/mds/snap.h +++ b/src/mds/snap.h @@ -124,6 +124,8 @@ struct SnapRealm { set cached_snaps; SnapContext cached_snap_context; + bufferlist cached_snap_trace; + xlist inodes_with_caps; // for efficient realm splits map > client_caps; // to identify clients who need snap notifications @@ -165,6 +167,7 @@ struct SnapRealm { snapid_t first, snapid_t last); void get_snap_info(map& infomap, snapid_t first=0, snapid_t last=CEPH_NOSNAP); + const bufferlist& get_snap_trace(); void build_snap_trace(bufferlist& snapbl); const string& get_snapname(snapid_t snapid, inodeno_t atino); diff --git a/src/messages/MClientCaps.h b/src/messages/MClientCaps.h index 0cba925ae9e16..fc832eeeec15d 100644 --- a/src/messages/MClientCaps.h +++ b/src/messages/MClientCaps.h @@ -80,6 +80,8 @@ class MClientCaps : public Message { head.gid = inode.gid; head.mode = inode.mode; + head.nlink = inode.nlink; + head.xattr_len = 0; // FIXME head.layout = inode.layout; diff --git a/src/messages/MClientReply.h b/src/messages/MClientReply.h index 678b18396f298..84bff4335d036 100644 --- a/src/messages/MClientReply.h +++ b/src/messages/MClientReply.h @@ -92,6 +92,8 @@ struct DirStat { struct InodeStat { vinodeno_t vino; version_t version; + ceph_mds_reply_cap cap; + ceph_file_layout layout; unsigned mode, uid, gid, nlink, rdev; loff_t size, max_size; @@ -179,16 +181,7 @@ public: int get_result() { return (__s32)(__u32)st.result; } - unsigned get_file_caps() { return st.file_caps; } - unsigned get_file_caps_seq() { return st.file_caps_seq; } - unsigned get_file_caps_mseq() { return st.file_caps_mseq; } - //uint64_t get_file_data_version() { return st.file_data_version; } - void set_result(int r) { st.result = r; } - void set_file_caps(unsigned char c) { st.file_caps = c; } - void set_file_caps_seq(capseq_t s) { st.file_caps_seq = s; } - void set_file_caps_mseq(capseq_t s) { st.file_caps_mseq = s; } - //void set_file_data_version(uint64_t v) { st.file_data_version = v; } void set_unsafe() { st.safe = 0; } -- 2.39.5