extern const char *ceph_mds_op_name(int op);
+// setattr mask is an int
#ifndef CEPH_SETATTR_MODE
-#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)
-#define CEPH_SETATTR_BTIME (1 << 9)
+#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)
+#define CEPH_SETATTR_BTIME (1 << 9)
+#define CEPH_SETATTR_KILL_SGUID (1 << 10)
+#define CEPH_SETATTR_FSCRYPT_AUTH (1 << 11)
+#define CEPH_SETATTR_FSCRYPT_FILE (1 << 12)
#endif
-#define CEPH_SETATTR_KILL_SGUID (1 << 10)
/*
* open request flags
struct snap_metadata *snap_metadata;
};
-/* setattr mask bits */
+/* setattr mask bits (up to an int in size) */
#ifndef CEPH_SETATTR_MODE
-# 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_MTIME_NOW 128
-# define CEPH_SETATTR_ATIME_NOW 256
-# define CEPH_SETATTR_BTIME 512
+#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)
+#define CEPH_SETATTR_BTIME (1 << 9)
+#define CEPH_SETATTR_KILL_SGUID (1 << 10)
+#define CEPH_SETATTR_FSCRYPT_AUTH (1 << 11)
+#define CEPH_SETATTR_FSCRYPT_FILE (1 << 12)
#endif
/* define error codes for the mount function*/
__u32 mask = req->head.args.setattr.mask;
__u32 access_mask = MAY_WRITE;
- // No changes to encrypted inodes from legacy clients
- if (!cur->get_inode()->fscrypt_file.empty() && req->get_header().version < 6) {
- respond_to_request(mdr, -CEPHFS_EPERM);
- return;
+ if (req->get_header().version < 6) {
+ // No changes to fscrypted inodes by downrevved clients
+ if (!cur->get_inode()->fscrypt_auth.empty()) {
+ respond_to_request(mdr, -CEPHFS_EPERM);
+ return;
+ }
+
+ // Only allow fscrypt field changes by capable clients
+ if (mask & (CEPH_SETATTR_FSCRYPT_FILE|CEPH_SETATTR_FSCRYPT_AUTH)) {
+ respond_to_request(mdr, -CEPHFS_EINVAL);
+ return;
+ }
}
// xlock inode
- if (mask & (CEPH_SETATTR_MODE|CEPH_SETATTR_UID|CEPH_SETATTR_GID|CEPH_SETATTR_BTIME|CEPH_SETATTR_KILL_SGUID))
+ if (mask & (CEPH_SETATTR_MODE|CEPH_SETATTR_UID|CEPH_SETATTR_GID|CEPH_SETATTR_BTIME|CEPH_SETATTR_KILL_SGUID|CEPH_SETATTR_FSCRYPT_AUTH))
lov.add_xlock(&cur->authlock);
- if (mask & (CEPH_SETATTR_MTIME|CEPH_SETATTR_ATIME|CEPH_SETATTR_SIZE))
+ if (mask & (CEPH_SETATTR_MTIME|CEPH_SETATTR_ATIME|CEPH_SETATTR_SIZE|CEPH_SETATTR_FSCRYPT_FILE))
lov.add_xlock(&cur->filelock);
if (mask & CEPH_SETATTR_CTIME)
lov.add_wrlock(&cur->versionlock);
pi.inode->size = req->head.args.setattr.size;
pi.inode->rstat.rbytes = pi.inode->size;
}
- if (req->get_header().version >= 6) {
- pi.inode->fscrypt_file = req->fscrypt_file;
- }
-
pi.inode->mtime = mdr->get_op_stamp();
// adjust client's max_size?
}
}
+ if (mask & CEPH_SETATTR_FSCRYPT_AUTH)
+ pi.inode->fscrypt_auth = req->fscrypt_auth;
+ if (mask & CEPH_SETATTR_FSCRYPT_FILE)
+ pi.inode->fscrypt_file = req->fscrypt_file;
+
pi.inode->version = cur->pre_dirty();
pi.inode->ctime = mdr->get_op_stamp();
if (mdr->get_op_stamp() > pi.inode->rstat.rctime)