diff options
author | Sage Weil <sage@newdream.net> | 2009-02-17 12:15:39 -0800 |
---|---|---|
committer | Sage Weil <sage@newdream.net> | 2009-02-17 12:15:39 -0800 |
commit | dbfa9c3e630d328a2dbd937bdb8fe0f89642748d (patch) | |
tree | f9058add9360c8d354863678c1e777e87a1ebbbb | |
parent | 4e88a943ed31eb2794a559e9cf0dd28870494ca0 (diff) | |
download | ceph-dbfa9c3e630d328a2dbd937bdb8fe0f89642748d.tar.gz |
mds: don't rdlock stat fields that client has EXCL cap for
-rw-r--r-- | src/mds/Server.cc | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/src/mds/Server.cc b/src/mds/Server.cc index 66080aecbc3..5b4cc80947b 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -1757,12 +1757,26 @@ void Server::handle_client_stat(MDRequest *mdr) set<SimpleLock*> rdlocks = mdr->rdlocks; set<SimpleLock*> wrlocks = mdr->wrlocks; set<SimpleLock*> xlocks = mdr->xlocks; - + + /* + * if client currently holds the EXCL cap on a field, do not rdlock + * it; client's stat() will result in valid info if _either_ EXCL + * cap is held or MDS rdlocks and reads the value here. + * + * handling this case here is easier than weakening rdlock + * semantics... that would cause problems elsewhere. + */ + int client = mdr->get_client(); + int issued = 0; + Capability *cap = ref->get_client_cap(client); + if (cap) + issued = cap->issued(); + int mask = req->head.args.stat.mask; - if (mask & CEPH_CAP_LINK_RDCACHE) rdlocks.insert(&ref->linklock); - if (mask & CEPH_CAP_AUTH_RDCACHE) rdlocks.insert(&ref->authlock); - if (mask & CEPH_CAP_FILE_RDCACHE) rdlocks.insert(&ref->filelock); - if (mask & CEPH_CAP_XATTR_RDCACHE) rdlocks.insert(&ref->xattrlock); + if ((mask & CEPH_CAP_LINK_RDCACHE) && (issued & CEPH_CAP_LINK_EXCL) == 0) rdlocks.insert(&ref->linklock); + if ((mask & CEPH_CAP_AUTH_RDCACHE) && (issued & CEPH_CAP_AUTH_EXCL) == 0) rdlocks.insert(&ref->authlock); + if ((mask & CEPH_CAP_FILE_RDCACHE) && (issued & CEPH_CAP_FILE_EXCL) == 0) rdlocks.insert(&ref->filelock); + if ((mask & CEPH_CAP_XATTR_RDCACHE) && (issued & CEPH_CAP_XATTR_EXCL) == 0) rdlocks.insert(&ref->xattrlock); if (!mds->locker->acquire_locks(mdr, rdlocks, wrlocks, xlocks)) return; |