]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
client: replace Inode's "best" logic with a UserPerm over gid/uid pair
authorGreg Farnum <gfarnum@redhat.com>
Wed, 3 Aug 2016 20:06:05 +0000 (13:06 -0700)
committerGreg Farnum <gfarnum@redhat.com>
Wed, 21 Sep 2016 23:33:54 +0000 (16:33 -0700)
Signed-off-by: Greg Farnum <gfarnum@redhat.com>
src/client/Client.cc
src/client/Client.h
src/client/Inode.cc
src/client/Inode.h

index 7b0c3d8e80b0e94e918cc0f97c7ae0c2a070b1f5..5726e371e550e6ff7bad4667b3f711ce7305b22f 100644 (file)
@@ -814,7 +814,7 @@ void Client::_fragmap_remove_non_leaves(Inode *in)
 
 Inode * Client::add_update_inode(InodeStat *st, utime_t from,
                                 MetaSession *session,
-                                uid_t request_uid, gid_t request_gid)
+                                const UserPerm& request_perms)
 {
   Inode *in;
   bool was_new = false;
@@ -913,7 +913,7 @@ Inode * Client::add_update_inode(InodeStat *st, utime_t from,
   if (in->snapid == CEPH_NOSNAP) {
     add_update_cap(in, session, st->cap.cap_id, st->cap.caps, st->cap.seq,
                   st->cap.mseq, inodeno_t(st->cap.realm), st->cap.flags,
-                  request_uid, request_gid);
+                  request_perms);
     if (in->auth_cap && in->auth_cap->session == session)
       in->max_size = st->max_size;
   } else
@@ -1148,7 +1148,7 @@ void Client::insert_readdir_results(MetaRequest *request, MetaSession *session,
       ldout(cct, 15) << "" << i << ": '" << dname << "'" << dendl;
 
       Inode *in = add_update_inode(&ist, request->sent_stamp, session,
-                                  request->get_uid(), request->get_gid());
+                                  request->perms);
       Dentry *dn;
       if (diri->dir->dentries.count(dname)) {
        Dentry *olddn = diri->dir->dentries[dname];
@@ -1304,13 +1304,13 @@ Inode* Client::insert_trace(MetaRequest *request, MetaSession *session)
     }
 
     in = add_update_inode(&ist, request->sent_stamp, session,
-                         request->get_uid(), request->get_gid());
+                         request->perms);
   }
 
   Inode *diri = NULL;
   if (reply->head.is_dentry) {
     diri = add_update_inode(&dirst, request->sent_stamp, session,
-                           request->get_uid(), request->get_gid());
+                           request->perms);
     update_dir_dist(diri, &dst);  // dir stat info is attached to ..
 
     if (in) {
@@ -3741,7 +3741,7 @@ void Client::check_cap_issue(Inode *in, Cap *cap, unsigned issued)
 
 void Client::add_update_cap(Inode *in, MetaSession *mds_session, uint64_t cap_id,
                            unsigned issued, unsigned seq, unsigned mseq, inodeno_t realm,
-                           int flags, uid_t cap_uid, gid_t cap_gid)
+                           int flags, const UserPerm& cap_perms)
 {
   Cap *cap = 0;
   mds_rank_t mds = mds_session->mds_num;
@@ -3803,8 +3803,7 @@ void Client::add_update_cap(Inode *in, MetaSession *mds_session, uint64_t cap_id
   cap->seq = seq;
   cap->issue_seq = seq;
   cap->mseq = mseq;
-  cap->latest_uid = cap_uid;
-  cap->latest_gid = cap_gid;
+  cap->latest_perms = cap_perms;
   ldout(cct, 10) << "add_update_cap issued " << ccap_string(old_caps) << " -> " << ccap_string(cap->issued)
           << " from mds." << mds
           << " on " << *in
@@ -4581,13 +4580,11 @@ void Client::handle_cap_import(MetaSession *session, Inode *in, MClientCaps *m)
 
   const mds_rank_t peer_mds = mds_rank_t(m->peer.mds);
   Cap *cap = NULL;
-  uid_t cap_uid = -1;
-  gid_t cap_gid = -1;
+  UserPerm cap_perms;
   if (m->peer.cap_id && in->caps.count(peer_mds)) {
     cap = in->caps[peer_mds];
     if (cap) {
-      cap_uid = cap->latest_uid;
-      cap_gid = cap->latest_gid;
+      cap_perms = cap->latest_perms;
     }
   }
 
@@ -4595,7 +4592,7 @@ void Client::handle_cap_import(MetaSession *session, Inode *in, MClientCaps *m)
   update_snap_trace(m->snapbl);
   add_update_cap(in, session, m->get_cap_id(),
                 m->get_caps(), m->get_seq(), m->get_mseq(), m->get_realm(),
-                CEPH_CAP_FLAG_AUTH, cap_uid, cap_gid);
+                CEPH_CAP_FLAG_AUTH, cap_perms);
   
   if (cap && cap->cap_id == m->peer.cap_id) {
       remove_cap(cap, (m->peer.flags & CEPH_CAP_FLAG_RELEASE));
@@ -4645,7 +4642,7 @@ void Client::handle_cap_export(MetaSession *session, Inode *in, MClientCaps *m)
        add_update_cap(in, tsession, m->peer.cap_id, cap->issued,
                       m->peer.seq - 1, m->peer.mseq, (uint64_t)-1,
                       cap == in->auth_cap ? CEPH_CAP_FLAG_AUTH : 0,
-                      cap->latest_uid, cap->latest_gid);
+                      cap->latest_perms);
       }
     } else {
       if (cap == in->auth_cap)
@@ -7864,7 +7861,11 @@ int Client::_renew_caps(Inode *in)
     req->head.args.open.mask = 0;
   req->set_inode(in);
 
-  UserPerm perms(in->get_best_cap_uid(), in->get_best_cap_gid());
+  // duplicate in case Cap goes away; not sure if that race is a concern?
+  const UserPerm *pperm = in->get_best_perms();
+  UserPerm perms;
+  if (pperm != NULL)
+    perms = *pperm;
   int ret = make_request(req, perms);
   return ret;
 }
