Skip to content

Commit

Permalink
Merge pull request #135 from hayley-leblanc/issue_116
Browse files Browse the repository at this point in the history
Make rename atomic with respect to crashes
  • Loading branch information
Andiry authored Feb 20, 2022
2 parents f95ae88 + 6d1dfd7 commit a1977ab
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 12 deletions.
4 changes: 2 additions & 2 deletions fs/nova/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ static int nova_inplace_update_dentry(struct super_block *sb,
* already been logged for consistency
*/
int nova_remove_dentry(struct dentry *dentry, int dec_link,
struct nova_inode_update *update, u64 epoch_id)
struct nova_inode_update *update, u64 epoch_id, bool rename)
{
struct inode *dir = dentry->d_parent->d_inode;
struct super_block *sb = dir->i_sb;
Expand Down Expand Up @@ -415,7 +415,7 @@ int nova_remove_dentry(struct dentry *dentry, int dec_link,

dir->i_mtime = dir->i_ctime = current_time(dir);

if (nova_can_inplace_update_dentry(sb, old_dentry, epoch_id)) {
if (!rename && nova_can_inplace_update_dentry(sb, old_dentry, epoch_id)) {
nova_inplace_update_dentry(sb, dir, old_dentry,
dec_link, epoch_id);
curr_entry = nova_get_addr_off(sbi, old_dentry);
Expand Down
12 changes: 10 additions & 2 deletions fs/nova/journal.c
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,8 @@ static u64 nova_append_dentry_journal(struct super_block *sb,
{
curr_p = nova_append_entry_journal(sb, curr_p, &dentry->ino);
curr_p = nova_append_entry_journal(sb, curr_p, &dentry->csum);
curr_p = nova_append_entry_journal(sb, curr_p, &dentry->reassigned);
curr_p = nova_append_entry_journal(sb, curr_p, &dentry->invalid);
return curr_p;
}

Expand Down Expand Up @@ -341,8 +343,8 @@ u64 nova_create_inode_transaction(struct super_block *sb,
/* Journaled transactions for rename operations */
u64 nova_create_rename_transaction(struct super_block *sb,
struct inode *old_inode, struct inode *old_dir, struct inode *new_inode,
struct inode *new_dir, struct nova_dentry *father_entry,
int invalidate_new_inode, int cpu)
struct inode *new_dir, struct nova_dentry *father_entry, struct nova_dentry *new_dentry,
struct nova_dentry *old_dentry, int invalidate_new_inode, int cpu)
{
struct journal_ptr_pair *pair;
u64 temp;
Expand Down Expand Up @@ -372,6 +374,12 @@ u64 nova_create_rename_transaction(struct super_block *sb,
if (father_entry)
temp = nova_append_dentry_journal(sb, temp, father_entry);

if (new_dentry)
temp = nova_append_dentry_journal(sb, temp, new_dentry);

if (old_dentry)
temp = nova_append_dentry_journal(sb, temp, old_dentry);

nova_flush_journal_in_batch(sb, pair->journal_head, temp);
pair->journal_tail = temp;
nova_flush_buffer(&pair->journal_head, CACHELINE_SIZE, 1);
Expand Down
4 changes: 2 additions & 2 deletions fs/nova/journal.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ u64 nova_create_inode_transaction(struct super_block *sb,
int new_inode, int invalidate);
u64 nova_create_rename_transaction(struct super_block *sb,
struct inode *old_inode, struct inode *old_dir, struct inode *new_inode,
struct inode *new_dir, struct nova_dentry *father_entry,
int invalidate_new_inode, int cpu);
struct inode *new_dir, struct nova_dentry *father_entry, struct nova_dentry *new_dentry,
struct nova_dentry *old_dentry, int invalidate_new_inode, int cpu);
u64 nova_create_logentry_transaction(struct super_block *sb,
void *entry, enum nova_entry_type type, int cpu);
void nova_commit_lite_transaction(struct super_block *sb, u64 tail, int cpu);
Expand Down
14 changes: 9 additions & 5 deletions fs/nova/namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ static int nova_unlink(struct inode *dir, struct dentry *dentry)

update_dir.tail = 0;
update_dir.alter_tail = 0;
retval = nova_remove_dentry(dentry, 0, &update_dir, epoch_id);
retval = nova_remove_dentry(dentry, 0, &update_dir, epoch_id, false);
if (retval)
goto out;

Expand Down Expand Up @@ -616,7 +616,7 @@ static int nova_rmdir(struct inode *dir, struct dentry *dentry)

update_dir.tail = 0;
update_dir.alter_tail = 0;
err = nova_remove_dentry(dentry, -1, &update_dir, epoch_id);
err = nova_remove_dentry(dentry, -1, &update_dir, epoch_id, false);
if (err)
goto end_rmdir;

Expand Down Expand Up @@ -765,7 +765,7 @@ static int nova_rename(struct inode *old_dir,
if (new_inode) {
/* First remove the old entry in the new directory */
err = nova_remove_dentry(new_dentry, 0, &update_dir_new,
epoch_id);
epoch_id, true);
if (err)
goto out;
}
Expand All @@ -787,7 +787,7 @@ static int nova_rename(struct inode *old_dir,
}

err = nova_remove_dentry(old_dentry, dec_link, &update_dir_old,
epoch_id);
epoch_id, true);
if (err)
goto out;

Expand Down Expand Up @@ -823,9 +823,13 @@ static int nova_rename(struct inode *old_dir,
new_inode,
old_dir != new_dir ? new_dir : NULL,
father_entry,
new_inode ? update_dir_new.create_dentry : NULL,
update_dir_old.create_dentry,
invalidate_new_inode,
cpu);

if (new_inode)
nova_reassign_logentry(sb, update_dir_new.create_dentry, DIR_LOG);
nova_reassign_logentry(sb, update_dir_old.create_dentry, DIR_LOG);
nova_update_inode(sb, old_inode, old_pi, &update_old, 0);
nova_update_inode(sb, old_dir, old_pidir, &update_dir_old, 0);

Expand Down
2 changes: 1 addition & 1 deletion fs/nova/nova.h
Original file line number Diff line number Diff line change
Expand Up @@ -1021,7 +1021,7 @@ int nova_append_dir_init_entries(struct super_block *sb,
int nova_add_dentry(struct dentry *dentry, u64 ino, int inc_link,
struct nova_inode_update *update, u64 epoch_id);
int nova_remove_dentry(struct dentry *dentry, int dec_link,
struct nova_inode_update *update, u64 epoch_id);
struct nova_inode_update *update, u64 epoch_id, bool rename);
int nova_invalidate_dentries(struct super_block *sb,
struct nova_inode_update *update);
void nova_print_dir_tree(struct super_block *sb,
Expand Down

0 comments on commit a1977ab

Please sign in to comment.