From: Sage Weil Date: Fri, 26 Jun 2009 00:49:59 +0000 (-0700) Subject: uclient: verify dentries belong to current session X-Git-Tag: v0.10~128 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=30a4dbf3437c5868c88af663d5f55ab22c4668a0;p=ceph.git uclient: verify dentries belong to current session Check against session cap_gen --- diff --git a/src/TODO b/src/TODO index 53dc7adf1b03..2b4589cb0916 100644 --- a/src/TODO +++ b/src/TODO @@ -135,6 +135,7 @@ osd - segregate backlog from log ondisk? - preserve pg logs on disk for longer period - make scrub interruptible +- salvage some way to allow both RMW and DELAYED mode ops? - optionally separate osd interfaces (ips) for clients and osds (replication, peering, etc.) - pg repair - pg split should be a work queue @@ -144,9 +145,7 @@ userspace client - handle session STALE - time out caps, wake up waiters on renewal - link caps with mds session -- validate dn leases - fix lease validation to check session ttl -- clean up ll_ interface, now that we have leases! - clean up client mds session vs mdsmap behavior? - stop using mds's inode_t? - fix readdir vs fragment race by keeping a separate frag pos, and ignoring dentries below it diff --git a/src/client/Client.cc b/src/client/Client.cc index bf5379070d00..af2a83121f5b 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -503,6 +503,7 @@ void Client::insert_dentry_inode(Dir *dir, const string& dname, LeaseStat *dleas dn->lease_ttl = dttl; dn->lease_mds = mds; dn->lease_seq = dlease->seq; + dn->lease_gen = mds_sessions[mds].cap_gen; } } dn->cap_shared_gen = dir->parent_inode->shared_gen; @@ -2565,11 +2566,21 @@ int Client::_lookup(Inode *dir, const string& dname, Inode **target) << " seq " << dn->lease_seq << dendl; - // is lease valid? - if ((dn->lease_mds >= 0 && - dn->lease_ttl > g_clock.now()) || - ((dir->caps_issued() & CEPH_CAP_FILE_SHARED) && - dn->cap_shared_gen == dir->shared_gen)) { + // is dn lease valid? + utime_t now = g_clock.now(); + if (dn->lease_mds >= 0 && + dn->lease_ttl > now && + mds_sessions.count(dn->lease_mds)) { + MDSSession &s = mds_sessions[dn->lease_mds]; + if (s.cap_ttl > now && + s.cap_gen == dn->lease_gen) { + *target = dn->inode; + goto done; + } + } + // dir lease? + if ((dir->caps_issued() & CEPH_CAP_FILE_SHARED) && + dn->cap_shared_gen == dir->shared_gen) { *target = dn->inode; goto done; } diff --git a/src/client/Client.h b/src/client/Client.h index f7ee455d8ad1..42d6d21b1da7 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -101,6 +101,7 @@ class Dentry : public LRUObject { int ref; // 1 if there's a dir beneath me. int lease_mds; utime_t lease_ttl; + __u64 lease_gen; ceph_seq_t lease_seq; int cap_shared_gen; @@ -113,7 +114,7 @@ class Dentry : public LRUObject { //cout << "dentry.put on " << this << " " << name << " now " << ref << std::endl; } - Dentry() : dir(0), inode(0), ref(0), lease_mds(-1), lease_seq(0), cap_shared_gen(0) { } + Dentry() : dir(0), inode(0), ref(0), lease_mds(-1), lease_gen(0), lease_seq(0), cap_shared_gen(0) { } }; class Dir {