]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
client: _getattr on quota_root before using in statfs
authorJohn Spray <john.spray@redhat.com>
Wed, 15 Mar 2017 17:51:44 +0000 (17:51 +0000)
committerNathan Cutler <ncutler@suse.com>
Tue, 4 Jul 2017 11:28:37 +0000 (13:28 +0200)
...so that after someone adjusts the quota settings
on an inode that another client is using as its mount root,
the change is visible immediately on the other client.

Signed-off-by: John Spray <john.spray@redhat.com>
(cherry picked from commit 3d25941aadd223669448d0f5d3c0bd1fefa72308)

src/client/Client.cc
src/client/Client.h

index 7b0a42d14a118ffe01b5c599e88183f3bb8b3c97..ec51df29f3e86e8242cabfbdfaec375367ebfa06 100644 (file)
@@ -2095,6 +2095,19 @@ void Client::handle_client_session(MClientSession *m)
   m->put();
 }
 
+bool Client::_any_stale_sessions() const
+{
+  assert(client_lock.is_locked_by_me());
+
+  for (const auto &i : mds_sessions) {
+    if (i.second->state == MetaSession::STATE_STALE) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
 void Client::_kick_stale_sessions()
 {
   ldout(cct, 1) << "kick_stale_sessions" << dendl;
@@ -9331,6 +9344,21 @@ int Client::statfs(const char *path, struct statvfs *stbuf,
   assert(cct->_conf->client_quota == false || quota_root != nullptr);
 
   if (quota_root && cct->_conf->client_quota_df && quota_root->quota.max_bytes) {
+
+    // Skip the getattr if any sessions are stale, as we don't want to
+    // block `df` if this client has e.g. been evicted, or if the MDS cluster
+    // is unhealthy.
+    if (!_any_stale_sessions()) {
+      int r = _getattr(quota_root, 0, perms, true);
+      if (r != 0) {
+        // Ignore return value: error getting latest inode metadata is not a good
+        // reason to break "df".
+        lderr(cct) << "Error in getattr on quota root 0x"
+                   << std::hex << quota_root->ino << std::dec
+                   << " statfs result may be outdated" << dendl;
+      }
+    }
+
     // Special case: if there is a size quota set on the Inode acting
     // as the root for this client mount, then report the quota status
     // as the filesystem statistics.
index d5c679749aeba2c5bcec1e8c734d1da36136439a..f74076842ae1ebc01201dc4a5b887353bdd4b32c 100644 (file)
@@ -339,6 +339,7 @@ protected:
   MetaSession *_open_mds_session(mds_rank_t mds);
   void _close_mds_session(MetaSession *s);
   void _closed_mds_session(MetaSession *s);
+  bool _any_stale_sessions() const;
   void _kick_stale_sessions();
   void handle_client_session(MClientSession *m);
   void send_reconnect(MetaSession *s);