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;
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))
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;
return r;
caps = CEPH_CAP_AUTH_SHARED;
}
-
- int r = _lookup(cur.get(), dname, caps, &next, uid, gid);
+
+ /* Get extra requested caps on the last component */
+ if (i == (path.depth() - 1))
+ caps |= mask;
+ int r = _lookup(cur.get(), dname, caps, &next, perms);
if (r < 0)
return r;
// only follow trailing symlink if followsym. always follow
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();
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;
}
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);
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;
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;
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;
return r;
}
- int r = path_walk(path, &in, flags & AT_SYMLINK_NOFOLLOW, mask);
+ 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);
+
- r = _getattr(in, 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, 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);
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;
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;
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) {
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;
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!
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;
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);
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);
{
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);
{
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);
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;
}
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);
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;
}
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;
}
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 &&
// 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);
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);
// 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);
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);
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(
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
- 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);
+ unsigned statx_to_mask(unsigned int flags, unsigned int want);
- int setattr(const char *relpath, struct stat *attr, int mask, const UserPerm& perms);
+ 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 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
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);
{
if (!cmount->is_mounted())
return -ENOTCONN;
- return cmount->get_client()->stat(path, stbuf);
+ return cmount->get_client()->stat(path, stbuf, cmount->default_perms);
}
- return cmount->get_client()->statx(path, stx, want, flags);
+ 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, cmount->default_perms,
++ want, flags);
+ }
+
extern "C" int ceph_lstat(struct ceph_mount_info *cmount, const char *path,
struct stat *stbuf)
{
{
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);
}
- return cmount->get_client()->setattrx(relpath, stx, mask, flags);
+ 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,
++ 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)
{
{
if (!cmount->is_mounted())
return -ENOTCONN;
- return cmount->get_client()->fstat(fd, stbuf);
+ return cmount->get_client()->fstat(fd, stbuf, cmount->default_perms);
}
- return cmount->get_client()->fstatx(fd, stx, want, flags);
+ 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, cmount->default_perms,
++ want, flags);
+ }
+
extern "C" int ceph_sync_fs(struct ceph_mount_info *cmount)
{
if (!cmount->is_mounted())
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));
}
- return (cmount->get_client()->ll_getattrx(in, stx, want, flags, uid, gid));
+ 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)
+ {
++ 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));
}
- return (cmount->get_client()->ll_setattrx(in, stx, mask, uid, gid));
+ extern "C" int ceph_ll_setattrx(class ceph_mount_info *cmount,
+ Inode *in, struct ceph_statx *stx,
+ int mask, int uid, int 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)
{