diff --git a/fs/ext4/acl.c b/fs/ext4/acl.c
index 5f09df4..e17e1a9 100644
--- a/fs/ext4/acl.c
+++ b/fs/ext4/acl.c
@@ -152,8 +152,10 @@ fail:
  * Inode operation get_posix_acl().
  *
  * inode->i_mutex: don't care
+ * We don't check whether posix acl is enabled or not.
+ * Caller should make sure of that.
  */
-static struct posix_acl *
+struct posix_acl *
 ext4_get_acl(struct inode *inode, int type)
 {
 	int name_index;
@@ -161,9 +163,6 @@ ext4_get_acl(struct inode *inode, int type)
 	struct posix_acl *acl;
 	int retval;
 
-	if (!posix_acl_enabled(inode->i_sb))
-		return NULL;
-
 	acl = get_cached_acl(inode, type);
 	if (acl != ACL_NOT_CACHED)
 		return acl;
@@ -261,7 +260,12 @@ ext4_set_acl(handle_t *handle, struct inode *inode, int type,
 int
 ext4_check_acl(struct inode *inode, int mask)
 {
-	struct posix_acl *acl = ext4_get_acl(inode, ACL_TYPE_ACCESS);
+	struct posix_acl *acl;
+
+	if (!posix_acl_enabled(inode->i_sb))
+		return -EAGAIN;
+
+	acl = ext4_get_acl(inode, ACL_TYPE_ACCESS);
 
 	if (IS_ERR(acl))
 		return PTR_ERR(acl);
diff --git a/fs/ext4/acl.h b/fs/ext4/acl.h
index 9d843d5..3e47cf3 100644
--- a/fs/ext4/acl.h
+++ b/fs/ext4/acl.h
@@ -57,6 +57,7 @@ static inline int ext4_acl_count(size_t size)
 extern int ext4_check_acl(struct inode *, int);
 extern int ext4_acl_chmod(struct inode *);
 extern int ext4_init_acl(handle_t *, struct inode *, struct inode *);
+extern struct posix_acl *ext4_get_acl(struct inode *inode, int type);
 
 #else  /* CONFIG_EXT4_FS_POSIX_ACL */
 #include <linux/sched.h>
diff --git a/fs/ext4/richacl.c b/fs/ext4/richacl.c
index 1c78086..a8702c7 100644
--- a/fs/ext4/richacl.c
+++ b/fs/ext4/richacl.c
@@ -20,6 +20,7 @@
 #include "ext4_jbd2.h"
 #include "xattr.h"
 #include "richacl.h"
+#include "acl.h"
 
 static inline struct richacl *
 ext4_iget_richacl(struct inode *inode)
@@ -47,13 +48,60 @@ ext4_iset_richacl(struct inode *inode, struct richacl *acl)
 	spin_unlock(&inode->i_lock);
 }
 
+static int ext4_map_pacl_to_richacl(struct inode *inode,
+				struct richacl **richacl)
+{
+	int retval = 0;
+	struct posix_acl *pacl = NULL, *dpacl = NULL;
+
+	*richacl  = NULL;
+	pacl = ext4_get_acl(inode, ACL_TYPE_ACCESS);
+	if (IS_ERR(pacl))
+		return PTR_ERR(pacl);
+
+
+	if (S_ISDIR(inode->i_mode)) {
+		dpacl = ext4_get_acl(inode, ACL_TYPE_DEFAULT);
+		if (IS_ERR(dpacl)) {
+			/* we need to fail for all errors
+			 * we will continue only with NULL dpacl
+			 * which is ENODATA on dpacl
+			 */
+			posix_acl_release(pacl);
+			return PTR_ERR(dpacl);
+		}
+	}
+
+	if (pacl == NULL && dpacl != NULL) {
+		/*
+		 * We have a default acl list. So derive the access acl
+		 * list from the mode so that we get a richacl that
+		 * include mode bits
+		 */
+		pacl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL);
+	}
+
+	if (pacl == NULL && dpacl == NULL)
+		return -ENODATA;
+
+	*richacl = map_posix_to_richacl(inode, pacl, dpacl);
+
+	if (IS_ERR(*richacl)) {
+		retval  = PTR_ERR(*richacl);
+		*richacl = NULL;
+	}
+	posix_acl_release(pacl);
+	posix_acl_release(dpacl);
+	return retval;
+}
+
 static struct richacl *
 ext4_get_richacl(struct inode *inode)
 {
 	const int name_index = EXT4_XATTR_INDEX_RICHACL;
 	void *value = NULL;
 	struct richacl *acl;
-	int retval;
+	int retval = 0;
 
 	if (!richacl_enabled(inode->i_sb))
 		return NULL;
@@ -61,22 +109,31 @@ ext4_get_richacl(struct inode *inode)
 	acl = ext4_iget_richacl(inode);
 	if (acl != EXT4_RICHACL_NOT_CACHED)
 		return acl;
+
 	retval = ext4_xattr_get(inode, name_index, "", NULL, 0);
 	if (retval > 0) {
 		value = kmalloc(retval, GFP_KERNEL);
 		if (!value)
 			return ERR_PTR(-ENOMEM);
 		retval = ext4_xattr_get(inode, name_index, "", value, retval);
+		if (retval > 0) {
+			acl = richacl_from_xattr(value, retval);
+			if (acl == ERR_PTR(-EINVAL))
+				acl = ERR_PTR(-EIO);
+		}
+		kfree(value);
+	} else if (retval == -ENODATA) {
+		/*
+		 * Check whether we have posix acl stored.
+		 * If so convert them to richacl
+		 */
+		retval = ext4_map_pacl_to_richacl(inode, &acl);
 	}
-	if (retval > 0) {
-		acl = richacl_from_xattr(value, retval);
-		if (acl == ERR_PTR(-EINVAL))
-			acl = ERR_PTR(-EIO);
-	} else if (retval == -ENODATA || retval == -ENOSYS)
+
+	if (retval == -ENODATA || retval == -ENOSYS)
 		acl = NULL;
-	else
+	else if (retval < 0)
 		acl = ERR_PTR(retval);
-	kfree(value);
 
 	if (!IS_ERR(acl))
 		ext4_iset_richacl(inode, acl);
