diff --git a/fs/lustre/llite/llite_lib.c b/fs/lustre/llite/llite_lib.c
index e3e871d..1121652 100644
--- a/fs/lustre/llite/llite_lib.c
+++ b/fs/lustre/llite/llite_lib.c
@@ -251,6 +251,8 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt)
 	u64 valid;
 	int size, err, checksum;
 	bool api32;
+	void *encctx;
+	int encctxlen;
 
 	sbi->ll_md_obd  = class_name2obd(md);
 	if (!sbi->ll_md_obd) {
@@ -625,7 +627,8 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt)
 	/* make root inode
 	 * XXX: move this to after cbd setup?
 	 */
-	valid = OBD_MD_FLGETATTR | OBD_MD_FLBLOCKS | OBD_MD_FLMODEASIZE;
+	valid = OBD_MD_FLGETATTR | OBD_MD_FLBLOCKS | OBD_MD_FLMODEASIZE |
+		OBD_MD_ENCCTX;
 	if (test_bit(LL_SBI_ACL, sbi->ll_flags))
 		valid |= OBD_MD_FLACL;
 
@@ -640,6 +643,14 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt)
 	op_data->op_valid = valid;
 
 	err = md_getattr(sbi->ll_md_exp, op_data, &request);
+
+	/* We need enc ctx info, so reset it in op_data to
+	 * prevent it from being freed.
+	 */
+	encctx = op_data->op_file_encctx;
+	encctxlen = op_data->op_file_encctx_size;
+	op_data->op_file_encctx = NULL;
+	op_data->op_file_encctx_size = 0;
 	kfree(op_data);
 	if (err) {
 		CERROR("%s: md_getattr failed for root: rc = %d\n",
@@ -659,15 +670,29 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt)
 	api32 = test_bit(LL_SBI_32BIT_API, sbi->ll_flags);
 	root = ll_iget(sb, cl_fid_build_ino(&sbi->ll_root_fid, api32), &lmd);
 	md_free_lustre_md(sbi->ll_md_exp, &lmd);
-	ptlrpc_req_finished(request);
 
 	if (IS_ERR(root)) {
 		lmd_clear_acl(&lmd);
 		err = IS_ERR(root) ? PTR_ERR(root) : -EBADF;
-		CERROR("lustre_lite: bad iget4 for root\n");
+		root = NULL;
+		CERROR("%s: bad ll_iget() for root: rc = %d\n",
+		       sbi->ll_fsname, err);
+		ptlrpc_req_finished(request);
 		goto out_root;
 	}
 
+	if (encctxlen) {
+		CDEBUG(D_SEC,
+		       "server returned encryption ctx for root inode "DFID"\n",
+		       PFID(&sbi->ll_root_fid));
+		err = ll_set_encflags(root, encctx, encctxlen, true);
+		if (err)
+			CWARN("%s: cannot set enc ctx for "DFID": rc = %d\n",
+			      sbi->ll_fsname,
+			      PFID(&sbi->ll_root_fid), err);
+	}
+	ptlrpc_req_finished(request);
+
 	checksum = test_bit(LL_SBI_CHECKSUM, sbi->ll_flags);
 	if (sbi->ll_checksum_set) {
 		err = obd_set_info_async(NULL, sbi->ll_dt_exp,
@@ -3164,9 +3189,11 @@ struct md_op_data *ll_prep_md_op_data(struct md_op_data *op_data,
 	if (ll_need_32bit_api(ll_i2sbi(i1)))
 		op_data->op_cli_flags |= CLI_API32;
 
-	if (opc == LUSTRE_OPC_LOOKUP || opc == LUSTRE_OPC_CREATE) {
+	if ((i2 && is_root_inode(i2)) ||
+	    opc == LUSTRE_OPC_LOOKUP || opc == LUSTRE_OPC_CREATE) {
 		/* In case of lookup, ll_setup_filename() has already been
 		 * called in ll_lookup_it(), so just take provided name.
+		 * Also take provided name if we are dealing with root inode.
 		 */
 		fname.disk_name.name = (unsigned char *)name;
 		fname.disk_name.len = namelen;
diff --git a/fs/lustre/mdc/mdc_dev.c b/fs/lustre/mdc/mdc_dev.c
index 0b1d257..de67720 100644
--- a/fs/lustre/mdc/mdc_dev.c
+++ b/fs/lustre/mdc/mdc_dev.c
@@ -1258,6 +1258,7 @@ static int mdc_io_data_version_start(const struct lu_env *env,
 
 	req_capsule_set_size(&req->rq_pill, &RMF_ACL, RCL_SERVER, 0);
 	req_capsule_set_size(&req->rq_pill, &RMF_MDT_MD, RCL_SERVER, 0);
+	req_capsule_set_size(&req->rq_pill, &RMF_FILE_ENCCTX, RCL_SERVER, 0);
 	ptlrpc_request_set_replen(req);
 
 	req->rq_interpret_reply = mdc_data_version_interpret;
diff --git a/fs/lustre/mdc/mdc_request.c b/fs/lustre/mdc/mdc_request.c
index 1064d9f..f553d44 100644
--- a/fs/lustre/mdc/mdc_request.c
+++ b/fs/lustre/mdc/mdc_request.c
@@ -158,7 +158,8 @@ static int mdc_get_root(struct obd_export *exp, const char *fileset,
  * layouts.  --umka
  */
 static int mdc_getattr_common(struct obd_export *exp,
-			      struct ptlrpc_request *req)
+			      struct ptlrpc_request *req,
+			      struct md_op_data *op_data)
 {
 	struct req_capsule *pill = &req->rq_pill;
 	struct mdt_body *body;
@@ -185,6 +186,18 @@ static int mdc_getattr_common(struct obd_export *exp,
 			return -EPROTO;
 	}
 
+	/* If encryption context was returned by MDT, put it in op_data
+	 * so that caller can set it on inode and save an extra getxattr.
+	 */
+	if (op_data && op_data->op_valid & OBD_MD_ENCCTX &&
+	    body->mbo_valid & OBD_MD_ENCCTX) {
+		op_data->op_file_encctx =
+			req_capsule_server_get(pill, &RMF_FILE_ENCCTX);
+		op_data->op_file_encctx_size =
+			req_capsule_get_size(pill, &RMF_FILE_ENCCTX,
+					     RCL_SERVER);
+	}
+
 	return 0;
 }
 
@@ -203,6 +216,7 @@ static int mdc_getattr(struct obd_export *exp, struct md_op_data *op_data,
 		       struct ptlrpc_request **request)
 {
 	struct ptlrpc_request *req;
+	struct obd_device *obd = class_exp2obd(exp);
 	struct obd_import *imp = class_exp2cliimp(exp);
 	u32 acl_bufsize = LUSTRE_POSIX_ACL_MAX_SIZE_OLD;
 	int rc;
@@ -233,9 +247,16 @@ static int mdc_getattr(struct obd_export *exp, struct md_op_data *op_data,
 	req_capsule_set_size(&req->rq_pill, &RMF_ACL, RCL_SERVER, acl_bufsize);
 	req_capsule_set_size(&req->rq_pill, &RMF_MDT_MD, RCL_SERVER,
 			     op_data->op_mode);
+	if (exp_connect_encrypt(exp) && op_data->op_valid & OBD_MD_ENCCTX)
+		req_capsule_set_size(&req->rq_pill, &RMF_FILE_ENCCTX,
+				     RCL_SERVER,
+				     obd->u.cli.cl_max_mds_easize);
+	else
+		req_capsule_set_size(&req->rq_pill, &RMF_FILE_ENCCTX,
+				     RCL_SERVER, 0);
 	ptlrpc_request_set_replen(req);
 
-	rc = mdc_getattr_common(exp, req);
+	rc = mdc_getattr_common(exp, req, op_data);
 	if (rc) {
 		if (rc == -ERANGE) {
 			acl_bufsize = min_t(u32,
@@ -289,6 +310,7 @@ static int mdc_getattr_name(struct obd_export *exp, struct md_op_data *op_data,
 	req_capsule_set_size(&req->rq_pill, &RMF_MDT_MD, RCL_SERVER,
 			     op_data->op_mode);
 	req_capsule_set_size(&req->rq_pill, &RMF_ACL, RCL_SERVER, acl_bufsize);
+	req_capsule_set_size(&req->rq_pill, &RMF_FILE_ENCCTX, RCL_SERVER, 0);
 	ptlrpc_request_set_replen(req);
 	if (op_data->op_bias & MDS_FID_OP) {
 		struct mdt_body *b = req_capsule_client_get(&req->rq_pill,
@@ -300,7 +322,7 @@ static int mdc_getattr_name(struct obd_export *exp, struct md_op_data *op_data,
 		}
 	}
 
-	rc = mdc_getattr_common(exp, req);
+	rc = mdc_getattr_common(exp, req, NULL);
 	if (rc) {
 		if (rc == -ERANGE) {
 			acl_bufsize = min_t(u32,
diff --git a/fs/lustre/ptlrpc/layout.c b/fs/lustre/ptlrpc/layout.c
index 8e3c97d..8725edd 100644
--- a/fs/lustre/ptlrpc/layout.c
+++ b/fs/lustre/ptlrpc/layout.c
@@ -547,7 +547,8 @@
 	&RMF_MDT_MD,
 	&RMF_ACL,
 	&RMF_CAPA1,
-	&RMF_CAPA2
+	&RMF_CAPA2,
+	&RMF_FILE_ENCCTX,
 };
 
 static const struct req_msg_field *mds_setattr_server[] = {
