diff options
author | Lachlan McIlroy <lachlan@redback.melbourne.sgi.com> | 2008-02-17 21:51:42 -0500 |
---|---|---|
committer | Lachlan McIlroy <lachlan@redback.melbourne.sgi.com> | 2008-02-17 21:51:42 -0500 |
commit | c58310bf4933986513020fa90b4190c7492995ae (patch) | |
tree | 143f2c7578d02ebef5db8fc57ae69e951ae0e2ee /fs/jffs2/write.c | |
parent | 269cdfaf769f5cd831284cc831790c7c5038040f (diff) | |
parent | 1309d4e68497184d2fd87e892ddf14076c2bda98 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6 into for-linus
Diffstat (limited to 'fs/jffs2/write.c')
-rw-r--r-- | fs/jffs2/write.c | 32 |
1 files changed, 17 insertions, 15 deletions
diff --git a/fs/jffs2/write.c b/fs/jffs2/write.c index 147e2cbee9e4..776f13cbf2b5 100644 --- a/fs/jffs2/write.c +++ b/fs/jffs2/write.c | |||
@@ -177,7 +177,7 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2 | |||
177 | void *hold_err = fn->raw; | 177 | void *hold_err = fn->raw; |
178 | /* Release the full_dnode which is now useless, and return */ | 178 | /* Release the full_dnode which is now useless, and return */ |
179 | jffs2_free_full_dnode(fn); | 179 | jffs2_free_full_dnode(fn); |
180 | return ERR_PTR(PTR_ERR(hold_err)); | 180 | return ERR_CAST(hold_err); |
181 | } | 181 | } |
182 | fn->ofs = je32_to_cpu(ri->offset); | 182 | fn->ofs = je32_to_cpu(ri->offset); |
183 | fn->size = je32_to_cpu(ri->dsize); | 183 | fn->size = je32_to_cpu(ri->dsize); |
@@ -313,7 +313,7 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff | |||
313 | void *hold_err = fd->raw; | 313 | void *hold_err = fd->raw; |
314 | /* Release the full_dirent which is now useless, and return */ | 314 | /* Release the full_dirent which is now useless, and return */ |
315 | jffs2_free_full_dirent(fd); | 315 | jffs2_free_full_dirent(fd); |
316 | return ERR_PTR(PTR_ERR(hold_err)); | 316 | return ERR_CAST(hold_err); |
317 | } | 317 | } |
318 | 318 | ||
319 | if (retried) { | 319 | if (retried) { |
@@ -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,21 +590,22 @@ 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); | ||
608 | } | 609 | } |
609 | up(&dir_f->sem); | 610 | up(&dir_f->sem); |
610 | } | 611 | } |
@@ -630,7 +631,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", | 631 | D1(printk(KERN_DEBUG "Removing deletion dirent for \"%s\" from dir ino #%u\n", |
631 | fd->name, dead_f->inocache->ino)); | 632 | fd->name, dead_f->inocache->ino)); |
632 | } | 633 | } |
633 | jffs2_mark_node_obsolete(c, fd->raw); | 634 | if (fd->raw) |
635 | jffs2_mark_node_obsolete(c, fd->raw); | ||
634 | jffs2_free_full_dirent(fd); | 636 | jffs2_free_full_dirent(fd); |
635 | } | 637 | } |
636 | } | 638 | } |