Commit d9ae977d authored by Luís Henriques's avatar Luís Henriques Committed by Ilya Dryomov
Browse files

ceph: switch ceph_lookup/atomic_open() to use new fscrypt helper



Instead of setting the no-key dentry, use the new
fscrypt_prepare_lookup_partial() helper.  We still need to mark the
directory as incomplete if the directory was just unlocked.

In ceph_atomic_open() this fixes a bug where a dentry is incorrectly
set with DCACHE_NOKEY_NAME when 'dir' has been evicted but the key is
still available (for example, where there's a drop_caches).

Signed-off-by: default avatarLuís Henriques <lhenriques@suse.de>
Reviewed-by: default avatarXiubo Li <xiubli@redhat.com>
Reviewed-by: default avatarMilind Changire <mchangir@redhat.com>
Signed-off-by: default avatarIlya Dryomov <idryomov@gmail.com>
parent 295fc4aa
Loading
Loading
Loading
Loading
+7 −6
Original line number Diff line number Diff line
@@ -785,14 +785,15 @@ static struct dentry *ceph_lookup(struct inode *dir, struct dentry *dentry,
		return ERR_PTR(-ENAMETOOLONG);

	if (IS_ENCRYPTED(dir)) {
		err = ceph_fscrypt_prepare_readdir(dir);
		bool had_key = fscrypt_has_encryption_key(dir);

		err = fscrypt_prepare_lookup_partial(dir, dentry);
		if (err < 0)
			return ERR_PTR(err);
		if (!fscrypt_has_encryption_key(dir)) {
			spin_lock(&dentry->d_lock);
			dentry->d_flags |= DCACHE_NOKEY_NAME;
			spin_unlock(&dentry->d_lock);
		}

		/* mark directory as incomplete if it has been unlocked */
		if (!had_key && fscrypt_has_encryption_key(dir))
			ceph_dir_clear_complete(dir);
	}

	/* can we conclude ENOENT locally? */
+3 −5
Original line number Diff line number Diff line
@@ -791,11 +791,9 @@ int ceph_atomic_open(struct inode *dir, struct dentry *dentry,
	ihold(dir);
	if (IS_ENCRYPTED(dir)) {
		set_bit(CEPH_MDS_R_FSCRYPT_FILE, &req->r_req_flags);
		if (!fscrypt_has_encryption_key(dir)) {
			spin_lock(&dentry->d_lock);
			dentry->d_flags |= DCACHE_NOKEY_NAME;
			spin_unlock(&dentry->d_lock);
		}
		err = fscrypt_prepare_lookup_partial(dir, dentry);
		if (err < 0)
			goto out_req;
	}

	if (flags & O_CREAT) {