summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSage Weil <sage@newdream.net>2009-02-17 12:15:39 -0800
committerSage Weil <sage@newdream.net>2009-02-17 12:15:39 -0800
commitdbfa9c3e630d328a2dbd937bdb8fe0f89642748d (patch)
treef9058add9360c8d354863678c1e777e87a1ebbbb
parent4e88a943ed31eb2794a559e9cf0dd28870494ca0 (diff)
downloadceph-dbfa9c3e630d328a2dbd937bdb8fe0f89642748d.tar.gz
mds: don't rdlock stat fields that client has EXCL cap for
-rw-r--r--src/mds/Server.cc24
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;