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.c84
1 files changed, 42 insertions, 42 deletions
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c
index 08f8c5ec6118..5f0652df5d47 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.142 2005/09/20 14:27:34 dedekind Exp $ 10 * $Id: readinode.c,v 1.143 2005/11/07 11:14:41 gleixner Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -116,19 +116,19 @@ static inline int read_direntry(struct jffs2_sb_info *c, struct jffs2_raw_node_r
116 uint32_t *latest_mctime, uint32_t *mctime_ver) 116 uint32_t *latest_mctime, uint32_t *mctime_ver)
117{ 117{
118 struct jffs2_full_dirent *fd; 118 struct jffs2_full_dirent *fd;
119 119
120 /* The direntry nodes are checked during the flash scanning */ 120 /* The direntry nodes are checked during the flash scanning */
121 BUG_ON(ref_flags(ref) == REF_UNCHECKED); 121 BUG_ON(ref_flags(ref) == REF_UNCHECKED);
122 /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */ 122 /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */
123 BUG_ON(ref_obsolete(ref)); 123 BUG_ON(ref_obsolete(ref));
124 124
125 /* Sanity check */ 125 /* Sanity check */
126 if (unlikely(PAD((rd->nsize + sizeof(*rd))) != PAD(je32_to_cpu(rd->totlen)))) { 126 if (unlikely(PAD((rd->nsize + sizeof(*rd))) != PAD(je32_to_cpu(rd->totlen)))) {
127 JFFS2_ERROR("illegal nsize in node at %#08x: nsize %#02x, totlen %#04x\n", 127 JFFS2_ERROR("illegal nsize in node at %#08x: nsize %#02x, totlen %#04x\n",
128 ref_offset(ref), rd->nsize, je32_to_cpu(rd->totlen)); 128 ref_offset(ref), rd->nsize, je32_to_cpu(rd->totlen));
129 return 1; 129 return 1;
130 } 130 }
131 131
132 fd = jffs2_alloc_full_dirent(rd->nsize + 1); 132 fd = jffs2_alloc_full_dirent(rd->nsize + 1);
133 if (unlikely(!fd)) 133 if (unlikely(!fd))
134 return -ENOMEM; 134 return -ENOMEM;
@@ -144,39 +144,39 @@ static inline int read_direntry(struct jffs2_sb_info *c, struct jffs2_raw_node_r
144 *latest_mctime = je32_to_cpu(rd->mctime); 144 *latest_mctime = je32_to_cpu(rd->mctime);
145 } 145 }
146 146
147 /* 147 /*
148 * Copy as much of the name as possible from the raw 148 * Copy as much of the name as possible from the raw
149 * dirent we've already read from the flash. 149 * dirent we've already read from the flash.
150 */ 150 */
151 if (read > sizeof(*rd)) 151 if (read > sizeof(*rd))
152 memcpy(&fd->name[0], &rd->name[0], 152 memcpy(&fd->name[0], &rd->name[0],
153 min_t(uint32_t, rd->nsize, (read - sizeof(*rd)) )); 153 min_t(uint32_t, rd->nsize, (read - sizeof(*rd)) ));
154 154
155 /* Do we need to copy any more of the name directly from the flash? */ 155 /* Do we need to copy any more of the name directly from the flash? */
156 if (rd->nsize + sizeof(*rd) > read) { 156 if (rd->nsize + sizeof(*rd) > read) {
157 /* FIXME: point() */ 157 /* FIXME: point() */
158 int err; 158 int err;
159 int already = read - sizeof(*rd); 159 int already = read - sizeof(*rd);
160 160
161 err = jffs2_flash_read(c, (ref_offset(ref)) + read, 161 err = jffs2_flash_read(c, (ref_offset(ref)) + read,
162 rd->nsize - already, &read, &fd->name[already]); 162 rd->nsize - already, &read, &fd->name[already]);
163 if (unlikely(read != rd->nsize - already) && likely(!err)) 163 if (unlikely(read != rd->nsize - already) && likely(!err))
164 return -EIO; 164 return -EIO;
165 165
166 if (unlikely(err)) { 166 if (unlikely(err)) {
167 JFFS2_ERROR("read remainder of name: error %d\n", err); 167 JFFS2_ERROR("read remainder of name: error %d\n", err);
168 jffs2_free_full_dirent(fd); 168 jffs2_free_full_dirent(fd);
169 return -EIO; 169 return -EIO;
170 } 170 }
171 } 171 }
172 172
173 fd->nhash = full_name_hash(fd->name, rd->nsize); 173 fd->nhash = full_name_hash(fd->name, rd->nsize);
174 fd->next = NULL; 174 fd->next = NULL;
175 fd->name[rd->nsize] = '\0'; 175 fd->name[rd->nsize] = '\0';
176 176
177 /* 177 /*
178 * Wheee. We now have a complete jffs2_full_dirent structure, with 178 * Wheee. We now have a complete jffs2_full_dirent structure, with
179 * the name in it and everything. Link it into the list 179 * the name in it and everything. Link it into the list
180 */ 180 */
181 jffs2_add_fd_to_list(c, fd, fdp); 181 jffs2_add_fd_to_list(c, fd, fdp);
182 182
@@ -198,7 +198,7 @@ static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
198 struct jffs2_tmp_dnode_info *tn; 198 struct jffs2_tmp_dnode_info *tn;
199 uint32_t len, csize; 199 uint32_t len, csize;
200 int ret = 1; 200 int ret = 1;
201 201
202 /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */ 202 /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */
203 BUG_ON(ref_obsolete(ref)); 203 BUG_ON(ref_obsolete(ref));
204 204
@@ -210,7 +210,7 @@ static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
210 210
211 tn->partial_crc = 0; 211 tn->partial_crc = 0;
212 csize = je32_to_cpu(rd->csize); 212 csize = je32_to_cpu(rd->csize);
213 213
214 /* If we've never checked the CRCs on this node, check them now */ 214 /* If we've never checked the CRCs on this node, check them now */
215 if (ref_flags(ref) == REF_UNCHECKED) { 215 if (ref_flags(ref) == REF_UNCHECKED) {
216 uint32_t crc; 216 uint32_t crc;
@@ -221,7 +221,7 @@ static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
221 ref_offset(ref), je32_to_cpu(rd->node_crc), crc); 221 ref_offset(ref), je32_to_cpu(rd->node_crc), crc);
222 goto free_out; 222 goto free_out;
223 } 223 }
224 224
225 /* Sanity checks */ 225 /* Sanity checks */
226 if (unlikely(je32_to_cpu(rd->offset) > je32_to_cpu(rd->isize)) || 226 if (unlikely(je32_to_cpu(rd->offset) > je32_to_cpu(rd->isize)) ||
227 unlikely(PAD(je32_to_cpu(rd->csize) + sizeof(*rd)) != PAD(je32_to_cpu(rd->totlen)))) { 227 unlikely(PAD(je32_to_cpu(rd->csize) + sizeof(*rd)) != PAD(je32_to_cpu(rd->totlen)))) {
@@ -313,13 +313,13 @@ static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
313 ret = -ENOMEM; 313 ret = -ENOMEM;
314 goto free_out; 314 goto free_out;
315 } 315 }
316 316
317 tn->version = je32_to_cpu(rd->version); 317 tn->version = je32_to_cpu(rd->version);
318 tn->fn->ofs = je32_to_cpu(rd->offset); 318 tn->fn->ofs = je32_to_cpu(rd->offset);
319 tn->data_crc = je32_to_cpu(rd->data_crc); 319 tn->data_crc = je32_to_cpu(rd->data_crc);
320 tn->csize = csize; 320 tn->csize = csize;
321 tn->fn->raw = ref; 321 tn->fn->raw = ref;
322 322
323 /* There was a bug where we wrote hole nodes out with 323 /* There was a bug where we wrote hole nodes out with
324 csize/dsize swapped. Deal with it */ 324 csize/dsize swapped. Deal with it */
325 if (rd->compr == JFFS2_COMPR_ZERO && !je32_to_cpu(rd->dsize) && csize) 325 if (rd->compr == JFFS2_COMPR_ZERO && !je32_to_cpu(rd->dsize) && csize)
@@ -329,7 +329,7 @@ static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
329 329
330 dbg_readinode("dnode @%08x: ver %u, offset %#04x, dsize %#04x, csize %#04x\n", 330 dbg_readinode("dnode @%08x: ver %u, offset %#04x, dsize %#04x, csize %#04x\n",
331 ref_offset(ref), je32_to_cpu(rd->version), je32_to_cpu(rd->offset), je32_to_cpu(rd->dsize), csize); 331 ref_offset(ref), je32_to_cpu(rd->version), je32_to_cpu(rd->offset), je32_to_cpu(rd->dsize), csize);
332 332
333 jffs2_add_tn_to_tree(tn, tnp); 333 jffs2_add_tn_to_tree(tn, tnp);
334 334
335 return 0; 335 return 0;
@@ -351,7 +351,7 @@ static inline int read_unknown(struct jffs2_sb_info *c, struct jffs2_raw_node_re
351{ 351{
352 /* We don't mark unknown nodes as REF_UNCHECKED */ 352 /* We don't mark unknown nodes as REF_UNCHECKED */
353 BUG_ON(ref_flags(ref) == REF_UNCHECKED); 353 BUG_ON(ref_flags(ref) == REF_UNCHECKED);
354 354
355 un->nodetype = cpu_to_je16(JFFS2_NODE_ACCURATE | je16_to_cpu(un->nodetype)); 355 un->nodetype = cpu_to_je16(JFFS2_NODE_ACCURATE | je16_to_cpu(un->nodetype));
356 356
357 if (crc32(0, un, sizeof(struct jffs2_unknown_node) - 4) != je32_to_cpu(un->hdr_crc)) { 357 if (crc32(0, un, sizeof(struct jffs2_unknown_node) - 4) != je32_to_cpu(un->hdr_crc)) {
@@ -423,7 +423,7 @@ static int read_more(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref,
423 bufstart = buf + *rdlen; 423 bufstart = buf + *rdlen;
424 len = right_size - *rdlen; 424 len = right_size - *rdlen;
425 } 425 }
426 426
427 dbg_readinode("read more %d bytes\n", len); 427 dbg_readinode("read more %d bytes\n", len);
428 428
429 err = jffs2_flash_read(c, offs, len, &retlen, bufstart); 429 err = jffs2_flash_read(c, offs, len, &retlen, bufstart);
@@ -432,7 +432,7 @@ static int read_more(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref,
432 "error code: %d.\n", len, offs, err); 432 "error code: %d.\n", len, offs, err);
433 return err; 433 return err;
434 } 434 }
435 435
436 if (retlen < len) { 436 if (retlen < len) {
437 JFFS2_ERROR("short read at %#08x: %d instead of %d.\n", 437 JFFS2_ERROR("short read at %#08x: %d instead of %d.\n",
438 offs, retlen, len); 438 offs, retlen, len);
@@ -460,7 +460,7 @@ static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_inf
460 int len, err; 460 int len, err;
461 461
462 *mctime_ver = 0; 462 *mctime_ver = 0;
463 463
464 dbg_readinode("ino #%u\n", f->inocache->ino); 464 dbg_readinode("ino #%u\n", f->inocache->ino);
465 465
466 if (jffs2_is_writebuffered(c)) { 466 if (jffs2_is_writebuffered(c)) {
@@ -487,7 +487,7 @@ static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_inf
487 buf = kmalloc(len, GFP_KERNEL); 487 buf = kmalloc(len, GFP_KERNEL);
488 if (!buf) 488 if (!buf)
489 return -ENOMEM; 489 return -ENOMEM;
490 490
491 spin_lock(&c->erase_completion_lock); 491 spin_lock(&c->erase_completion_lock);
492 valid_ref = jffs2_first_valid_node(f->inocache->nodes); 492 valid_ref = jffs2_first_valid_node(f->inocache->nodes);
493 if (!valid_ref && f->inocache->ino != 1) 493 if (!valid_ref && f->inocache->ino != 1)
@@ -514,7 +514,7 @@ static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_inf
514 * size = JFFS2_MIN_NODE_HEADER. 514 * size = JFFS2_MIN_NODE_HEADER.
515 */ 515 */
516 if (jffs2_is_writebuffered(c)) { 516 if (jffs2_is_writebuffered(c)) {
517 /* 517 /*
518 * We treat 'buf' as 2 adjacent wbufs. We want to 518 * We treat 'buf' as 2 adjacent wbufs. We want to
519 * adjust bufstart such as it points to the 519 * adjust bufstart such as it points to the
520 * beginning of the node within this wbuf. 520 * beginning of the node within this wbuf.
@@ -540,17 +540,17 @@ static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_inf
540 JFFS2_ERROR("can not read %d bytes from 0x%08x, " "error code: %d.\n", len, ref_offset(ref), err); 540 JFFS2_ERROR("can not read %d bytes from 0x%08x, " "error code: %d.\n", len, ref_offset(ref), err);
541 goto free_out; 541 goto free_out;
542 } 542 }
543 543
544 if (retlen < len) { 544 if (retlen < len) {
545 JFFS2_ERROR("short read at %#08x: %d instead of %d.\n", ref_offset(ref), retlen, len); 545 JFFS2_ERROR("short read at %#08x: %d instead of %d.\n", ref_offset(ref), retlen, len);
546 err = -EIO; 546 err = -EIO;
547 goto free_out; 547 goto free_out;
548 } 548 }
549 549
550 node = (union jffs2_node_union *)bufstart; 550 node = (union jffs2_node_union *)bufstart;
551 551
552 switch (je16_to_cpu(node->u.nodetype)) { 552 switch (je16_to_cpu(node->u.nodetype)) {
553 553
554 case JFFS2_NODETYPE_DIRENT: 554 case JFFS2_NODETYPE_DIRENT:
555 555
556 if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_raw_dirent)) { 556 if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_raw_dirent)) {
@@ -558,21 +558,21 @@ static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_inf
558 if (unlikely(err)) 558 if (unlikely(err))
559 goto free_out; 559 goto free_out;
560 } 560 }
561 561
562 err = read_direntry(c, ref, &node->d, retlen, &ret_fd, latest_mctime, mctime_ver); 562 err = read_direntry(c, ref, &node->d, retlen, &ret_fd, latest_mctime, mctime_ver);
563 if (err == 1) { 563 if (err == 1) {
564 jffs2_mark_node_obsolete(c, ref); 564 jffs2_mark_node_obsolete(c, ref);
565 break; 565 break;
566 } else if (unlikely(err)) 566 } else if (unlikely(err))
567 goto free_out; 567 goto free_out;
568 568
569 if (je32_to_cpu(node->d.version) > *highest_version) 569 if (je32_to_cpu(node->d.version) > *highest_version)
570 *highest_version = je32_to_cpu(node->d.version); 570 *highest_version = je32_to_cpu(node->d.version);
571 571
572 break; 572 break;
573 573
574 case JFFS2_NODETYPE_INODE: 574 case JFFS2_NODETYPE_INODE:
575 575
576 if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_raw_inode)) { 576 if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_raw_inode)) {
577 err = read_more(c, ref, sizeof(struct jffs2_raw_inode), &len, buf, bufstart); 577 err = read_more(c, ref, sizeof(struct jffs2_raw_inode), &len, buf, bufstart);
578 if (unlikely(err)) 578 if (unlikely(err))
@@ -588,7 +588,7 @@ static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_inf
588 588
589 if (je32_to_cpu(node->i.version) > *highest_version) 589 if (je32_to_cpu(node->i.version) > *highest_version)
590 *highest_version = je32_to_cpu(node->i.version); 590 *highest_version = je32_to_cpu(node->i.version);
591 591
592 break; 592 break;
593 593
594 default: 594 default:
@@ -597,7 +597,7 @@ static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_inf
597 if (unlikely(err)) 597 if (unlikely(err))
598 goto free_out; 598 goto free_out;
599 } 599 }
600 600
601 err = read_unknown(c, ref, &node->u); 601 err = read_unknown(c, ref, &node->u);
602 if (err == 1) { 602 if (err == 1) {
603 jffs2_mark_node_obsolete(c, ref); 603 jffs2_mark_node_obsolete(c, ref);
@@ -625,7 +625,7 @@ static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_inf
625 return err; 625 return err;
626} 626}
627 627
628static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c, 628static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
629 struct jffs2_inode_info *f, 629 struct jffs2_inode_info *f,
630 struct jffs2_raw_inode *latest_node) 630 struct jffs2_raw_inode *latest_node)
631{ 631{
@@ -677,7 +677,7 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
677 ret = 0; /* Prevent freeing the metadata update node */ 677 ret = 0; /* Prevent freeing the metadata update node */
678 } else 678 } else
679 jffs2_mark_node_obsolete(c, fn->raw); 679 jffs2_mark_node_obsolete(c, fn->raw);
680 680
681 BUG_ON(rb->rb_left); 681 BUG_ON(rb->rb_left);
682 if (rb->rb_parent && rb->rb_parent->rb_left == rb) { 682 if (rb->rb_parent && rb->rb_parent->rb_left == rb) {
683 /* We were then left-hand child of our parent. We need 683 /* We were then left-hand child of our parent. We need
@@ -763,7 +763,7 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
763 } 763 }
764 break; 764 break;
765 765
766 766
767 case S_IFREG: 767 case S_IFREG:
768 /* If it was a regular file, truncate it to the latest node's isize */ 768 /* If it was a regular file, truncate it to the latest node's isize */
769 jffs2_truncate_fragtree(c, &f->fragtree, je32_to_cpu(latest_node->isize)); 769 jffs2_truncate_fragtree(c, &f->fragtree, je32_to_cpu(latest_node->isize));
@@ -788,10 +788,10 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
788 jffs2_do_clear_inode(c, f); 788 jffs2_do_clear_inode(c, f);
789 return -ENOMEM; 789 return -ENOMEM;
790 } 790 }
791 791
792 ret = jffs2_flash_read(c, ref_offset(fn->raw) + sizeof(*latest_node), 792 ret = jffs2_flash_read(c, ref_offset(fn->raw) + sizeof(*latest_node),
793 je32_to_cpu(latest_node->csize), &retlen, (char *)f->target); 793 je32_to_cpu(latest_node->csize), &retlen, (char *)f->target);
794 794
795 if (ret || retlen != je32_to_cpu(latest_node->csize)) { 795 if (ret || retlen != je32_to_cpu(latest_node->csize)) {
796 if (retlen != je32_to_cpu(latest_node->csize)) 796 if (retlen != je32_to_cpu(latest_node->csize))
797 ret = -EIO; 797 ret = -EIO;
@@ -805,7 +805,7 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
805 f->target[je32_to_cpu(latest_node->csize)] = '\0'; 805 f->target[je32_to_cpu(latest_node->csize)] = '\0';
806 dbg_readinode("symlink's target '%s' cached\n", f->target); 806 dbg_readinode("symlink's target '%s' cached\n", f->target);
807 } 807 }
808 808
809 /* fall through... */ 809 /* fall through... */
810 810
811 case S_IFBLK: 811 case S_IFBLK:
@@ -848,7 +848,7 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
848} 848}
849 849
850/* Scan the list of all nodes present for this ino, build map of versions, etc. */ 850/* Scan the list of all nodes present for this ino, build map of versions, etc. */
851int jffs2_do_read_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, 851int jffs2_do_read_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
852 uint32_t ino, struct jffs2_raw_inode *latest_node) 852 uint32_t ino, struct jffs2_raw_inode *latest_node)
853{ 853{
854 dbg_readinode("read inode #%u\n", ino); 854 dbg_readinode("read inode #%u\n", ino);
@@ -864,7 +864,7 @@ int jffs2_do_read_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
864 case INO_STATE_CHECKEDABSENT: 864 case INO_STATE_CHECKEDABSENT:
865 f->inocache->state = INO_STATE_READING; 865 f->inocache->state = INO_STATE_READING;
866 break; 866 break;
867 867
868 case INO_STATE_CHECKING: 868 case INO_STATE_CHECKING:
869 case INO_STATE_GC: 869 case INO_STATE_GC:
870 /* If it's in either of these states, we need 870 /* If it's in either of these states, we need
@@ -957,7 +957,7 @@ void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f)
957 kfree(f->target); 957 kfree(f->target);
958 f->target = NULL; 958 f->target = NULL;
959 } 959 }
960 960
961 fds = f->dents; 961 fds = f->dents;
962 while(fds) { 962 while(fds) {
963 fd = fds; 963 fd = fds;