fs: Import sdFAT version 2.4.5
[GitHub/LineageOS/android_kernel_motorola_exynos9610.git] / fs / sdfat / amap_smart.h
diff --git a/fs/sdfat/amap_smart.h b/fs/sdfat/amap_smart.h
new file mode 100644 (file)
index 0000000..caee6f6
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ *  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 */