xref: /OK3568_Linux_fs/u-boot/fs/ubifs/ubifs.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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