Browse Source

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.
pull/2/head
root 9 years ago
parent
commit
c879d4700f
  1. 86
      lwext4/ext4.c

86
lwext4/ext4.c

@ -758,7 +758,7 @@ static int ext4_generic_open(ext4_file *f, const char *path, const char *flags,
}
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 @@ static int __ext4_create_hardlink(const char *path,
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,85 +850,93 @@ static int __ext4_create_hardlink(const char *path,
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;
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;
}
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;
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;
}
/****************************************************************************/

Loading…
Cancel
Save