[PATCH] ceph: send the fscrypt_auth to MDS via request

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Xiubo Li <xiubli@xxxxxxxxxx>

Currently when creating new files or directories the kclient will
create a new inode and fill the fscrypt auth locally, without sending
it to MDS via requests. Then the MDS reply with it to empty too.
And the kclient will update it later together with the cap update
requests.

It's buggy if just after the create requests succeeds but the kclient
crash and reboot, then in MDS side the fscrypt_auth will keep empty.

Signed-off-by: Xiubo Li <xiubli@xxxxxxxxxx>
---
 fs/ceph/dir.c  | 37 +++++++++++++++++++++++++++++++++++--
 fs/ceph/file.c | 15 ++++++++++++++-
 2 files changed, 49 insertions(+), 3 deletions(-)

diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c
index 123e3b9c8161..a63a4923e33b 100644
--- a/fs/ceph/dir.c
+++ b/fs/ceph/dir.c
@@ -926,8 +926,20 @@ static int ceph_mknod(struct user_namespace *mnt_userns, struct inode *dir,
 		goto out_req;
 	}
 
-	if (S_ISREG(mode) && IS_ENCRYPTED(dir))
-		set_bit(CEPH_MDS_R_FSCRYPT_FILE, &req->r_req_flags);
+	if (IS_ENCRYPTED(dir)) {
+		struct ceph_inode_info *ci = ceph_inode(req->r_new_inode);
+
+		if (S_ISREG(mode))
+			set_bit(CEPH_MDS_R_FSCRYPT_FILE, &req->r_req_flags);
+
+		req->r_fscrypt_auth = kmemdup(ci->fscrypt_auth,
+					      ci->fscrypt_auth_len,
+					      GFP_KERNEL);
+		if (!req->r_fscrypt_auth) {
+			err = -ENOMEM;
+			goto out_req;
+		}
+	}
 
 	req->r_dentry = dget(dentry);
 	req->r_num_caps = 2;
@@ -1030,9 +1042,19 @@ static int ceph_symlink(struct user_namespace *mnt_userns, struct inode *dir,
 	ihold(dir);
 
 	if (IS_ENCRYPTED(req->r_new_inode)) {
+		struct ceph_inode_info *ci = ceph_inode(req->r_new_inode);
+
 		err = prep_encrypted_symlink_target(req, dest);
 		if (err)
 			goto out_req;
+
+		req->r_fscrypt_auth = kmemdup(ci->fscrypt_auth,
+					      ci->fscrypt_auth_len,
+					      GFP_KERNEL);
+		if (!req->r_fscrypt_auth) {
+			err = -ENOMEM;
+			goto out_req;
+		}
 	} else {
 		req->r_path2 = kstrdup(dest, GFP_KERNEL);
 		if (!req->r_path2) {
@@ -1112,6 +1134,17 @@ static int ceph_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
 		goto out_req;
 	}
 
+	if (IS_ENCRYPTED(dir)) {
+		struct ceph_inode_info *ci = ceph_inode(req->r_new_inode);
+
+		req->r_fscrypt_auth = kmemdup(ci->fscrypt_auth,
+					      ci->fscrypt_auth_len,
+					      GFP_KERNEL);
+		if (!req->r_fscrypt_auth) {
+			err = -ENOMEM;
+			goto out_req;
+		}
+	}
 	req->r_dentry = dget(dentry);
 	req->r_num_caps = 2;
 	req->r_parent = dir;
diff --git a/fs/ceph/file.c b/fs/ceph/file.c
index 61ffbda5b934..55db91be4d7b 100644
--- a/fs/ceph/file.c
+++ b/fs/ceph/file.c
@@ -771,9 +771,22 @@ int ceph_atomic_open(struct inode *dir, struct dentry *dentry,
 	req->r_args.open.mask = cpu_to_le32(mask);
 	req->r_parent = dir;
 	ihold(dir);
-	if (IS_ENCRYPTED(dir))
+	if (IS_ENCRYPTED(dir)) {
 		set_bit(CEPH_MDS_R_FSCRYPT_FILE, &req->r_req_flags);
 
+		if (new_inode) {
+			struct ceph_inode_info *ci = ceph_inode(new_inode);
+
+			req->r_fscrypt_auth = kmemdup(ci->fscrypt_auth,
+						      ci->fscrypt_auth_len,
+						      GFP_KERNEL);
+			if (!req->r_fscrypt_auth) {
+				err = -ENOMEM;
+				goto out_req;
+			}
+		}
+	}
+
 	if (flags & O_CREAT) {
 		struct ceph_file_layout lo;
 
-- 
2.27.0




[Index of Archives]     [CEPH Users]     [Ceph Large]     [Ceph Dev]     [Information on CEPH]     [Linux BTRFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux