Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]

Diff markup

Differences between /linux/fs/jffs2/summary.c (Version 2.6.25.8) and /linux/fs/jffs2/summary.c (Version 2.6.25)


  1 /*                                                  1 /*
  2  * JFFS2 -- Journalling Flash File System, Ver      2  * JFFS2 -- Journalling Flash File System, Version 2.
  3  *                                                  3  *
  4  * Copyright © 2004  Ferenc Havasi <havasi@in      4  * Copyright © 2004  Ferenc Havasi <havasi@inf.u-szeged.hu>,
  5  *                   Zoltan Sogor <weth@inf.u-      5  *                   Zoltan Sogor <weth@inf.u-szeged.hu>,
  6  *                   Patrik Kluba <pajko@halom      6  *                   Patrik Kluba <pajko@halom.u-szeged.hu>,
  7  *                   University of Szeged, Hun      7  *                   University of Szeged, Hungary
  8  *             2006  KaiGai Kohei <kaigai@ak.j      8  *             2006  KaiGai Kohei <kaigai@ak.jp.nec.com>
  9  *                                                  9  *
 10  * For licensing information, see the file 'LI     10  * For licensing information, see the file 'LICENCE' in this directory.
 11  *                                                 11  *
 12  */                                                12  */
 13                                                    13 
 14 #include <linux/kernel.h>                          14 #include <linux/kernel.h>
 15 #include <linux/slab.h>                            15 #include <linux/slab.h>
 16 #include <linux/mtd/mtd.h>                         16 #include <linux/mtd/mtd.h>
 17 #include <linux/pagemap.h>                         17 #include <linux/pagemap.h>
 18 #include <linux/crc32.h>                           18 #include <linux/crc32.h>
 19 #include <linux/compiler.h>                        19 #include <linux/compiler.h>
 20 #include <linux/vmalloc.h>                         20 #include <linux/vmalloc.h>
 21 #include "nodelist.h"                              21 #include "nodelist.h"
 22 #include "debug.h"                                 22 #include "debug.h"
 23                                                    23 
 24 int jffs2_sum_init(struct jffs2_sb_info *c)        24 int jffs2_sum_init(struct jffs2_sb_info *c)
 25 {                                                  25 {
 26         c->summary = kzalloc(sizeof(struct jff     26         c->summary = kzalloc(sizeof(struct jffs2_summary), GFP_KERNEL);
 27                                                    27 
 28         if (!c->summary) {                         28         if (!c->summary) {
 29                 JFFS2_WARNING("Can't allocate      29                 JFFS2_WARNING("Can't allocate memory for summary information!\n");
 30                 return -ENOMEM;                    30                 return -ENOMEM;
 31         }                                          31         }
 32                                                    32 
 33         c->summary->sum_buf = vmalloc(c->secto     33         c->summary->sum_buf = vmalloc(c->sector_size);
 34                                                    34 
 35         if (!c->summary->sum_buf) {                35         if (!c->summary->sum_buf) {
 36                 JFFS2_WARNING("Can't allocate      36                 JFFS2_WARNING("Can't allocate buffer for writing out summary information!\n");
 37                 kfree(c->summary);                 37                 kfree(c->summary);
 38                 return -ENOMEM;                    38                 return -ENOMEM;
 39         }                                          39         }
 40                                                    40 
 41         dbg_summary("returned successfully\n")     41         dbg_summary("returned successfully\n");
 42                                                    42 
 43         return 0;                                  43         return 0;
 44 }                                                  44 }
 45                                                    45 
 46 void jffs2_sum_exit(struct jffs2_sb_info *c)       46 void jffs2_sum_exit(struct jffs2_sb_info *c)
 47 {                                                  47 {
 48         dbg_summary("called\n");                   48         dbg_summary("called\n");
 49                                                    49 
 50         jffs2_sum_disable_collecting(c->summar     50         jffs2_sum_disable_collecting(c->summary);
 51                                                    51 
 52         vfree(c->summary->sum_buf);                52         vfree(c->summary->sum_buf);
 53         c->summary->sum_buf = NULL;                53         c->summary->sum_buf = NULL;
 54                                                    54 
 55         kfree(c->summary);                         55         kfree(c->summary);
 56         c->summary = NULL;                         56         c->summary = NULL;
 57 }                                                  57 }
 58                                                    58 
 59 static int jffs2_sum_add_mem(struct jffs2_summ     59 static int jffs2_sum_add_mem(struct jffs2_summary *s, union jffs2_sum_mem *item)
 60 {                                                  60 {
 61         if (!s->sum_list_head)                     61         if (!s->sum_list_head)
 62                 s->sum_list_head = (union jffs     62                 s->sum_list_head = (union jffs2_sum_mem *) item;
 63         if (s->sum_list_tail)                      63         if (s->sum_list_tail)
 64                 s->sum_list_tail->u.next = (un     64                 s->sum_list_tail->u.next = (union jffs2_sum_mem *) item;
 65         s->sum_list_tail = (union jffs2_sum_me     65         s->sum_list_tail = (union jffs2_sum_mem *) item;
 66                                                    66 
 67         switch (je16_to_cpu(item->u.nodetype))     67         switch (je16_to_cpu(item->u.nodetype)) {
 68                 case JFFS2_NODETYPE_INODE:         68                 case JFFS2_NODETYPE_INODE:
 69                         s->sum_size += JFFS2_S     69                         s->sum_size += JFFS2_SUMMARY_INODE_SIZE;
 70                         s->sum_num++;              70                         s->sum_num++;
 71                         dbg_summary("inode (%u     71                         dbg_summary("inode (%u) added to summary\n",
 72                                                    72                                                 je32_to_cpu(item->i.inode));
 73                         break;                     73                         break;
 74                 case JFFS2_NODETYPE_DIRENT:        74                 case JFFS2_NODETYPE_DIRENT:
 75                         s->sum_size += JFFS2_S     75                         s->sum_size += JFFS2_SUMMARY_DIRENT_SIZE(item->d.nsize);
 76                         s->sum_num++;              76                         s->sum_num++;
 77                         dbg_summary("dirent (%     77                         dbg_summary("dirent (%u) added to summary\n",
 78                                                    78                                                 je32_to_cpu(item->d.ino));
 79                         break;                     79                         break;
 80 #ifdef CONFIG_JFFS2_FS_XATTR                       80 #ifdef CONFIG_JFFS2_FS_XATTR
 81                 case JFFS2_NODETYPE_XATTR:         81                 case JFFS2_NODETYPE_XATTR:
 82                         s->sum_size += JFFS2_S     82                         s->sum_size += JFFS2_SUMMARY_XATTR_SIZE;
 83                         s->sum_num++;              83                         s->sum_num++;
 84                         dbg_summary("xattr (xi     84                         dbg_summary("xattr (xid=%u, version=%u) added to summary\n",
 85                                     je32_to_cp     85                                     je32_to_cpu(item->x.xid), je32_to_cpu(item->x.version));
 86                         break;                     86                         break;
 87                 case JFFS2_NODETYPE_XREF:          87                 case JFFS2_NODETYPE_XREF:
 88                         s->sum_size += JFFS2_S     88                         s->sum_size += JFFS2_SUMMARY_XREF_SIZE;
 89                         s->sum_num++;              89                         s->sum_num++;
 90                         dbg_summary("xref adde     90                         dbg_summary("xref added to summary\n");
 91                         break;                     91                         break;
 92 #endif                                             92 #endif
 93                 default:                           93                 default:
 94                         JFFS2_WARNING("UNKNOWN     94                         JFFS2_WARNING("UNKNOWN node type %u\n",
 95                                             je     95                                             je16_to_cpu(item->u.nodetype));
 96                         return 1;                  96                         return 1;
 97         }                                          97         }
 98         return 0;                                  98         return 0;
 99 }                                                  99 }
100                                                   100 
101                                                   101 
102 /* The following 3 functions are called from s    102 /* The following 3 functions are called from scan.c to collect summary info for not closed jeb */
103                                                   103 
104 int jffs2_sum_add_padding_mem(struct jffs2_sum    104 int jffs2_sum_add_padding_mem(struct jffs2_summary *s, uint32_t size)
105 {                                                 105 {
106         dbg_summary("called with %u\n", size);    106         dbg_summary("called with %u\n", size);
107         s->sum_padded += size;                    107         s->sum_padded += size;
108         return 0;                                 108         return 0;
109 }                                                 109 }
110                                                   110 
111 int jffs2_sum_add_inode_mem(struct jffs2_summa    111 int jffs2_sum_add_inode_mem(struct jffs2_summary *s, struct jffs2_raw_inode *ri,
112                                 uint32_t ofs)     112                                 uint32_t ofs)
113 {                                                 113 {
114         struct jffs2_sum_inode_mem *temp = kma    114         struct jffs2_sum_inode_mem *temp = kmalloc(sizeof(struct jffs2_sum_inode_mem), GFP_KERNEL);
115                                                   115 
116         if (!temp)                                116         if (!temp)
117                 return -ENOMEM;                   117                 return -ENOMEM;
118                                                   118 
119         temp->nodetype = ri->nodetype;            119         temp->nodetype = ri->nodetype;
120         temp->inode = ri->ino;                    120         temp->inode = ri->ino;
121         temp->version = ri->version;              121         temp->version = ri->version;
122         temp->offset = cpu_to_je32(ofs); /* re    122         temp->offset = cpu_to_je32(ofs); /* relative offset from the begining of the jeb */
123         temp->totlen = ri->totlen;                123         temp->totlen = ri->totlen;
124         temp->next = NULL;                        124         temp->next = NULL;
125                                                   125 
126         return jffs2_sum_add_mem(s, (union jff    126         return jffs2_sum_add_mem(s, (union jffs2_sum_mem *)temp);
127 }                                                 127 }
128                                                   128 
129 int jffs2_sum_add_dirent_mem(struct jffs2_summ    129 int jffs2_sum_add_dirent_mem(struct jffs2_summary *s, struct jffs2_raw_dirent *rd,
130                                 uint32_t ofs)     130                                 uint32_t ofs)
131 {                                                 131 {
132         struct jffs2_sum_dirent_mem *temp =       132         struct jffs2_sum_dirent_mem *temp =
133                 kmalloc(sizeof(struct jffs2_su    133                 kmalloc(sizeof(struct jffs2_sum_dirent_mem) + rd->nsize, GFP_KERNEL);
134                                                   134 
135         if (!temp)                                135         if (!temp)
136                 return -ENOMEM;                   136                 return -ENOMEM;
137                                                   137 
138         temp->nodetype = rd->nodetype;            138         temp->nodetype = rd->nodetype;
139         temp->totlen = rd->totlen;                139         temp->totlen = rd->totlen;
140         temp->offset = cpu_to_je32(ofs);          140         temp->offset = cpu_to_je32(ofs);        /* relative from the begining of the jeb */
141         temp->pino = rd->pino;                    141         temp->pino = rd->pino;
142         temp->version = rd->version;              142         temp->version = rd->version;
143         temp->ino = rd->ino;                      143         temp->ino = rd->ino;
144         temp->nsize = rd->nsize;                  144         temp->nsize = rd->nsize;
145         temp->type = rd->type;                    145         temp->type = rd->type;
146         temp->next = NULL;                        146         temp->next = NULL;
147                                                   147 
148         memcpy(temp->name, rd->name, rd->nsize    148         memcpy(temp->name, rd->name, rd->nsize);
149                                                   149 
150         return jffs2_sum_add_mem(s, (union jff    150         return jffs2_sum_add_mem(s, (union jffs2_sum_mem *)temp);
151 }                                                 151 }
152                                                   152 
153 #ifdef CONFIG_JFFS2_FS_XATTR                      153 #ifdef CONFIG_JFFS2_FS_XATTR
154 int jffs2_sum_add_xattr_mem(struct jffs2_summa    154 int jffs2_sum_add_xattr_mem(struct jffs2_summary *s, struct jffs2_raw_xattr *rx, uint32_t ofs)
155 {                                                 155 {
156         struct jffs2_sum_xattr_mem *temp;         156         struct jffs2_sum_xattr_mem *temp;
157                                                   157 
158         temp = kmalloc(sizeof(struct jffs2_sum    158         temp = kmalloc(sizeof(struct jffs2_sum_xattr_mem), GFP_KERNEL);
159         if (!temp)                                159         if (!temp)
160                 return -ENOMEM;                   160                 return -ENOMEM;
161                                                   161 
162         temp->nodetype = rx->nodetype;            162         temp->nodetype = rx->nodetype;
163         temp->xid = rx->xid;                      163         temp->xid = rx->xid;
164         temp->version = rx->version;              164         temp->version = rx->version;
165         temp->offset = cpu_to_je32(ofs);          165         temp->offset = cpu_to_je32(ofs);
166         temp->totlen = rx->totlen;                166         temp->totlen = rx->totlen;
167         temp->next = NULL;                        167         temp->next = NULL;
168                                                   168 
169         return jffs2_sum_add_mem(s, (union jff    169         return jffs2_sum_add_mem(s, (union jffs2_sum_mem *)temp);
170 }                                                 170 }
171                                                   171 
172 int jffs2_sum_add_xref_mem(struct jffs2_summar    172 int jffs2_sum_add_xref_mem(struct jffs2_summary *s, struct jffs2_raw_xref *rr, uint32_t ofs)
173 {                                                 173 {
174         struct jffs2_sum_xref_mem *temp;          174         struct jffs2_sum_xref_mem *temp;
175                                                   175 
176         temp = kmalloc(sizeof(struct jffs2_sum    176         temp = kmalloc(sizeof(struct jffs2_sum_xref_mem), GFP_KERNEL);
177         if (!temp)                                177         if (!temp)
178                 return -ENOMEM;                   178                 return -ENOMEM;
179                                                   179 
180         temp->nodetype = rr->nodetype;            180         temp->nodetype = rr->nodetype;
181         temp->offset = cpu_to_je32(ofs);          181         temp->offset = cpu_to_je32(ofs);
182         temp->next = NULL;                        182         temp->next = NULL;
183                                                   183 
184         return jffs2_sum_add_mem(s, (union jff    184         return jffs2_sum_add_mem(s, (union jffs2_sum_mem *)temp);
185 }                                                 185 }
186 #endif                                            186 #endif
187 /* Cleanup every collected summary information    187 /* Cleanup every collected summary information */
188                                                   188 
189 static void jffs2_sum_clean_collected(struct j    189 static void jffs2_sum_clean_collected(struct jffs2_summary *s)
190 {                                                 190 {
191         union jffs2_sum_mem *temp;                191         union jffs2_sum_mem *temp;
192                                                   192 
193         if (!s->sum_list_head) {                  193         if (!s->sum_list_head) {
194                 dbg_summary("already empty\n")    194                 dbg_summary("already empty\n");
195         }                                         195         }
196         while (s->sum_list_head) {                196         while (s->sum_list_head) {
197                 temp = s->sum_list_head;          197                 temp = s->sum_list_head;
198                 s->sum_list_head = s->sum_list    198                 s->sum_list_head = s->sum_list_head->u.next;
199                 kfree(temp);                      199                 kfree(temp);
200         }                                         200         }
201         s->sum_list_tail = NULL;                  201         s->sum_list_tail = NULL;
202         s->sum_padded = 0;                        202         s->sum_padded = 0;
203         s->sum_num = 0;                           203         s->sum_num = 0;
204 }                                                 204 }
205                                                   205 
206 void jffs2_sum_reset_collected(struct jffs2_su    206 void jffs2_sum_reset_collected(struct jffs2_summary *s)
207 {                                                 207 {
208         dbg_summary("called\n");                  208         dbg_summary("called\n");
209         jffs2_sum_clean_collected(s);             209         jffs2_sum_clean_collected(s);
210         s->sum_size = 0;                          210         s->sum_size = 0;
211 }                                                 211 }
212                                                   212 
213 void jffs2_sum_disable_collecting(struct jffs2    213 void jffs2_sum_disable_collecting(struct jffs2_summary *s)
214 {                                                 214 {
215         dbg_summary("called\n");                  215         dbg_summary("called\n");
216         jffs2_sum_clean_collected(s);             216         jffs2_sum_clean_collected(s);
217         s->sum_size = JFFS2_SUMMARY_NOSUM_SIZE    217         s->sum_size = JFFS2_SUMMARY_NOSUM_SIZE;
218 }                                                 218 }
219                                                   219 
220 int jffs2_sum_is_disabled(struct jffs2_summary    220 int jffs2_sum_is_disabled(struct jffs2_summary *s)
221 {                                                 221 {
222         return (s->sum_size == JFFS2_SUMMARY_N    222         return (s->sum_size == JFFS2_SUMMARY_NOSUM_SIZE);
223 }                                                 223 }
224                                                   224 
225 /* Move the collected summary information into    225 /* Move the collected summary information into sb (called from scan.c) */
226                                                   226 
227 void jffs2_sum_move_collected(struct jffs2_sb_    227 void jffs2_sum_move_collected(struct jffs2_sb_info *c, struct jffs2_summary *s)
228 {                                                 228 {
229         dbg_summary("oldsize=0x%x oldnum=%u =>    229         dbg_summary("oldsize=0x%x oldnum=%u => newsize=0x%x newnum=%u\n",
230                                 c->summary->su    230                                 c->summary->sum_size, c->summary->sum_num,
231                                 s->sum_size, s    231                                 s->sum_size, s->sum_num);
232                                                   232 
233         c->summary->sum_size = s->sum_size;       233         c->summary->sum_size = s->sum_size;
234         c->summary->sum_num = s->sum_num;         234         c->summary->sum_num = s->sum_num;
235         c->summary->sum_padded = s->sum_padded    235         c->summary->sum_padded = s->sum_padded;
236         c->summary->sum_list_head = s->sum_lis    236         c->summary->sum_list_head = s->sum_list_head;
237         c->summary->sum_list_tail = s->sum_lis    237         c->summary->sum_list_tail = s->sum_list_tail;
238                                                   238 
239         s->sum_list_head = s->sum_list_tail =     239         s->sum_list_head = s->sum_list_tail = NULL;
240 }                                                 240 }
241                                                   241 
242 /* Called from wbuf.c to collect writed node i    242 /* Called from wbuf.c to collect writed node info */
243                                                   243 
244 int jffs2_sum_add_kvec(struct jffs2_sb_info *c    244 int jffs2_sum_add_kvec(struct jffs2_sb_info *c, const struct kvec *invecs,
245                                 unsigned long     245                                 unsigned long count, uint32_t ofs)
246 {                                                 246 {
247         union jffs2_node_union *node;             247         union jffs2_node_union *node;
248         struct jffs2_eraseblock *jeb;             248         struct jffs2_eraseblock *jeb;
249                                                   249 
250         if (c->summary->sum_size == JFFS2_SUMM    250         if (c->summary->sum_size == JFFS2_SUMMARY_NOSUM_SIZE) {
251                 dbg_summary("Summary is disabl    251                 dbg_summary("Summary is disabled for this jeb! Skipping summary info!\n");
252                 return 0;                         252                 return 0;
253         }                                         253         }
254                                                   254 
255         node = invecs[0].iov_base;                255         node = invecs[0].iov_base;
256         jeb = &c->blocks[ofs / c->sector_size]    256         jeb = &c->blocks[ofs / c->sector_size];
257         ofs -= jeb->offset;                       257         ofs -= jeb->offset;
258                                                   258 
259         switch (je16_to_cpu(node->u.nodetype))    259         switch (je16_to_cpu(node->u.nodetype)) {
260                 case JFFS2_NODETYPE_INODE: {      260                 case JFFS2_NODETYPE_INODE: {
261                         struct jffs2_sum_inode    261                         struct jffs2_sum_inode_mem *temp =
262                                 kmalloc(sizeof    262                                 kmalloc(sizeof(struct jffs2_sum_inode_mem), GFP_KERNEL);
263                                                   263 
264                         if (!temp)                264                         if (!temp)
265                                 goto no_mem;      265                                 goto no_mem;
266                                                   266 
267                         temp->nodetype = node-    267                         temp->nodetype = node->i.nodetype;
268                         temp->inode = node->i.    268                         temp->inode = node->i.ino;
269                         temp->version = node->    269                         temp->version = node->i.version;
270                         temp->offset = cpu_to_    270                         temp->offset = cpu_to_je32(ofs);
271                         temp->totlen = node->i    271                         temp->totlen = node->i.totlen;
272                         temp->next = NULL;        272                         temp->next = NULL;
273                                                   273 
274                         return jffs2_sum_add_m    274                         return jffs2_sum_add_mem(c->summary, (union jffs2_sum_mem *)temp);
275                 }                                 275                 }
276                                                   276 
277                 case JFFS2_NODETYPE_DIRENT: {     277                 case JFFS2_NODETYPE_DIRENT: {
278                         struct jffs2_sum_diren    278                         struct jffs2_sum_dirent_mem *temp =
279                                 kmalloc(sizeof    279                                 kmalloc(sizeof(struct jffs2_sum_dirent_mem) + node->d.nsize, GFP_KERNEL);
280                                                   280 
281                         if (!temp)                281                         if (!temp)
282                                 goto no_mem;      282                                 goto no_mem;
283                                                   283 
284                         temp->nodetype = node-    284                         temp->nodetype = node->d.nodetype;
285                         temp->totlen = node->d    285                         temp->totlen = node->d.totlen;
286                         temp->offset = cpu_to_    286                         temp->offset = cpu_to_je32(ofs);
287                         temp->pino = node->d.p    287                         temp->pino = node->d.pino;
288                         temp->version = node->    288                         temp->version = node->d.version;
289                         temp->ino = node->d.in    289                         temp->ino = node->d.ino;
290                         temp->nsize = node->d.    290                         temp->nsize = node->d.nsize;
291                         temp->type = node->d.t    291                         temp->type = node->d.type;
292                         temp->next = NULL;        292                         temp->next = NULL;
293                                                   293 
294                         switch (count) {          294                         switch (count) {
295                                 case 1:           295                                 case 1:
296                                         memcpy    296                                         memcpy(temp->name,node->d.name,node->d.nsize);
297                                         break;    297                                         break;
298                                                   298 
299                                 case 2:           299                                 case 2:
300                                         memcpy    300                                         memcpy(temp->name,invecs[1].iov_base,node->d.nsize);
301                                         break;    301                                         break;
302                                                   302 
303                                 default:          303                                 default:
304                                         BUG();    304                                         BUG();  /* impossible count value */
305                                         break;    305                                         break;
306                         }                         306                         }
307                                                   307 
308                         return jffs2_sum_add_m    308                         return jffs2_sum_add_mem(c->summary, (union jffs2_sum_mem *)temp);
309                 }                                 309                 }
310 #ifdef CONFIG_JFFS2_FS_XATTR                      310 #ifdef CONFIG_JFFS2_FS_XATTR
311                 case JFFS2_NODETYPE_XATTR: {      311                 case JFFS2_NODETYPE_XATTR: {
312                         struct jffs2_sum_xattr    312                         struct jffs2_sum_xattr_mem *temp;
313                         temp = kmalloc(sizeof(    313                         temp = kmalloc(sizeof(struct jffs2_sum_xattr_mem), GFP_KERNEL);
314                         if (!temp)                314                         if (!temp)
315                                 goto no_mem;      315                                 goto no_mem;
316                                                   316 
317                         temp->nodetype = node-    317                         temp->nodetype = node->x.nodetype;
318                         temp->xid = node->x.xi    318                         temp->xid = node->x.xid;
319                         temp->version = node->    319                         temp->version = node->x.version;
320                         temp->totlen = node->x    320                         temp->totlen = node->x.totlen;
321                         temp->offset = cpu_to_    321                         temp->offset = cpu_to_je32(ofs);
322                         temp->next = NULL;        322                         temp->next = NULL;
323                                                   323 
324                         return jffs2_sum_add_m    324                         return jffs2_sum_add_mem(c->summary, (union jffs2_sum_mem *)temp);
325                 }                                 325                 }
326                 case JFFS2_NODETYPE_XREF: {       326                 case JFFS2_NODETYPE_XREF: {
327                         struct jffs2_sum_xref_    327                         struct jffs2_sum_xref_mem *temp;
328                         temp = kmalloc(sizeof(    328                         temp = kmalloc(sizeof(struct jffs2_sum_xref_mem), GFP_KERNEL);
329                         if (!temp)                329                         if (!temp)
330                                 goto no_mem;      330                                 goto no_mem;
331                         temp->nodetype = node-    331                         temp->nodetype = node->r.nodetype;
332                         temp->offset = cpu_to_    332                         temp->offset = cpu_to_je32(ofs);
333                         temp->next = NULL;        333                         temp->next = NULL;
334                                                   334 
335                         return jffs2_sum_add_m    335                         return jffs2_sum_add_mem(c->summary, (union jffs2_sum_mem *)temp);
336                 }                                 336                 }
337 #endif                                            337 #endif
338                 case JFFS2_NODETYPE_PADDING:      338                 case JFFS2_NODETYPE_PADDING:
339                         dbg_summary("node PADD    339                         dbg_summary("node PADDING\n");
340                         c->summary->sum_padded    340                         c->summary->sum_padded += je32_to_cpu(node->u.totlen);
341                         break;                    341                         break;
342                                                   342 
343                 case JFFS2_NODETYPE_CLEANMARKE    343                 case JFFS2_NODETYPE_CLEANMARKER:
344                         dbg_summary("node CLEA    344                         dbg_summary("node CLEANMARKER\n");
345                         break;                    345                         break;
346                                                   346 
347                 case JFFS2_NODETYPE_SUMMARY:      347                 case JFFS2_NODETYPE_SUMMARY:
348                         dbg_summary("node SUMM    348                         dbg_summary("node SUMMARY\n");
349                         break;                    349                         break;
350                                                   350 
351                 default:                          351                 default:
352                         /* If you implement a     352                         /* If you implement a new node type you should also implement
353                            summary support for    353                            summary support for it or disable summary.
354                         */                        354                         */
355                         BUG();                    355                         BUG();
356                         break;                    356                         break;
357         }                                         357         }
358                                                   358 
359         return 0;                                 359         return 0;
360                                                   360 
361 no_mem:                                           361 no_mem:
362         JFFS2_WARNING("MEMORY ALLOCATION ERROR    362         JFFS2_WARNING("MEMORY ALLOCATION ERROR!");
363         return -ENOMEM;                           363         return -ENOMEM;
364 }                                                 364 }
365                                                   365 
366 static struct jffs2_raw_node_ref *sum_link_nod    366 static struct jffs2_raw_node_ref *sum_link_node_ref(struct jffs2_sb_info *c,
367                                                   367                                                     struct jffs2_eraseblock *jeb,
368                                                   368                                                     uint32_t ofs, uint32_t len,
369                                                   369                                                     struct jffs2_inode_cache *ic)
370 {                                                 370 {
371         /* If there was a gap, mark it dirty *    371         /* If there was a gap, mark it dirty */
372         if ((ofs & ~3) > c->sector_size - jeb-    372         if ((ofs & ~3) > c->sector_size - jeb->free_size) {
373                 /* Ew. Summary doesn't actuall    373                 /* Ew. Summary doesn't actually tell us explicitly about dirty space */
374                 jffs2_scan_dirty_space(c, jeb,    374                 jffs2_scan_dirty_space(c, jeb, (ofs & ~3) - (c->sector_size - jeb->free_size));
375         }                                         375         }
376                                                   376 
377         return jffs2_link_node_ref(c, jeb, jeb    377         return jffs2_link_node_ref(c, jeb, jeb->offset + ofs, len, ic);
378 }                                                 378 }
379                                                   379 
380 /* Process the stored summary information - he    380 /* Process the stored summary information - helper function for jffs2_sum_scan_sumnode() */
381                                                   381 
382 static int jffs2_sum_process_sum_data(struct j    382 static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
383                                 struct jffs2_r    383                                 struct jffs2_raw_summary *summary, uint32_t *pseudo_random)
384 {                                                 384 {
385         struct jffs2_inode_cache *ic;             385         struct jffs2_inode_cache *ic;
386         struct jffs2_full_dirent *fd;             386         struct jffs2_full_dirent *fd;
387         void *sp;                                 387         void *sp;
388         int i, ino;                               388         int i, ino;
389         int err;                                  389         int err;
390                                                   390 
391         sp = summary->sum;                        391         sp = summary->sum;
392                                                   392 
393         for (i=0; i<je32_to_cpu(summary->sum_n    393         for (i=0; i<je32_to_cpu(summary->sum_num); i++) {
394                 dbg_summary("processing summar    394                 dbg_summary("processing summary index %d\n", i);
395                                                   395 
396                 cond_resched();                   396                 cond_resched();
397                                                   397 
398                 /* Make sure there's a spare r    398                 /* Make sure there's a spare ref for dirty space */
399                 err = jffs2_prealloc_raw_node_    399                 err = jffs2_prealloc_raw_node_refs(c, jeb, 2);
400                 if (err)                          400                 if (err)
401                         return err;               401                         return err;
402                                                   402 
403                 switch (je16_to_cpu(((struct j    403                 switch (je16_to_cpu(((struct jffs2_sum_unknown_flash *)sp)->nodetype)) {
404                         case JFFS2_NODETYPE_IN    404                         case JFFS2_NODETYPE_INODE: {
405                                 struct jffs2_s    405                                 struct jffs2_sum_inode_flash *spi;
406                                 spi = sp;         406                                 spi = sp;
407                                                   407 
408                                 ino = je32_to_    408                                 ino = je32_to_cpu(spi->inode);
409                                                   409 
410                                 dbg_summary("I    410                                 dbg_summary("Inode at 0x%08x-0x%08x\n",
411                                             je    411                                             jeb->offset + je32_to_cpu(spi->offset),
412                                             je    412                                             jeb->offset + je32_to_cpu(spi->offset) + je32_to_cpu(spi->totlen));
413                                                   413 
414                                 ic = jffs2_sca    414                                 ic = jffs2_scan_make_ino_cache(c, ino);
415                                 if (!ic) {        415                                 if (!ic) {
416                                         JFFS2_    416                                         JFFS2_NOTICE("scan_make_ino_cache failed\n");
417                                         return    417                                         return -ENOMEM;
418                                 }                 418                                 }
419                                                   419 
420                                 sum_link_node_    420                                 sum_link_node_ref(c, jeb, je32_to_cpu(spi->offset) | REF_UNCHECKED,
421                                                   421                                                   PAD(je32_to_cpu(spi->totlen)), ic);
422                                                   422 
423                                 *pseudo_random    423                                 *pseudo_random += je32_to_cpu(spi->version);
424                                                   424 
425                                 sp += JFFS2_SU    425                                 sp += JFFS2_SUMMARY_INODE_SIZE;
426                                                   426 
427                                 break;            427                                 break;
428                         }                         428                         }
429                                                   429 
430                         case JFFS2_NODETYPE_DI    430                         case JFFS2_NODETYPE_DIRENT: {
431                                 struct jffs2_s    431                                 struct jffs2_sum_dirent_flash *spd;
432                                 int checkedlen    432                                 int checkedlen;
433                                 spd = sp;         433                                 spd = sp;
434                                                   434 
435                                 dbg_summary("D    435                                 dbg_summary("Dirent at 0x%08x-0x%08x\n",
436                                             je    436                                             jeb->offset + je32_to_cpu(spd->offset),
437                                             je    437                                             jeb->offset + je32_to_cpu(spd->offset) + je32_to_cpu(spd->totlen));
438                                                   438 
439                                                   439 
440                                 /* This should    440                                 /* This should never happen, but https://dev.laptop.org/ticket/4184 */
441                                 checkedlen = s    441                                 checkedlen = strnlen(spd->name, spd->nsize);
442                                 if (!checkedle    442                                 if (!checkedlen) {
443                                         printk    443                                         printk(KERN_ERR "Dirent at %08x has zero at start of name. Aborting mount.\n",
444                                                   444                                                jeb->offset + je32_to_cpu(spd->offset));
445                                         return    445                                         return -EIO;
446                                 }                 446                                 }
447                                 if (checkedlen    447                                 if (checkedlen < spd->nsize) {
448                                         printk    448                                         printk(KERN_ERR "Dirent at %08x has zeroes in name. Truncating to %d chars\n",
449                                                   449                                                jeb->offset + je32_to_cpu(spd->offset), checkedlen);
450                                 }                 450                                 }
451                                                   451 
452                                                   452 
453                                 fd = jffs2_all    453                                 fd = jffs2_alloc_full_dirent(checkedlen+1);
454                                 if (!fd)          454                                 if (!fd)
455                                         return    455                                         return -ENOMEM;
456                                                   456 
457                                 memcpy(&fd->na    457                                 memcpy(&fd->name, spd->name, checkedlen);
458                                 fd->name[check    458                                 fd->name[checkedlen] = 0;
459                                                   459 
460                                 ic = jffs2_sca    460                                 ic = jffs2_scan_make_ino_cache(c, je32_to_cpu(spd->pino));
461                                 if (!ic) {        461                                 if (!ic) {
462                                         jffs2_    462                                         jffs2_free_full_dirent(fd);
463                                         return    463                                         return -ENOMEM;
464                                 }                 464                                 }
465                                                   465 
466                                 fd->raw = sum_    466                                 fd->raw = sum_link_node_ref(c, jeb,  je32_to_cpu(spd->offset) | REF_UNCHECKED,
467                                                   467                                                             PAD(je32_to_cpu(spd->totlen)), ic);
468                                                   468 
469                                 fd->next = NUL    469                                 fd->next = NULL;
470                                 fd->version =     470                                 fd->version = je32_to_cpu(spd->version);
471                                 fd->ino = je32    471                                 fd->ino = je32_to_cpu(spd->ino);
472                                 fd->nhash = fu    472                                 fd->nhash = full_name_hash(fd->name, checkedlen);
473                                 fd->type = spd    473                                 fd->type = spd->type;
474                                                   474 
475                                 jffs2_add_fd_t    475                                 jffs2_add_fd_to_list(c, fd, &ic->scan_dents);
476                                                   476 
477                                 *pseudo_random    477                                 *pseudo_random += je32_to_cpu(spd->version);
478                                                   478 
479                                 sp += JFFS2_SU    479                                 sp += JFFS2_SUMMARY_DIRENT_SIZE(spd->nsize);
480                                                   480 
481                                 break;            481                                 break;
482                         }                         482                         }
483 #ifdef CONFIG_JFFS2_FS_XATTR                      483 #ifdef CONFIG_JFFS2_FS_XATTR
484                         case JFFS2_NODETYPE_XA    484                         case JFFS2_NODETYPE_XATTR: {
485                                 struct jffs2_x    485                                 struct jffs2_xattr_datum *xd;
486                                 struct jffs2_s    486                                 struct jffs2_sum_xattr_flash *spx;
487                                                   487 
488                                 spx = (struct     488                                 spx = (struct jffs2_sum_xattr_flash *)sp;
489                                 dbg_summary("x    489                                 dbg_summary("xattr at %#08x-%#08x (xid=%u, version=%u)\n", 
490                                             je    490                                             jeb->offset + je32_to_cpu(spx->offset),
491                                             je    491                                             jeb->offset + je32_to_cpu(spx->offset) + je32_to_cpu(spx->totlen),
492                                             je    492                                             je32_to_cpu(spx->xid), je32_to_cpu(spx->version));
493                                                   493 
494                                 xd = jffs2_set    494                                 xd = jffs2_setup_xattr_datum(c, je32_to_cpu(spx->xid),
495                                                   495                                                                 je32_to_cpu(spx->version));
496                                 if (IS_ERR(xd)    496                                 if (IS_ERR(xd))
497                                         return    497                                         return PTR_ERR(xd);
498                                 if (xd->versio    498                                 if (xd->version > je32_to_cpu(spx->version)) {
499                                         /* nod    499                                         /* node is not the newest one */
500                                         struct    500                                         struct jffs2_raw_node_ref *raw
501                                                   501                                                 = sum_link_node_ref(c, jeb, je32_to_cpu(spx->offset) | REF_UNCHECKED,
502                                                   502                                                                     PAD(je32_to_cpu(spx->totlen)), NULL);
503                                         raw->n    503                                         raw->next_in_ino = xd->node->next_in_ino;
504                                         xd->no    504                                         xd->node->next_in_ino = raw;
505                                 } else {          505                                 } else {
506                                         xd->ve    506                                         xd->version = je32_to_cpu(spx->version);
507                                         sum_li    507                                         sum_link_node_ref(c, jeb, je32_to_cpu(spx->offset) | REF_UNCHECKED,
508                                                   508                                                           PAD(je32_to_cpu(spx->totlen)), (void *)xd);
509                                 }                 509                                 }
510                                 *pseudo_random    510                                 *pseudo_random += je32_to_cpu(spx->xid);
511                                 sp += JFFS2_SU    511                                 sp += JFFS2_SUMMARY_XATTR_SIZE;
512                                                   512 
513                                 break;            513                                 break;
514                         }                         514                         }
515                         case JFFS2_NODETYPE_XR    515                         case JFFS2_NODETYPE_XREF: {
516                                 struct jffs2_x    516                                 struct jffs2_xattr_ref *ref;
517                                 struct jffs2_s    517                                 struct jffs2_sum_xref_flash *spr;
518                                                   518 
519                                 spr = (struct     519                                 spr = (struct jffs2_sum_xref_flash *)sp;
520                                 dbg_summary("x    520                                 dbg_summary("xref at %#08x-%#08x\n",
521                                             je    521                                             jeb->offset + je32_to_cpu(spr->offset),
522                                             je    522                                             jeb->offset + je32_to_cpu(spr->offset) + 
523                                             (u    523                                             (uint32_t)PAD(sizeof(struct jffs2_raw_xref)));
524                                                   524 
525                                 ref = jffs2_al    525                                 ref = jffs2_alloc_xattr_ref();
526                                 if (!ref) {       526                                 if (!ref) {
527                                         JFFS2_    527                                         JFFS2_NOTICE("allocation of xattr_datum failed\n");
528                                         return    528                                         return -ENOMEM;
529                                 }                 529                                 }
530                                 ref->next = c-    530                                 ref->next = c->xref_temp;
531                                 c->xref_temp =    531                                 c->xref_temp = ref;
532                                                   532 
533                                 sum_link_node_    533                                 sum_link_node_ref(c, jeb, je32_to_cpu(spr->offset) | REF_UNCHECKED,
534                                                   534                                                   PAD(sizeof(struct jffs2_raw_xref)), (void *)ref);
535                                                   535 
536                                 *pseudo_random    536                                 *pseudo_random += ref->node->flash_offset;
537                                 sp += JFFS2_SU    537                                 sp += JFFS2_SUMMARY_XREF_SIZE;
538                                                   538 
539                                 break;            539                                 break;
540                         }                         540                         }
541 #endif                                            541 #endif
542                         default : {               542                         default : {
543                                 uint16_t nodet    543                                 uint16_t nodetype = je16_to_cpu(((struct jffs2_sum_unknown_flash *)sp)->nodetype);
544                                 JFFS2_WARNING(    544                                 JFFS2_WARNING("Unsupported node type %x found in summary! Exiting...\n", nodetype);
545                                 if ((nodetype     545                                 if ((nodetype & JFFS2_COMPAT_MASK) == JFFS2_FEATURE_INCOMPAT)
546                                         return    546                                         return -EIO;
547                                                   547 
548                                 /* For compati    548                                 /* For compatible node types, just fall back to the full scan */
549                                 c->wasted_size    549                                 c->wasted_size -= jeb->wasted_size;
550                                 c->free_size +    550                                 c->free_size += c->sector_size - jeb->free_size;
551                                 c->used_size -    551                                 c->used_size -= jeb->used_size;
552                                 c->dirty_size     552                                 c->dirty_size -= jeb->dirty_size;
553                                 jeb->wasted_si    553                                 jeb->wasted_size = jeb->used_size = jeb->dirty_size = 0;
554                                 jeb->free_size    554                                 jeb->free_size = c->sector_size;
555                                                   555 
556                                 jffs2_free_jeb    556                                 jffs2_free_jeb_node_refs(c, jeb);
557                                 return -ENOTRE    557                                 return -ENOTRECOVERABLE;
558                         }                         558                         }
559                 }                                 559                 }
560         }                                         560         }
561         return 0;                                 561         return 0;
562 }                                                 562 }
563                                                   563 
564 /* Process the summary node - called from jffs    564 /* Process the summary node - called from jffs2_scan_eraseblock() */
565 int jffs2_sum_scan_sumnode(struct jffs2_sb_inf    565 int jffs2_sum_scan_sumnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
566                            struct jffs2_raw_su    566                            struct jffs2_raw_summary *summary, uint32_t sumsize,
567                            uint32_t *pseudo_ra    567                            uint32_t *pseudo_random)
568 {                                                 568 {
569         struct jffs2_unknown_node crcnode;        569         struct jffs2_unknown_node crcnode;
570         int ret, ofs;                             570         int ret, ofs;
571         uint32_t crc;                             571         uint32_t crc;
572                                                   572 
573         ofs = c->sector_size - sumsize;           573         ofs = c->sector_size - sumsize;
574                                                   574 
575         dbg_summary("summary found for 0x%08x     575         dbg_summary("summary found for 0x%08x at 0x%08x (0x%x bytes)\n",
576                     jeb->offset, jeb->offset +    576                     jeb->offset, jeb->offset + ofs, sumsize);
577                                                   577 
578         /* OK, now check for node validity and    578         /* OK, now check for node validity and CRC */
579         crcnode.magic = cpu_to_je16(JFFS2_MAGI    579         crcnode.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
580         crcnode.nodetype = cpu_to_je16(JFFS2_N    580         crcnode.nodetype = cpu_to_je16(JFFS2_NODETYPE_SUMMARY);
581         crcnode.totlen = summary->totlen;         581         crcnode.totlen = summary->totlen;
582         crc = crc32(0, &crcnode, sizeof(crcnod    582         crc = crc32(0, &crcnode, sizeof(crcnode)-4);
583                                                   583 
584         if (je32_to_cpu(summary->hdr_crc) != c    584         if (je32_to_cpu(summary->hdr_crc) != crc) {
585                 dbg_summary("Summary node head    585                 dbg_summary("Summary node header is corrupt (bad CRC or "
586                                 "no summary at    586                                 "no summary at all)\n");
587                 goto crc_err;                     587                 goto crc_err;
588         }                                         588         }
589                                                   589 
590         if (je32_to_cpu(summary->totlen) != su    590         if (je32_to_cpu(summary->totlen) != sumsize) {
591                 dbg_summary("Summary node is c    591                 dbg_summary("Summary node is corrupt (wrong erasesize?)\n");
592                 goto crc_err;                     592                 goto crc_err;
593         }                                         593         }
594                                                   594 
595         crc = crc32(0, summary, sizeof(struct     595         crc = crc32(0, summary, sizeof(struct jffs2_raw_summary)-8);
596                                                   596 
597         if (je32_to_cpu(summary->node_crc) !=     597         if (je32_to_cpu(summary->node_crc) != crc) {
598                 dbg_summary("Summary node is c    598                 dbg_summary("Summary node is corrupt (bad CRC)\n");
599                 goto crc_err;                     599                 goto crc_err;
600         }                                         600         }
601                                                   601 
602         crc = crc32(0, summary->sum, sumsize -    602         crc = crc32(0, summary->sum, sumsize - sizeof(struct jffs2_raw_summary));
603                                                   603 
604         if (je32_to_cpu(summary->sum_crc) != c    604         if (je32_to_cpu(summary->sum_crc) != crc) {
605                 dbg_summary("Summary node data    605                 dbg_summary("Summary node data is corrupt (bad CRC)\n");
606                 goto crc_err;                     606                 goto crc_err;
607         }                                         607         }
608                                                   608 
609         if ( je32_to_cpu(summary->cln_mkr) ) {    609         if ( je32_to_cpu(summary->cln_mkr) ) {
610                                                   610 
611                 dbg_summary("Summary : CLEANMA    611                 dbg_summary("Summary : CLEANMARKER node \n");
612                                                   612 
613                 ret = jffs2_prealloc_raw_node_    613                 ret = jffs2_prealloc_raw_node_refs(c, jeb, 1);
614                 if (ret)                          614                 if (ret)
615                         return ret;               615                         return ret;
616                                                   616 
617                 if (je32_to_cpu(summary->cln_m    617                 if (je32_to_cpu(summary->cln_mkr) != c->cleanmarker_size) {
618                         dbg_summary("CLEANMARK    618                         dbg_summary("CLEANMARKER node has totlen 0x%x != normal 0x%x\n",
619                                 je32_to_cpu(su    619                                 je32_to_cpu(summary->cln_mkr), c->cleanmarker_size);
620                         if ((ret = jffs2_scan_    620                         if ((ret = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(summary->cln_mkr)))))
621                                 return ret;       621                                 return ret;
622                 } else if (jeb->first_node) {     622                 } else if (jeb->first_node) {
623                         dbg_summary("CLEANMARK    623                         dbg_summary("CLEANMARKER node not first node in block "
624                                         "(0x%0    624                                         "(0x%08x)\n", jeb->offset);
625                         if ((ret = jffs2_scan_    625                         if ((ret = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(summary->cln_mkr)))))
626                                 return ret;       626                                 return ret;
627                 } else {                          627                 } else {
628                         jffs2_link_node_ref(c,    628                         jffs2_link_node_ref(c, jeb, jeb->offset | REF_NORMAL,
629                                             je    629                                             je32_to_cpu(summary->cln_mkr), NULL);
630                 }                                 630                 }
631         }                                         631         }
632                                                   632 
633         ret = jffs2_sum_process_sum_data(c, je    633         ret = jffs2_sum_process_sum_data(c, jeb, summary, pseudo_random);
634         /* -ENOTRECOVERABLE isn't a fatal erro    634         /* -ENOTRECOVERABLE isn't a fatal error -- it means we should do a full
635            scan of this eraseblock. So return     635            scan of this eraseblock. So return zero */
636         if (ret == -ENOTRECOVERABLE)              636         if (ret == -ENOTRECOVERABLE)
637                 return 0;                         637                 return 0;
638         if (ret)                                  638         if (ret)
639                 return ret;             /* rea    639                 return ret;             /* real error */
640                                                   640 
641         /* for PARANOIA_CHECK */                  641         /* for PARANOIA_CHECK */
642         ret = jffs2_prealloc_raw_node_refs(c,     642         ret = jffs2_prealloc_raw_node_refs(c, jeb, 2);
643         if (ret)                                  643         if (ret)
644                 return ret;                       644                 return ret;
645                                                   645 
646         sum_link_node_ref(c, jeb, ofs | REF_NO    646         sum_link_node_ref(c, jeb, ofs | REF_NORMAL, sumsize, NULL);
647                                                   647 
648         if (unlikely(jeb->free_size)) {           648         if (unlikely(jeb->free_size)) {
649                 JFFS2_WARNING("Free size 0x%x     649                 JFFS2_WARNING("Free size 0x%x bytes in eraseblock @0x%08x with summary?\n",
650                               jeb->free_size,     650                               jeb->free_size, jeb->offset);
651                 jeb->wasted_size += jeb->free_    651                 jeb->wasted_size += jeb->free_size;
652                 c->wasted_size += jeb->free_si    652                 c->wasted_size += jeb->free_size;
653                 c->free_size -= jeb->free_size    653                 c->free_size -= jeb->free_size;
654                 jeb->free_size = 0;               654                 jeb->free_size = 0;
655         }                                         655         }
656                                                   656 
657         return jffs2_scan_classify_jeb(c, jeb)    657         return jffs2_scan_classify_jeb(c, jeb);
658                                                   658 
659 crc_err:                                          659 crc_err:
660         JFFS2_WARNING("Summary node crc error,    660         JFFS2_WARNING("Summary node crc error, skipping summary information.\n");
661                                                   661 
662         return 0;                                 662         return 0;
663 }                                                 663 }
664                                                   664 
665 /* Write summary data to flash - helper functi    665 /* Write summary data to flash - helper function for jffs2_sum_write_sumnode() */
666                                                   666 
667 static int jffs2_sum_write_data(struct jffs2_s    667 static int jffs2_sum_write_data(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
668                                         uint32    668                                         uint32_t infosize, uint32_t datasize, int padsize)
669 {                                                 669 {
670         struct jffs2_raw_summary isum;            670         struct jffs2_raw_summary isum;
671         union jffs2_sum_mem *temp;                671         union jffs2_sum_mem *temp;
672         struct jffs2_sum_marker *sm;              672         struct jffs2_sum_marker *sm;
673         struct kvec vecs[2];                      673         struct kvec vecs[2];
674         uint32_t sum_ofs;                         674         uint32_t sum_ofs;
675         void *wpage;                              675         void *wpage;
676         int ret;                                  676         int ret;
677         size_t retlen;                            677         size_t retlen;
678                                                   678 
679         memset(c->summary->sum_buf, 0xff, data    679         memset(c->summary->sum_buf, 0xff, datasize);
680         memset(&isum, 0, sizeof(isum));           680         memset(&isum, 0, sizeof(isum));
681                                                   681 
682         isum.magic = cpu_to_je16(JFFS2_MAGIC_B    682         isum.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
683         isum.nodetype = cpu_to_je16(JFFS2_NODE    683         isum.nodetype = cpu_to_je16(JFFS2_NODETYPE_SUMMARY);
684         isum.totlen = cpu_to_je32(infosize);      684         isum.totlen = cpu_to_je32(infosize);
685         isum.hdr_crc = cpu_to_je32(crc32(0, &i    685         isum.hdr_crc = cpu_to_je32(crc32(0, &isum, sizeof(struct jffs2_unknown_node) - 4));
686         isum.padded = cpu_to_je32(c->summary->    686         isum.padded = cpu_to_je32(c->summary->sum_padded);
687         isum.cln_mkr = cpu_to_je32(c->cleanmar    687         isum.cln_mkr = cpu_to_je32(c->cleanmarker_size);
688         isum.sum_num = cpu_to_je32(c->summary-    688         isum.sum_num = cpu_to_je32(c->summary->sum_num);
689         wpage = c->summary->sum_buf;              689         wpage = c->summary->sum_buf;
690                                                   690 
691         while (c->summary->sum_num) {             691         while (c->summary->sum_num) {
692                 temp = c->summary->sum_list_he    692                 temp = c->summary->sum_list_head;
693                                                   693 
694                 switch (je16_to_cpu(temp->u.no    694                 switch (je16_to_cpu(temp->u.nodetype)) {
695                         case JFFS2_NODETYPE_IN    695                         case JFFS2_NODETYPE_INODE: {
696                                 struct jffs2_s    696                                 struct jffs2_sum_inode_flash *sino_ptr = wpage;
697                                                   697 
698                                 sino_ptr->node    698                                 sino_ptr->nodetype = temp->i.nodetype;
699                                 sino_ptr->inod    699                                 sino_ptr->inode = temp->i.inode;
700                                 sino_ptr->vers    700                                 sino_ptr->version = temp->i.version;
701                                 sino_ptr->offs    701                                 sino_ptr->offset = temp->i.offset;
702                                 sino_ptr->totl    702                                 sino_ptr->totlen = temp->i.totlen;
703                                                   703 
704                                 wpage += JFFS2    704                                 wpage += JFFS2_SUMMARY_INODE_SIZE;
705                                                   705 
706                                 break;            706                                 break;
707                         }                         707                         }
708                                                   708 
709                         case JFFS2_NODETYPE_DI    709                         case JFFS2_NODETYPE_DIRENT: {
710                                 struct jffs2_s    710                                 struct jffs2_sum_dirent_flash *sdrnt_ptr = wpage;
711                                                   711 
712                                 sdrnt_ptr->nod    712                                 sdrnt_ptr->nodetype = temp->d.nodetype;
713                                 sdrnt_ptr->tot    713                                 sdrnt_ptr->totlen = temp->d.totlen;
714                                 sdrnt_ptr->off    714                                 sdrnt_ptr->offset = temp->d.offset;
715                                 sdrnt_ptr->pin    715                                 sdrnt_ptr->pino = temp->d.pino;
716                                 sdrnt_ptr->ver    716                                 sdrnt_ptr->version = temp->d.version;
717                                 sdrnt_ptr->ino    717                                 sdrnt_ptr->ino = temp->d.ino;
718                                 sdrnt_ptr->nsi    718                                 sdrnt_ptr->nsize = temp->d.nsize;
719                                 sdrnt_ptr->typ    719                                 sdrnt_ptr->type = temp->d.type;
720                                                   720 
721                                 memcpy(sdrnt_p    721                                 memcpy(sdrnt_ptr->name, temp->d.name,
722                                                   722                                                         temp->d.nsize);
723                                                   723 
724                                 wpage += JFFS2    724                                 wpage += JFFS2_SUMMARY_DIRENT_SIZE(temp->d.nsize);
725                                                   725 
726                                 break;            726                                 break;
727                         }                         727                         }
728 #ifdef CONFIG_JFFS2_FS_XATTR                      728 #ifdef CONFIG_JFFS2_FS_XATTR
729                         case JFFS2_NODETYPE_XA    729                         case JFFS2_NODETYPE_XATTR: {
730                                 struct jffs2_s    730                                 struct jffs2_sum_xattr_flash *sxattr_ptr = wpage;
731                                                   731 
732                                 temp = c->summ    732                                 temp = c->summary->sum_list_head;
733                                 sxattr_ptr->no    733                                 sxattr_ptr->nodetype = temp->x.nodetype;
734                                 sxattr_ptr->xi    734                                 sxattr_ptr->xid = temp->x.xid;
735                                 sxattr_ptr->ve    735                                 sxattr_ptr->version = temp->x.version;
736                                 sxattr_ptr->of    736                                 sxattr_ptr->offset = temp->x.offset;
737                                 sxattr_ptr->to    737                                 sxattr_ptr->totlen = temp->x.totlen;
738                                                   738 
739                                 wpage += JFFS2    739                                 wpage += JFFS2_SUMMARY_XATTR_SIZE;
740                                 break;            740                                 break;
741                         }                         741                         }
742                         case JFFS2_NODETYPE_XR    742                         case JFFS2_NODETYPE_XREF: {
743                                 struct jffs2_s    743                                 struct jffs2_sum_xref_flash *sxref_ptr = wpage;
744                                                   744 
745                                 temp = c->summ    745                                 temp = c->summary->sum_list_head;
746                                 sxref_ptr->nod    746                                 sxref_ptr->nodetype = temp->r.nodetype;
747                                 sxref_ptr->off    747                                 sxref_ptr->offset = temp->r.offset;
748                                                   748 
749                                 wpage += JFFS2    749                                 wpage += JFFS2_SUMMARY_XREF_SIZE;
750                                 break;            750                                 break;
751                         }                         751                         }
752 #endif                                            752 #endif
753                         default : {               753                         default : {
754                                 if ((je16_to_c    754                                 if ((je16_to_cpu(temp->u.nodetype) & JFFS2_COMPAT_MASK)
755                                     == JFFS2_F    755                                     == JFFS2_FEATURE_RWCOMPAT_COPY) {
756                                         dbg_su    756                                         dbg_summary("Writing unknown RWCOMPAT_COPY node type %x\n",
757                                                   757                                                     je16_to_cpu(temp->u.nodetype));
758                                         jffs2_    758                                         jffs2_sum_disable_collecting(c->summary);
759                                 } else {          759                                 } else {
760                                         BUG();    760                                         BUG();  /* unknown node in summary information */
761                                 }                 761                                 }
762                         }                         762                         }
763                 }                                 763                 }
764                                                   764 
765                 c->summary->sum_list_head = te    765                 c->summary->sum_list_head = temp->u.next;
766                 kfree(temp);                      766                 kfree(temp);
767                                                   767 
768                 c->summary->sum_num--;            768                 c->summary->sum_num--;
769         }                                         769         }
770                                                   770 
771         jffs2_sum_reset_collected(c->summary);    771         jffs2_sum_reset_collected(c->summary);
772                                                   772 
773         wpage += padsize;                         773         wpage += padsize;
774                                                   774 
775         sm = wpage;                               775         sm = wpage;
776         sm->offset = cpu_to_je32(c->sector_siz    776         sm->offset = cpu_to_je32(c->sector_size - jeb->free_size);
777         sm->magic = cpu_to_je32(JFFS2_SUM_MAGI    777         sm->magic = cpu_to_je32(JFFS2_SUM_MAGIC);
778                                                   778 
779         isum.sum_crc = cpu_to_je32(crc32(0, c-    779         isum.sum_crc = cpu_to_je32(crc32(0, c->summary->sum_buf, datasize));
780         isum.node_crc = cpu_to_je32(crc32(0, &    780         isum.node_crc = cpu_to_je32(crc32(0, &isum, sizeof(isum) - 8));
781                                                   781 
782         vecs[0].iov_base = &isum;                 782         vecs[0].iov_base = &isum;
783         vecs[0].iov_len = sizeof(isum);           783         vecs[0].iov_len = sizeof(isum);
784         vecs[1].iov_base = c->summary->sum_buf    784         vecs[1].iov_base = c->summary->sum_buf;
785         vecs[1].iov_len = datasize;               785         vecs[1].iov_len = datasize;
786                                                   786 
787         sum_ofs = jeb->offset + c->sector_size    787         sum_ofs = jeb->offset + c->sector_size - jeb->free_size;
788                                                   788 
789         dbg_summary("JFFS2: writing out data t    789         dbg_summary("JFFS2: writing out data to flash to pos : 0x%08x\n",
790                     sum_ofs);                     790                     sum_ofs);
791                                                   791 
792         ret = jffs2_flash_writev(c, vecs, 2, s    792         ret = jffs2_flash_writev(c, vecs, 2, sum_ofs, &retlen, 0);
793                                                   793 
794         if (ret || (retlen != infosize)) {        794         if (ret || (retlen != infosize)) {
795                                                   795 
796                 JFFS2_WARNING("Write of %u byt    796                 JFFS2_WARNING("Write of %u bytes at 0x%08x failed. returned %d, retlen %zd\n",
797                               infosize, sum_of    797                               infosize, sum_ofs, ret, retlen);
798                                                   798 
799                 if (retlen) {                     799                 if (retlen) {
800                         /* Waste remaining spa    800                         /* Waste remaining space */
801                         spin_lock(&c->erase_co    801                         spin_lock(&c->erase_completion_lock);
802                         jffs2_link_node_ref(c,    802                         jffs2_link_node_ref(c, jeb, sum_ofs | REF_OBSOLETE, infosize, NULL);
803                         spin_unlock(&c->erase_    803                         spin_unlock(&c->erase_completion_lock);
804                 }                                 804                 }
805                                                   805 
806                 c->summary->sum_size = JFFS2_S    806                 c->summary->sum_size = JFFS2_SUMMARY_NOSUM_SIZE;
807                                                   807 
808                 return 0;                         808                 return 0;
809         }                                         809         }
810                                                   810 
811         spin_lock(&c->erase_completion_lock);     811         spin_lock(&c->erase_completion_lock);
812         jffs2_link_node_ref(c, jeb, sum_ofs |     812         jffs2_link_node_ref(c, jeb, sum_ofs | REF_NORMAL, infosize, NULL);
813         spin_unlock(&c->erase_completion_lock)    813         spin_unlock(&c->erase_completion_lock);
814                                                   814 
815         return 0;                                 815         return 0;
816 }                                                 816 }
817                                                   817 
818 /* Write out summary information - called from    818 /* Write out summary information - called from jffs2_do_reserve_space */
819                                                   819 
820 int jffs2_sum_write_sumnode(struct jffs2_sb_in    820 int jffs2_sum_write_sumnode(struct jffs2_sb_info *c)
821 {                                                 821 {
822         int datasize, infosize, padsize;          822         int datasize, infosize, padsize;
823         struct jffs2_eraseblock *jeb;             823         struct jffs2_eraseblock *jeb;
824         int ret;                                  824         int ret;
825                                                   825 
826         dbg_summary("called\n");                  826         dbg_summary("called\n");
827                                                   827 
828         spin_unlock(&c->erase_completion_lock)    828         spin_unlock(&c->erase_completion_lock);
829                                                   829 
830         jeb = c->nextblock;                       830         jeb = c->nextblock;
831         jffs2_prealloc_raw_node_refs(c, jeb, 1    831         jffs2_prealloc_raw_node_refs(c, jeb, 1);
832                                                   832 
833         if (!c->summary->sum_num || !c->summar    833         if (!c->summary->sum_num || !c->summary->sum_list_head) {
834                 JFFS2_WARNING("Empty summary i    834                 JFFS2_WARNING("Empty summary info!!!\n");
835                 BUG();                            835                 BUG();
836         }                                         836         }
837                                                   837 
838         datasize = c->summary->sum_size + size    838         datasize = c->summary->sum_size + sizeof(struct jffs2_sum_marker);
839         infosize = sizeof(struct jffs2_raw_sum    839         infosize = sizeof(struct jffs2_raw_summary) + datasize;
840         padsize = jeb->free_size - infosize;      840         padsize = jeb->free_size - infosize;
841         infosize += padsize;                      841         infosize += padsize;
842         datasize += padsize;                      842         datasize += padsize;
843                                                   843 
844         /* Is there enough space for summary?     844         /* Is there enough space for summary? */
845         if (padsize < 0) {                        845         if (padsize < 0) {
846                 /* don't try to write out summ    846                 /* don't try to write out summary for this jeb */
847                 jffs2_sum_disable_collecting(c    847                 jffs2_sum_disable_collecting(c->summary);
848                                                   848 
849                 JFFS2_WARNING("Not enough spac    849                 JFFS2_WARNING("Not enough space for summary, padsize = %d\n", padsize);
850                 spin_lock(&c->erase_completion    850                 spin_lock(&c->erase_completion_lock);
851                 return 0;                         851                 return 0;
852         }                                         852         }
853                                                   853 
854         ret = jffs2_sum_write_data(c, jeb, inf    854         ret = jffs2_sum_write_data(c, jeb, infosize, datasize, padsize);
855         spin_lock(&c->erase_completion_lock);     855         spin_lock(&c->erase_completion_lock);
856         return ret;                               856         return ret;
857 }                                                 857 }
858                                                   858 
  This page was automatically generated by the LXR engine.