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