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