shithub: lwext4

Download patch

ref: c879d4700facd0ce86ad3781432f01bb0952e4bb
parent: 69e6bc56cee09945f574051fa4df0d63eb1c8625
author: root <ngkaho1234@gmail.com>
date: Sun Sep 20 12:09:45 EDT 2015

Rename process being refined.
Before removing reference from the original parent directory, we should first create reference to the new parent directory, that sounds better.

--- a/lwext4/ext4.c
+++ b/lwext4/ext4.c
@@ -758,7 +758,7 @@
 }
 
 static int __ext4_create_hardlink(const char *path,
-				  struct ext4_inode_ref *child_ref)
+		struct ext4_inode_ref *child_ref)
 {
 	bool is_goal = false;
 	uint8_t inode_type = EXT4_DIRECTORY_FILETYPE_DIR;
@@ -810,9 +810,9 @@
 			break;
 		}
 
-		next_inode = ext4_dir_entry_ll_get_inode(result.dentry);
+		next_inode = result.dentry->inode;
 		inode_type =
-		    ext4_dir_entry_ll_get_inode_type(&mp->fs.sb, result.dentry);
+			ext4_dir_entry_ll_get_inode_type(&mp->fs.sb, result.dentry);
 
 		r = ext4_dir_destroy_result(&ref, &result);
 		if (r != EOK)
@@ -850,43 +850,19 @@
 	return r;
 }
 
-static int __ext4_get_inode_ref_remove_hardlink(const char *path,
-						struct ext4_inode_ref *child)
+static int __ext4_remove_hardlink(const char *path,
+				  uint32_t name_off,
+				  struct ext4_inode_ref *parent_ref,
+				  struct ext4_inode_ref *child_ref)
 {
-	ext4_file f;
-	uint32_t parent_inode;
-	uint32_t name_off;
 	bool is_goal;
 	int r;
 	int len;
-	struct ext4_inode_ref parent;
 	struct ext4_mountpoint *mp = ext4_get_mount(path);
 
 	if (!mp)
 		return ENOENT;
 
-	r = ext4_generic_open2(&f, path, O_RDONLY,
-			       EXT4_DIRECTORY_FILETYPE_UNKNOWN, &parent_inode,
-			       &name_off);
-	if (r != EOK)
-		return r;
-
-	/*Load parent*/
-	r = ext4_fs_get_inode_ref(&mp->fs, parent_inode, &parent);
-	if (r != EOK) {
-		return r;
-	}
-
-	/*We have file to unlink. Load it.*/
-	r = ext4_fs_get_inode_ref(&mp->fs, f.inode, child);
-	if (r != EOK) {
-		ext4_fs_put_inode_ref(&parent);
-		return r;
-	}
-
-	if (r != EOK)
-		goto Finish;
-
 	/*Set path*/
 	path += name_off;
 
@@ -893,15 +869,15 @@
 	len = ext4_path_check(path, &is_goal);
 
 	/*Unlink from parent*/
-	r = ext4_unlink(mp, &parent, child, path, len);
+	r = ext4_unlink(mp, parent_ref, child_ref, path, len);
 	if (r != EOK)
 		goto Finish;
 
 Finish:
 	if (r != EOK)
-		ext4_fs_put_inode_ref(child);
+		ext4_fs_put_inode_ref(child_ref);
 
-	ext4_fs_put_inode_ref(&parent);
+	ext4_fs_put_inode_ref(parent_ref);
 	return r;
 }
 
@@ -908,8 +884,12 @@
 int ext4_frename(const char *path, const char *new_path)
 {
 	int r;
+	ext4_file f;
+	uint32_t name_off;
+	bool parent_loaded = false, child_loaded = false;
+	uint32_t parent_inode, child_inode;
 	struct ext4_mountpoint *mp = ext4_get_mount(path);
-	struct ext4_inode_ref inode_ref;
+	struct ext4_inode_ref child_ref, parent_ref;
 
 	if (!mp)
 		return ENOENT;
@@ -916,19 +896,47 @@
 
 	EXT4_MP_LOCK(mp);
 
-	r = __ext4_get_inode_ref_remove_hardlink(path, &inode_ref);
+	r = ext4_generic_open2(&f, path, O_RDONLY,
+			EXT4_DIRECTORY_FILETYPE_UNKNOWN,
+			&parent_inode, &name_off);
 	if (r != EOK)
 		goto Finish;
 
-	r = __ext4_create_hardlink(new_path, &inode_ref);
+	child_inode = f.inode;
+	ext4_fclose(&f);
+
+	/*Load parent*/
+	r = ext4_fs_get_inode_ref(&mp->fs, parent_inode, &parent_ref);
 	if (r != EOK)
-		r = __ext4_create_hardlink(path, &inode_ref);
+		goto Finish;
 
-	ext4_fs_put_inode_ref(&inode_ref);
+	parent_loaded = true;
 
+	/*We have file to unlink. Load it.*/
+	r = ext4_fs_get_inode_ref(&mp->fs, child_inode, &child_ref);
+	if (r != EOK)
+		goto Finish;
+
+	child_loaded = true;
+
+	r = __ext4_create_hardlink(new_path, &child_ref);
+	if (r != EOK)
+		goto Finish;
+
+	r = __ext4_remove_hardlink(path, name_off, &parent_ref, &child_ref);
+	if (r != EOK)
+		goto Finish;
+
 Finish:
+	if (parent_loaded)
+		ext4_fs_put_inode_ref(&parent_ref);
+
+	if (child_loaded)
+		ext4_fs_put_inode_ref(&child_ref);
+
 	EXT4_MP_UNLOCK(mp);
 	return r;
+
 }
 
 /****************************************************************************/