]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
client: do sync setattr when caller != last cap dirtier
authorSage Weil <sage@redhat.com>
Wed, 19 Aug 2015 13:48:16 +0000 (09:48 -0400)
committerSage Weil <sage@redhat.com>
Thu, 1 Oct 2015 13:42:35 +0000 (09:42 -0400)
This way we can still do cap writeback in general when the caller is not
the same as the mount_uid/gid, but we flip to a sync setattr when we have
to because the dirty caps have a different uid/gid than the current
caller.

Signed-off-by: Sage Weil <sage@redhat.com>
src/client/Client.cc
src/client/Inode.h

index 8d3fd279b48ad2c503b2d0ecf74d3d5a8eec3ab6..b1da7a896bb046d4ac8ceedaf39ba8d1a4e8daf0 100644 (file)
@@ -3025,10 +3025,8 @@ void Client::send_cap(Inode *in, MetaSession *session, Cap *cap,
                                   flush,
                                   cap->mseq,
                                    cap_epoch_barrier);
-  if (user_id >= 0)
-    m->caller_uid = user_id;
-  if (group_id >= 0)
-    m->caller_gid = group_id;
+  m->caller_uid = in->cap_dirtier_uid;
+  m->caller_gid = in->cap_dirtier_gid;
 
   m->head.issue_seq = cap->issue_seq;
   m->set_tid(flush_tid);
@@ -4498,6 +4496,11 @@ void Client::handle_cap_flush_ack(MetaSession *session, Inode *in, Cap *cap, MCl
       sync_cond.Signal();
   }
 
+  if (!dirty) {
+    in->cap_dirtier_uid = -1;
+    in->cap_dirtier_gid = -1;
+  }
+
   if (!cleaned) {
     ldout(cct, 10) << " tid " << m->get_client_tid() << " != any cap bit tids" << dendl;
   } else {
@@ -5791,19 +5794,24 @@ int Client::_setattr(Inode *in, struct stat *attr, int mask, int uid, int gid,
       is_quota_bytes_exceeded(in, (unsigned long)attr->st_size - in->size)) {
     return -EDQUOT;
   }
+
+  if (uid < 0) {
+    uid = get_uid();
+    gid = get_gid();
+  }
+
   // make the change locally?
-  if ((uid >= 0 && user_id >= 0 && uid != user_id) ||
-      (gid >= 0 && group_id >= 0 && gid != group_id)) {
+  if ((in->cap_dirtier_uid >= 0 && uid != in->cap_dirtier_uid) ||
+      (in->cap_dirtier_gid >= 0 && gid != in->cap_dirtier_gid)) {
+    ldout(cct, 10) << __func__ << " caller " << uid << ":" << gid
+                  << " != cap dirtier " << in->cap_dirtier_uid << ":"
+                  << in->cap_dirtier_gid << ", forcing sync setattr"
+                  << dendl;
     if (!mask)
       mask |= CEPH_SETATTR_CTIME;
     goto force_request;
   }
 
-  if (uid < 0) {
-    uid = geteuid();
-    gid = getegid();
-  }
-
   if (!mask) {
     // caller just needs us to bump the ctime
     in->ctime = ceph_clock_now(cct);
index b4d1475ad548742af8f71bf0bf95b43efe1c7d91..a13fd98bc7bee47d562d601b7dccc388121aba77 100644 (file)
@@ -234,8 +234,8 @@ struct Inode {
   // per-mds caps
   map<mds_rank_t, Cap*> caps;            // mds -> Cap
   Cap *auth_cap;
-  __u32 cap_dirtier_uid;
-  __u32 cap_dirtier_gid;
+  int64_t cap_dirtier_uid;
+  int64_t cap_dirtier_gid;
   unsigned dirty_caps, flushing_caps;
   std::map<ceph_tid_t, int> flushing_cap_tids;
   int shared_gen, cache_gen;
@@ -306,6 +306,7 @@ struct Inode {
       flags(0),
       qtree(NULL),
       dir_hashed(false), dir_replicated(false), auth_cap(NULL),
+      cap_dirtier_uid(-1), cap_dirtier_gid(-1),
       dirty_caps(0), flushing_caps(0), shared_gen(0), cache_gen(0),
       snap_caps(0), snap_cap_refs(0),
       cap_item(this), flushing_cap_item(this),