Skip to content

Commit a1977ab

Browse files
authored
Merge pull request #135 from hayley-leblanc/issue_116
Make rename atomic with respect to crashes
2 parents f95ae88 + 6d1dfd7 commit a1977ab

5 files changed

Lines changed: 24 additions & 12 deletions

File tree

fs/nova/dir.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ static int nova_inplace_update_dentry(struct super_block *sb,
380380
* already been logged for consistency
381381
*/
382382
int nova_remove_dentry(struct dentry *dentry, int dec_link,
383-
struct nova_inode_update *update, u64 epoch_id)
383+
struct nova_inode_update *update, u64 epoch_id, bool rename)
384384
{
385385
struct inode *dir = dentry->d_parent->d_inode;
386386
struct super_block *sb = dir->i_sb;
@@ -415,7 +415,7 @@ int nova_remove_dentry(struct dentry *dentry, int dec_link,
415415

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

418-
if (nova_can_inplace_update_dentry(sb, old_dentry, epoch_id)) {
418+
if (!rename && nova_can_inplace_update_dentry(sb, old_dentry, epoch_id)) {
419419
nova_inplace_update_dentry(sb, dir, old_dentry,
420420
dec_link, epoch_id);
421421
curr_entry = nova_get_addr_off(sbi, old_dentry);

fs/nova/journal.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,8 @@ static u64 nova_append_dentry_journal(struct super_block *sb,
281281
{
282282
curr_p = nova_append_entry_journal(sb, curr_p, &dentry->ino);
283283
curr_p = nova_append_entry_journal(sb, curr_p, &dentry->csum);
284+
curr_p = nova_append_entry_journal(sb, curr_p, &dentry->reassigned);
285+
curr_p = nova_append_entry_journal(sb, curr_p, &dentry->invalid);
284286
return curr_p;
285287
}
286288

@@ -341,8 +343,8 @@ u64 nova_create_inode_transaction(struct super_block *sb,
341343
/* Journaled transactions for rename operations */
342344
u64 nova_create_rename_transaction(struct super_block *sb,
343345
struct inode *old_inode, struct inode *old_dir, struct inode *new_inode,
344-
struct inode *new_dir, struct nova_dentry *father_entry,
345-
int invalidate_new_inode, int cpu)
346+
struct inode *new_dir, struct nova_dentry *father_entry, struct nova_dentry *new_dentry,
347+
struct nova_dentry *old_dentry, int invalidate_new_inode, int cpu)
346348
{
347349
struct journal_ptr_pair *pair;
348350
u64 temp;
@@ -372,6 +374,12 @@ u64 nova_create_rename_transaction(struct super_block *sb,
372374
if (father_entry)
373375
temp = nova_append_dentry_journal(sb, temp, father_entry);
374376

377+
if (new_dentry)
378+
temp = nova_append_dentry_journal(sb, temp, new_dentry);
379+
380+
if (old_dentry)
381+
temp = nova_append_dentry_journal(sb, temp, old_dentry);
382+
375383
nova_flush_journal_in_batch(sb, pair->journal_head, temp);
376384
pair->journal_tail = temp;
377385
nova_flush_buffer(&pair->journal_head, CACHELINE_SIZE, 1);

fs/nova/journal.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ u64 nova_create_inode_transaction(struct super_block *sb,
5050
int new_inode, int invalidate);
5151
u64 nova_create_rename_transaction(struct super_block *sb,
5252
struct inode *old_inode, struct inode *old_dir, struct inode *new_inode,
53-
struct inode *new_dir, struct nova_dentry *father_entry,
54-
int invalidate_new_inode, int cpu);
53+
struct inode *new_dir, struct nova_dentry *father_entry, struct nova_dentry *new_dentry,
54+
struct nova_dentry *old_dentry, int invalidate_new_inode, int cpu);
5555
u64 nova_create_logentry_transaction(struct super_block *sb,
5656
void *entry, enum nova_entry_type type, int cpu);
5757
void nova_commit_lite_transaction(struct super_block *sb, u64 tail, int cpu);

fs/nova/namei.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@ static int nova_unlink(struct inode *dir, struct dentry *dentry)
434434

435435
update_dir.tail = 0;
436436
update_dir.alter_tail = 0;
437-
retval = nova_remove_dentry(dentry, 0, &update_dir, epoch_id);
437+
retval = nova_remove_dentry(dentry, 0, &update_dir, epoch_id, false);
438438
if (retval)
439439
goto out;
440440

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

617617
update_dir.tail = 0;
618618
update_dir.alter_tail = 0;
619-
err = nova_remove_dentry(dentry, -1, &update_dir, epoch_id);
619+
err = nova_remove_dentry(dentry, -1, &update_dir, epoch_id, false);
620620
if (err)
621621
goto end_rmdir;
622622

@@ -765,7 +765,7 @@ static int nova_rename(struct inode *old_dir,
765765
if (new_inode) {
766766
/* First remove the old entry in the new directory */
767767
err = nova_remove_dentry(new_dentry, 0, &update_dir_new,
768-
epoch_id);
768+
epoch_id, true);
769769
if (err)
770770
goto out;
771771
}
@@ -787,7 +787,7 @@ static int nova_rename(struct inode *old_dir,
787787
}
788788

789789
err = nova_remove_dentry(old_dentry, dec_link, &update_dir_old,
790-
epoch_id);
790+
epoch_id, true);
791791
if (err)
792792
goto out;
793793

@@ -823,9 +823,13 @@ static int nova_rename(struct inode *old_dir,
823823
new_inode,
824824
old_dir != new_dir ? new_dir : NULL,
825825
father_entry,
826+
new_inode ? update_dir_new.create_dentry : NULL,
827+
update_dir_old.create_dentry,
826828
invalidate_new_inode,
827829
cpu);
828-
830+
if (new_inode)
831+
nova_reassign_logentry(sb, update_dir_new.create_dentry, DIR_LOG);
832+
nova_reassign_logentry(sb, update_dir_old.create_dentry, DIR_LOG);
829833
nova_update_inode(sb, old_inode, old_pi, &update_old, 0);
830834
nova_update_inode(sb, old_dir, old_pidir, &update_dir_old, 0);
831835

fs/nova/nova.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1021,7 +1021,7 @@ int nova_append_dir_init_entries(struct super_block *sb,
10211021
int nova_add_dentry(struct dentry *dentry, u64 ino, int inc_link,
10221022
struct nova_inode_update *update, u64 epoch_id);
10231023
int nova_remove_dentry(struct dentry *dentry, int dec_link,
1024-
struct nova_inode_update *update, u64 epoch_id);
1024+
struct nova_inode_update *update, u64 epoch_id, bool rename);
10251025
int nova_invalidate_dentries(struct super_block *sb,
10261026
struct nova_inode_update *update);
10271027
void nova_print_dir_tree(struct super_block *sb,

0 commit comments

Comments
 (0)