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