ldout(cct, 20) << __func__ << " " << *in << "; " << perms << dendl;
unsigned want = 0;
+ if (!in->is_dir() && is_inode_locked(in))
+ return -ENOKEY;
+
if ((flags & O_ACCMODE) == O_WRONLY)
want = CLIENT_MAY_WRITE;
else if ((flags & O_ACCMODE) == O_RDWR)
int Client::may_lookup(const InodeRef& dir, const UserPerm& perms)
{
ldout(cct, 20) << __func__ << " " << *dir << "; " << perms << dendl;
+
int r = _getattr_for_perm(dir, perms);
if (r < 0)
goto out;
int Client::may_create(const InodeRef& dir, const UserPerm& perms)
{
ldout(cct, 20) << __func__ << " " << *dir << "; " << perms << dendl;
+ if (dir->is_dir() && is_inode_locked(dir))
+ return -ENOKEY;
+
int r = _getattr_for_perm(dir, perms);
if (r < 0)
goto out;
return _rmdir(in, name, perms);
}
+bool Client::is_inode_locked(Inode *to_check)
+{
+ if (to_check && to_check->fscrypt_ctx) {
+ FSCryptKeyHandlerRef kh;
+ int r = fscrypt->get_key_store().find(to_check->fscrypt_ctx->master_key_identifier, kh);
+ if (r < 0) {
+ return true;
+ }
+ }
+ return false;
+}
+
int Client::_rename(Inode *fromdir, const char *fromname, Inode *todir, const char *toname, const UserPerm& perm, std::string alternate_name)
{
ldout(cct, 8) << "_rename(" << fromdir->ino << " " << fromname << " to "
return -EINVAL;
}
+ bool source_locked = is_inode_locked(fromdir);
+ bool dest_locked = is_inode_locked(todir);
+ if (source_locked || dest_locked)
+ return -ENOKEY;
+
if (wdr_from.diri->snapid != wdr_to.diri->snapid)
return -EXDEV;
int _link(Inode *diri_from, const char* path_from, Inode* diri_to, const char* path_to, const UserPerm& perm, std::string alternate_name);
int _unlink(Inode *dir, const char *name, const UserPerm& perm);
+ bool is_inode_locked(Inode *to_check);
int _rename(Inode *olddir, const char *oname, Inode *ndir, const char *nname, const UserPerm& perm, std::string alternate_name);
int _mkdir(const walk_dentry_result& wdr, mode_t mode, const UserPerm& perm,
InodeRef *inp = 0, const std::map<std::string, std::string> &metadata={},
uint32_t mode = 0;
uid_t uid = 0;
gid_t gid = 0;
+ uint32_t i_flags;
// nlink
int32_t nlink = 0;
bool is_symlink() const { return (mode & S_IFMT) == S_IFLNK; }
bool is_dir() const { return (mode & S_IFMT) == S_IFDIR; }
bool is_file() const { return (mode & S_IFMT) == S_IFREG; }
- bool is_encrypted() const { return (mode & S_ENCRYPTED) == S_ENCRYPTED; }
+
+ // use i_flags as 1 << 14 will overlap with other mode bits.
+ bool is_encrypted() const { return (i_flags & S_ENCRYPTED) == S_ENCRYPTED; }
bool has_dir_layout() const {
return layout != file_layout_t();