index a479d29be94ff84cd726ea8e5fbfb7900d461ec2..df25eb978cef0daf0f8d2b1e382bea65732dd17e 100644 (file)
@@ -620,7 +620,7 @@ protected:
   void check_cap_issue(Inode *in, Cap *cap, unsigned issued);
   void add_update_cap(Inode *in, MetaSession *session, uint64_t cap_id,
                      unsigned issued, unsigned seq, unsigned mseq, inodeno_t realm,
-                     int flags, uid_t cap_uid, gid_t cap_gid);
+                     int flags, const UserPerm& perms);
   void remove_cap(Cap *cap, bool queue_release);
   void remove_all_caps(Inode *in);
   void remove_session_caps(MetaSession *session);
@@ -705,7 +705,7 @@ protected:
                              version_t inline_version, bufferlist& inline_data,
                              int issued);
   Inode *add_update_inode(InodeStat *st, utime_t ttl, MetaSession *session,
-                         uid_t request_uid, gid_t request_gid);
+                         const UserPerm& request_perms);
   Dentry *insert_dentry_inode(Dir *dir, const string& dname, LeaseStat *dlease, 
                              Inode *in, utime_t from, MetaSession *session,
                              Dentry *old_dentry = NULL);
index de59869e943b988d8bd1a909c79e50afc004a177..06e111c19b3fbb7107f31b9cd35061e9e7e0ba54 100644 (file)
@@ -288,26 +288,25 @@ int Inode::caps_dirty()
   return dirty_caps | flushing_caps;
 }
 
-uid_t Inode::get_best_cap_uid()
+const UserPerm* Inode::get_best_perms()
 {
-  uid_t any = -1;
+  const UserPerm *perms = NULL;
   for (const auto ci : caps) {
-    if (ci.second->latest_uid == uid)
-      return uid;
-    any = ci.second->latest_uid;
-  }
-  return any;
-}
-
-gid_t Inode::get_best_cap_gid()
-{
-  gid_t any = -1;
-  for (const auto ci : caps) {
-    if (ci.second->latest_gid == uid)
-      return uid;
-    any = ci.second->latest_gid;
+    const UserPerm& iperm = ci.second->latest_perms;
+    if (!perms) { // we don't have any, take what's present
+      perms = &iperm;
+    } else if (iperm.uid() == uid) {
+      if (iperm.gid() == gid) { // we have the best possible, return
+       return &iperm;
+      }
+      if (perms->uid() != uid) { // take uid > gid every time
+       perms = &iperm;
+      }
+    } else if (perms->uid() != uid && iperm.gid() == gid) {
+      perms = &iperm; // a matching gid is better than nothing
+    }
   }
-  return any;
+  return perms;
 }
 
 bool Inode::have_valid_size()
index 5115f6a794ddb165e29398a5cb2936f0dea985b5..2c74b8b1e641180f0aac3030952e1ef3044981e9 100644 (file)
@@ -13,6 +13,7 @@
 #include "include/assert.h"
 
 #include "InodeRef.h"
+#include "UserPerm.h"
 
 class Client;
 struct MetaSession;
@@ -37,12 +38,11 @@ struct Cap {
   uint64_t seq, issue_seq;
   __u32 mseq;  // migration seq
   __u32 gen;
-  uid_t latest_uid;
-  gid_t latest_gid;
+  UserPerm latest_perms;
 
   Cap() : session(NULL), inode(NULL), cap_item(this), cap_id(0), issued(0),
          implemented(0), wanted(0), seq(0), issue_seq(0), mseq(0), gen(0),
-         latest_uid(-1), latest_gid(-1) {}
+         latest_perms()  {}
 
   void dump(Formatter *f) const;
 };
@@ -279,8 +279,7 @@ struct Inode {
   int caps_wanted();
   int caps_mds_wanted();
   int caps_dirty();
-  uid_t get_best_cap_uid();
-  gid_t get_best_cap_gid();
+  const UserPerm *get_best_perms();
 
   bool have_valid_size();
   Dir *open_dir();