]> git.sur5r.net Git - u-boot/blob - fs/ubifs/ubifs.c
mpc83xx: Add strider board
[u-boot] / fs / ubifs / ubifs.c
1 /*
2  * This file is part of UBIFS.
3  *
4  * Copyright (C) 2006-2008 Nokia Corporation.
5  *
6  * (C) Copyright 2008-2010
7  * Stefan Roese, DENX Software Engineering, sr@denx.de.
8  *
9  * This program is free software; you can redistribute it and/or modify it
10  * under the terms of the GNU General Public License version 2 as published by
11  * the Free Software Foundation.
12  *
13  * This program is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
16  * more details.
17  *
18  * You should have received a copy of the GNU General Public License along with
19  * this program; if not, write to the Free Software Foundation, Inc., 51
20  * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21  *
22  * Authors: Artem Bityutskiy (Битюцкий Артём)
23  *          Adrian Hunter
24  */
25
26 #include <common.h>
27 #include <memalign.h>
28 #include "ubifs.h"
29 #include <u-boot/zlib.h>
30
31 #include <linux/err.h>
32 #include <linux/lzo.h>
33
34 DECLARE_GLOBAL_DATA_PTR;
35
36 /* compress.c */
37
38 /*
39  * We need a wrapper for zunzip() because the parameters are
40  * incompatible with the lzo decompressor.
41  */
42 static int gzip_decompress(const unsigned char *in, size_t in_len,
43                            unsigned char *out, size_t *out_len)
44 {
45         return zunzip(out, *out_len, (unsigned char *)in,
46                       (unsigned long *)out_len, 0, 0);
47 }
48
49 /* Fake description object for the "none" compressor */
50 static struct ubifs_compressor none_compr = {
51         .compr_type = UBIFS_COMPR_NONE,
52         .name = "none",
53         .capi_name = "",
54         .decompress = NULL,
55 };
56
57 static struct ubifs_compressor lzo_compr = {
58         .compr_type = UBIFS_COMPR_LZO,
59 #ifndef __UBOOT__
60         .comp_mutex = &lzo_mutex,
61 #endif
62         .name = "lzo",
63         .capi_name = "lzo",
64         .decompress = lzo1x_decompress_safe,
65 };
66
67 static struct ubifs_compressor zlib_compr = {
68         .compr_type = UBIFS_COMPR_ZLIB,
69 #ifndef __UBOOT__
70         .comp_mutex = &deflate_mutex,
71         .decomp_mutex = &inflate_mutex,
72 #endif
73         .name = "zlib",
74         .capi_name = "deflate",
75         .decompress = gzip_decompress,
76 };
77
78 /* All UBIFS compressors */
79 struct ubifs_compressor *ubifs_compressors[UBIFS_COMPR_TYPES_CNT];
80
81
82 #ifdef __UBOOT__
83 /* from mm/util.c */
84
85 /**
86  * kmemdup - duplicate region of memory
87  *
88  * @src: memory region to duplicate
89  * @len: memory region length
90  * @gfp: GFP mask to use
91  */
92 void *kmemdup(const void *src, size_t len, gfp_t gfp)
93 {
94         void *p;
95
96         p = kmalloc(len, gfp);
97         if (p)
98                 memcpy(p, src, len);
99         return p;
100 }
101
102 struct crypto_comp {
103         int compressor;
104 };
105
106 static inline struct crypto_comp
107 *crypto_alloc_comp(const char *alg_name, u32 type, u32 mask)
108 {
109         struct ubifs_compressor *comp;
110         struct crypto_comp *ptr;
111         int i = 0;
112
113         ptr = malloc_cache_aligned(sizeof(struct crypto_comp));
114         while (i < UBIFS_COMPR_TYPES_CNT) {
115                 comp = ubifs_compressors[i];
116                 if (!comp) {
117                         i++;
118                         continue;
119                 }
120                 if (strncmp(alg_name, comp->capi_name, strlen(alg_name)) == 0) {
121                         ptr->compressor = i;
122                         return ptr;
123                 }
124                 i++;
125         }
126         if (i >= UBIFS_COMPR_TYPES_CNT) {
127                 dbg_gen("invalid compression type %s", alg_name);
128                 free (ptr);
129                 return NULL;
130         }
131         return ptr;
132 }
133 static inline int
134 crypto_comp_decompress(const struct ubifs_info *c, struct crypto_comp *tfm,
135                        const u8 *src, unsigned int slen, u8 *dst,
136                        unsigned int *dlen)
137 {
138         struct ubifs_compressor *compr = ubifs_compressors[tfm->compressor];
139         int err;
140
141         if (compr->compr_type == UBIFS_COMPR_NONE) {
142                 memcpy(dst, src, slen);
143                 *dlen = slen;
144                 return 0;
145         }
146
147         err = compr->decompress(src, slen, dst, (size_t *)dlen);
148         if (err)
149                 ubifs_err(c, "cannot decompress %d bytes, compressor %s, "
150                           "error %d", slen, compr->name, err);
151
152         return err;
153
154         return 0;
155 }
156
157 /* from shrinker.c */
158
159 /* Global clean znode counter (for all mounted UBIFS instances) */
160 atomic_long_t ubifs_clean_zn_cnt;
161
162 #endif
163
164 /**
165  * ubifs_decompress - decompress data.
166  * @in_buf: data to decompress
167  * @in_len: length of the data to decompress
168  * @out_buf: output buffer where decompressed data should
169  * @out_len: output length is returned here
170  * @compr_type: type of compression
171  *
172  * This function decompresses data from buffer @in_buf into buffer @out_buf.
173  * The length of the uncompressed data is returned in @out_len. This functions
174  * returns %0 on success or a negative error code on failure.
175  */
176 int ubifs_decompress(const struct ubifs_info *c, const void *in_buf,
177                      int in_len, void *out_buf, int *out_len, int compr_type)
178 {
179         int err;
180         struct ubifs_compressor *compr;
181
182         if (unlikely(compr_type < 0 || compr_type >= UBIFS_COMPR_TYPES_CNT)) {
183                 ubifs_err(c, "invalid compression type %d", compr_type);
184                 return -EINVAL;
185         }
186
187         compr = ubifs_compressors[compr_type];
188
189         if (unlikely(!compr->capi_name)) {
190                 ubifs_err(c, "%s compression is not compiled in", compr->name);
191                 return -EINVAL;
192         }
193
194         if (compr_type == UBIFS_COMPR_NONE) {
195                 memcpy(out_buf, in_buf, in_len);
196                 *out_len = in_len;
197                 return 0;
198         }
199
200         if (compr->decomp_mutex)
201                 mutex_lock(compr->decomp_mutex);
202         err = crypto_comp_decompress(c, compr->cc, in_buf, in_len, out_buf,
203                                      (unsigned int *)out_len);
204         if (compr->decomp_mutex)
205                 mutex_unlock(compr->decomp_mutex);
206         if (err)
207                 ubifs_err(c, "cannot decompress %d bytes, compressor %s,"
208                           " error %d", in_len, compr->name, err);
209
210         return err;
211 }
212
213 /**
214  * compr_init - initialize a compressor.
215  * @compr: compressor description object
216  *
217  * This function initializes the requested compressor and returns zero in case
218  * of success or a negative error code in case of failure.
219  */
220 static int __init compr_init(struct ubifs_compressor *compr)
221 {
222         ubifs_compressors[compr->compr_type] = compr;
223
224 #ifdef CONFIG_NEEDS_MANUAL_RELOC
225         ubifs_compressors[compr->compr_type]->name += gd->reloc_off;
226         ubifs_compressors[compr->compr_type]->capi_name += gd->reloc_off;
227         ubifs_compressors[compr->compr_type]->decompress += gd->reloc_off;
228 #endif
229
230         if (compr->capi_name) {
231                 compr->cc = crypto_alloc_comp(compr->capi_name, 0, 0);
232                 if (IS_ERR(compr->cc)) {
233                         dbg_gen("cannot initialize compressor %s,"
234                                   " error %ld", compr->name,
235                                   PTR_ERR(compr->cc));
236                         return PTR_ERR(compr->cc);
237                 }
238         }
239
240         return 0;
241 }
242
243 /**
244  * ubifs_compressors_init - initialize UBIFS compressors.
245  *
246  * This function initializes the compressor which were compiled in. Returns
247  * zero in case of success and a negative error code in case of failure.
248  */
249 int __init ubifs_compressors_init(void)
250 {
251         int err;
252
253         err = compr_init(&lzo_compr);
254         if (err)
255                 return err;
256
257         err = compr_init(&zlib_compr);
258         if (err)
259                 return err;
260
261         err = compr_init(&none_compr);
262         if (err)
263                 return err;
264
265         return 0;
266 }
267
268 /*
269  * ubifsls...
270  */
271
272 static int filldir(struct ubifs_info *c, const char *name, int namlen,
273                    u64 ino, unsigned int d_type)
274 {
275         struct inode *inode;
276         char filetime[32];
277
278         switch (d_type) {
279         case UBIFS_ITYPE_REG:
280                 printf("\t");
281                 break;
282         case UBIFS_ITYPE_DIR:
283                 printf("<DIR>\t");
284                 break;
285         case UBIFS_ITYPE_LNK:
286                 printf("<LNK>\t");
287                 break;
288         default:
289                 printf("other\t");
290                 break;
291         }
292
293         inode = ubifs_iget(c->vfs_sb, ino);
294         if (IS_ERR(inode)) {
295                 printf("%s: Error in ubifs_iget(), ino=%lld ret=%p!\n",
296                        __func__, ino, inode);
297                 return -1;
298         }
299         ctime_r((time_t *)&inode->i_mtime, filetime);
300         printf("%9lld  %24.24s  ", inode->i_size, filetime);
301 #ifndef __UBOOT__
302         ubifs_iput(inode);
303 #endif
304
305         printf("%s\n", name);
306
307         return 0;
308 }
309
310 static int ubifs_printdir(struct file *file, void *dirent)
311 {
312         int err, over = 0;
313         struct qstr nm;
314         union ubifs_key key;
315         struct ubifs_dent_node *dent;
316         struct inode *dir = file->f_path.dentry->d_inode;
317         struct ubifs_info *c = dir->i_sb->s_fs_info;
318
319         dbg_gen("dir ino %lu, f_pos %#llx", dir->i_ino, file->f_pos);
320
321         if (file->f_pos > UBIFS_S_KEY_HASH_MASK || file->f_pos == 2)
322                 /*
323                  * The directory was seek'ed to a senseless position or there
324                  * are no more entries.
325                  */
326                 return 0;
327
328         if (file->f_pos == 1) {
329                 /* Find the first entry in TNC and save it */
330                 lowest_dent_key(c, &key, dir->i_ino);
331                 nm.name = NULL;
332                 dent = ubifs_tnc_next_ent(c, &key, &nm);
333                 if (IS_ERR(dent)) {
334                         err = PTR_ERR(dent);
335                         goto out;
336                 }
337
338                 file->f_pos = key_hash_flash(c, &dent->key);
339                 file->private_data = dent;
340         }
341
342         dent = file->private_data;
343         if (!dent) {
344                 /*
345                  * The directory was seek'ed to and is now readdir'ed.
346                  * Find the entry corresponding to @file->f_pos or the
347                  * closest one.
348                  */
349                 dent_key_init_hash(c, &key, dir->i_ino, file->f_pos);
350                 nm.name = NULL;
351                 dent = ubifs_tnc_next_ent(c, &key, &nm);
352                 if (IS_ERR(dent)) {
353                         err = PTR_ERR(dent);
354                         goto out;
355                 }
356                 file->f_pos = key_hash_flash(c, &dent->key);
357                 file->private_data = dent;
358         }
359
360         while (1) {
361                 dbg_gen("feed '%s', ino %llu, new f_pos %#x",
362                         dent->name, (unsigned long long)le64_to_cpu(dent->inum),
363                         key_hash_flash(c, &dent->key));
364                 ubifs_assert(le64_to_cpu(dent->ch.sqnum) > ubifs_inode(dir)->creat_sqnum);
365
366                 nm.len = le16_to_cpu(dent->nlen);
367                 over = filldir(c, (char *)dent->name, nm.len,
368                                le64_to_cpu(dent->inum), dent->type);
369                 if (over)
370                         return 0;
371
372                 /* Switch to the next entry */
373                 key_read(c, &dent->key, &key);
374                 nm.name = (char *)dent->name;
375                 dent = ubifs_tnc_next_ent(c, &key, &nm);
376                 if (IS_ERR(dent)) {
377                         err = PTR_ERR(dent);
378                         goto out;
379                 }
380
381                 kfree(file->private_data);
382                 file->f_pos = key_hash_flash(c, &dent->key);
383                 file->private_data = dent;
384                 cond_resched();
385         }
386
387 out:
388         if (err != -ENOENT) {
389                 ubifs_err(c, "cannot find next direntry, error %d", err);
390                 return err;
391         }
392
393         kfree(file->private_data);
394         file->private_data = NULL;
395         file->f_pos = 2;
396         return 0;
397 }
398
399 static int ubifs_finddir(struct super_block *sb, char *dirname,
400                          unsigned long root_inum, unsigned long *inum)
401 {
402         int err;
403         struct qstr nm;
404         union ubifs_key key;
405         struct ubifs_dent_node *dent;
406         struct ubifs_info *c;
407         struct file *file;
408         struct dentry *dentry;
409         struct inode *dir;
410         int ret = 0;
411
412         file = kzalloc(sizeof(struct file), 0);
413         dentry = kzalloc(sizeof(struct dentry), 0);
414         dir = kzalloc(sizeof(struct inode), 0);
415         if (!file || !dentry || !dir) {
416                 printf("%s: Error, no memory for malloc!\n", __func__);
417                 err = -ENOMEM;
418                 goto out;
419         }
420
421         dir->i_sb = sb;
422         file->f_path.dentry = dentry;
423         file->f_path.dentry->d_parent = dentry;
424         file->f_path.dentry->d_inode = dir;
425         file->f_path.dentry->d_inode->i_ino = root_inum;
426         c = sb->s_fs_info;
427
428         dbg_gen("dir ino %lu, f_pos %#llx", dir->i_ino, file->f_pos);
429
430         /* Find the first entry in TNC and save it */
431         lowest_dent_key(c, &key, dir->i_ino);
432         nm.name = NULL;
433         dent = ubifs_tnc_next_ent(c, &key, &nm);
434         if (IS_ERR(dent)) {
435                 err = PTR_ERR(dent);
436                 goto out;
437         }
438
439         file->f_pos = key_hash_flash(c, &dent->key);
440         file->private_data = dent;
441
442         while (1) {
443                 dbg_gen("feed '%s', ino %llu, new f_pos %#x",
444                         dent->name, (unsigned long long)le64_to_cpu(dent->inum),
445                         key_hash_flash(c, &dent->key));
446                 ubifs_assert(le64_to_cpu(dent->ch.sqnum) > ubifs_inode(dir)->creat_sqnum);
447
448                 nm.len = le16_to_cpu(dent->nlen);
449                 if ((strncmp(dirname, (char *)dent->name, nm.len) == 0) &&
450                     (strlen(dirname) == nm.len)) {
451                         *inum = le64_to_cpu(dent->inum);
452                         ret = 1;
453                         goto out_free;
454                 }
455
456                 /* Switch to the next entry */
457                 key_read(c, &dent->key, &key);
458                 nm.name = (char *)dent->name;
459                 dent = ubifs_tnc_next_ent(c, &key, &nm);
460                 if (IS_ERR(dent)) {
461                         err = PTR_ERR(dent);
462                         goto out;
463                 }
464
465                 kfree(file->private_data);
466                 file->f_pos = key_hash_flash(c, &dent->key);
467                 file->private_data = dent;
468                 cond_resched();
469         }
470
471 out:
472         if (err != -ENOENT)
473                 dbg_gen("cannot find next direntry, error %d", err);
474
475 out_free:
476         if (file->private_data)
477                 kfree(file->private_data);
478         if (file)
479                 free(file);
480         if (dentry)
481                 free(dentry);
482         if (dir)
483                 free(dir);
484
485         return ret;
486 }
487
488 static unsigned long ubifs_findfile(struct super_block *sb, char *filename)
489 {
490         int ret;
491         char *next;
492         char fpath[128];
493         char symlinkpath[128];
494         char *name = fpath;
495         unsigned long root_inum = 1;
496         unsigned long inum;
497         int symlink_count = 0; /* Don't allow symlink recursion */
498         char link_name[64];
499
500         strcpy(fpath, filename);
501
502         /* Remove all leading slashes */
503         while (*name == '/')
504                 name++;
505
506         /*
507          * Handle root-direcoty ('/')
508          */
509         inum = root_inum;
510         if (!name || *name == '\0')
511                 return inum;
512
513         for (;;) {
514                 struct inode *inode;
515                 struct ubifs_inode *ui;
516
517                 /* Extract the actual part from the pathname.  */
518                 next = strchr(name, '/');
519                 if (next) {
520                         /* Remove all leading slashes.  */
521                         while (*next == '/')
522                                 *(next++) = '\0';
523                 }
524
525                 ret = ubifs_finddir(sb, name, root_inum, &inum);
526                 if (!ret)
527                         return 0;
528                 inode = ubifs_iget(sb, inum);
529
530                 if (!inode)
531                         return 0;
532                 ui = ubifs_inode(inode);
533
534                 if ((inode->i_mode & S_IFMT) == S_IFLNK) {
535                         char buf[128];
536
537                         /* We have some sort of symlink recursion, bail out */
538                         if (symlink_count++ > 8) {
539                                 printf("Symlink recursion, aborting\n");
540                                 return 0;
541                         }
542                         memcpy(link_name, ui->data, ui->data_len);
543                         link_name[ui->data_len] = '\0';
544
545                         if (link_name[0] == '/') {
546                                 /* Absolute path, redo everything without
547                                  * the leading slash */
548                                 next = name = link_name + 1;
549                                 root_inum = 1;
550                                 continue;
551                         }
552                         /* Relative to cur dir */
553                         sprintf(buf, "%s/%s",
554                                         link_name, next == NULL ? "" : next);
555                         memcpy(symlinkpath, buf, sizeof(buf));
556                         next = name = symlinkpath;
557                         continue;
558                 }
559
560                 /*
561                  * Check if directory with this name exists
562                  */
563
564                 /* Found the node!  */
565                 if (!next || *next == '\0')
566                         return inum;
567
568                 root_inum = inum;
569                 name = next;
570         }
571
572         return 0;
573 }
574
575 int ubifs_set_blk_dev(block_dev_desc_t *rbdd, disk_partition_t *info)
576 {
577         if (rbdd) {
578                 debug("UBIFS cannot be used with normal block devices\n");
579                 return -1;
580         }
581
582         /*
583          * Should never happen since get_device_and_partition() already checks
584          * this, but better safe then sorry.
585          */
586         if (!ubifs_is_mounted()) {
587                 debug("UBIFS not mounted, use ubifsmount to mount volume first!\n");
588                 return -1;
589         }
590
591         return 0;
592 }
593
594 int ubifs_ls(const char *filename)
595 {
596         struct ubifs_info *c = ubifs_sb->s_fs_info;
597         struct file *file;
598         struct dentry *dentry;
599         struct inode *dir;
600         void *dirent = NULL;
601         unsigned long inum;
602         int ret = 0;
603
604         c->ubi = ubi_open_volume(c->vi.ubi_num, c->vi.vol_id, UBI_READONLY);
605         inum = ubifs_findfile(ubifs_sb, (char *)filename);
606         if (!inum) {
607                 ret = -1;
608                 goto out;
609         }
610
611         file = kzalloc(sizeof(struct file), 0);
612         dentry = kzalloc(sizeof(struct dentry), 0);
613         dir = kzalloc(sizeof(struct inode), 0);
614         if (!file || !dentry || !dir) {
615                 printf("%s: Error, no memory for malloc!\n", __func__);
616                 ret = -ENOMEM;
617                 goto out_mem;
618         }
619
620         dir->i_sb = ubifs_sb;
621         file->f_path.dentry = dentry;
622         file->f_path.dentry->d_parent = dentry;
623         file->f_path.dentry->d_inode = dir;
624         file->f_path.dentry->d_inode->i_ino = inum;
625         file->f_pos = 1;
626         file->private_data = NULL;
627         ubifs_printdir(file, dirent);
628
629 out_mem:
630         if (file)
631                 free(file);
632         if (dentry)
633                 free(dentry);
634         if (dir)
635                 free(dir);
636
637 out:
638         ubi_close_volume(c->ubi);
639         return ret;
640 }
641
642 int ubifs_exists(const char *filename)
643 {
644         struct ubifs_info *c = ubifs_sb->s_fs_info;
645         unsigned long inum;
646
647         c->ubi = ubi_open_volume(c->vi.ubi_num, c->vi.vol_id, UBI_READONLY);
648         inum = ubifs_findfile(ubifs_sb, (char *)filename);
649         ubi_close_volume(c->ubi);
650
651         return inum != 0;
652 }
653
654 int ubifs_size(const char *filename, loff_t *size)
655 {
656         struct ubifs_info *c = ubifs_sb->s_fs_info;
657         unsigned long inum;
658         struct inode *inode;
659         int err = 0;
660
661         c->ubi = ubi_open_volume(c->vi.ubi_num, c->vi.vol_id, UBI_READONLY);
662
663         inum = ubifs_findfile(ubifs_sb, (char *)filename);
664         if (!inum) {
665                 err = -1;
666                 goto out;
667         }
668
669         inode = ubifs_iget(ubifs_sb, inum);
670         if (IS_ERR(inode)) {
671                 printf("%s: Error reading inode %ld!\n", __func__, inum);
672                 err = PTR_ERR(inode);
673                 goto out;
674         }
675
676         *size = inode->i_size;
677
678         ubifs_iput(inode);
679 out:
680         ubi_close_volume(c->ubi);
681         return err;
682 }
683
684 /*
685  * ubifsload...
686  */
687
688 /* file.c */
689
690 static inline void *kmap(struct page *page)
691 {
692         return page->addr;
693 }
694
695 static int read_block(struct inode *inode, void *addr, unsigned int block,
696                       struct ubifs_data_node *dn)
697 {
698         struct ubifs_info *c = inode->i_sb->s_fs_info;
699         int err, len, out_len;
700         union ubifs_key key;
701         unsigned int dlen;
702
703         data_key_init(c, &key, inode->i_ino, block);
704         err = ubifs_tnc_lookup(c, &key, dn);
705         if (err) {
706                 if (err == -ENOENT)
707                         /* Not found, so it must be a hole */
708                         memset(addr, 0, UBIFS_BLOCK_SIZE);
709                 return err;
710         }
711
712         ubifs_assert(le64_to_cpu(dn->ch.sqnum) > ubifs_inode(inode)->creat_sqnum);
713
714         len = le32_to_cpu(dn->size);
715         if (len <= 0 || len > UBIFS_BLOCK_SIZE)
716                 goto dump;
717
718         dlen = le32_to_cpu(dn->ch.len) - UBIFS_DATA_NODE_SZ;
719         out_len = UBIFS_BLOCK_SIZE;
720         err = ubifs_decompress(c, &dn->data, dlen, addr, &out_len,
721                                le16_to_cpu(dn->compr_type));
722         if (err || len != out_len)
723                 goto dump;
724
725         /*
726          * Data length can be less than a full block, even for blocks that are
727          * not the last in the file (e.g., as a result of making a hole and
728          * appending data). Ensure that the remainder is zeroed out.
729          */
730         if (len < UBIFS_BLOCK_SIZE)
731                 memset(addr + len, 0, UBIFS_BLOCK_SIZE - len);
732
733         return 0;
734
735 dump:
736         ubifs_err(c, "bad data node (block %u, inode %lu)",
737                   block, inode->i_ino);
738         ubifs_dump_node(c, dn);
739         return -EINVAL;
740 }
741
742 static int do_readpage(struct ubifs_info *c, struct inode *inode,
743                        struct page *page, int last_block_size)
744 {
745         void *addr;
746         int err = 0, i;
747         unsigned int block, beyond;
748         struct ubifs_data_node *dn;
749         loff_t i_size = inode->i_size;
750
751         dbg_gen("ino %lu, pg %lu, i_size %lld",
752                 inode->i_ino, page->index, i_size);
753
754         addr = kmap(page);
755
756         block = page->index << UBIFS_BLOCKS_PER_PAGE_SHIFT;
757         beyond = (i_size + UBIFS_BLOCK_SIZE - 1) >> UBIFS_BLOCK_SHIFT;
758         if (block >= beyond) {
759                 /* Reading beyond inode */
760                 memset(addr, 0, PAGE_CACHE_SIZE);
761                 goto out;
762         }
763
764         dn = kmalloc(UBIFS_MAX_DATA_NODE_SZ, GFP_NOFS);
765         if (!dn)
766                 return -ENOMEM;
767
768         i = 0;
769         while (1) {
770                 int ret;
771
772                 if (block >= beyond) {
773                         /* Reading beyond inode */
774                         err = -ENOENT;
775                         memset(addr, 0, UBIFS_BLOCK_SIZE);
776                 } else {
777                         /*
778                          * Reading last block? Make sure to not write beyond
779                          * the requested size in the destination buffer.
780                          */
781                         if (((block + 1) == beyond) || last_block_size) {
782                                 void *buff;
783                                 int dlen;
784
785                                 /*
786                                  * We need to buffer the data locally for the
787                                  * last block. This is to not pad the
788                                  * destination area to a multiple of
789                                  * UBIFS_BLOCK_SIZE.
790                                  */
791                                 buff = malloc_cache_aligned(UBIFS_BLOCK_SIZE);
792                                 if (!buff) {
793                                         printf("%s: Error, malloc fails!\n",
794                                                __func__);
795                                         err = -ENOMEM;
796                                         break;
797                                 }
798
799                                 /* Read block-size into temp buffer */
800                                 ret = read_block(inode, buff, block, dn);
801                                 if (ret) {
802                                         err = ret;
803                                         if (err != -ENOENT) {
804                                                 free(buff);
805                                                 break;
806                                         }
807                                 }
808
809                                 if (last_block_size)
810                                         dlen = last_block_size;
811                                 else
812                                         dlen = le32_to_cpu(dn->size);
813
814                                 /* Now copy required size back to dest */
815                                 memcpy(addr, buff, dlen);
816
817                                 free(buff);
818                         } else {
819                                 ret = read_block(inode, addr, block, dn);
820                                 if (ret) {
821                                         err = ret;
822                                         if (err != -ENOENT)
823                                                 break;
824                                 }
825                         }
826                 }
827                 if (++i >= UBIFS_BLOCKS_PER_PAGE)
828                         break;
829                 block += 1;
830                 addr += UBIFS_BLOCK_SIZE;
831         }
832         if (err) {
833                 if (err == -ENOENT) {
834                         /* Not found, so it must be a hole */
835                         dbg_gen("hole");
836                         goto out_free;
837                 }
838                 ubifs_err(c, "cannot read page %lu of inode %lu, error %d",
839                           page->index, inode->i_ino, err);
840                 goto error;
841         }
842
843 out_free:
844         kfree(dn);
845 out:
846         return 0;
847
848 error:
849         kfree(dn);
850         return err;
851 }
852
853 int ubifs_read(const char *filename, void *buf, loff_t offset,
854                loff_t size, loff_t *actread)
855 {
856         struct ubifs_info *c = ubifs_sb->s_fs_info;
857         unsigned long inum;
858         struct inode *inode;
859         struct page page;
860         int err = 0;
861         int i;
862         int count;
863         int last_block_size = 0;
864
865         *actread = 0;
866
867         if (offset & (PAGE_SIZE - 1)) {
868                 printf("ubifs: Error offset must be a multple of %d\n",
869                        PAGE_SIZE);
870                 return -1;
871         }
872
873         c->ubi = ubi_open_volume(c->vi.ubi_num, c->vi.vol_id, UBI_READONLY);
874         /* ubifs_findfile will resolve symlinks, so we know that we get
875          * the real file here */
876         inum = ubifs_findfile(ubifs_sb, (char *)filename);
877         if (!inum) {
878                 err = -1;
879                 goto out;
880         }
881
882         /*
883          * Read file inode
884          */
885         inode = ubifs_iget(ubifs_sb, inum);
886         if (IS_ERR(inode)) {
887                 printf("%s: Error reading inode %ld!\n", __func__, inum);
888                 err = PTR_ERR(inode);
889                 goto out;
890         }
891
892         if (offset > inode->i_size) {
893                 printf("ubifs: Error offset (%lld) > file-size (%lld)\n",
894                        offset, size);
895                 err = -1;
896                 goto put_inode;
897         }
898
899         /*
900          * If no size was specified or if size bigger than filesize
901          * set size to filesize
902          */
903         if ((size == 0) || (size > (inode->i_size - offset)))
904                 size = inode->i_size - offset;
905
906         count = (size + UBIFS_BLOCK_SIZE - 1) >> UBIFS_BLOCK_SHIFT;
907
908         page.addr = buf;
909         page.index = offset / PAGE_SIZE;
910         page.inode = inode;
911         for (i = 0; i < count; i++) {
912                 /*
913                  * Make sure to not read beyond the requested size
914                  */
915                 if (((i + 1) == count) && (size < inode->i_size))
916                         last_block_size = size - (i * PAGE_SIZE);
917
918                 err = do_readpage(c, inode, &page, last_block_size);
919                 if (err)
920                         break;
921
922                 page.addr += PAGE_SIZE;
923                 page.index++;
924         }
925
926         if (err) {
927                 printf("Error reading file '%s'\n", filename);
928                 *actread = i * PAGE_SIZE;
929         } else {
930                 *actread = size;
931         }
932
933 put_inode:
934         ubifs_iput(inode);
935
936 out:
937         ubi_close_volume(c->ubi);
938         return err;
939 }
940
941 void ubifs_close(void)
942 {
943 }
944
945 /* Compat wrappers for common/cmd_ubifs.c */
946 int ubifs_load(char *filename, u32 addr, u32 size)
947 {
948         loff_t actread;
949         int err;
950
951         printf("Loading file '%s' to addr 0x%08x...\n", filename, addr);
952
953         err = ubifs_read(filename, (void *)addr, 0, size, &actread);
954         if (err == 0) {
955                 setenv_hex("filesize", actread);
956                 printf("Done\n");
957         }
958
959         return err;
960 }
961
962 void uboot_ubifs_umount(void)
963 {
964         if (ubifs_sb) {
965                 printf("Unmounting UBIFS volume %s!\n",
966                        ((struct ubifs_info *)(ubifs_sb->s_fs_info))->vi.name);
967                 ubifs_umount(ubifs_sb->s_fs_info);
968                 ubifs_sb = NULL;
969         }
970 }