aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jffs2/readinode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/jffs2/readinode.c')
-rw-r--r--fs/jffs2/readinode.c45
1 files changed, 20 insertions, 25 deletions
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c
index cf39bcf3e3cf..49da1a6cfc81 100644
--- a/fs/jffs2/readinode.c
+++ b/fs/jffs2/readinode.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: readinode.c,v 1.126 2005/07/17 06:56:21 dedekind Exp $ 10 * $Id: readinode.c,v 1.127 2005/07/17 11:13:46 dedekind Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -547,11 +547,10 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
547 547
548 if (f->inocache->state != INO_STATE_CHECKING) { 548 if (f->inocache->state != INO_STATE_CHECKING) {
549 /* Symlink's inode data is the target path. Read it and 549 /* Symlink's inode data is the target path. Read it and
550 * keep in RAM to facilitate quick follow symlink operation. 550 * keep in RAM to facilitate quick follow symlink
551 * We use f->dents field to store the target path, which 551 * operation. */
552 * is somewhat ugly. */ 552 f->target = kmalloc(je32_to_cpu(latest_node->csize) + 1, GFP_KERNEL);
553 f->dents = kmalloc(je32_to_cpu(latest_node->csize) + 1, GFP_KERNEL); 553 if (!f->target) {
554 if (!f->dents) {
555 printk(KERN_WARNING "Can't allocate %d bytes of memory " 554 printk(KERN_WARNING "Can't allocate %d bytes of memory "
556 "for the symlink target path cache\n", 555 "for the symlink target path cache\n",
557 je32_to_cpu(latest_node->csize)); 556 je32_to_cpu(latest_node->csize));
@@ -561,21 +560,21 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
561 } 560 }
562 561
563 ret = jffs2_flash_read(c, ref_offset(fn->raw) + sizeof(*latest_node), 562 ret = jffs2_flash_read(c, ref_offset(fn->raw) + sizeof(*latest_node),
564 je32_to_cpu(latest_node->csize), &retlen, (char *)f->dents); 563 je32_to_cpu(latest_node->csize), &retlen, (char *)f->target);
565 564
566 if (ret || retlen != je32_to_cpu(latest_node->csize)) { 565 if (ret || retlen != je32_to_cpu(latest_node->csize)) {
567 if (retlen != je32_to_cpu(latest_node->csize)) 566 if (retlen != je32_to_cpu(latest_node->csize))
568 ret = -EIO; 567 ret = -EIO;
569 kfree(f->dents); 568 kfree(f->target);
570 f->dents = NULL; 569 f->target = NULL;
571 up(&f->sem); 570 up(&f->sem);
572 jffs2_do_clear_inode(c, f); 571 jffs2_do_clear_inode(c, f);
573 return -ret; 572 return -ret;
574 } 573 }
575 574
576 ((char *)f->dents)[je32_to_cpu(latest_node->csize)] = '\0'; 575 f->target[je32_to_cpu(latest_node->csize)] = '\0';
577 D1(printk(KERN_DEBUG "jffs2_do_read_inode(): symlink's target '%s' cached\n", 576 D1(printk(KERN_DEBUG "jffs2_do_read_inode(): symlink's target '%s' cached\n",
578 (char *)f->dents)); 577 f->target));
579 } 578 }
580 579
581 /* fall through... */ 580 /* fall through... */
@@ -638,20 +637,16 @@ void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f)
638 637
639 jffs2_kill_fragtree(&f->fragtree, deleted?c:NULL); 638 jffs2_kill_fragtree(&f->fragtree, deleted?c:NULL);
640 639
641 /* For symlink inodes we us f->dents to store the target path name */ 640 if (f->target) {
642 if (S_ISLNK(OFNI_EDONI_2SFFJ(f)->i_mode)) { 641 kfree(f->target);
643 if (f->dents) { 642 f->target = NULL;
644 kfree(f->dents); 643 }
645 f->dents = NULL; 644
646 } 645 fds = f->dents;
647 } else { 646 while(fds) {
648 fds = f->dents; 647 fd = fds;
649 648 fds = fd->next;
650 while(fds) { 649 jffs2_free_full_dirent(fd);
651 fd = fds;
652 fds = fd->next;
653 jffs2_free_full_dirent(fd);
654 }
655 } 650 }
656 651
657 if (f->inocache && f->inocache->state != INO_STATE_CHECKING) { 652 if (f->inocache && f->inocache->state != INO_STATE_CHECKING) {