From: Greg Farnum Date: Sat, 24 Sep 2016 01:12:33 +0000 (-0700) Subject: Merge remote-tracking branch 'origin/master' into wip-getuid X-Git-Tag: v11.0.1~36^2~3 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=7d2a8b71528760c0a3c357d09c9eeea682b43e11;p=ceph.git Merge remote-tracking branch 'origin/master' into wip-getuid Conflicts: src/client/Client.cc src/client/Client.h src/client/Makefile.am src/client/fuse_ll.cc Signed-off-by: Greg Farnum --- 7d2a8b71528760c0a3c357d09c9eeea682b43e11 diff --cc src/client/Client.cc index 256f6060b5e5,0339c2807dbf..a764e87f240d --- a/src/client/Client.cc +++ b/src/client/Client.cc @@@ -5059,15 -5068,15 +5076,16 @@@ out return r; } -int Client::may_setattr(Inode *in, struct ceph_statx *stx, int mask, int uid, int gid) -{ - if (uid < 0) - uid = get_uid(); - if (gid < 0) - gid = get_gid(); - RequestUserGroups groups(this, uid, gid); +ostream& operator<<(ostream &out, const UserPerm& perm) { + out << "UserPerm(uid: " << perm.uid() << ", gid: " << perm.gid() << ")"; + return out; +} - int Client::may_setattr(Inode *in, struct stat *st, int mask, const UserPerm& perms) - int r = _getattr_for_perm(in, uid, gid); ++int Client::may_setattr(Inode *in, struct ceph_statx *stx, int mask, ++ const UserPerm& perms) +{ + ldout(cct, 20) << __func__ << *in << "; " << perms << dendl; + int r = _getattr_for_perm(in, perms); if (r < 0) goto out; @@@ -5079,27 -5088,27 +5097,28 @@@ r = -EPERM; if (mask & CEPH_SETATTR_UID) { - if (perms.uid() != 0 && (perms.uid() != in->uid || st->st_uid != in->uid)) - if (uid != 0 && ((uid_t)uid != in->uid || stx->stx_uid != in->uid)) ++ if (perms.uid() != 0 && (perms.uid() != in->uid || stx->stx_uid != in->uid)) goto out; } if (mask & CEPH_SETATTR_GID) { - if (uid != 0 && ((uid_t)uid != in->uid || - (!groups.is_in(stx->stx_gid) && stx->stx_gid != in->gid))) + if (perms.uid() != 0 && (perms.uid() != in->uid || - (!perms.gid_in_groups(st->st_gid) && st->st_gid != in->gid))) ++ (!perms.gid_in_groups(stx->stx_gid) && stx->stx_gid != in->gid))) goto out; } if (mask & CEPH_SETATTR_MODE) { - if (uid != 0 && (uid_t)uid != in->uid) + if (perms.uid() != 0 && perms.uid() != in->uid) goto out; - gid_t i_gid = (mask & CEPH_SETATTR_GID) ? st->st_gid : in->gid; + gid_t i_gid = (mask & CEPH_SETATTR_GID) ? stx->stx_gid : in->gid; - if (uid != 0 && !groups.is_in(i_gid)) + if (perms.uid() != 0 && !perms.gid_in_groups(i_gid)) - st->st_mode &= ~S_ISGID; + stx->stx_mode &= ~S_ISGID; } - if (mask & (CEPH_SETATTR_CTIME | CEPH_SETATTR_MTIME | CEPH_SETATTR_ATIME)) { - if (mask & (CEPH_SETATTR_CTIME | CEPH_SETATTR_BTIME | CEPH_SETATTR_MTIME | CEPH_SETATTR_ATIME)) { - if (uid != 0 && (uid_t)uid != in->uid) { ++ if (mask & (CEPH_SETATTR_CTIME | CEPH_SETATTR_BTIME | ++ CEPH_SETATTR_MTIME | CEPH_SETATTR_ATIME)) { + if (perms.uid() != 0 && perms.uid() != in->uid) { - int check_mask = CEPH_SETATTR_CTIME; + int check_mask = CEPH_SETATTR_CTIME | CEPH_SETATTR_BTIME; if (!(mask & CEPH_SETATTR_MTIME_NOW)) check_mask |= CEPH_SETATTR_MTIME; if (!(mask & CEPH_SETATTR_ATIME_NOW)) @@@ -6015,8 -6048,8 +6034,9 @@@ int Client::get_or_create(Inode *dir, c return 0; } -int Client::path_walk(const filepath& origpath, InodeRef *end, bool followsym, +int Client::path_walk(const filepath& origpath, InodeRef *end, - const UserPerm& perms, bool followsym) ++ const UserPerm& perms, bool followsym, + int mask, int uid, int gid) { filepath path = origpath; InodeRef cur; @@@ -6043,7 -6081,12 +6063,11 @@@ return r; caps = CEPH_CAP_AUTH_SHARED; } + + /* Get extra requested caps on the last component */ + if (i == (path.depth() - 1)) + caps |= mask; - - int r = _lookup(cur.get(), dname, caps, &next, uid, gid); + int r = _lookup(cur.get(), dname, caps, &next, perms); if (r < 0) return r; // only follow trailing symlink if followsym. always follow @@@ -6379,8 -6425,8 +6403,8 @@@ int Client::_getattr(Inode *in, int mas return res; } - int Client::_do_setattr(Inode *in, struct stat *attr, int mask, -int Client::_do_setattr(Inode *in, struct ceph_statx *stx, int mask, int uid, int gid, - InodeRef *inp) ++int Client::_do_setattr(Inode *in, struct ceph_statx *stx, int mask, + const UserPerm& perms, InodeRef *inp) { int issued = in->caps_issued(); @@@ -6391,9 -6437,8 +6415,9 @@@ return -EROFS; } if ((mask & CEPH_SETATTR_SIZE) && - (unsigned long)attr->st_size > in->size && - is_quota_bytes_exceeded(in, (unsigned long)attr->st_size - in->size, + (unsigned long)stx->stx_size > in->size && - is_quota_bytes_exceeded(in, (unsigned long)stx->stx_size - in->size)) { ++ is_quota_bytes_exceeded(in, (unsigned long)stx->stx_size - in->size, + perms)) { return -EDQUOT; } @@@ -6438,41 -6488,50 +6462,50 @@@ if (in->caps_issued_mask(CEPH_CAP_AUTH_EXCL)) { if (mask & CEPH_SETATTR_MODE) { in->ctime = ceph_clock_now(cct); - in->cap_dirtier_uid = uid; - in->cap_dirtier_gid = gid; + in->cap_dirtier_uid = perms.uid(); + in->cap_dirtier_gid = perms.gid(); - in->mode = (in->mode & ~07777) | (attr->st_mode & 07777); + in->mode = (in->mode & ~07777) | (stx->stx_mode & 07777); mark_caps_dirty(in, CEPH_CAP_AUTH_EXCL); mask &= ~CEPH_SETATTR_MODE; - ldout(cct,10) << "changing mode to " << attr->st_mode << dendl; + ldout(cct,10) << "changing mode to " << stx->stx_mode << dendl; } if (mask & CEPH_SETATTR_UID) { in->ctime = ceph_clock_now(cct); - in->cap_dirtier_uid = uid; - in->cap_dirtier_gid = gid; + in->cap_dirtier_uid = perms.uid(); + in->cap_dirtier_gid = perms.gid(); - in->uid = attr->st_uid; + in->uid = stx->stx_uid; mark_caps_dirty(in, CEPH_CAP_AUTH_EXCL); mask &= ~CEPH_SETATTR_UID; - ldout(cct,10) << "changing uid to " << attr->st_uid << dendl; + ldout(cct,10) << "changing uid to " << stx->stx_uid << dendl; } if (mask & CEPH_SETATTR_GID) { in->ctime = ceph_clock_now(cct); - in->cap_dirtier_uid = uid; - in->cap_dirtier_gid = gid; + in->cap_dirtier_uid = perms.uid(); + in->cap_dirtier_gid = perms.gid(); - in->gid = attr->st_gid; + in->gid = stx->stx_gid; mark_caps_dirty(in, CEPH_CAP_AUTH_EXCL); mask &= ~CEPH_SETATTR_GID; - ldout(cct,10) << "changing gid to " << attr->st_gid << dendl; + ldout(cct,10) << "changing gid to " << stx->stx_gid << dendl; + } + if (mask & CEPH_SETATTR_BTIME) { + in->ctime = ceph_clock_now(cct); - in->cap_dirtier_uid = uid; - in->cap_dirtier_gid = gid; ++ in->cap_dirtier_uid = perms.uid(); ++ in->cap_dirtier_gid = perms.gid(); + in->btime = utime_t(stx->stx_btime); + mark_caps_dirty(in, CEPH_CAP_AUTH_EXCL); + mask &= ~CEPH_SETATTR_BTIME; + ldout(cct,10) << "changing btime to " << in->btime << dendl; } } if (in->caps_issued_mask(CEPH_CAP_FILE_EXCL)) { if (mask & (CEPH_SETATTR_MTIME|CEPH_SETATTR_ATIME)) { if (mask & CEPH_SETATTR_MTIME) - in->mtime = utime_t(stat_get_mtime_sec(attr), stat_get_mtime_nsec(attr)); + in->mtime = utime_t(stx->stx_mtime); if (mask & CEPH_SETATTR_ATIME) - in->atime = utime_t(stat_get_atime_sec(attr), stat_get_atime_nsec(attr)); + in->atime = utime_t(stx->stx_atime); in->ctime = ceph_clock_now(cct); - in->cap_dirtier_uid = uid; - in->cap_dirtier_gid = gid; + in->cap_dirtier_uid = perms.uid(); + in->cap_dirtier_gid = perms.gid(); in->time_warp_seq++; mark_caps_dirty(in, CEPH_CAP_FILE_EXCL); mask &= ~(CEPH_SETATTR_MTIME|CEPH_SETATTR_ATIME); @@@ -6535,34 -6600,52 +6574,55 @@@ force_request return res; } - int Client::_setattr(Inode *in, struct stat *attr, int mask, - const UserPerm& perms, InodeRef *inp) + /* Note that we only care about attrs that setattr cares about */ + void Client::stat_to_statx(struct stat *st, struct ceph_statx *stx) { - int ret = _do_setattr(in, attr, mask, perms, inp); + stx->stx_size = st->st_size; + stx->stx_mode = st->st_mode; + stx->stx_uid = st->st_uid; + stx->stx_gid = st->st_gid; + stx->stx_mtime = st->st_mtim; + stx->stx_atime = st->st_atim; + } + -int Client::__setattrx(Inode *in, struct ceph_statx *stx, int mask, int uid, int gid, - InodeRef *inp) ++int Client::__setattrx(Inode *in, struct ceph_statx *stx, int mask, ++ const UserPerm& perms, InodeRef *inp) + { - int ret = _do_setattr(in, stx, mask, uid, gid, inp); ++ int ret = _do_setattr(in, stx, mask, perms, inp); if (ret < 0) return ret; if (mask & CEPH_SETATTR_MODE) - ret = _posix_acl_chmod(in, attr->st_mode, perms); - ret = _posix_acl_chmod(in, stx->stx_mode, uid, gid); ++ ret = _posix_acl_chmod(in, stx->stx_mode, perms); return ret; } - int Client::_setattr(InodeRef &in, struct stat *attr, int mask, - const UserPerm& perms) -int Client::_setattrx(InodeRef &in, struct ceph_statx *stx, int mask) ++int Client::_setattrx(InodeRef &in, struct ceph_statx *stx, int mask, ++ const UserPerm& perms) { mask &= (CEPH_SETATTR_MODE | CEPH_SETATTR_UID | CEPH_SETATTR_GID | CEPH_SETATTR_MTIME | CEPH_SETATTR_ATIME | CEPH_SETATTR_SIZE | - CEPH_SETATTR_CTIME); + CEPH_SETATTR_CTIME | CEPH_SETATTR_BTIME); if (cct->_conf->client_permissions) { - int r = may_setattr(in.get(), attr, mask, perms); - int r = may_setattr(in.get(), stx, mask); ++ int r = may_setattr(in.get(), stx, mask, perms); if (r < 0) return r; } - return _setattr(in.get(), attr, mask, perms); - return __setattrx(in.get(), stx, mask); ++ return __setattrx(in.get(), stx, mask, perms); + } + -int Client::_setattr(InodeRef &in, struct stat *attr, int mask) ++int Client::_setattr(InodeRef &in, struct stat *attr, int mask, ++ const UserPerm& perms) + { + struct ceph_statx stx; + + stat_to_statx(attr, &stx); + mask &= ~CEPH_SETATTR_BTIME; - return _setattrx(in, &stx, mask); ++ return _setattrx(in, &stx, mask, perms); } -int Client::setattr(const char *relpath, struct stat *attr, int mask) +int Client::setattr(const char *relpath, struct stat *attr, int mask, + const UserPerm& perms) { Mutex::Locker lock(client_lock); tout(cct) << "setattr" << std::endl; @@@ -6571,14 -6654,28 +6631,29 @@@ filepath path(relpath); InodeRef in; - int r = path_walk(path, &in); + int r = path_walk(path, &in, perms); if (r < 0) return r; - return _setattr(in, attr, mask); + return _setattr(in, attr, mask, perms); } - int Client::fsetattr(int fd, struct stat *attr, int mask, - const UserPerm& perms) -int Client::setattrx(const char *relpath, struct ceph_statx *stx, int mask, int flags) ++int Client::setattrx(const char *relpath, struct ceph_statx *stx, int mask, ++ const UserPerm& perms, int flags) + { + Mutex::Locker lock(client_lock); + tout(cct) << "setattrx" << std::endl; + tout(cct) << relpath << std::endl; + tout(cct) << mask << std::endl; + + filepath path(relpath); + InodeRef in; - int r = path_walk(path, &in, flags & AT_SYMLINK_NOFOLLOW); ++ int r = path_walk(path, &in, perms, flags & AT_SYMLINK_NOFOLLOW); + if (r < 0) + return r; - return _setattrx(in, stx, mask); ++ return _setattrx(in, stx, mask, perms); + } + -int Client::fsetattr(int fd, struct stat *attr, int mask) ++int Client::fsetattr(int fd, struct stat *attr, int mask, const UserPerm& perms) { Mutex::Locker lock(client_lock); tout(cct) << "fsetattr" << std::endl; @@@ -6604,10 -6701,10 +6679,10 @@@ int Client::stat(const char *relpath, s tout(cct) << relpath << std::endl; filepath path(relpath); InodeRef in; - int r = path_walk(path, &in, perms); - int r = path_walk(path, &in, true, mask); ++ int r = path_walk(path, &in, perms, true, mask); if (r < 0) return r; - r = _getattr(in, mask); + r = _getattr(in, mask, perms); if (r < 0) { ldout(cct, 3) << "stat exit on error!" << dendl; return r; @@@ -6617,8 -6714,59 +6692,60 @@@ return r; } + unsigned Client::statx_to_mask(unsigned int flags, unsigned int want) + { + unsigned mask = 0; + + /* if NO_ATTR_SYNC is set, then we don't need any -- just use what's in cache */ + if (flags & AT_NO_ATTR_SYNC) + goto out; + + /* Always set PIN to distinguish from AT_NO_ATTR_SYNC case */ + mask |= CEPH_CAP_PIN; + if (want & (CEPH_STATX_MODE|CEPH_STATX_UID|CEPH_STATX_GID|CEPH_STATX_BTIME|CEPH_STATX_CTIME|CEPH_STATX_VERSION)) + mask |= CEPH_CAP_AUTH_SHARED; + if (want & (CEPH_STATX_NLINK|CEPH_STATX_CTIME|CEPH_STATX_VERSION)) + mask |= CEPH_CAP_LINK_SHARED; + if (want & (CEPH_STATX_ATIME|CEPH_STATX_MTIME|CEPH_STATX_CTIME|CEPH_STATX_SIZE|CEPH_STATX_BLOCKS|CEPH_STATX_VERSION)) + mask |= CEPH_CAP_FILE_SHARED; + if (want & (CEPH_STATX_VERSION|CEPH_STATX_CTIME)) + mask |= CEPH_CAP_XATTR_SHARED; + out: + return mask; + } + + int Client::statx(const char *relpath, struct ceph_statx *stx, ++ const UserPerm& perms, + unsigned int want, unsigned int flags) + { + ldout(cct, 3) << "statx enter (relpath " << relpath << " want " << want << ")" << dendl; + Mutex::Locker lock(client_lock); + tout(cct) << "statx" << std::endl; + tout(cct) << relpath << std::endl; + filepath path(relpath); + InodeRef in; + + unsigned mask = statx_to_mask(flags, want); + - int r = path_walk(path, &in, flags & AT_SYMLINK_NOFOLLOW, mask); ++ int r = path_walk(path, &in, perms, flags & AT_SYMLINK_NOFOLLOW, mask); + if (r < 0) + return r; + + if (mask && !in->caps_issued_mask(mask)) { - r = _getattr(in, mask); ++ r = _getattr(in, mask, perms); + if (r < 0) { + ldout(cct, 3) << "statx exit on error!" << dendl; + return r; + } + } + + fill_statx(in, mask, stx); + ldout(cct, 3) << "statx exit (relpath " << relpath << " mask " << stx->stx_mask << ")" << dendl; + return r; + } + int Client::lstat(const char *relpath, struct stat *stbuf, - frag_info_t *dirstat, int mask) + const UserPerm& perms, frag_info_t *dirstat, int mask) { ldout(cct, 3) << "lstat enter (relpath " << relpath << " mask " << mask << ")" << dendl; Mutex::Locker lock(client_lock); @@@ -6627,10 -6775,10 +6754,10 @@@ filepath path(relpath); InodeRef in; // don't follow symlinks - int r = path_walk(path, &in, perms, false); - int r = path_walk(path, &in, false, mask); ++ int r = path_walk(path, &in, perms, false, mask); if (r < 0) return r; - r = _getattr(in, mask); + r = _getattr(in, mask, perms); if (r < 0) { ldout(cct, 3) << "lstat exit on error!" << dendl; return r; @@@ -7530,7 -7742,7 +7722,7 @@@ int Client::open(const char *relpath, i bool created = false; /* O_CREATE with O_EXCL enforces O_NOFOLLOW. */ bool followsym = !((flags & O_NOFOLLOW) || ((flags & O_CREAT) && (flags & O_EXCL))); - int r = path_walk(path, &in, perms, followsym); - int r = path_walk(path, &in, followsym, ceph_caps_for_mode(mode), uid, gid); ++ int r = path_walk(path, &in, perms, followsym, ceph_caps_for_mode(mode)); if (r == 0 && (flags & O_CREAT) && (flags & O_EXCL)) return -EEXIST; @@@ -7547,7 -7759,9 +7739,8 @@@ string dname = dirpath.last_dentry(); dirpath.pop_dentry(); InodeRef dir; - r = path_walk(dirpath, &dir, perms, true); - r = path_walk(dirpath, &dir, true, - cct->_conf->client_permissions ? CEPH_CAP_AUTH_SHARED : 0, - uid, gid); ++ r = path_walk(dirpath, &dir, perms, true, ++ cct->_conf->client_permissions ? CEPH_CAP_AUTH_SHARED : 0); if (r < 0) goto out; if (cct->_conf->client_permissions) { @@@ -8693,14 -8891,14 +8887,14 @@@ int Client::_flush(Fh *f return err; } -int Client::truncate(const char *relpath, loff_t length) +int Client::truncate(const char *relpath, loff_t length, const UserPerm& perms) { - struct stat attr; - attr.st_size = length; - return setattr(relpath, &attr, CEPH_SETATTR_SIZE, perms); + struct ceph_statx stx; + stx.stx_size = length; - return setattrx(relpath, &stx, CEPH_SETATTR_SIZE); ++ return setattrx(relpath, &stx, CEPH_SETATTR_SIZE, perms); } -int Client::ftruncate(int fd, loff_t length) +int Client::ftruncate(int fd, loff_t length, const UserPerm& perms) { Mutex::Locker lock(client_lock); tout(cct) << "ftruncate" << std::endl; @@@ -8832,6 -9030,31 +9026,32 @@@ int Client::fstat(int fd, struct stat * return r; } -int Client::fstatx(int fd, struct ceph_statx *stx, unsigned int want, unsigned int flags) ++int Client::fstatx(int fd, struct ceph_statx *stx, const UserPerm& perms, ++ unsigned int want, unsigned int flags) + { + Mutex::Locker lock(client_lock); + tout(cct) << "fstatx flags " << hex << flags << " want " << want << dec << std::endl; + tout(cct) << fd << std::endl; + + Fh *f = get_filehandle(fd); + if (!f) + return -EBADF; + + unsigned mask = statx_to_mask(flags, want); + + int r = 0; + if (mask && !f->inode->caps_issued_mask(mask)) { - r = _getattr(f->inode, mask); ++ r = _getattr(f->inode, mask, perms); + if (r < 0) { + ldout(cct, 3) << "fstatx exit on error!" << dendl; + return r; + } + } + + fill_statx(f->inode, mask, stx); + ldout(cct, 3) << "fstatx(" << fd << ", " << stx << ") = " << r << dendl; + return r; + } // not written yet, but i want to link! @@@ -9550,7 -9771,7 +9772,7 @@@ int Client::ll_walk(const char* name, I tout(cct) << "ll_walk" << std::endl; tout(cct) << name << std::endl; - rc = path_walk(fp, &in, perms, false); - rc = path_walk(fp, &in, false, CEPH_STAT_CAP_INODE_ALL); ++ rc = path_walk(fp, &in, perms, false, CEPH_STAT_CAP_INODE_ALL); if (rc < 0) { attr->st_ino = 0; *out = NULL; @@@ -9669,30 -9890,51 +9891,51 @@@ Inode *Client::ll_get_inode(vinodeno_t return in; } - int Client::ll_getattr(Inode *in, struct stat *attr, const UserPerm& perms) -int Client::_ll_getattr(Inode *in, int uid, int gid) ++int Client::_ll_getattr(Inode *in, const UserPerm& perms) { - Mutex::Locker lock(client_lock); - vinodeno_t vino = _get_vino(in); ldout(cct, 3) << "ll_getattr " << vino << dendl; tout(cct) << "ll_getattr" << std::endl; tout(cct) << vino.ino.val << std::endl; - int res; if (vino.snapid < CEPH_NOSNAP) - res = 0; + return 0; else - res = _getattr(in, CEPH_STAT_CAP_INODE_ALL, perms); - return _getattr(in, CEPH_STAT_CAP_INODE_ALL, uid, gid); ++ return _getattr(in, CEPH_STAT_CAP_INODE_ALL, perms); + } + -int Client::ll_getattr(Inode *in, struct stat *attr, int uid, int gid) ++int Client::ll_getattr(Inode *in, struct stat *attr, const UserPerm& perms) + { + Mutex::Locker lock(client_lock); + - int res = _ll_getattr(in, uid, gid); ++ int res = _ll_getattr(in, perms); + if (res == 0) fill_stat(in, attr); - ldout(cct, 3) << "ll_getattr " << vino << " = " << res << dendl; + ldout(cct, 3) << "ll_getattr " << _get_vino(in) << " = " << res << dendl; return res; } - int Client::ll_setattr(Inode *in, struct stat *attr, int mask, - const UserPerm& perms) + int Client::ll_getattrx(Inode *in, struct ceph_statx *stx, unsigned int want, - unsigned int flags, int uid, int gid) ++ unsigned int flags, const UserPerm& perms) + { + Mutex::Locker lock(client_lock); + + int res = 0; + unsigned mask = statx_to_mask(flags, want); + + if (mask && !in->caps_issued_mask(mask)) - res = _ll_getattr(in, uid, gid); ++ res = _ll_getattr(in, perms); + + if (res == 0) + fill_statx(in, mask, stx); + ldout(cct, 3) << "ll_getattrx " << _get_vino(in) << " = " << res << dendl; + return res; + } -int Client::_ll_setattrx(Inode *in, struct ceph_statx *stx, int mask, int uid, - int gid, InodeRef *inp) ++int Client::_ll_setattrx(Inode *in, struct ceph_statx *stx, int mask, ++ const UserPerm& perms, InodeRef *inp) { Mutex::Locker lock(client_lock); @@@ -9711,15 -9954,39 +9955,39 @@@ tout(cct) << mask << std::endl; if (!cct->_conf->fuse_default_permissions) { - int res = may_setattr(in, attr, mask, perms); - int res = may_setattr(in, stx, mask, uid, gid); ++ int res = may_setattr(in, stx, mask, perms); if (res < 0) return res; } mask &= ~(CEPH_SETATTR_MTIME_NOW | CEPH_SETATTR_ATIME_NOW); - return __setattrx(in, stx, mask, uid, gid, inp); ++ return __setattrx(in, stx, mask, perms, inp); + } + -int Client::ll_setattrx(Inode *in, struct ceph_statx *stx, int mask, int uid, - int gid) ++int Client::ll_setattrx(Inode *in, struct ceph_statx *stx, int mask, ++ const UserPerm& perms) + { InodeRef target(in); - int res = _setattr(in, attr, mask, perms, &target); - int res = _ll_setattrx(in, stx, mask, uid, gid, &target); ++ int res = _ll_setattrx(in, stx, mask, perms, &target); + if (res == 0) { + assert(in == target.get()); + fill_statx(in, in->caps_issued(), stx); + } + + ldout(cct, 3) << "ll_setattrx " << _get_vino(in) << " = " << res << dendl; + return res; + } + -int Client::ll_setattr(Inode *in, struct stat *attr, int mask, int uid, - int gid) ++int Client::ll_setattr(Inode *in, struct stat *attr, int mask, ++ const UserPerm& perms) + { + struct ceph_statx stx; + + stat_to_statx(attr, &stx); + + InodeRef target(in); - int res = _ll_setattrx(in, &stx, mask, uid, gid, &target); ++ int res = _ll_setattrx(in, &stx, mask, perms, &target); if (res == 0) { assert(in == target.get()); fill_stat(in, attr); @@@ -9738,25 -10004,23 +10006,25 @@@ int Client::getxattr(const char *path, { Mutex::Locker lock(client_lock); InodeRef in; - int r = Client::path_walk(path, &in, perms, true); - int r = Client::path_walk(path, &in, true, CEPH_STAT_CAP_XATTR); ++ int r = Client::path_walk(path, &in, perms, true, CEPH_STAT_CAP_XATTR); if (r < 0) return r; - return _getxattr(in, name, value, size); + return _getxattr(in, name, value, size, perms); } -int Client::lgetxattr(const char *path, const char *name, void *value, size_t size) +int Client::lgetxattr(const char *path, const char *name, void *value, size_t size, + const UserPerm& perms) { Mutex::Locker lock(client_lock); InodeRef in; - int r = Client::path_walk(path, &in, perms, false); - int r = Client::path_walk(path, &in, false, CEPH_STAT_CAP_XATTR); ++ int r = Client::path_walk(path, &in, perms, false, CEPH_STAT_CAP_XATTR); if (r < 0) return r; - return _getxattr(in, name, value, size); + return _getxattr(in, name, value, size, perms); } -int Client::fgetxattr(int fd, const char *name, void *value, size_t size) +int Client::fgetxattr(int fd, const char *name, void *value, size_t size, + const UserPerm& perms) { Mutex::Locker lock(client_lock); Fh *f = get_filehandle(fd); @@@ -9770,24 -10033,23 +10038,24 @@@ int Client::listxattr(const char *path { Mutex::Locker lock(client_lock); InodeRef in; - int r = Client::path_walk(path, &in, perms, true); - int r = Client::path_walk(path, &in, true, CEPH_STAT_CAP_XATTR); ++ int r = Client::path_walk(path, &in, perms, true, CEPH_STAT_CAP_XATTR); if (r < 0) return r; - return Client::_listxattr(in.get(), list, size); + return Client::_listxattr(in.get(), list, size, perms); } -int Client::llistxattr(const char *path, char *list, size_t size) +int Client::llistxattr(const char *path, char *list, size_t size, + const UserPerm& perms) { Mutex::Locker lock(client_lock); InodeRef in; - int r = Client::path_walk(path, &in, perms, false); - int r = Client::path_walk(path, &in, false, CEPH_STAT_CAP_XATTR); ++ int r = Client::path_walk(path, &in, perms, false, CEPH_STAT_CAP_XATTR); if (r < 0) return r; - return Client::_listxattr(in.get(), list, size); + return Client::_listxattr(in.get(), list, size, perms); } -int Client::flistxattr(int fd, char *list, size_t size) +int Client::flistxattr(int fd, char *list, size_t size, const UserPerm& perms) { Mutex::Locker lock(client_lock); Fh *f = get_filehandle(fd); @@@ -10061,9 -10316,9 +10329,9 @@@ int Client::_setxattr(Inode *in, const size = 0; } if (new_mode != in->mode) { - struct stat attr; - attr.st_mode = new_mode; - ret = _do_setattr(in, &attr, CEPH_SETATTR_MODE, perms, NULL); + struct ceph_statx stx; + stx.stx_mode = new_mode; - ret = _do_setattr(in, &stx, CEPH_SETATTR_MODE, uid, gid, NULL); ++ ret = _do_setattr(in, &stx, CEPH_SETATTR_MODE, perms, NULL); if (ret < 0) return ret; } @@@ -11341,8 -11596,10 +11609,10 @@@ int Client::ll_open(Inode *in, int flag int Client::ll_create(Inode *parent, const char *name, mode_t mode, int flags, struct stat *attr, Inode **outp, Fh **fhp, - int uid, int gid) + const UserPerm& perms) { + *fhp = NULL; + Mutex::Locker lock(client_lock); vinodeno_t vparent = _get_vino(parent); @@@ -11369,8 -11625,8 +11639,8 @@@ if (r < 0) goto out; } - r = _create(parent, name, flags, mode, &in, fhp /* may be NULL */, - 0, 0, 0, NULL, &created, perms); + r = _create(parent, name, flags, mode, &in, fhp, 0, 0, 0, NULL, &created, - uid, gid); ++ perms); if (r < 0) goto out; } @@@ -11384,17 -11640,17 +11654,17 @@@ ldout(cct, 20) << "ll_create created = " << created << dendl; if (!created) { if (!cct->_conf->fuse_default_permissions) { - r = may_open(in.get(), flags, uid, gid); + r = may_open(in.get(), flags, perms); if (r < 0) { - if (fhp && *fhp) { + if (*fhp) { int release_r = _release_fh(*fhp); assert(release_r == 0); // during create, no async data ops should have happened } goto out; } } - if (fhp && (*fhp == NULL)) { + if (*fhp == NULL) { - r = _open(in.get(), flags, mode, fhp, uid, gid); + r = _open(in.get(), flags, mode, fhp, perms); if (r < 0) goto out; } @@@ -11722,9 -11978,10 +11993,10 @@@ int Client::_fallocate(Fh *fh, int mode if (size > in->size) { in->size = size; in->mtime = ceph_clock_now(cct); + in->change_attr++; mark_caps_dirty(in, CEPH_CAP_FILE_WR); - if (is_quota_bytes_approaching(in)) { + if (is_quota_bytes_approaching(in, fh->actor_perms)) { check_caps(in, true); } else { if ((in->size << 1) >= in->max_size && diff --cc src/client/Client.h index 23e623b74569,9c1bf4dfdd08..75a35d21e0f4 --- a/src/client/Client.h +++ b/src/client/Client.h @@@ -516,8 -518,8 +516,9 @@@ protected // path traversal for high-level interface InodeRef cwd; - int path_walk(const filepath& fp, InodeRef *end, bool followsym=true, - int mask=0, int uid=-1, int gid=-1); + int path_walk(const filepath& fp, InodeRef *end, const UserPerm& perms, - bool followsym=true); ++ bool followsym=true, int mask=0, int uid=-1, int gid=-1); ++ int fill_stat(Inode *in, struct stat *st, frag_info_t *dirstat=0, nest_info_t *rstat=0); int fill_stat(InodeRef& in, struct stat *st, frag_info_t *dirstat=0, nest_info_t *rstat=0) { return fill_stat(in.get(), st, dirstat, rstat); @@@ -691,13 -700,11 +699,12 @@@ void clear_dir_complete_and_ordered(Inode *diri, bool complete); void insert_readdir_results(MetaRequest *request, MetaSession *session, Inode *diri); Inode* insert_trace(MetaRequest *request, MetaSession *session); - void update_inode_file_bits(Inode *in, - uint64_t truncate_seq, uint64_t truncate_size, uint64_t size, - uint64_t time_warp_seq, utime_t ctime, utime_t mtime, utime_t atime, - version_t inline_version, bufferlist& inline_data, - int issued); + void update_inode_file_bits(Inode *in, uint64_t truncate_seq, uint64_t truncate_size, uint64_t size, + uint64_t change_attr, uint64_t time_warp_seq, utime_t ctime, + utime_t mtime, utime_t atime, version_t inline_version, + bufferlist& inline_data, int issued); - Inode *add_update_inode(InodeStat *st, utime_t ttl, MetaSession *session); + Inode *add_update_inode(InodeStat *st, utime_t ttl, MetaSession *session, + 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); @@@ -749,56 -756,43 +756,61 @@@ private // internal interface // call these with client_lock held! - int _do_lookup(Inode *dir, const string& name, int mask, InodeRef *target, int uid, int gid); - int _lookup(Inode *dir, const string& dname, int mask, InodeRef *target, int uid, int gid); - - int _link(Inode *in, Inode *dir, const char *name, int uid=-1, int gid=-1, InodeRef *inp = 0); - int _unlink(Inode *dir, const char *name, int uid=-1, int gid=-1); - int _rename(Inode *olddir, const char *oname, Inode *ndir, const char *nname, int uid=-1, int gid=-1); - int _mkdir(Inode *dir, const char *name, mode_t mode, int uid=-1, int gid=-1, InodeRef *inp = 0); - int _rmdir(Inode *dir, const char *name, int uid=-1, int gid=-1); - int _symlink(Inode *dir, const char *name, const char *target, int uid=-1, int gid=-1, InodeRef *inp = 0); - int _mknod(Inode *dir, const char *name, mode_t mode, dev_t rdev, int uid=-1, int gid=-1, InodeRef *inp = 0); - int _do_setattr(Inode *in, struct ceph_statx *stx, int mask, int uid, int gid, InodeRef *inp); + int _do_lookup(Inode *dir, const string& name, int mask, InodeRef *target, + const UserPerm& perms); + + int _lookup(Inode *dir, const string& dname, int mask, InodeRef *target, + const UserPerm& perm); + + int _link(Inode *in, Inode *dir, const char *name, const UserPerm& perm, + InodeRef *inp = 0); + int _unlink(Inode *dir, const char *name, const UserPerm& perm); + int _rename(Inode *olddir, const char *oname, Inode *ndir, const char *nname, const UserPerm& perm); + int _mkdir(Inode *dir, const char *name, mode_t mode, const UserPerm& perm, + InodeRef *inp = 0); + int _rmdir(Inode *dir, const char *name, const UserPerm& perms); + int _symlink(Inode *dir, const char *name, const char *target, + const UserPerm& perms, InodeRef *inp = 0); + int _mknod(Inode *dir, const char *name, mode_t mode, dev_t rdev, + const UserPerm& perms, InodeRef *inp = 0); - int _do_setattr(Inode *in, struct stat *attr, int mask, const UserPerm& perms, - InodeRef *inp); - int _setattr(Inode *in, struct stat *attr, int mask, const UserPerm& perms, - InodeRef *inp = 0); ++ int _do_setattr(Inode *in, struct ceph_statx *stx, int mask, ++ const UserPerm& perms, InodeRef *inp); + void stat_to_statx(struct stat *st, struct ceph_statx *stx); - int __setattrx(Inode *in, struct ceph_statx *stx, int mask, int uid=-1, int gid=-1, InodeRef *inp = 0); - int _setattrx(InodeRef &in, struct ceph_statx *stx, int mask); - int _setattr(InodeRef &in, struct stat *attr, int mask); - int _ll_setattrx(Inode *in, struct ceph_statx *stx, int mask, int uid = -1, - int gid = -1, InodeRef *inp = 0); - int _getattr(Inode *in, int mask, int uid=-1, int gid=-1, bool force=false); - int _getattr(InodeRef &in, int mask, int uid=-1, int gid=-1, bool force=false) { - return _getattr(in.get(), mask, uid, gid, force); ++ int __setattrx(Inode *in, struct ceph_statx *stx, int mask, ++ const UserPerm& perms, InodeRef *inp = 0); ++ int _setattrx(InodeRef &in, struct ceph_statx *stx, int mask, ++ const UserPerm& perms); + int _setattr(InodeRef &in, struct stat *attr, int mask, + const UserPerm& perms); ++ int _ll_setattrx(Inode *in, struct ceph_statx *stx, int mask, ++ const UserPerm& perms, InodeRef *inp = 0); + int _getattr(Inode *in, int mask, const UserPerm& perms, bool force=false); + int _getattr(InodeRef &in, int mask, const UserPerm& perms, bool force=false) { + return _getattr(in.get(), mask, perms, force); } int _readlink(Inode *in, char *buf, size_t size); - int _getxattr(Inode *in, const char *name, void *value, size_t len, int uid=-1, int gid=-1); - int _getxattr(InodeRef &in, const char *name, void *value, size_t len); - int _listxattr(Inode *in, char *names, size_t len, int uid=-1, int gid=-1); - int _do_setxattr(Inode *in, const char *name, const void *value, size_t len, int flags, int uid, int gid); - int _setxattr(Inode *in, const char *name, const void *value, size_t len, int flags, int uid=-1, int gid=-1); - int _setxattr(InodeRef &in, const char *name, const void *value, size_t len, int flags); - int _removexattr(Inode *in, const char *nm, int uid=-1, int gid=-1); - int _removexattr(InodeRef &in, const char *nm); - int _open(Inode *in, int flags, mode_t mode, Fh **fhp, int uid, int gid); + int _getxattr(Inode *in, const char *name, void *value, size_t len, + const UserPerm& perms); + int _getxattr(InodeRef &in, const char *name, void *value, size_t len, + const UserPerm& perms); + int _listxattr(Inode *in, char *names, size_t len, const UserPerm& perms); + int _do_setxattr(Inode *in, const char *name, const void *value, size_t len, + int flags, const UserPerm& perms); + int _setxattr(Inode *in, const char *name, const void *value, size_t len, + int flags, const UserPerm& perms); + int _setxattr(InodeRef &in, const char *name, const void *value, size_t len, + int flags, const UserPerm& perms); + int _removexattr(Inode *in, const char *nm, const UserPerm& perms); + int _removexattr(InodeRef &in, const char *nm, const UserPerm& perms); + int _open(Inode *in, int flags, mode_t mode, Fh **fhp, + const UserPerm& perms); int _renew_caps(Inode *in); - int _create(Inode *in, const char *name, int flags, mode_t mode, InodeRef *inp, Fh **fhp, - int stripe_unit, int stripe_count, int object_size, const char *data_pool, - bool *created, int uid, int gid); + int _create(Inode *in, const char *name, int flags, mode_t mode, InodeRef *inp, + Fh **fhp, int stripe_unit, int stripe_count, int object_size, + const char *data_pool, bool *created, const UserPerm &perms); loff_t _lseek(Fh *fh, loff_t offset, int whence); + loff_t _lseek(Fh *fh, loff_t offset, int whence, const UserPerm& perms); int _read(Fh *fh, int64_t offset, uint64_t size, bufferlist *bl); int _write(Fh *fh, int64_t offset, uint64_t size, const char *buf, const struct iovec *iov, int iovcnt); @@@ -826,20 -820,36 +838,21 @@@ MAY_READ = 4, }; - class RequestUserGroups : public UserGroups { - Client *client; - uid_t uid; - gid_t gid; - int sgid_count; - gid_t *sgids; - void init() { - sgid_count = client->_getgrouplist(&sgids, uid, gid); - } - public: - RequestUserGroups(Client *c, uid_t u, gid_t g) : - client(c), uid(u), gid(g), sgid_count(-1), sgids(NULL) {} - ~RequestUserGroups() { - free(sgids); - } - gid_t get_gid() { return gid; } - bool is_in(gid_t id); - int get_gids(const gid_t **out); - }; + void init_groups(UserPerm *groups); + + int inode_permission(Inode *in, const UserPerm& perms, unsigned want); + int xattr_permission(Inode *in, const char *name, unsigned want, + const UserPerm& perms); - int may_setattr(Inode *in, struct stat *st, int mask, const UserPerm& perms); ++ int may_setattr(Inode *in, struct ceph_statx *stx, int mask, ++ const UserPerm& perms); + int may_open(Inode *in, int flags, const UserPerm& perms); + int may_lookup(Inode *dir, const UserPerm& perms); + int may_create(Inode *dir, const UserPerm& perms); + int may_delete(Inode *dir, const char *name, const UserPerm& perms); + int may_hardlink(Inode *in, const UserPerm& perms); - int inode_permission(Inode *in, uid_t uid, UserGroups& groups, unsigned want); - int xattr_permission(Inode *in, const char *name, unsigned want, int uid=-1, int gid=-1); - int may_setattr(Inode *in, struct ceph_statx *stx, int mask, int uid=-1, int gid=-1); - int may_open(Inode *in, int flags, int uid=-1, int gid=-1); - int may_lookup(Inode *dir, int uid=-1, int gid=-1); - int may_create(Inode *dir, int uid=-1, int gid=-1); - int may_delete(Inode *dir, const char *name, int uid=-1, int gid=-1); - int may_hardlink(Inode *in, int uid=-1, int gid=-1); - int _getattr_for_perm(Inode *in, int uid, int gid); - int _getgrouplist(gid_t **sgids, int uid, int gid); + int _getattr_for_perm(Inode *in, const UserPerm& perms); + int _getgrouplist(gid_t **sgids, uid_t uid, gid_t gid); int check_data_pool_exist(string name, string value, const OSDMap *osdmap); @@@ -909,9 -918,10 +922,11 @@@ mds_rank_t _get_random_up_mds() const; - int _ll_getattr(Inode *in, int uid, int gid); ++ int _ll_getattr(Inode *in, const UserPerm& perms); + public: - int mount(const std::string &mount_root, bool require_mds=false); + int mount(const std::string &mount_root, const UserPerm& perms, + bool require_mds=false); void unmount(); int mds_command( @@@ -965,63 -974,60 +980,72 @@@ loff_t telldir(dir_result_t *dirp); void seekdir(dir_result_t *dirp, loff_t offset); - int link(const char *existing, const char *newname); - int unlink(const char *path); - int rename(const char *from, const char *to); + int link(const char *existing, const char *newname, const UserPerm& perm); + int unlink(const char *path, const UserPerm& perm); + int rename(const char *from, const char *to, const UserPerm& perm); // dirs - int mkdir(const char *path, mode_t mode); - int mkdirs(const char *path, mode_t mode); - int rmdir(const char *path); + int mkdir(const char *path, mode_t mode, const UserPerm& perm); + int mkdirs(const char *path, mode_t mode, const UserPerm& perms); + int rmdir(const char *path, const UserPerm& perms); // symlinks - int readlink(const char *path, char *buf, loff_t size); + int readlink(const char *path, char *buf, loff_t size, const UserPerm& perms); - int symlink(const char *existing, const char *newname); + int symlink(const char *existing, const char *newname, const UserPerm& perms); // inode stuff + unsigned statx_to_mask(unsigned int flags, unsigned int want); - int stat(const char *path, struct stat *stbuf, frag_info_t *dirstat=0, int mask=CEPH_STAT_CAP_INODE_ALL); - int statx(const char *path, struct ceph_statx *stx, unsigned int want, unsigned int flags); - int lstat(const char *path, struct stat *stbuf, frag_info_t *dirstat=0, int mask=CEPH_STAT_CAP_INODE_ALL); - int lstatlite(const char *path, struct statlite *buf); - - int setattr(const char *relpath, struct stat *attr, int mask); - int setattrx(const char *relpath, struct ceph_statx *stx, int mask, int flags=0); - int fsetattr(int fd, struct stat *attr, int mask); - int chmod(const char *path, mode_t mode); - int fchmod(int fd, mode_t mode); - int lchmod(const char *path, mode_t mode); - int chown(const char *path, int uid, int gid); - int fchown(int fd, int uid, int gid); - int lchown(const char *path, int uid, int gid); - int utime(const char *path, struct utimbuf *buf); - int lutime(const char *path, struct utimbuf *buf); + int stat(const char *path, struct stat *stbuf, const UserPerm& perms, + frag_info_t *dirstat=0, int mask=CEPH_STAT_CAP_INODE_ALL); ++ int statx(const char *path, struct ceph_statx *stx, ++ const UserPerm& perms, ++ unsigned int want, unsigned int flags); + int lstat(const char *path, struct stat *stbuf, const UserPerm& perms, + frag_info_t *dirstat=0, int mask=CEPH_STAT_CAP_INODE_ALL); + - int setattr(const char *relpath, struct stat *attr, int mask, const UserPerm& perms); ++ int setattr(const char *relpath, struct stat *attr, int mask, ++ const UserPerm& perms); ++ int setattrx(const char *relpath, struct ceph_statx *stx, int mask, ++ const UserPerm& perms, int flags=0); + int fsetattr(int fd, struct stat *attr, int mask, const UserPerm& perms); + int chmod(const char *path, mode_t mode, const UserPerm& perms); + int fchmod(int fd, mode_t mode, const UserPerm& perms); + int lchmod(const char *path, mode_t mode, const UserPerm& perms); + int chown(const char *path, uid_t new_uid, gid_t new_gid, + const UserPerm& perms); + int fchown(int fd, uid_t new_uid, gid_t new_gid, const UserPerm& perms); + int lchown(const char *path, uid_t new_uid, gid_t new_gid, + const UserPerm& perms); + int utime(const char *path, struct utimbuf *buf, const UserPerm& perms); + int lutime(const char *path, struct utimbuf *buf, const UserPerm& perms); int flock(int fd, int operation, uint64_t owner); - int truncate(const char *path, loff_t size); + int truncate(const char *path, loff_t size, const UserPerm& perms); // file ops - int mknod(const char *path, mode_t mode, dev_t rdev=0); - int open(const char *path, int flags, mode_t mode=0); - int open(const char *path, int flags, mode_t mode, int stripe_unit, int stripe_count, int object_size, const char *data_pool); - int lookup_hash(inodeno_t ino, inodeno_t dirino, const char *name); - int lookup_ino(inodeno_t ino, Inode **inode=NULL); - int lookup_parent(Inode *in, Inode **parent=NULL); - int lookup_name(Inode *in, Inode *parent); + int mknod(const char *path, mode_t mode, const UserPerm& perms, dev_t rdev=0); + int open(const char *path, int flags, const UserPerm& perms, mode_t mode=0); + int open(const char *path, int flags, const UserPerm& perms, + mode_t mode, int stripe_unit, int stripe_count, int object_size, + const char *data_pool); + int lookup_hash(inodeno_t ino, inodeno_t dirino, const char *name, + const UserPerm& perms); + int lookup_ino(inodeno_t ino, const UserPerm& perms, Inode **inode=NULL); + int lookup_parent(Inode *in, const UserPerm& perms, Inode **parent=NULL); + int lookup_name(Inode *in, Inode *parent, const UserPerm& perms); int close(int fd); - loff_t lseek(int fd, loff_t offset, int whence); + loff_t lseek(int fd, loff_t offset, int whence, const UserPerm& perms); int read(int fd, char *buf, loff_t size, loff_t offset=-1); int preadv(int fd, const struct iovec *iov, int iovcnt, loff_t offset=-1); int write(int fd, const char *buf, loff_t size, loff_t offset=-1); int pwritev(int fd, const struct iovec *iov, int iovcnt, loff_t offset=-1); int fake_write_size(int fd, loff_t size); - int ftruncate(int fd, loff_t size); + int ftruncate(int fd, loff_t size, const UserPerm& perms); int fsync(int fd, bool syncdataonly); - int fstat(int fd, struct stat *stbuf, int mask=CEPH_STAT_CAP_INODE_ALL); - int fstatx(int fd, struct ceph_statx *stx, unsigned int want, unsigned int flags); + int fstat(int fd, struct stat *stbuf, const UserPerm& perms, + int mask=CEPH_STAT_CAP_INODE_ALL); ++ int fstatx(int fd, struct ceph_statx *stx, const UserPerm& perms, ++ unsigned int want, unsigned int flags); int fallocate(int fd, int mode, loff_t offset, loff_t length); // full path xattr ops @@@ -1090,38 -1089,42 +1114,43 @@@ Inode *ll_get_inode(ino_t ino); Inode *ll_get_inode(vinodeno_t vino); int ll_lookup(Inode *parent, const char *name, struct stat *attr, - Inode **out, int uid = -1, int gid = -1); + Inode **out, const UserPerm& perms); bool ll_forget(Inode *in, int count); bool ll_put(Inode *in); - int ll_getattr(Inode *in, struct stat *st, int uid = -1, int gid = -1); + int ll_getattr(Inode *in, struct stat *st, const UserPerm& perms); - int ll_setattr(Inode *in, struct stat *st, int mask, const UserPerm& perms); + int ll_getattrx(Inode *in, struct ceph_statx *stx, unsigned int want, - unsigned int flags, int uid = -1, int gid = -1); - int ll_setattrx(Inode *in, struct ceph_statx *stx, int mask, int uid = -1, - int gid = -1); - int ll_setattr(Inode *in, struct stat *st, int mask, int uid = -1, - int gid = -1); ++ unsigned int flags, const UserPerm& perms); ++ int ll_setattrx(Inode *in, struct ceph_statx *stx, int mask, ++ const UserPerm& perms); ++ int ll_setattr(Inode *in, struct stat *st, int mask, ++ const UserPerm& perms); int ll_getxattr(Inode *in, const char *name, void *value, size_t size, - int uid=-1, int gid=-1); + const UserPerm& perms); int ll_setxattr(Inode *in, const char *name, const void *value, size_t size, - int flags, int uid=-1, int gid=-1); - int ll_removexattr(Inode *in, const char *name, int uid=-1, int gid=-1); - int ll_listxattr(Inode *in, char *list, size_t size, int uid=-1, int gid=-1); - int ll_opendir(Inode *in, int flags, dir_result_t **dirpp, int uid = -1, int gid = -1); + int flags, const UserPerm& perms); + int ll_removexattr(Inode *in, const char *name, const UserPerm& perms); + int ll_listxattr(Inode *in, char *list, size_t size, const UserPerm& perms); + int ll_opendir(Inode *in, int flags, dir_result_t **dirpp, + const UserPerm& perms); int ll_releasedir(dir_result_t* dirp); int ll_fsyncdir(dir_result_t* dirp); - int ll_readlink(Inode *in, char *buf, size_t bufsize, int uid = -1, int gid = -1); + int ll_readlink(Inode *in, char *buf, size_t bufsize, const UserPerm& perms); int ll_mknod(Inode *in, const char *name, mode_t mode, dev_t rdev, - struct stat *attr, Inode **out, int uid = -1, int gid = -1); + struct stat *attr, Inode **out, const UserPerm& perms); int ll_mkdir(Inode *in, const char *name, mode_t mode, struct stat *attr, - Inode **out, int uid = -1, int gid = -1); + Inode **out, const UserPerm& perm); int ll_symlink(Inode *in, const char *name, const char *value, - struct stat *attr, Inode **out, int uid = -1, int gid = -1); - int ll_unlink(Inode *in, const char *name, int uid = -1, int gid = -1); - int ll_rmdir(Inode *in, const char *name, int uid = -1, int gid = -1); + struct stat *attr, Inode **out, const UserPerm& perms); + int ll_unlink(Inode *in, const char *name, const UserPerm& perm); + int ll_rmdir(Inode *in, const char *name, const UserPerm& perms); int ll_rename(Inode *parent, const char *name, Inode *newparent, - const char *newname, int uid = -1, int gid = -1); + const char *newname, const UserPerm& perm); int ll_link(Inode *in, Inode *newparent, const char *newname, - struct stat *attr, int uid = -1, int gid = -1); - int ll_open(Inode *in, int flags, Fh **fh, int uid = -1, int gid = -1); + struct stat *attr, const UserPerm& perm); + int ll_open(Inode *in, int flags, Fh **fh, const UserPerm& perms); int ll_create(Inode *parent, const char *name, mode_t mode, int flags, - struct stat *attr, Inode **out, Fh **fhp, int uid = -1, - int gid = -1); + struct stat *attr, Inode **out, Fh **fhp, + const UserPerm& perms); int ll_read_block(Inode *in, uint64_t blockid, char *buf, uint64_t offset, uint64_t length, file_layout_t* layout); diff --cc src/libcephfs.cc index c38cbcf78e0d,9e65bff95d29..f24ff945fe4d --- a/src/libcephfs.cc +++ b/src/libcephfs.cc @@@ -610,9 -607,17 +610,18 @@@ extern "C" int ceph_stat(struct ceph_mo { if (!cmount->is_mounted()) return -ENOTCONN; - return cmount->get_client()->stat(path, stbuf); + return cmount->get_client()->stat(path, stbuf, cmount->default_perms); } + extern "C" int ceph_statx(struct ceph_mount_info *cmount, const char *path, + struct ceph_statx *stx, unsigned int want, unsigned int flags) + { + if (!cmount->is_mounted()) + return -ENOTCONN; - return cmount->get_client()->statx(path, stx, want, flags); ++ return cmount->get_client()->statx(path, stx, cmount->default_perms, ++ want, flags); + } + extern "C" int ceph_lstat(struct ceph_mount_info *cmount, const char *path, struct stat *stbuf) { @@@ -626,9 -631,17 +635,18 @@@ extern "C" int ceph_setattr(struct ceph { if (!cmount->is_mounted()) return -ENOTCONN; - return cmount->get_client()->setattr(relpath, attr, mask); + return cmount->get_client()->setattr(relpath, attr, mask, cmount->default_perms); } + extern "C" int ceph_setattrx(struct ceph_mount_info *cmount, const char *relpath, + struct ceph_statx *stx, int mask, int flags) + { + if (!cmount->is_mounted()) + return -ENOTCONN; - return cmount->get_client()->setattrx(relpath, stx, mask, flags); ++ return cmount->get_client()->setattrx(relpath, stx, mask, ++ cmount->default_perms, flags); + } + // *xattr() calls supporting samba/vfs extern "C" int ceph_getxattr(struct ceph_mount_info *cmount, const char *path, const char *name, void *value, size_t size) { @@@ -876,9 -887,17 +894,18 @@@ extern "C" int ceph_fstat(struct ceph_m { if (!cmount->is_mounted()) return -ENOTCONN; - return cmount->get_client()->fstat(fd, stbuf); + return cmount->get_client()->fstat(fd, stbuf, cmount->default_perms); } + extern "C" int ceph_fstatx(struct ceph_mount_info *cmount, int fd, struct ceph_statx *stx, + unsigned int want, unsigned int flags) + { + if (!cmount->is_mounted()) + return -ENOTCONN; - return cmount->get_client()->fstatx(fd, stx, want, flags); ++ return cmount->get_client()->fstatx(fd, stx, cmount->default_perms, ++ want, flags); + } + extern "C" int ceph_sync_fs(struct ceph_mount_info *cmount) { if (!cmount->is_mounted()) @@@ -1411,18 -1427,31 +1438,35 @@@ extern "C" int ceph_ll_getattr(class ce Inode *in, struct stat *attr, int uid, int gid) { - return (cmount->get_client()->ll_getattr(in, attr, uid, gid)); + UserPerm perms(uid, gid); + return (cmount->get_client()->ll_getattr(in, attr, perms)); } + extern "C" int ceph_ll_getattrx(class ceph_mount_info *cmount, + Inode *in, struct ceph_statx *stx, + unsigned int want, unsigned int flags, + int uid, int gid) + { - return (cmount->get_client()->ll_getattrx(in, stx, want, flags, uid, gid)); ++ UserPerm perms(uid, gid); ++ return (cmount->get_client()->ll_getattrx(in, stx, want, flags, perms)); + } + extern "C" int ceph_ll_setattr(class ceph_mount_info *cmount, Inode *in, struct stat *st, int mask, int uid, int gid) { - return (cmount->get_client()->ll_setattr(in, st, mask, uid, gid)); + UserPerm perms(uid, gid); + return (cmount->get_client()->ll_setattr(in, st, mask, perms)); } + extern "C" int ceph_ll_setattrx(class ceph_mount_info *cmount, + Inode *in, struct ceph_statx *stx, + int mask, int uid, int gid) + { - return (cmount->get_client()->ll_setattrx(in, stx, mask, uid, gid)); ++ UserPerm perms(uid, gid); ++ return (cmount->get_client()->ll_setattrx(in, stx, mask, perms)); + } + extern "C" int ceph_ll_open(class ceph_mount_info *cmount, Inode *in, int flags, Fh **fh, int uid, int gid) {