linux/fs/f2fs/extent_cache.c
<<
>>
Prefs
   1/*
   2 * f2fs extent cache support
   3 *
   4 * Copyright (c) 2015 Motorola Mobility
   5 * Copyright (c) 2015 Samsung Electronics
   6 * Authors: Jaegeuk Kim <jaegeuk@kernel.org>
   7 *          Chao Yu <chao2.yu@samsung.com>
   8 *
   9 * This program is free software; you can redistribute it and/or modify
  10 * it under the terms of the GNU General Public License version 2 as
  11 * published by the Free Software Foundation.
  12 */
  13
  14#include <linux/fs.h>
  15#include <linux/f2fs_fs.h>
  16
  17#include "f2fs.h"
  18#include "node.h"
  19#include <trace/events/f2fs.h>
  20
  21static struct kmem_cache *extent_tree_slab;
  22static struct kmem_cache *extent_node_slab;
  23
  24static struct extent_node *__attach_extent_node(struct f2fs_sb_info *sbi,
  25                                struct extent_tree *et, struct extent_info *ei,
  26                                struct rb_node *parent, struct rb_node **p)
  27{
  28        struct extent_node *en;
  29
  30        en = kmem_cache_alloc(extent_node_slab, GFP_ATOMIC);
  31        if (!en)
  32                return NULL;
  33
  34        en->ei = *ei;
  35        INIT_LIST_HEAD(&en->list);
  36
  37        rb_link_node(&en->rb_node, parent, p);
  38        rb_insert_color(&en->rb_node, &et->root);
  39        et->count++;
  40        atomic_inc(&sbi->total_ext_node);
  41        return en;
  42}
  43
  44static void __detach_extent_node(struct f2fs_sb_info *sbi,
  45                                struct extent_tree *et, struct extent_node *en)
  46{
  47        rb_erase(&en->rb_node, &et->root);
  48        et->count--;
  49        atomic_dec(&sbi->total_ext_node);
  50
  51        if (et->cached_en == en)
  52                et->cached_en = NULL;
  53}
  54
  55static struct extent_tree *__grab_extent_tree(struct inode *inode)
  56{
  57        struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
  58        struct extent_tree *et;
  59        nid_t ino = inode->i_ino;
  60
  61        down_write(&sbi->extent_tree_lock);
  62        et = radix_tree_lookup(&sbi->extent_tree_root, ino);
  63        if (!et) {
  64                et = f2fs_kmem_cache_alloc(extent_tree_slab, GFP_NOFS);
  65                f2fs_radix_tree_insert(&sbi->extent_tree_root, ino, et);
  66                memset(et, 0, sizeof(struct extent_tree));
  67                et->ino = ino;
  68                et->root = RB_ROOT;
  69                et->cached_en = NULL;
  70                rwlock_init(&et->lock);
  71                atomic_set(&et->refcount, 0);
  72                et->count = 0;
  73                sbi->total_ext_tree++;
  74        }
  75        atomic_inc(&et->refcount);
  76        up_write(&sbi->extent_tree_lock);
  77
  78        /* never died until evict_inode */
  79        F2FS_I(inode)->extent_tree = et;
  80
  81        return et;
  82}
  83
  84static struct extent_node *__lookup_extent_tree(struct f2fs_sb_info *sbi,
  85                                struct extent_tree *et, unsigned int fofs)
  86{
  87        struct rb_node *node = et->root.rb_node;
  88        struct extent_node *en = et->cached_en;
  89
  90        if (en) {
  91                struct extent_info *cei = &en->ei;
  92
  93                if (cei->fofs <= fofs && cei->fofs + cei->len > fofs) {
  94                        stat_inc_cached_node_hit(sbi);
  95                        return en;
  96                }
  97        }
  98
  99        while (node) {
 100                en = rb_entry(node, struct extent_node, rb_node);
 101
 102                if (fofs < en->ei.fofs) {
 103                        node = node->rb_left;
 104                } else if (fofs >= en->ei.fofs + en->ei.len) {
 105                        node = node->rb_right;
 106                } else {
 107                        stat_inc_rbtree_node_hit(sbi);
 108                        return en;
 109                }
 110        }
 111        return NULL;
 112}
 113
 114static struct extent_node *__init_extent_tree(struct f2fs_sb_info *sbi,
 115                                struct extent_tree *et, struct extent_info *ei)
 116{
 117        struct rb_node **p = &et->root.rb_node;
 118        struct extent_node *en;
 119
 120        en = __attach_extent_node(sbi, et, ei, NULL, p);
 121        if (!en)
 122                return NULL;
 123
 124        et->largest = en->ei;
 125        et->cached_en = en;
 126        return en;
 127}
 128
 129static unsigned int __free_extent_tree(struct f2fs_sb_info *sbi,
 130                                        struct extent_tree *et, bool free_all)
 131{
 132        struct rb_node *node, *next;
 133        struct extent_node *en;
 134        unsigned int count = et->count;
 135
 136        node = rb_first(&et->root);
 137        while (node) {
 138                next = rb_next(node);
 139                en = rb_entry(node, struct extent_node, rb_node);
 140
 141                if (free_all) {
 142                        spin_lock(&sbi->extent_lock);
 143                        if (!list_empty(&en->list))
 144                                list_del_init(&en->list);
 145                        spin_unlock(&sbi->extent_lock);
 146                }
 147
 148                if (free_all || list_empty(&en->list)) {
 149                        __detach_extent_node(sbi, et, en);
 150                        kmem_cache_free(extent_node_slab, en);
 151                }
 152                node = next;
 153        }
 154
 155        return count - et->count;
 156}
 157
 158static void __drop_largest_extent(struct inode *inode,
 159                                        pgoff_t fofs, unsigned int len)
 160{
 161        struct extent_info *largest = &F2FS_I(inode)->extent_tree->largest;
 162
 163        if (fofs < largest->fofs + largest->len && fofs + len > largest->fofs)
 164                largest->len = 0;
 165}
 166
 167void f2fs_drop_largest_extent(struct inode *inode, pgoff_t fofs)
 168{
 169        if (!f2fs_may_extent_tree(inode))
 170                return;
 171
 172        __drop_largest_extent(inode, fofs, 1);
 173}
 174
 175void f2fs_init_extent_tree(struct inode *inode, struct f2fs_extent *i_ext)
 176{
 177        struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
 178        struct extent_tree *et;
 179        struct extent_node *en;
 180        struct extent_info ei;
 181
 182        if (!f2fs_may_extent_tree(inode))
 183                return;
 184
 185        et = __grab_extent_tree(inode);
 186
 187        if (!i_ext || le32_to_cpu(i_ext->len) < F2FS_MIN_EXTENT_LEN)
 188                return;
 189
 190        set_extent_info(&ei, le32_to_cpu(i_ext->fofs),
 191                le32_to_cpu(i_ext->blk), le32_to_cpu(i_ext->len));
 192
 193        write_lock(&et->lock);
 194        if (et->count)
 195                goto out;
 196
 197        en = __init_extent_tree(sbi, et, &ei);
 198        if (en) {
 199                spin_lock(&sbi->extent_lock);
 200                list_add_tail(&en->list, &sbi->extent_list);
 201                spin_unlock(&sbi->extent_lock);
 202        }
 203out:
 204        write_unlock(&et->lock);
 205}
 206
 207static bool f2fs_lookup_extent_tree(struct inode *inode, pgoff_t pgofs,
 208                                                        struct extent_info *ei)
 209{
 210        struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
 211        struct extent_tree *et = F2FS_I(inode)->extent_tree;
 212        struct extent_node *en;
 213        bool ret = false;
 214
 215        f2fs_bug_on(sbi, !et);
 216
 217        trace_f2fs_lookup_extent_tree_start(inode, pgofs);
 218
 219        read_lock(&et->lock);
 220
 221        if (et->largest.fofs <= pgofs &&
 222                        et->largest.fofs + et->largest.len > pgofs) {
 223                *ei = et->largest;
 224                ret = true;
 225                stat_inc_largest_node_hit(sbi);
 226                goto out;
 227        }
 228
 229        en = __lookup_extent_tree(sbi, et, pgofs);
 230        if (en) {
 231                *ei = en->ei;
 232                spin_lock(&sbi->extent_lock);
 233                if (!list_empty(&en->list))
 234                        list_move_tail(&en->list, &sbi->extent_list);
 235                et->cached_en = en;
 236                spin_unlock(&sbi->extent_lock);
 237                ret = true;
 238        }
 239out:
 240        stat_inc_total_hit(sbi);
 241        read_unlock(&et->lock);
 242
 243        trace_f2fs_lookup_extent_tree_end(inode, pgofs, ei);
 244        return ret;
 245}
 246
 247
 248/*
 249 * lookup extent at @fofs, if hit, return the extent
 250 * if not, return NULL and
 251 * @prev_ex: extent before fofs
 252 * @next_ex: extent after fofs
 253 * @insert_p: insert point for new extent at fofs
 254 * in order to simpfy the insertion after.
 255 * tree must stay unchanged between lookup and insertion.
 256 */
 257static struct extent_node *__lookup_extent_tree_ret(struct extent_tree *et,
 258                                unsigned int fofs,
 259                                struct extent_node **prev_ex,
 260                                struct extent_node **next_ex,
 261                                struct rb_node ***insert_p,
 262                                struct rb_node **insert_parent)
 263{
 264        struct rb_node **pnode = &et->root.rb_node;
 265        struct rb_node *parent = NULL, *tmp_node;
 266        struct extent_node *en = et->cached_en;
 267
 268        *insert_p = NULL;
 269        *insert_parent = NULL;
 270        *prev_ex = NULL;
 271        *next_ex = NULL;
 272
 273        if (RB_EMPTY_ROOT(&et->root))
 274                return NULL;
 275
 276        if (en) {
 277                struct extent_info *cei = &en->ei;
 278
 279                if (cei->fofs <= fofs && cei->fofs + cei->len > fofs)
 280                        goto lookup_neighbors;
 281        }
 282
 283        while (*pnode) {
 284                parent = *pnode;
 285                en = rb_entry(*pnode, struct extent_node, rb_node);
 286
 287                if (fofs < en->ei.fofs)
 288                        pnode = &(*pnode)->rb_left;
 289                else if (fofs >= en->ei.fofs + en->ei.len)
 290                        pnode = &(*pnode)->rb_right;
 291                else
 292                        goto lookup_neighbors;
 293        }
 294
 295        *insert_p = pnode;
 296        *insert_parent = parent;
 297
 298        en = rb_entry(parent, struct extent_node, rb_node);
 299        tmp_node = parent;
 300        if (parent && fofs > en->ei.fofs)
 301                tmp_node = rb_next(parent);
 302        *next_ex = tmp_node ?
 303                rb_entry(tmp_node, struct extent_node, rb_node) : NULL;
 304
 305        tmp_node = parent;
 306        if (parent && fofs < en->ei.fofs)
 307                tmp_node = rb_prev(parent);
 308        *prev_ex = tmp_node ?
 309                rb_entry(tmp_node, struct extent_node, rb_node) : NULL;
 310        return NULL;
 311
 312lookup_neighbors:
 313        if (fofs == en->ei.fofs) {
 314                /* lookup prev node for merging backward later */
 315                tmp_node = rb_prev(&en->rb_node);
 316                *prev_ex = tmp_node ?
 317                        rb_entry(tmp_node, struct extent_node, rb_node) : NULL;
 318        }
 319        if (fofs == en->ei.fofs + en->ei.len - 1) {
 320                /* lookup next node for merging frontward later */
 321                tmp_node = rb_next(&en->rb_node);
 322                *next_ex = tmp_node ?
 323                        rb_entry(tmp_node, struct extent_node, rb_node) : NULL;
 324        }
 325        return en;
 326}
 327
 328static struct extent_node *__try_merge_extent_node(struct f2fs_sb_info *sbi,
 329                                struct extent_tree *et, struct extent_info *ei,
 330                                struct extent_node **den,
 331                                struct extent_node *prev_ex,
 332                                struct extent_node *next_ex)
 333{
 334        struct extent_node *en = NULL;
 335
 336        if (prev_ex && __is_back_mergeable(ei, &prev_ex->ei)) {
 337                prev_ex->ei.len += ei->len;
 338                ei = &prev_ex->ei;
 339                en = prev_ex;
 340        }
 341
 342        if (next_ex && __is_front_mergeable(ei, &next_ex->ei)) {
 343                if (en) {
 344                        __detach_extent_node(sbi, et, prev_ex);
 345                        *den = prev_ex;
 346                }
 347                next_ex->ei.fofs = ei->fofs;
 348                next_ex->ei.blk = ei->blk;
 349                next_ex->ei.len += ei->len;
 350                en = next_ex;
 351        }
 352
 353        if (en) {
 354                __try_update_largest_extent(et, en);
 355                et->cached_en = en;
 356        }
 357        return en;
 358}
 359
 360static struct extent_node *__insert_extent_tree(struct f2fs_sb_info *sbi,
 361                                struct extent_tree *et, struct extent_info *ei,
 362                                struct rb_node **insert_p,
 363                                struct rb_node *insert_parent)
 364{
 365        struct rb_node **p = &et->root.rb_node;
 366        struct rb_node *parent = NULL;
 367        struct extent_node *en = NULL;
 368
 369        if (insert_p && insert_parent) {
 370                parent = insert_parent;
 371                p = insert_p;
 372                goto do_insert;
 373        }
 374
 375        while (*p) {
 376                parent = *p;
 377                en = rb_entry(parent, struct extent_node, rb_node);
 378
 379                if (ei->fofs < en->ei.fofs)
 380                        p = &(*p)->rb_left;
 381                else if (ei->fofs >= en->ei.fofs + en->ei.len)
 382                        p = &(*p)->rb_right;
 383                else
 384                        f2fs_bug_on(sbi, 1);
 385        }
 386do_insert:
 387        en = __attach_extent_node(sbi, et, ei, parent, p);
 388        if (!en)
 389                return NULL;
 390
 391        __try_update_largest_extent(et, en);
 392        et->cached_en = en;
 393        return en;
 394}
 395
 396static unsigned int f2fs_update_extent_tree_range(struct inode *inode,
 397                                pgoff_t fofs, block_t blkaddr, unsigned int len)
 398{
 399        struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
 400        struct extent_tree *et = F2FS_I(inode)->extent_tree;
 401        struct extent_node *en = NULL, *en1 = NULL;
 402        struct extent_node *prev_en = NULL, *next_en = NULL;
 403        struct extent_info ei, dei, prev;
 404        struct rb_node **insert_p = NULL, *insert_parent = NULL;
 405        unsigned int end = fofs + len;
 406        unsigned int pos = (unsigned int)fofs;
 407
 408        if (!et)
 409                return false;
 410
 411        trace_f2fs_update_extent_tree_range(inode, fofs, blkaddr, len);
 412
 413        write_lock(&et->lock);
 414
 415        if (is_inode_flag_set(F2FS_I(inode), FI_NO_EXTENT)) {
 416                write_unlock(&et->lock);
 417                return false;
 418        }
 419
 420        prev = et->largest;
 421        dei.len = 0;
 422
 423        /*
 424         * drop largest extent before lookup, in case it's already
 425         * been shrunk from extent tree
 426         */
 427        __drop_largest_extent(inode, fofs, len);
 428
 429        /* 1. lookup first extent node in range [fofs, fofs + len - 1] */
 430        en = __lookup_extent_tree_ret(et, fofs, &prev_en, &next_en,
 431                                        &insert_p, &insert_parent);
 432        if (!en)
 433                en = next_en;
 434
 435        /* 2. invlidate all extent nodes in range [fofs, fofs + len - 1] */
 436        while (en && en->ei.fofs < end) {
 437                unsigned int org_end;
 438                int parts = 0;  /* # of parts current extent split into */
 439
 440                next_en = en1 = NULL;
 441
 442                dei = en->ei;
 443                org_end = dei.fofs + dei.len;
 444                f2fs_bug_on(sbi, pos >= org_end);
 445
 446                if (pos > dei.fofs &&   pos - dei.fofs >= F2FS_MIN_EXTENT_LEN) {
 447                        en->ei.len = pos - en->ei.fofs;
 448                        prev_en = en;
 449                        parts = 1;
 450                }
 451
 452                if (end < org_end && org_end - end >= F2FS_MIN_EXTENT_LEN) {
 453                        if (parts) {
 454                                set_extent_info(&ei, end,
 455                                                end - dei.fofs + dei.blk,
 456                                                org_end - end);
 457                                en1 = __insert_extent_tree(sbi, et, &ei,
 458                                                        NULL, NULL);
 459                                next_en = en1;
 460                        } else {
 461                                en->ei.fofs = end;
 462                                en->ei.blk += end - dei.fofs;
 463                                en->ei.len -= end - dei.fofs;
 464                                next_en = en;
 465                        }
 466                        parts++;
 467                }
 468
 469                if (!next_en) {
 470                        struct rb_node *node = rb_next(&en->rb_node);
 471
 472                        next_en = node ?
 473                                rb_entry(node, struct extent_node, rb_node)
 474                                : NULL;
 475                }
 476
 477                if (parts)
 478                        __try_update_largest_extent(et, en);
 479                else
 480                        __detach_extent_node(sbi, et, en);
 481
 482                /*
 483                 * if original extent is split into zero or two parts, extent
 484                 * tree has been altered by deletion or insertion, therefore
 485                 * invalidate pointers regard to tree.
 486                 */
 487                if (parts != 1) {
 488                        insert_p = NULL;
 489                        insert_parent = NULL;
 490                }
 491
 492                /* update in global extent list */
 493                spin_lock(&sbi->extent_lock);
 494                if (!parts && !list_empty(&en->list))
 495                        list_del(&en->list);
 496                if (en1)
 497                        list_add_tail(&en1->list, &sbi->extent_list);
 498                spin_unlock(&sbi->extent_lock);
 499
 500                /* release extent node */
 501                if (!parts)
 502                        kmem_cache_free(extent_node_slab, en);
 503
 504                en = next_en;
 505        }
 506
 507        /* 3. update extent in extent cache */
 508        if (blkaddr) {
 509                struct extent_node *den = NULL;
 510
 511                set_extent_info(&ei, fofs, blkaddr, len);
 512                en1 = __try_merge_extent_node(sbi, et, &ei, &den,
 513                                                        prev_en, next_en);
 514                if (!en1)
 515                        en1 = __insert_extent_tree(sbi, et, &ei,
 516                                                insert_p, insert_parent);
 517
 518                /* give up extent_cache, if split and small updates happen */
 519                if (dei.len >= 1 &&
 520                                prev.len < F2FS_MIN_EXTENT_LEN &&
 521                                et->largest.len < F2FS_MIN_EXTENT_LEN) {
 522                        et->largest.len = 0;
 523                        set_inode_flag(F2FS_I(inode), FI_NO_EXTENT);
 524                }
 525
 526                spin_lock(&sbi->extent_lock);
 527                if (en1) {
 528                        if (list_empty(&en1->list))
 529                                list_add_tail(&en1->list, &sbi->extent_list);
 530                        else
 531                                list_move_tail(&en1->list, &sbi->extent_list);
 532                }
 533                if (den && !list_empty(&den->list))
 534                        list_del(&den->list);
 535                spin_unlock(&sbi->extent_lock);
 536
 537                if (den)
 538                        kmem_cache_free(extent_node_slab, den);
 539        }
 540
 541        if (is_inode_flag_set(F2FS_I(inode), FI_NO_EXTENT))
 542                __free_extent_tree(sbi, et, true);
 543
 544        write_unlock(&et->lock);
 545
 546        return !__is_extent_same(&prev, &et->largest);
 547}
 548
 549unsigned int f2fs_shrink_extent_tree(struct f2fs_sb_info *sbi, int nr_shrink)
 550{
 551        struct extent_tree *treevec[EXT_TREE_VEC_SIZE];
 552        struct extent_node *en, *tmp;
 553        unsigned long ino = F2FS_ROOT_INO(sbi);
 554        struct radix_tree_root *root = &sbi->extent_tree_root;
 555        unsigned int found;
 556        unsigned int node_cnt = 0, tree_cnt = 0;
 557        int remained;
 558
 559        if (!test_opt(sbi, EXTENT_CACHE))
 560                return 0;
 561
 562        if (!down_write_trylock(&sbi->extent_tree_lock))
 563                goto out;
 564
 565        /* 1. remove unreferenced extent tree */
 566        while ((found = radix_tree_gang_lookup(root,
 567                                (void **)treevec, ino, EXT_TREE_VEC_SIZE))) {
 568                unsigned i;
 569
 570                ino = treevec[found - 1]->ino + 1;
 571                for (i = 0; i < found; i++) {
 572                        struct extent_tree *et = treevec[i];
 573
 574                        if (!atomic_read(&et->refcount)) {
 575                                write_lock(&et->lock);
 576                                node_cnt += __free_extent_tree(sbi, et, true);
 577                                write_unlock(&et->lock);
 578
 579                                radix_tree_delete(root, et->ino);
 580                                kmem_cache_free(extent_tree_slab, et);
 581                                sbi->total_ext_tree--;
 582                                tree_cnt++;
 583
 584                                if (node_cnt + tree_cnt >= nr_shrink)
 585                                        goto unlock_out;
 586                        }
 587                }
 588        }
 589        up_write(&sbi->extent_tree_lock);
 590
 591        /* 2. remove LRU extent entries */
 592        if (!down_write_trylock(&sbi->extent_tree_lock))
 593                goto out;
 594
 595        remained = nr_shrink - (node_cnt + tree_cnt);
 596
 597        spin_lock(&sbi->extent_lock);
 598        list_for_each_entry_safe(en, tmp, &sbi->extent_list, list) {
 599                if (!remained--)
 600                        break;
 601                list_del_init(&en->list);
 602        }
 603        spin_unlock(&sbi->extent_lock);
 604
 605        /*
 606         * reset ino for searching victims from beginning of global extent tree.
 607         */
 608        ino = F2FS_ROOT_INO(sbi);
 609
 610        while ((found = radix_tree_gang_lookup(root,
 611                                (void **)treevec, ino, EXT_TREE_VEC_SIZE))) {
 612                unsigned i;
 613
 614                ino = treevec[found - 1]->ino + 1;
 615                for (i = 0; i < found; i++) {
 616                        struct extent_tree *et = treevec[i];
 617
 618                        write_lock(&et->lock);
 619                        node_cnt += __free_extent_tree(sbi, et, false);
 620                        write_unlock(&et->lock);
 621
 622                        if (node_cnt + tree_cnt >= nr_shrink)
 623                                goto unlock_out;
 624                }
 625        }
 626unlock_out:
 627        up_write(&sbi->extent_tree_lock);
 628out:
 629        trace_f2fs_shrink_extent_tree(sbi, node_cnt, tree_cnt);
 630
 631        return node_cnt + tree_cnt;
 632}
 633
 634unsigned int f2fs_destroy_extent_node(struct inode *inode)
 635{
 636        struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
 637        struct extent_tree *et = F2FS_I(inode)->extent_tree;
 638        unsigned int node_cnt = 0;
 639
 640        if (!et)
 641                return 0;
 642
 643        write_lock(&et->lock);
 644        node_cnt = __free_extent_tree(sbi, et, true);
 645        write_unlock(&et->lock);
 646
 647        return node_cnt;
 648}
 649
 650void f2fs_destroy_extent_tree(struct inode *inode)
 651{
 652        struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
 653        struct extent_tree *et = F2FS_I(inode)->extent_tree;
 654        unsigned int node_cnt = 0;
 655
 656        if (!et)
 657                return;
 658
 659        if (inode->i_nlink && !is_bad_inode(inode) && et->count) {
 660                atomic_dec(&et->refcount);
 661                return;
 662        }
 663
 664        /* free all extent info belong to this extent tree */
 665        node_cnt = f2fs_destroy_extent_node(inode);
 666
 667        /* delete extent tree entry in radix tree */
 668        down_write(&sbi->extent_tree_lock);
 669        atomic_dec(&et->refcount);
 670        f2fs_bug_on(sbi, atomic_read(&et->refcount) || et->count);
 671        radix_tree_delete(&sbi->extent_tree_root, inode->i_ino);
 672        kmem_cache_free(extent_tree_slab, et);
 673        sbi->total_ext_tree--;
 674        up_write(&sbi->extent_tree_lock);
 675
 676        F2FS_I(inode)->extent_tree = NULL;
 677
 678        trace_f2fs_destroy_extent_tree(inode, node_cnt);
 679}
 680
 681bool f2fs_lookup_extent_cache(struct inode *inode, pgoff_t pgofs,
 682                                        struct extent_info *ei)
 683{
 684        if (!f2fs_may_extent_tree(inode))
 685                return false;
 686
 687        return f2fs_lookup_extent_tree(inode, pgofs, ei);
 688}
 689
 690void f2fs_update_extent_cache(struct dnode_of_data *dn)
 691{
 692        struct f2fs_inode_info *fi = F2FS_I(dn->inode);
 693        pgoff_t fofs;
 694
 695        if (!f2fs_may_extent_tree(dn->inode))
 696                return;
 697
 698        f2fs_bug_on(F2FS_I_SB(dn->inode), dn->data_blkaddr == NEW_ADDR);
 699
 700
 701        fofs = start_bidx_of_node(ofs_of_node(dn->node_page), fi) +
 702                                                        dn->ofs_in_node;
 703
 704        if (f2fs_update_extent_tree_range(dn->inode, fofs, dn->data_blkaddr, 1))
 705                sync_inode_page(dn);
 706}
 707
 708void f2fs_update_extent_cache_range(struct dnode_of_data *dn,
 709                                pgoff_t fofs, block_t blkaddr, unsigned int len)
 710
 711{
 712        if (!f2fs_may_extent_tree(dn->inode))
 713                return;
 714
 715        if (f2fs_update_extent_tree_range(dn->inode, fofs, blkaddr, len))
 716                sync_inode_page(dn);
 717}
 718
 719void init_extent_cache_info(struct f2fs_sb_info *sbi)
 720{
 721        INIT_RADIX_TREE(&sbi->extent_tree_root, GFP_NOIO);
 722        init_rwsem(&sbi->extent_tree_lock);
 723        INIT_LIST_HEAD(&sbi->extent_list);
 724        spin_lock_init(&sbi->extent_lock);
 725        sbi->total_ext_tree = 0;
 726        atomic_set(&sbi->total_ext_node, 0);
 727}
 728
 729int __init create_extent_cache(void)
 730{
 731        extent_tree_slab = f2fs_kmem_cache_create("f2fs_extent_tree",
 732                        sizeof(struct extent_tree));
 733        if (!extent_tree_slab)
 734                return -ENOMEM;
 735        extent_node_slab = f2fs_kmem_cache_create("f2fs_extent_node",
 736                        sizeof(struct extent_node));
 737        if (!extent_node_slab) {
 738                kmem_cache_destroy(extent_tree_slab);
 739                return -ENOMEM;
 740        }
 741        return 0;
 742}
 743
 744void destroy_extent_cache(void)
 745{
 746        kmem_cache_destroy(extent_node_slab);
 747        kmem_cache_destroy(extent_tree_slab);
 748}
 749