123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- /*
- * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
- #ifndef _SDFAT_AMAP_H
- #define _SDFAT_AMAP_H
- #include <linux/fs.h>
- #include <linux/list.h>
- #include <linux/rbtree.h>
- /* AMAP Configuration Variable */
- #define SMART_ALLOC_N_HOT_AU (5)
- /* Allocating Destination (for smart allocator):
- * moved to sdfat.h
- */
- /*
- * #define ALLOC_COLD_ALIGNED (1)
- * #define ALLOC_COLD_PACKING (2)
- * #define ALLOC_COLD_SEQ (4)
- */
- /* Minimum sectors for support AMAP create */
- #define AMAP_MIN_SUPPORT_SECTORS (1048576)
- #define amap_add_hot_au(amap, au) amap_insert_to_list(au, &amap->slist_hot)
- /* singly linked list */
- struct slist_head {
- struct slist_head *next;
- struct slist_head *head;
- };
- /* AU entry type */
- typedef struct __AU_INFO_T {
- uint16_t idx; /* the index of the AU (0, 1, 2, ... ) */
- uint16_t free_clusters; /* # of available cluster */
- union {
- struct list_head head;
- struct slist_head shead;/* singly linked list head for hot list */
- };
- } AU_INFO_T;
- /* Allocation Target AU */
- typedef struct __TARGET_AU_T {
- AU_INFO_T *au; /* Working AU */
- uint16_t idx; /* Intra-AU cluster index */
- uint16_t clu_to_skip; /* Clusters to skip */
- } TARGET_AU_T;
- /* AMAP free-clusters-based node */
- typedef struct {
- struct list_head head; /* the list of AUs */
- } FCLU_NODE_T;
- /* AMAP options */
- typedef struct {
- unsigned int packing_ratio; /* Tunable packing ratio */
- unsigned int au_size; /* AU size in sectors */
- unsigned int au_align_factor; /* Hidden sectors % au_size */
- } AMAP_OPT_T;
- typedef struct __AMAP_T {
- spinlock_t amap_lock; /* obsolete */
- struct super_block *sb;
- int n_au;
- int n_clean_au, n_full_au;
- int clu_align_bias;
- uint16_t clusters_per_au;
- AU_INFO_T **au_table; /* An array of AU_INFO entries */
- AMAP_OPT_T option;
- /* Size-based AU management pool (cold) */
- FCLU_NODE_T *fclu_nodes; /* An array of listheads */
- int fclu_order; /* Page order that fclu_nodes needs */
- int fclu_hint; /* maximum # of free clusters in an AU */
- /* Hot AU list */
- unsigned int total_fclu_hot; /* Free clusters in hot list */
- struct slist_head slist_hot; /* Hot AU list */
- /* Ignored AU list */
- struct slist_head slist_ignored;
- /* Allocator variables (keep 2 AUs at maximum) */
- TARGET_AU_T cur_cold;
- TARGET_AU_T cur_hot;
- int n_need_packing;
- } AMAP_T;
- /* AU table */
- #define N_AU_PER_TABLE (int)(PAGE_SIZE / sizeof(AU_INFO_T))
- #define GET_AU(amap, i_AU) (amap->au_table[(i_AU) / N_AU_PER_TABLE] + ((i_AU) % N_AU_PER_TABLE))
- //#define MAX_CLU_PER_AU (int)(PAGE_SIZE / sizeof(FCLU_NODE_T))
- #define MAX_CLU_PER_AU (1024)
- /* Cold AU bucket <-> # of freeclusters */
- #define NODE_CLEAN(amap) (&amap->fclu_nodes[amap->clusters_per_au - 1])
- #define NODE(fclu, amap) (&amap->fclu_nodes[fclu - 1])
- #define FREE_CLUSTERS(node, amap) ((int)(node - amap->fclu_nodes) + 1)
- /* AU status */
- #define MAGIC_WORKING ((struct slist_head *)0xFFFF5091)
- #define IS_AU_HOT(au, amap) (au->shead.head == &amap->slist_hot)
- #define IS_AU_IGNORED(au, amap) (au->shead.head == &amap->slist_ignored)
- #define IS_AU_WORKING(au, amap) (au->shead.head == MAGIC_WORKING)
- #define SET_AU_WORKING(au) (au->shead.head = MAGIC_WORKING)
- /* AU <-> cluster */
- #define i_AU_of_CLU(amap, clu) ((amap->clu_align_bias + clu) / amap->clusters_per_au)
- #define CLU_of_i_AU(amap, i_au, idx) \
- ((uint32_t)(i_au) * (uint32_t)amap->clusters_per_au + (idx) - amap->clu_align_bias)
- /*
- * NOTE : AMAP internal functions are moved to core.h
- */
- #endif /* _SDFAT_AMAP_H */
|