}
if (mask & (CEPH_SETATTR_CTIME | CEPH_SETATTR_MTIME | CEPH_SETATTR_ATIME)) {
- if (uid != 0 && (uid_t)uid != in->uid)
- goto out;
+ if (uid != 0 && (uid_t)uid != in->uid) {
+ int check_mask = CEPH_SETATTR_CTIME;
+ if (!(mask & CEPH_SETATTR_MTIME_NOW))
+ check_mask |= CEPH_SETATTR_MTIME;
+ if (!(mask & CEPH_SETATTR_ATIME_NOW))
+ check_mask |= CEPH_SETATTR_ATIME;
+ if (check_mask & mask) {
+ goto out;
+ } else {
+ r = inode_permission(in, uid, groups, MAY_WRITE);
+ if (r < 0)
+ goto out;
+ }
+ }
}
r = 0;
out:
int Client::_setattr(InodeRef &in, struct stat *attr, int mask)
{
+ mask &= (CEPH_SETATTR_MODE | CEPH_SETATTR_UID |
+ CEPH_SETATTR_GID | CEPH_SETATTR_MTIME |
+ CEPH_SETATTR_ATIME | CEPH_SETATTR_SIZE |
+ CEPH_SETATTR_CTIME);
if (cct->_conf->client_permissions) {
int r = may_setattr(in.get(), attr, mask);
if (r < 0)
return res;
}
+ mask &= ~(CEPH_SETATTR_MTIME_NOW | CEPH_SETATTR_ATIME_NOW);
+
InodeRef target(in);
int res = _setattr(in, attr, mask, uid, gid, &target);
if (res == 0) {
if (to_set & FUSE_SET_ATTR_MTIME) mask |= CEPH_SETATTR_MTIME;
if (to_set & FUSE_SET_ATTR_ATIME) mask |= CEPH_SETATTR_ATIME;
if (to_set & FUSE_SET_ATTR_SIZE) mask |= CEPH_SETATTR_SIZE;
+ if (to_set & FUSE_SET_ATTR_MTIME_NOW) mask |= CEPH_SETATTR_MTIME_NOW;
+ if (to_set & FUSE_SET_ATTR_ATIME_NOW) mask |= CEPH_SETATTR_ATIME_NOW;
int r = cfuse->client->ll_setattr(in, attr, mask, ctx->uid, ctx->gid);
if (r == 0)
extern const char *ceph_mds_op_name(int op);
-#define CEPH_SETATTR_MODE 1
-#define CEPH_SETATTR_UID 2
-#define CEPH_SETATTR_GID 4
-#define CEPH_SETATTR_MTIME 8
-#define CEPH_SETATTR_ATIME 16
-#define CEPH_SETATTR_SIZE 32
-#define CEPH_SETATTR_CTIME 64
+#define CEPH_SETATTR_MODE (1 << 0)
+#define CEPH_SETATTR_UID (1 << 1)
+#define CEPH_SETATTR_GID (1 << 2)
+#define CEPH_SETATTR_MTIME (1 << 3)
+#define CEPH_SETATTR_ATIME (1 << 4)
+#define CEPH_SETATTR_SIZE (1 << 5)
+#define CEPH_SETATTR_CTIME (1 << 6)
+#define CEPH_SETATTR_MTIME_NOW (1 << 7)
+#define CEPH_SETATTR_ATIME_NOW (1 << 8)
/*
* Ceph setxattr request flags.
*/
#include "gtest/gtest.h"
+#include "common/ceph_argparse.h"
#include "include/buffer.h"
+#include "include/stringify.h"
#include "include/cephfs/libcephfs.h"
#include "include/rados/librados.h"
#include <errno.h>
#include <sys/uio.h>
#include <iostream>
#include <vector>
-#include "common/ceph_argparse.h"
-#include "include/stringify.h"
#include "json_spirit/json_spirit.h"
#ifdef __linux__
#include "include/int_types.h"
#include "gtest/gtest.h"
-#include "include/cephfs/libcephfs.h"
#include "include/ceph_fs.h"
+#include "include/cephfs/libcephfs.h"
#include <errno.h>
#include <sys/fcntl.h>
#include <unistd.h>