From: Sage Weil Date: Wed, 19 Aug 2015 13:48:16 +0000 (-0400) Subject: client: do sync setattr when caller != last cap dirtier X-Git-Tag: v10.0.0~123^2~18 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=1957aeddbf05f2ecf3be0a760ff5b5c313370eea;p=ceph.git client: do sync setattr when caller != last cap dirtier 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 --- diff --git a/src/client/Client.cc b/src/client/Client.cc index 8d3fd279b48a..b1da7a896bb0 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -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); diff --git a/src/client/Inode.h b/src/client/Inode.h index b4d1475ad548..a13fd98bc7be 100644 --- a/src/client/Inode.h +++ b/src/client/Inode.h @@ -234,8 +234,8 @@ struct Inode { // per-mds caps map 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 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),