read.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:5k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * JFFS2 -- Journalling Flash File System, Version 2.
  3.  *
  4.  * Copyright (C) 2001 Red Hat, Inc.
  5.  *
  6.  * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
  7.  *
  8.  * The original JFFS, from which the design for JFFS2 was derived,
  9.  * was designed and implemented by Axis Communications AB.
  10.  *
  11.  * The contents of this file are subject to the Red Hat eCos Public
  12.  * License Version 1.1 (the "Licence"); you may not use this file
  13.  * except in compliance with the Licence.  You may obtain a copy of
  14.  * the Licence at http://www.redhat.com/
  15.  *
  16.  * Software distributed under the Licence is distributed on an "AS IS"
  17.  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
  18.  * See the Licence for the specific language governing rights and
  19.  * limitations under the Licence.
  20.  *
  21.  * The Original Code is JFFS2 - Journalling Flash File System, version 2
  22.  *
  23.  * Alternatively, the contents of this file may be used under the
  24.  * terms of the GNU General Public License version 2 (the "GPL"), in
  25.  * which case the provisions of the GPL are applicable instead of the
  26.  * above.  If you wish to allow the use of your version of this file
  27.  * only under the terms of the GPL and not to allow others to use your
  28.  * version of this file under the RHEPL, indicate your decision by
  29.  * deleting the provisions above and replace them with the notice and
  30.  * other provisions required by the GPL.  If you do not delete the
  31.  * provisions above, a recipient may use your version of this file
  32.  * under either the RHEPL or the GPL.
  33.  *
  34.  * $Id: read.c,v 1.13.2.1 2002/02/01 23:32:33 dwmw2 Exp $
  35.  *
  36.  */
  37. #include <linux/kernel.h>
  38. #include <linux/slab.h>
  39. #include <linux/jffs2.h>
  40. #include <linux/mtd/mtd.h>
  41. #include "nodelist.h"
  42. #include "crc32.h"
  43. int jffs2_read_dnode(struct jffs2_sb_info *c, struct jffs2_full_dnode *fd, unsigned char *buf, int ofs, int len)
  44. {
  45. struct jffs2_raw_inode *ri;
  46. size_t readlen;
  47. __u32 crc;
  48. unsigned char *decomprbuf = NULL;
  49. unsigned char *readbuf = NULL;
  50. int ret = 0;
  51. ri = jffs2_alloc_raw_inode();
  52. if (!ri)
  53. return -ENOMEM;
  54. ret = c->mtd->read(c->mtd, fd->raw->flash_offset & ~3, sizeof(*ri), &readlen, (char *)ri);
  55. if (ret) {
  56. jffs2_free_raw_inode(ri);
  57. printk(KERN_WARNING "Error reading node from 0x%08x: %dn", fd->raw->flash_offset & ~3, ret);
  58. return ret;
  59. }
  60. if (readlen != sizeof(*ri)) {
  61. jffs2_free_raw_inode(ri);
  62. printk(KERN_WARNING "Short read from 0x%08x: wanted 0x%x bytes, got 0x%xn", 
  63.        fd->raw->flash_offset & ~3, sizeof(*ri), readlen);
  64. return -EIO;
  65. }
  66. crc = crc32(0, ri, sizeof(*ri)-8);
  67. D1(printk(KERN_DEBUG "Node read from %08x: node_crc %08x, calculated CRC %08x. dsize %x, csize %x, offset %x, buf %pn", fd->raw->flash_offset & ~3, ri->node_crc, crc, ri->dsize, ri->csize, ri->offset, buf));
  68. if (crc != ri->node_crc) {
  69. printk(KERN_WARNING "Node CRC %08x != calculated CRC %08x for node at %08xn", ri->node_crc, crc, fd->raw->flash_offset & ~3);
  70. ret = -EIO;
  71. goto out_ri;
  72. }
  73. /* There was a bug where we wrote hole nodes out with csize/dsize
  74.    swapped. Deal with it */
  75. if (ri->compr == JFFS2_COMPR_ZERO && !ri->dsize && ri->csize) {
  76. ri->dsize = ri->csize;
  77. ri->csize = 0;
  78. }
  79. D1(if(ofs + len > ri->dsize) {
  80. printk(KERN_WARNING "jffs2_read_dnode() asked for %d bytes at %d from %d-byte noden", len, ofs, ri->dsize);
  81. ret = -EINVAL;
  82. goto out_ri;
  83. });
  84. if (ri->compr == JFFS2_COMPR_ZERO) {
  85. memset(buf, 0, len);
  86. goto out_ri;
  87. }
  88. /* Cases:
  89.    Reading whole node and it's uncompressed - read directly to buffer provided, check CRC.
  90.    Reading whole node and it's compressed - read into comprbuf, check CRC and decompress to buffer provided 
  91.    Reading partial node and it's uncompressed - read into readbuf, check CRC, and copy 
  92.    Reading partial node and it's compressed - read into readbuf, check checksum, decompress to decomprbuf and copy
  93. */
  94. if (ri->compr == JFFS2_COMPR_NONE && len == ri->dsize) {
  95. readbuf = buf;
  96. } else {
  97. readbuf = kmalloc(ri->csize, GFP_KERNEL);
  98. if (!readbuf) {
  99. ret = -ENOMEM;
  100. goto out_ri;
  101. }
  102. }
  103. if (ri->compr != JFFS2_COMPR_NONE) {
  104. if (len < ri->dsize) {
  105. decomprbuf = kmalloc(ri->dsize, GFP_KERNEL);
  106. if (!decomprbuf) {
  107. ret = -ENOMEM;
  108. goto out_readbuf;
  109. }
  110. } else {
  111. decomprbuf = buf;
  112. }
  113. } else {
  114. decomprbuf = readbuf;
  115. }
  116. D2(printk(KERN_DEBUG "Read %d bytes to %pn", ri->csize, readbuf));
  117. ret = c->mtd->read(c->mtd, (fd->raw->flash_offset &~3) + sizeof(*ri), ri->csize, &readlen, readbuf);
  118. if (!ret && readlen != ri->csize)
  119. ret = -EIO;
  120. if (ret)
  121. goto out_decomprbuf;
  122. crc = crc32(0, readbuf, ri->csize);
  123. if (crc != ri->data_crc) {
  124. printk(KERN_WARNING "Data CRC %08x != calculated CRC %08x for node at %08xn", ri->data_crc, crc, fd->raw->flash_offset & ~3);
  125. ret = -EIO;
  126. goto out_decomprbuf;
  127. }
  128. D2(printk(KERN_DEBUG "Data CRC matches calculated CRC %08xn", crc));
  129. if (ri->compr != JFFS2_COMPR_NONE) {
  130. D2(printk(KERN_DEBUG "Decompress %d bytes from %p to %d bytes at %pn", ri->csize, readbuf, ri->dsize, decomprbuf)); 
  131. ret = jffs2_decompress(ri->compr, readbuf, decomprbuf, ri->csize, ri->dsize);
  132. if (ret) {
  133. printk(KERN_WARNING "Error: jffs2_decompress returned %dn", ret);
  134. goto out_decomprbuf;
  135. }
  136. }
  137. if (len < ri->dsize) {
  138. memcpy(buf, decomprbuf+ofs, len);
  139. }
  140.  out_decomprbuf:
  141. if(decomprbuf != buf && decomprbuf != readbuf)
  142. kfree(decomprbuf);
  143.  out_readbuf:
  144. if(readbuf != buf)
  145. kfree(readbuf);
  146.  out_ri:
  147. jffs2_free_raw_inode(ri);
  148. return ret;
  149. }