aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jffs2/write.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/jffs2/write.c')
-rw-r--r--fs/jffs2/write.c27
1 files changed, 15 insertions, 12 deletions
diff --git a/fs/jffs2/write.c b/fs/jffs2/write.c
index 147e2cbee9e4..611012f7c8ae 100644
--- a/fs/jffs2/write.c
+++ b/fs/jffs2/write.c
@@ -582,7 +582,7 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,
582 jffs2_add_fd_to_list(c, fd, &dir_f->dents); 582 jffs2_add_fd_to_list(c, fd, &dir_f->dents);
583 up(&dir_f->sem); 583 up(&dir_f->sem);
584 } else { 584 } else {
585 struct jffs2_full_dirent **prev = &dir_f->dents; 585 struct jffs2_full_dirent *fd = dir_f->dents;
586 uint32_t nhash = full_name_hash(name, namelen); 586 uint32_t nhash = full_name_hash(name, namelen);
587 587
588 /* We don't actually want to reserve any space, but we do 588 /* We don't actually want to reserve any space, but we do
@@ -590,18 +590,20 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,
590 down(&c->alloc_sem); 590 down(&c->alloc_sem);
591 down(&dir_f->sem); 591 down(&dir_f->sem);
592 592
593 while ((*prev) && (*prev)->nhash <= nhash) { 593 for (fd = dir_f->dents; fd; fd = fd->next) {
594 if ((*prev)->nhash == nhash && 594 if (fd->nhash == nhash &&
595 !memcmp((*prev)->name, name, namelen) && 595 !memcmp(fd->name, name, namelen) &&
596 !(*prev)->name[namelen]) { 596 !fd->name[namelen]) {
597 struct jffs2_full_dirent *this = *prev;
598 597
599 D1(printk(KERN_DEBUG "Marking old dirent node (ino #%u) @%08x obsolete\n", 598 D1(printk(KERN_DEBUG "Marking old dirent node (ino #%u) @%08x obsolete\n",
600 this->ino, ref_offset(this->raw))); 599 fd->ino, ref_offset(fd->raw)));
601 600 jffs2_mark_node_obsolete(c, fd->raw);
602 *prev = this->next; 601 /* We don't want to remove it from the list immediately,
603 jffs2_mark_node_obsolete(c, (this->raw)); 602 because that screws up getdents()/seek() semantics even
604 jffs2_free_full_dirent(this); 603 more than they're screwed already. Turn it into a
604 node-less deletion dirent instead -- a placeholder */
605 fd->raw = NULL;
606 fd->ino = 0;
605 break; 607 break;
606 } 608 }
607 prev = &((*prev)->next); 609 prev = &((*prev)->next);
@@ -630,7 +632,8 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,
630 D1(printk(KERN_DEBUG "Removing deletion dirent for \"%s\" from dir ino #%u\n", 632 D1(printk(KERN_DEBUG "Removing deletion dirent for \"%s\" from dir ino #%u\n",
631 fd->name, dead_f->inocache->ino)); 633 fd->name, dead_f->inocache->ino));
632 } 634 }
633 jffs2_mark_node_obsolete(c, fd->raw); 635 if (fd->raw)
636 jffs2_mark_node_obsolete(c, fd->raw);
634 jffs2_free_full_dirent(fd); 637 jffs2_free_full_dirent(fd);
635 } 638 }
636 } 639 }