uboot/fs/ubifs/ubifs.c
<<
>>
Prefs
   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#ifdef CONFIG_NEEDS_MANUAL_RELOC
 205        ubifs_compressors[compr->compr_type]->name += gd->reloc_off;
 206        ubifs_compressors[compr->compr_type]->capi_name += gd->reloc_off;
 207        ubifs_compressors[compr->compr_type]->decompress += gd->reloc_off;
 208#endif
 209
 210        if (compr->capi_name) {
 211                compr->cc = crypto_alloc_comp(compr->capi_name, 0, 0);
 212                if (IS_ERR(compr->cc)) {
 213                        dbg_gen("cannot initialize compressor %s,"
 214                                  " error %ld", compr->name,
 215                                  PTR_ERR(compr->cc));
 216                        return PTR_ERR(compr->cc);
 217                }
 218        }
 219
 220        return 0;
 221}
 222
 223/**
 224 * ubifs_compressors_init - initialize UBIFS compressors.
 225 *
 226 * This function initializes the compressor which were compiled in. Returns
 227 * zero in case of success and a negative error code in case of failure.
 228 */
 229int __init ubifs_compressors_init(void)
 230{
 231        int err;
 232
 233        err = compr_init(&lzo_compr);
 234        if (err)
 235                return err;
 236
 237        err = compr_init(&zlib_compr);
 238        if (err)
 239                return err;
 240
 241        err = compr_init(&none_compr);
 242        if (err)
 243                return err;
 244
 245        return 0;
 246}
 247
 248/*
 249 * ubifsls...
 250 */
 251
 252static int filldir(struct ubifs_info *c, const char *name, int namlen,
 253                   u64 ino, unsigned int d_type)
 254{
 255        struct inode *inode;
 256        char filetime[32];
 257
 258        switch (d_type) {
 259        case UBIFS_ITYPE_REG:
 260                printf("\t");
 261                break;
 262        case UBIFS_ITYPE_DIR:
 263                printf("<DIR>\t");
 264                break;
 265        case UBIFS_ITYPE_LNK:
 266                printf("<LNK>\t");
 267                break;
 268        default:
 269                printf("other\t");
 270                break;
 271        }
 272
 273        inode = ubifs_iget(c->vfs_sb, ino);
 274        if (IS_ERR(inode)) {
 275                printf("%s: Error in ubifs_iget(), ino=%lld ret=%p!\n",
 276                       __func__, ino, inode);
 277                return -1;
 278        }
 279        ctime_r((time_t *)&inode->i_mtime, filetime);
 280        printf("%9lld  %24.24s  ", inode->i_size, filetime);
 281#ifndef __UBOOT__
 282        ubifs_iput(inode);
 283#endif
 284
 285        printf("%s\n", name);
 286
 287        return 0;
 288}
 289
 290static int ubifs_printdir(struct file *file, void *dirent)
 291{
 292        int err, over = 0;
 293        struct qstr nm;
 294        union ubifs_key key;
 295        struct ubifs_dent_node *dent;
 296        struct inode *dir = file->f_path.dentry->d_inode;
 297        struct ubifs_info *c = dir->i_sb->s_fs_info;
 298
 299        dbg_gen("dir ino %lu, f_pos %#llx", dir->i_ino, file->f_pos);
 300
 301        if (file->f_pos > UBIFS_S_KEY_HASH_MASK || file->f_pos == 2)
 302                /*
 303                 * The directory was seek'ed to a senseless position or there
 304                 * are no more entries.
 305                 */
 306                return 0;
 307
 308        if (file->f_pos == 1) {
 309                /* Find the first entry in TNC and save it */
 310                lowest_dent_key(c, &key, dir->i_ino);
 311                nm.name = NULL;
 312                dent = ubifs_tnc_next_ent(c, &key, &nm);
 313                if (IS_ERR(dent)) {
 314                        err = PTR_ERR(dent);
 315                        goto out;
 316                }
 317
 318                file->f_pos = key_hash_flash(c, &dent->key);
 319                file->private_data = dent;
 320        }
 321
 322        dent = file->private_data;
 323        if (!dent) {
 324                /*
 325                 * The directory was seek'ed to and is now readdir'ed.
 326                 * Find the entry corresponding to @file->f_pos or the
 327                 * closest one.
 328                 */
 329                dent_key_init_hash(c, &key, dir->i_ino, file->f_pos);
 330                nm.name = NULL;
 331                dent = ubifs_tnc_next_ent(c, &key, &nm);
 332                if (IS_ERR(dent)) {
 333                        err = PTR_ERR(dent);
 334                        goto out;
 335                }
 336                file->f_pos = key_hash_flash(c, &dent->key);
 337                file->private_data = dent;
 338        }
 339
 340        while (1) {
 341                dbg_gen("feed '%s', ino %llu, new f_pos %#x",
 342                        dent->name, (unsigned long long)le64_to_cpu(dent->inum),
 343                        key_hash_flash(c, &dent->key));
 344#ifndef __UBOOT__
 345                ubifs_assert(le64_to_cpu(dent->ch.sqnum) > ubifs_inode(dir)->creat_sqnum);
 346#endif
 347
 348                nm.len = le16_to_cpu(dent->nlen);
 349                over = filldir(c, (char *)dent->name, nm.len,
 350                               le64_to_cpu(dent->inum), dent->type);
 351                if (over)
 352                        return 0;
 353
 354                /* Switch to the next entry */
 355                key_read(c, &dent->key, &key);
 356                nm.name = (char *)dent->name;
 357                dent = ubifs_tnc_next_ent(c, &key, &nm);
 358                if (IS_ERR(dent)) {
 359                        err = PTR_ERR(dent);
 360                        goto out;
 361                }
 362
 363                kfree(file->private_data);
 364                file->f_pos = key_hash_flash(c, &dent->key);
 365                file->private_data = dent;
 366                cond_resched();
 367        }
 368
 369out:
 370        if (err != -ENOENT) {
 371                ubifs_err(c, "cannot find next direntry, error %d", err);
 372                return err;
 373        }
 374
 375        kfree(file->private_data);
 376        file->private_data = NULL;
 377        file->f_pos = 2;
 378        return 0;
 379}
 380
 381static int ubifs_finddir(struct super_block *sb, char *dirname,
 382                         unsigned long root_inum, unsigned long *inum)
 383{
 384        int err;
 385        struct qstr nm;
 386        union ubifs_key key;
 387        struct ubifs_dent_node *dent;
 388        struct ubifs_info *c;
 389        struct file *file;
 390        struct dentry *dentry;
 391        struct inode *dir;
 392        int ret = 0;
 393
 394        file = kzalloc(sizeof(struct file), 0);
 395        dentry = kzalloc(sizeof(struct dentry), 0);
 396        dir = kzalloc(sizeof(struct inode), 0);
 397        if (!file || !dentry || !dir) {
 398                printf("%s: Error, no memory for malloc!\n", __func__);
 399                err = -ENOMEM;
 400                goto out;
 401        }
 402
 403        dir->i_sb = sb;
 404        file->f_path.dentry = dentry;
 405        file->f_path.dentry->d_parent = dentry;
 406        file->f_path.dentry->d_inode = dir;
 407        file->f_path.dentry->d_inode->i_ino = root_inum;
 408        c = sb->s_fs_info;
 409
 410        dbg_gen("dir ino %lu, f_pos %#llx", dir->i_ino, file->f_pos);
 411
 412        /* Find the first entry in TNC and save it */
 413        lowest_dent_key(c, &key, dir->i_ino);
 414        nm.name = NULL;
 415        dent = ubifs_tnc_next_ent(c, &key, &nm);
 416        if (IS_ERR(dent)) {
 417                err = PTR_ERR(dent);
 418                goto out;
 419        }
 420
 421        file->f_pos = key_hash_flash(c, &dent->key);
 422        file->private_data = dent;
 423
 424        while (1) {
 425                dbg_gen("feed '%s', ino %llu, new f_pos %#x",
 426                        dent->name, (unsigned long long)le64_to_cpu(dent->inum),
 427                        key_hash_flash(c, &dent->key));
 428#ifndef __UBOOT__
 429                ubifs_assert(le64_to_cpu(dent->ch.sqnum) > ubifs_inode(dir)->creat_sqnum);
 430#endif
 431
 432                nm.len = le16_to_cpu(dent->nlen);
 433                if ((strncmp(dirname, (char *)dent->name, nm.len) == 0) &&
 434                    (strlen(dirname) == nm.len)) {
 435                        *inum = le64_to_cpu(dent->inum);
 436                        ret = 1;
 437                        goto out_free;
 438                }
 439
 440                /* Switch to the next entry */
 441                key_read(c, &dent->key, &key);
 442                nm.name = (char *)dent->name;
 443                dent = ubifs_tnc_next_ent(c, &key, &nm);
 444                if (IS_ERR(dent)) {
 445                        err = PTR_ERR(dent);
 446                        goto out;
 447                }
 448
 449                kfree(file->private_data);
 450                file->f_pos = key_hash_flash(c, &dent->key);
 451                file->private_data = dent;
 452                cond_resched();
 453        }
 454
 455out:
 456        if (err != -ENOENT)
 457                dbg_gen("cannot find next direntry, error %d", err);
 458
 459out_free:
 460        kfree(file->private_data);
 461        free(file);
 462        free(dentry);
 463        free(dir);
 464
 465        return ret;
 466}
 467
 468static unsigned long ubifs_findfile(struct super_block *sb, char *filename)
 469{
 470        int ret;
 471        char *next;
 472        char fpath[128];
 473        char symlinkpath[128];
 474        char *name = fpath;
 475        unsigned long root_inum = 1;
 476        unsigned long inum;
 477        int symlink_count = 0; /* Don't allow symlink recursion */
 478        char link_name[64];
 479
 480        strcpy(fpath, filename);
 481
 482        /* Remove all leading slashes */
 483        while (*name == '/')
 484                name++;
 485
 486        /*
 487         * Handle root-direcoty ('/')
 488         */
 489        inum = root_inum;
 490        if (!name || *name == '\0')
 491                return inum;
 492
 493        for (;;) {
 494                struct inode *inode;
 495                struct ubifs_inode *ui;
 496
 497                /* Extract the actual part from the pathname.  */
 498                next = strchr(name, '/');
 499                if (next) {
 500                        /* Remove all leading slashes.  */
 501                        while (*next == '/')
 502                                *(next++) = '\0';
 503                }
 504
 505                ret = ubifs_finddir(sb, name, root_inum, &inum);
 506                if (!ret)
 507                        return 0;
 508                inode = ubifs_iget(sb, inum);
 509
 510                if (!inode)
 511                        return 0;
 512                ui = ubifs_inode(inode);
 513
 514                if ((inode->i_mode & S_IFMT) == S_IFLNK) {
 515                        char buf[128];
 516
 517                        /* We have some sort of symlink recursion, bail out */
 518                        if (symlink_count++ > 8) {
 519                                printf("Symlink recursion, aborting\n");
 520                                return 0;
 521                        }
 522                        memcpy(link_name, ui->data, ui->data_len);
 523                        link_name[ui->data_len] = '\0';
 524
 525                        if (link_name[0] == '/') {
 526                                /* Absolute path, redo everything without
 527                                 * the leading slash */
 528                                next = name = link_name + 1;
 529                                root_inum = 1;
 530                                continue;
 531                        }
 532                        /* Relative to cur dir */
 533                        sprintf(buf, "%s/%s",
 534                                        link_name, next == NULL ? "" : next);
 535                        memcpy(symlinkpath, buf, sizeof(buf));
 536                        next = name = symlinkpath;
 537                        continue;
 538                }
 539
 540                /*
 541                 * Check if directory with this name exists
 542                 */
 543
 544                /* Found the node!  */
 545                if (!next || *next == '\0')
 546                        return inum;
 547
 548                root_inum = inum;
 549                name = next;
 550        }
 551
 552        return 0;
 553}
 554
 555int ubifs_set_blk_dev(struct blk_desc *rbdd, struct disk_partition *info)
 556{
 557        if (rbdd) {
 558                debug("UBIFS cannot be used with normal block devices\n");
 559                return -1;
 560        }
 561
 562        /*
 563         * Should never happen since blk_get_device_part_str() already checks
 564         * this, but better safe then sorry.
 565         */
 566        if (!ubifs_is_mounted()) {
 567                debug("UBIFS not mounted, use ubifsmount to mount volume first!\n");
 568                return -1;
 569        }
 570
 571        return 0;
 572}
 573
 574int ubifs_ls(const char *filename)
 575{
 576        struct ubifs_info *c = ubifs_sb->s_fs_info;
 577        struct file *file;
 578        struct dentry *dentry;
 579        struct inode *dir;
 580        void *dirent = NULL;
 581        unsigned long inum;
 582        int ret = 0;
 583
 584        c->ubi = ubi_open_volume(c->vi.ubi_num, c->vi.vol_id, UBI_READONLY);
 585        inum = ubifs_findfile(ubifs_sb, (char *)filename);
 586        if (!inum) {
 587                ret = -1;
 588                goto out;
 589        }
 590
 591        file = kzalloc(sizeof(struct file), 0);
 592        dentry = kzalloc(sizeof(struct dentry), 0);
 593        dir = kzalloc(sizeof(struct inode), 0);
 594        if (!file || !dentry || !dir) {
 595                printf("%s: Error, no memory for malloc!\n", __func__);
 596                ret = -ENOMEM;
 597                goto out_mem;
 598        }
 599
 600        dir->i_sb = ubifs_sb;
 601        file->f_path.dentry = dentry;
 602        file->f_path.dentry->d_parent = dentry;
 603        file->f_path.dentry->d_inode = dir;
 604        file->f_path.dentry->d_inode->i_ino = inum;
 605        file->f_pos = 1;
 606        file->private_data = NULL;
 607        ubifs_printdir(file, dirent);
 608
 609out_mem:
 610        if (file)
 611                free(file);
 612        if (dentry)
 613                free(dentry);
 614        if (dir)
 615                free(dir);
 616
 617out:
 618        ubi_close_volume(c->ubi);
 619        return ret;
 620}
 621
 622int ubifs_exists(const char *filename)
 623{
 624        struct ubifs_info *c = ubifs_sb->s_fs_info;
 625        unsigned long inum;
 626
 627        c->ubi = ubi_open_volume(c->vi.ubi_num, c->vi.vol_id, UBI_READONLY);
 628        inum = ubifs_findfile(ubifs_sb, (char *)filename);
 629        ubi_close_volume(c->ubi);
 630
 631        return inum != 0;
 632}
 633
 634int ubifs_size(const char *filename, loff_t *size)
 635{
 636        struct ubifs_info *c = ubifs_sb->s_fs_info;
 637        unsigned long inum;
 638        struct inode *inode;
 639        int err = 0;
 640
 641        c->ubi = ubi_open_volume(c->vi.ubi_num, c->vi.vol_id, UBI_READONLY);
 642
 643        inum = ubifs_findfile(ubifs_sb, (char *)filename);
 644        if (!inum) {
 645                err = -1;
 646                goto out;
 647        }
 648
 649        inode = ubifs_iget(ubifs_sb, inum);
 650        if (IS_ERR(inode)) {
 651                printf("%s: Error reading inode %ld!\n", __func__, inum);
 652                err = PTR_ERR(inode);
 653                goto out;
 654        }
 655
 656        *size = inode->i_size;
 657
 658        ubifs_iput(inode);
 659out:
 660        ubi_close_volume(c->ubi);
 661        return err;
 662}
 663
 664/*
 665 * ubifsload...
 666 */
 667
 668/* file.c */
 669
 670static inline void *kmap(struct page *page)
 671{
 672        return page->addr;
 673}
 674
 675static int read_block(struct inode *inode, void *addr, unsigned int block,
 676                      struct ubifs_data_node *dn)
 677{
 678        struct ubifs_info *c = inode->i_sb->s_fs_info;
 679        int err, len, out_len;
 680        union ubifs_key key;
 681        unsigned int dlen;
 682
 683        data_key_init(c, &key, inode->i_ino, block);
 684        err = ubifs_tnc_lookup(c, &key, dn);
 685        if (err) {
 686                if (err == -ENOENT)
 687                        /* Not found, so it must be a hole */
 688                        memset(addr, 0, UBIFS_BLOCK_SIZE);
 689                return err;
 690        }
 691
 692        ubifs_assert(le64_to_cpu(dn->ch.sqnum) > ubifs_inode(inode)->creat_sqnum);
 693
 694        len = le32_to_cpu(dn->size);
 695        if (len <= 0 || len > UBIFS_BLOCK_SIZE)
 696                goto dump;
 697
 698        dlen = le32_to_cpu(dn->ch.len) - UBIFS_DATA_NODE_SZ;
 699        out_len = UBIFS_BLOCK_SIZE;
 700        err = ubifs_decompress(c, &dn->data, dlen, addr, &out_len,
 701                               le16_to_cpu(dn->compr_type));
 702        if (err || len != out_len)
 703                goto dump;
 704
 705        /*
 706         * Data length can be less than a full block, even for blocks that are
 707         * not the last in the file (e.g., as a result of making a hole and
 708         * appending data). Ensure that the remainder is zeroed out.
 709         */
 710        if (len < UBIFS_BLOCK_SIZE)
 711                memset(addr + len, 0, UBIFS_BLOCK_SIZE - len);
 712
 713        return 0;
 714
 715dump:
 716        ubifs_err(c, "bad data node (block %u, inode %lu)",
 717                  block, inode->i_ino);
 718        ubifs_dump_node(c, dn);
 719        return -EINVAL;
 720}
 721
 722static int do_readpage(struct ubifs_info *c, struct inode *inode,
 723                       struct page *page, int last_block_size)
 724{
 725        void *addr;
 726        int err = 0, i;
 727        unsigned int block, beyond;
 728        struct ubifs_data_node *dn;
 729        loff_t i_size = inode->i_size;
 730
 731        dbg_gen("ino %lu, pg %lu, i_size %lld",
 732                inode->i_ino, page->index, i_size);
 733
 734        addr = kmap(page);
 735
 736        block = page->index << UBIFS_BLOCKS_PER_PAGE_SHIFT;
 737        beyond = (i_size + UBIFS_BLOCK_SIZE - 1) >> UBIFS_BLOCK_SHIFT;
 738        if (block >= beyond) {
 739                /* Reading beyond inode */
 740                memset(addr, 0, PAGE_CACHE_SIZE);
 741                goto out;
 742        }
 743
 744        dn = kmalloc(UBIFS_MAX_DATA_NODE_SZ, GFP_NOFS);
 745        if (!dn)
 746                return -ENOMEM;
 747
 748        i = 0;
 749        while (1) {
 750                int ret;
 751
 752                if (block >= beyond) {
 753                        /* Reading beyond inode */
 754                        err = -ENOENT;
 755                        memset(addr, 0, UBIFS_BLOCK_SIZE);
 756                } else {
 757                        /*
 758                         * Reading last block? Make sure to not write beyond
 759                         * the requested size in the destination buffer.
 760                         */
 761                        if (((block + 1) == beyond) || last_block_size) {
 762                                void *buff;
 763                                int dlen;
 764
 765                                /*
 766                                 * We need to buffer the data locally for the
 767                                 * last block. This is to not pad the
 768                                 * destination area to a multiple of
 769                                 * UBIFS_BLOCK_SIZE.
 770                                 */
 771                                buff = malloc_cache_aligned(UBIFS_BLOCK_SIZE);
 772                                if (!buff) {
 773                                        printf("%s: Error, malloc fails!\n",
 774                                               __func__);
 775                                        err = -ENOMEM;
 776                                        break;
 777                                }
 778
 779                                /* Read block-size into temp buffer */
 780                                ret = read_block(inode, buff, block, dn);
 781                                if (ret) {
 782                                        err = ret;
 783                                        if (err != -ENOENT) {
 784                                                free(buff);
 785                                                break;
 786                                        }
 787                                }
 788
 789                                if (last_block_size)
 790                                        dlen = last_block_size;
 791                                else
 792                                        dlen = le32_to_cpu(dn->size);
 793
 794                                /* Now copy required size back to dest */
 795                                memcpy(addr, buff, dlen);
 796
 797                                free(buff);
 798                        } else {
 799                                ret = read_block(inode, addr, block, dn);
 800                                if (ret) {
 801                                        err = ret;
 802                                        if (err != -ENOENT)
 803                                                break;
 804                                }
 805                        }
 806                }
 807                if (++i >= UBIFS_BLOCKS_PER_PAGE)
 808                        break;
 809                block += 1;
 810                addr += UBIFS_BLOCK_SIZE;
 811        }
 812        if (err) {
 813                if (err == -ENOENT) {
 814                        /* Not found, so it must be a hole */
 815                        dbg_gen("hole");
 816                        goto out_free;
 817                }
 818                ubifs_err(c, "cannot read page %lu of inode %lu, error %d",
 819                          page->index, inode->i_ino, err);
 820                goto error;
 821        }
 822
 823out_free:
 824        kfree(dn);
 825out:
 826        return 0;
 827
 828error:
 829        kfree(dn);
 830        return err;
 831}
 832
 833int ubifs_read(const char *filename, void *buf, loff_t offset,
 834               loff_t size, loff_t *actread)
 835{
 836        struct ubifs_info *c = ubifs_sb->s_fs_info;
 837        unsigned long inum;
 838        struct inode *inode;
 839        struct page page;
 840        int err = 0;
 841        int i;
 842        int count;
 843        int last_block_size = 0;
 844
 845        *actread = 0;
 846
 847        if (offset & (PAGE_SIZE - 1)) {
 848                printf("ubifs: Error offset must be a multiple of %d\n",
 849                       PAGE_SIZE);
 850                return -1;
 851        }
 852
 853        c->ubi = ubi_open_volume(c->vi.ubi_num, c->vi.vol_id, UBI_READONLY);
 854        /* ubifs_findfile will resolve symlinks, so we know that we get
 855         * the real file here */
 856        inum = ubifs_findfile(ubifs_sb, (char *)filename);
 857        if (!inum) {
 858                err = -1;
 859                goto out;
 860        }
 861
 862        /*
 863         * Read file inode
 864         */
 865        inode = ubifs_iget(ubifs_sb, inum);
 866        if (IS_ERR(inode)) {
 867                printf("%s: Error reading inode %ld!\n", __func__, inum);
 868                err = PTR_ERR(inode);
 869                goto out;
 870        }
 871
 872        if (offset > inode->i_size) {
 873                printf("ubifs: Error offset (%lld) > file-size (%lld)\n",
 874                       offset, size);
 875                err = -1;
 876                goto put_inode;
 877        }
 878
 879        /*
 880         * If no size was specified or if size bigger than filesize
 881         * set size to filesize
 882         */
 883        if ((size == 0) || (size > (inode->i_size - offset)))
 884                size = inode->i_size - offset;
 885
 886        count = (size + UBIFS_BLOCK_SIZE - 1) >> UBIFS_BLOCK_SHIFT;
 887
 888        page.addr = buf;
 889        page.index = offset / PAGE_SIZE;
 890        page.inode = inode;
 891        for (i = 0; i < count; i++) {
 892                /*
 893                 * Make sure to not read beyond the requested size
 894                 */
 895                if (((i + 1) == count) && (size < inode->i_size))
 896                        last_block_size = size - (i * PAGE_SIZE);
 897
 898                err = do_readpage(c, inode, &page, last_block_size);
 899                if (err)
 900                        break;
 901
 902                page.addr += PAGE_SIZE;
 903                page.index++;
 904        }
 905
 906        if (err) {
 907                printf("Error reading file '%s'\n", filename);
 908                *actread = i * PAGE_SIZE;
 909        } else {
 910                *actread = size;
 911        }
 912
 913put_inode:
 914        ubifs_iput(inode);
 915
 916out:
 917        ubi_close_volume(c->ubi);
 918        return err;
 919}
 920
 921void ubifs_close(void)
 922{
 923}
 924
 925/* Compat wrappers for common/cmd_ubifs.c */
 926int ubifs_load(char *filename, u32 addr, u32 size)
 927{
 928        loff_t actread;
 929        int err;
 930
 931        printf("Loading file '%s' to addr 0x%08x...\n", filename, addr);
 932
 933        err = ubifs_read(filename, (void *)(uintptr_t)addr, 0, size, &actread);
 934        if (err == 0) {
 935                env_set_hex("filesize", actread);
 936                printf("Done\n");
 937        }
 938
 939        return err;
 940}
 941
 942void uboot_ubifs_umount(void)
 943{
 944        if (ubifs_sb) {
 945                printf("Unmounting UBIFS volume %s!\n",
 946                       ((struct ubifs_info *)(ubifs_sb->s_fs_info))->vi.name);
 947                ubifs_umount(ubifs_sb->s_fs_info);
 948                ubifs_sb = NULL;
 949        }
 950}
 951