From: Sage Weil Date: Wed, 1 Jul 2009 23:46:36 +0000 (-0700) Subject: uclient: use session->caps list an lru X-Git-Tag: v0.10~91 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=5fd1b70927103dc095f7c9503c65d669e5cf82f2;p=ceph.git uclient: use session->caps list an lru Touch caps on use, via bool caps_issued_mask(mask) --- diff --git a/src/TODO b/src/TODO index 29979c02453c..11ee3b6397c0 100644 --- a/src/TODO +++ b/src/TODO @@ -121,8 +121,6 @@ osd - optimize remove wrt recovery pushes? userspace client -- make session cap list an LRU - - make caps_issued_mask, touch_cap helpers to || kclient - 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 5f9441d417dc..d6d4eb98ad87 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -2695,7 +2695,7 @@ int Client::_lookup(Inode *dir, const string& dname, Inode **target) } } // dir lease? - if ((dir->caps_issued() & CEPH_CAP_FILE_SHARED) && + if (dir->caps_issued_mask(CEPH_CAP_FILE_SHARED) && dn->cap_shared_gen == dir->shared_gen) { *target = dn->inode; goto done; @@ -2925,12 +2925,11 @@ int Client::readlink(const char *relpath, char *buf, loff_t size) int Client::_getattr(Inode *in, int mask, int uid, int gid) { - int issued = in->caps_issued(); + bool yes = in->caps_issued_mask(mask); - dout(10) << "_getattr mask " << ccap_string(mask) << " issued " << ccap_string(issued) << dendl; - if ((issued & mask) == mask) { + dout(10) << "_getattr mask " << ccap_string(mask) << " issued=" << yes << dendl; + if (yes) return 0; - } MClientRequest *req = new MClientRequest(CEPH_MDS_OP_GETATTR); filepath path; @@ -2952,7 +2951,7 @@ int Client::_setattr(Inode *in, struct stat *attr, int mask, int uid, int gid) dout(10) << "_setattr mask " << mask << " issued " << ccap_string(issued) << dendl; // make the change locally? - if (issued & CEPH_CAP_AUTH_EXCL) { + if (in->caps_issued_mask(CEPH_CAP_AUTH_EXCL)) { if (mask & CEPH_SETATTR_MODE) { in->inode.mode = attr->st_mode; mark_caps_dirty(in, CEPH_CAP_AUTH_EXCL); @@ -2969,7 +2968,7 @@ int Client::_setattr(Inode *in, struct stat *attr, int mask, int uid, int gid) mask &= ~CEPH_SETATTR_GID; } } - if (issued & CEPH_CAP_FILE_EXCL) { + if (in->caps_issued_mask(CEPH_CAP_FILE_EXCL)) { if (mask & (CEPH_SETATTR_MTIME|CEPH_SETATTR_ATIME)) { if (mask & CEPH_SETATTR_MTIME) in->inode.mtime = utime_t(attr->st_mtime, 0); @@ -3480,7 +3479,7 @@ int Client::_open(Inode *in, int flags, mode_t mode, Fh **fhp, int uid, int gid) in->get_open_ref(cmode); // make note of pending open, since it effects _wanted_ caps. - if ((in->caps_issued() & want) == want) { + if (in->caps_issued_mask(want)) { // update wanted? check_caps(in, true); } else { @@ -3684,7 +3683,7 @@ int Client::_read(Fh *f, __s64 offset, __u64 size, bufferlist *bl) } } else { // wait for RD cap? - while ((issued & CEPH_CAP_FILE_RD) == 0) { + while (!in->caps_issued_mask(CEPH_CAP_FILE_RD)) { dout(7) << " don't have read cap, waiting" << dendl; goto wait; } @@ -3735,7 +3734,7 @@ int Client::_read(Fh *f, __s64 offset, __u64 size, bufferlist *bl) int r = 0; if (g_conf.client_oc) { - if (issued & CEPH_CAP_FILE_CACHE) { + if (in->caps_issued_mask(CEPH_CAP_FILE_CACHE)) { // we will populate the cache here if (in->cap_refs[CEPH_CAP_FILE_CACHE] == 0) in->get_cap_ref(CEPH_CAP_FILE_CACHE); @@ -3928,7 +3927,7 @@ int Client::_write(Fh *f, __s64 offset, __u64 size, const char *buf) // wait for caps, max_size while ((lazy && (in->caps_issued() & CEPH_CAP_FILE_LAZYIO) == 0) || - (!lazy && (in->caps_issued() & CEPH_CAP_FILE_WR) == 0 && + (!lazy && in->caps_issued_mask(CEPH_CAP_FILE_WR) == false && (in->cap_snaps.empty() || !in->cap_snaps.rbegin()->second.writing)) || endoff > in->inode.max_size) { dout(7) << "missing wr|lazy cap OR endoff " << endoff @@ -3945,7 +3944,7 @@ int Client::_write(Fh *f, __s64 offset, __u64 size, const char *buf) dout(10) << " snaprealm " << *in->snaprealm << dendl; if (g_conf.client_oc) { - if (in->caps_issued() & CEPH_CAP_FILE_BUFFER) { + if (in->caps_issued_mask(CEPH_CAP_FILE_BUFFER)) { // do buffered write if (in->cap_refs[CEPH_CAP_FILE_BUFFER] == 0) in->get_cap_ref(CEPH_CAP_FILE_BUFFER); diff --git a/src/client/Client.h b/src/client/Client.h index 1d4f59192221..09374217f34d 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -436,6 +436,35 @@ class Inode { c |= it->second->issued; return c; } + void touch_cap(InodeCap *cap) { + // move to back of LRU + cap->session->caps.push_back(&cap->cap_item); + } + bool caps_issued_mask(unsigned mask) { + int c = exporting_issued | snap_caps; + if ((c & mask) == mask) + return true; + for (map::iterator it = caps.begin(); + it != caps.end(); + it++) { + if (cap_is_valid(it->second)) { + if ((it->second->issued & mask) == mask) { + touch_cap(it->second); + return true; + } + c |= it->second->issued; + } + } + if ((c & mask) == mask) { + // bah.. touch them all + for (map::iterator it = caps.begin(); + it != caps.end(); + it++) + touch_cap(it->second); + return true; + } + return false; + } int caps_used() { int w = 0;