} __attribute__ ((packed));
#define CEPH_LEASE_VALID (1 | 2) /* old and new bit values */
+#define CEPH_LEASE_PRIMARY_LINK 4 /* primary linkage */
struct ceph_mds_reply_dirfrag {
__le32 frag; /* fragment */
}
-void Locker::issue_client_lease(CDentry *dn, client_t client,
- bufferlist &bl, utime_t now, Session *session)
+void Locker::issue_client_lease(CDentry *dn, MDRequestRef &mdr, int mask,
+ utime_t now, bufferlist &bl)
{
+ client_t client = mdr->get_client();
+ Session *session = mdr->session;
+
CInode *diri = dn->get_dir()->get_inode();
- if (!diri->is_stray() && // do not issue dn leases in stray dir!
- ((!diri->filelock.can_lease(client) &&
- (diri->get_client_cap_pending(client) & (CEPH_CAP_FILE_SHARED | CEPH_CAP_FILE_EXCL)) == 0)) &&
- dn->lock.can_lease(client)) {
- int pool = 1; // fixme.. do something smart!
+ if (mdr->snapid == CEPH_NOSNAP &&
+ dn->lock.can_lease(client) &&
+ !diri->is_stray() && // do not issue dn leases in stray dir!
+ !diri->filelock.can_lease(client) &&
+ !(diri->get_client_cap_pending(client) & (CEPH_CAP_FILE_SHARED | CEPH_CAP_FILE_EXCL))) {
// issue a dentry lease
ClientLease *l = dn->add_client_lease(client, session);
session->touch_lease(l);
+ int pool = 1; // fixme.. do something smart!
now += mdcache->client_lease_durations[pool];
mdcache->touch_client_lease(l, pool, now);
LeaseStat lstat;
- lstat.mask = CEPH_LEASE_VALID;
+ lstat.mask = CEPH_LEASE_VALID | mask;
lstat.duration_ms = (uint32_t)(1000 * mdcache->client_lease_durations[pool]);
lstat.seq = ++l->seq;
encode_lease(bl, session->info, lstat);
} else {
// null lease
LeaseStat lstat;
+ lstat.mask = mask;
encode_lease(bl, session->info, lstat);
dout(20) << "issue_client_lease no/null lease on " << *dn << dendl;
}
// -- client leases --
void handle_client_lease(const cref_t<MClientLease> &m);
- void issue_client_lease(CDentry *dn, client_t client, bufferlist &bl, utime_t now, Session *session);
+ void issue_client_lease(CDentry *dn, MDRequestRef &mdr, int mask, utime_t now, bufferlist &bl);
void revoke_client_leases(SimpleLock *lock);
static void encode_lease(bufferlist& bl, const session_info_t& info, const LeaseStat& ls);
bufferlist bl;
mds_rank_t whoami = mds->get_nodeid();
Session *session = mdr->session;
- client_t client = mdr->get_client();
snapid_t snapid = mdr->snapid;
utime_t now = ceph_clock_now();
dout(20) << "set_trace_dist added dir " << *dir << dendl;
encode(dn->get_name(), bl);
- if (snapid == CEPH_NOSNAP)
- mds->locker->issue_client_lease(dn, client, bl, now, session);
- else {
- //null lease
- LeaseStat e;
- mds->locker->encode_lease(bl, session->info, e);
+
+ int lease_mask = 0;
+ CDentry::linkage_t *dnl = dn->get_linkage(mdr->get_client(), mdr);
+ if (dnl->is_primary()) {
+ ceph_assert(dnl->get_inode() == in);
+ lease_mask = CEPH_LEASE_PRIMARY_LINK;
+ } else {
+ if (dnl->is_remote())
+ ceph_assert(dnl->get_remote_ino() == in->ino());
+ else
+ ceph_assert(!in);
}
+ mds->locker->issue_client_lease(dn, mdr, lease_mask, now, bl);
dout(20) << "set_trace_dist added dn " << snapid << " " << *dn << dendl;
} else
reply->head.is_dentry = 0;
// dentry
dout(12) << "including dn " << *dn << dendl;
encode(dn->get_name(), dnbl);
- mds->locker->issue_client_lease(dn, client, dnbl, now, mdr->session);
+ int lease_mask = dnl->is_primary() ? CEPH_LEASE_PRIMARY_LINK : 0;
+ mds->locker->issue_client_lease(dn, mdr, lease_mask, now, dnbl);
// inode
dout(12) << "including inode " << *in << dendl;
dn->push_projected_linkage();
}
- journal_and_reply(mdr, targeti, dn, le, new C_MDS_link_remote_finish(this, mdr, inc, dn, targeti));
+ journal_and_reply(mdr, (inc ? targeti : nullptr), dn, le,
+ new C_MDS_link_remote_finish(this, mdr, inc, dn, targeti));
}
void Server::_link_remote_finish(MDRequestRef& mdr, bool inc,