}
if (in->caps_issued_mask(CEPH_CAP_AUTH_EXCL)) {
- kill_sguid = mask & (CEPH_SETATTR_SIZE|CEPH_SETATTR_KILL_SGUID);
- } else if (mask & CEPH_SETATTR_SIZE) {
- /* If we don't have Ax, then we must ask the server to clear them on truncate */
- mask |= CEPH_SETATTR_KILL_SGUID;
- inode_drop |= CEPH_CAP_AUTH_SHARED;
+ kill_sguid = !!(mask & CEPH_SETATTR_KILL_SGUID);
}
if (mask & CEPH_SETATTR_UID) {
int Client::__setattrx(Inode *in, struct ceph_statx *stx, int mask,
const UserPerm& perms, InodeRef *inp)
{
+ if (mask & CEPH_SETATTR_SIZE) {
+ mask |= clear_suid_sgid(in, perms, true);
+ }
+
int ret = _do_setattr(in, stx, mask, perms, inp);
if (ret < 0)
return ret;
return _fsync(in, syncdataonly);
}
-int Client::clear_suid_sgid(Inode *in, const UserPerm& perms)
+int Client::clear_suid_sgid(Inode *in, const UserPerm& perms, bool defer)
{
- ldout(cct, 20) << __func__ << " " << *in << "; " << perms << dendl;
+ ldout(cct, 20) << __func__ << " " << *in << "; " << perms << " defer "
+ << defer << dendl;
if (!in->is_file()) {
return 0;
return 0;
}
- int mask;
+ int mask = 0;
// always drop the suid
if (unlikely(in->mode & S_ISUID)) {
}
ldout(cct, 20) << __func__ << " mask " << mask << dendl;
+ if (defer) {
+ return mask;
+ }
+
struct ceph_statx stx = { 0 };
return __setattrx(in, &stx, mask, perms);
}
int _fsync(Fh *fh, bool syncdataonly);
int _fsync(Inode *in, bool syncdataonly);
int _sync_fs();
- int clear_suid_sgid(Inode *in, const UserPerm& perms);
+ int clear_suid_sgid(Inode *in, const UserPerm& perms, bool defer=false);
int _fallocate(Fh *fh, int mode, int64_t offset, int64_t length);
int _getlk(Fh *fh, struct flock *fl, uint64_t owner);
int _setlk(Fh *fh, struct flock *fl, uint64_t owner, int sleep);