shithub: lwext4

Download patch

ref: d9dec8dc9f60f42149ca5d55c0de7c8a2d37fc06
parent: 4e32e2da452116b1cc8f79902fb7ea704726557f
author: ngkaho1234 <ngkaho1234@gmail.com>
date: Sun Nov 1 09:09:16 EST 2015

ext4_generic_open2: add EXT4_FINCOM_FILETYPE check

When following the path, we should check whether
EXT4_FINCOM_FILETYPE is enabled.

--- a/lwext4/ext4.c
+++ b/lwext4/ext4.c
@@ -583,7 +583,7 @@
 			      uint32_t *name_off)
 {
 	bool is_goal = false;
-	uint8_t inode_type = EXT4_DIRENTRY_UNKNOWN;
+	uint32_t inode_mode = EXT4_INODE_MODE_DIRECTORY;
 	uint32_t next_inode;
 
 	int r;
@@ -673,20 +673,37 @@
 			*parent_inode = ref.index;
 
 		next_inode = ext4_dir_entry_ll_get_inode(result.dentry);
-		inode_type =
-		    ext4_dir_entry_ll_get_inode_type(&mp->fs.sb, result.dentry);
+		if (ext4_sb_feature_incom(&mp->fs.sb, EXT4_FINCOM_FILETYPE)) {
+			int inode_type =
+				ext4_dir_entry_ll_get_inode_type(&mp->fs.sb,
+						result.dentry);
+			inode_mode = ext4_fs_correspond_inode_mode(inode_type);
+		} else {
+			struct ext4_inode_ref child_ref;
+			r = ext4_fs_get_inode_ref(&mp->fs, next_inode,
+					&child_ref);
+			if (r != EOK)
+				break;
 
+			inode_mode = ext4_inode_type(&mp->fs.sb,
+					child_ref.inode);
+
+			ext4_fs_put_inode_ref(&child_ref);
+		}
+
 		r = ext4_dir_destroy_result(&ref, &result);
 		if (r != EOK)
 			break;
 
 		/*If expected file error*/
-		if (inode_type != EXT4_DIRENTRY_DIR && !is_goal) {
+		if (inode_mode != EXT4_INODE_MODE_DIRECTORY &&
+		    !is_goal) {
 			r = ENOENT;
 			break;
 		}
 		if (filetype != EXT4_DIRENTRY_UNKNOWN) {
-			if ((inode_type != filetype) && is_goal) {
+			if ((inode_mode != ext4_fs_correspond_inode_mode(filetype)) &&
+			    is_goal) {
 				r = ENOENT;
 				break;
 			}
@@ -717,7 +734,7 @@
 	if (is_goal) {
 
 		if ((f->flags & O_TRUNC) &&
-		    (inode_type == EXT4_DIRENTRY_REG_FILE)) {
+		    (inode_mode == EXT4_INODE_MODE_FILE)) {
 
 			r = ext4_fs_truncate_inode(&ref, 0);
 			if (r != EOK) {
@@ -765,7 +782,7 @@
 		bool rename)
 {
 	bool is_goal = false;
-	uint8_t inode_type = EXT4_DIRENTRY_DIR;
+	uint32_t inode_mode = EXT4_INODE_MODE_DIRECTORY;
 	uint32_t next_inode;
 
 	int r;
@@ -820,14 +837,29 @@
 		}
 
 		next_inode = result.dentry->inode;
-		inode_type =
-			ext4_dir_entry_ll_get_inode_type(&mp->fs.sb, result.dentry);
+		if (ext4_sb_feature_incom(&mp->fs.sb, EXT4_FINCOM_FILETYPE)) {
+			int inode_type =
+				ext4_dir_entry_ll_get_inode_type(&mp->fs.sb,
+						result.dentry);
+			inode_mode = ext4_fs_correspond_inode_mode(inode_type);
+		} else {
+			struct ext4_inode_ref child_ref;
+			r = ext4_fs_get_inode_ref(&mp->fs, next_inode,
+					&child_ref);
+			if (r != EOK)
+				break;
 
+			inode_mode = ext4_inode_type(&mp->fs.sb,
+					child_ref.inode);
+
+			ext4_fs_put_inode_ref(&child_ref);
+		}
+
 		r = ext4_dir_destroy_result(&ref, &result);
 		if (r != EOK)
 			break;
 
-		if (inode_type == EXT4_DIRENTRY_REG_FILE) {
+		if (inode_mode != EXT4_INODE_MODE_DIRECTORY) {
 			if (is_goal)
 				r = EEXIST;
 			else
--- a/lwext4/ext4_fs.c
+++ b/lwext4/ext4_fs.c
@@ -837,7 +837,7 @@
 #endif
 }
 
-static uint32_t ext4_fs_correspond_inode_mode(int filetype)
+uint32_t ext4_fs_correspond_inode_mode(int filetype)
 {
 	switch (filetype) {
 	case EXT4_DIRENTRY_DIR:
--- a/lwext4/ext4_fs.h
+++ b/lwext4/ext4_fs.h
@@ -145,6 +145,12 @@
  */
 int ext4_fs_put_inode_ref(struct ext4_inode_ref *ref);
 
+/**@brief Convert filetype to inode mode.
+ * @param filetype
+ * @return inode mode
+ */
+uint32_t ext4_fs_correspond_inode_mode(int filetype);
+
 /**@brief Allocate new i-node in the filesystem.
  * @param fs        Filesystem to allocated i-node on
  * @param inode_ref Output pointer to return reference to allocated i-node