diff options
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/ubifs/gc.c | 96 |
1 files changed, 1 insertions, 95 deletions
diff --git a/fs/ubifs/gc.c b/fs/ubifs/gc.c index 618c2701d3a7..e5a3d8e96bb7 100644 --- a/fs/ubifs/gc.c +++ b/fs/ubifs/gc.c | |||
| @@ -54,6 +54,7 @@ | |||
| 54 | */ | 54 | */ |
| 55 | 55 | ||
| 56 | #include <linux/pagemap.h> | 56 | #include <linux/pagemap.h> |
| 57 | #include <linux/list_sort.h> | ||
| 57 | #include "ubifs.h" | 58 | #include "ubifs.h" |
| 58 | 59 | ||
| 59 | /* | 60 | /* |
| @@ -108,101 +109,6 @@ static int switch_gc_head(struct ubifs_info *c) | |||
| 108 | } | 109 | } |
| 109 | 110 | ||
| 110 | /** | 111 | /** |
| 111 | * list_sort - sort a list. | ||
| 112 | * @priv: private data, passed to @cmp | ||
| 113 | * @head: the list to sort | ||
| 114 | * @cmp: the elements comparison function | ||
| 115 | * | ||
| 116 | * This function has been implemented by Mark J Roberts <mjr@znex.org>. It | ||
| 117 | * implements "merge sort" which has O(nlog(n)) complexity. The list is sorted | ||
| 118 | * in ascending order. | ||
| 119 | * | ||
| 120 | * The comparison function @cmp is supposed to return a negative value if @a is | ||
| 121 | * than @b, and a positive value if @a is greater than @b. If @a and @b are | ||
| 122 | * equivalent, then it does not matter what this function returns. | ||
| 123 | */ | ||
| 124 | static void list_sort(void *priv, struct list_head *head, | ||
| 125 | int (*cmp)(void *priv, struct list_head *a, | ||
| 126 | struct list_head *b)) | ||
| 127 | { | ||
| 128 | struct list_head *p, *q, *e, *list, *tail, *oldhead; | ||
| 129 | int insize, nmerges, psize, qsize, i; | ||
| 130 | |||
| 131 | if (list_empty(head)) | ||
| 132 | return; | ||
| 133 | |||
| 134 | list = head->next; | ||
| 135 | list_del(head); | ||
| 136 | insize = 1; | ||
| 137 | for (;;) { | ||
| 138 | p = oldhead = list; | ||
| 139 | list = tail = NULL; | ||
| 140 | nmerges = 0; | ||
| 141 | |||
| 142 | while (p) { | ||
| 143 | nmerges++; | ||
| 144 | q = p; | ||
| 145 | psize = 0; | ||
| 146 | for (i = 0; i < insize; i++) { | ||
| 147 | psize++; | ||
| 148 | q = q->next == oldhead ? NULL : q->next; | ||
| 149 | if (!q) | ||
| 150 | break; | ||
| 151 | } | ||
| 152 | |||
| 153 | qsize = insize; | ||
| 154 | while (psize > 0 || (qsize > 0 && q)) { | ||
| 155 | if (!psize) { | ||
| 156 | e = q; | ||
| 157 | q = q->next; | ||
| 158 | qsize--; | ||
| 159 | if (q == oldhead) | ||
| 160 | q = NULL; | ||
| 161 | } else if (!qsize || !q) { | ||
| 162 | e = p; | ||
| 163 | p = p->next; | ||
| 164 | psize--; | ||
| 165 | if (p == oldhead) | ||
| 166 | p = NULL; | ||
| 167 | } else if (cmp(priv, p, q) <= 0) { | ||
| 168 | e = p; | ||
| 169 | p = p->next; | ||
| 170 | psize--; | ||
| 171 | if (p == oldhead) | ||
| 172 | p = NULL; | ||
| 173 | } else { | ||
| 174 | e = q; | ||
| 175 | q = q->next; | ||
| 176 | qsize--; | ||
| 177 | if (q == oldhead) | ||
| 178 | q = NULL; | ||
| 179 | } | ||
| 180 | if (tail) | ||
| 181 | tail->next = e; | ||
| 182 | else | ||
| 183 | list = e; | ||
| 184 | e->prev = tail; | ||
| 185 | tail = e; | ||
| 186 | } | ||
| 187 | p = q; | ||
| 188 | } | ||
| 189 | |||
| 190 | tail->next = list; | ||
| 191 | list->prev = tail; | ||
| 192 | |||
| 193 | if (nmerges <= 1) | ||
| 194 | break; | ||
| 195 | |||
| 196 | insize *= 2; | ||
| 197 | } | ||
| 198 | |||
| 199 | head->next = list; | ||
| 200 | head->prev = list->prev; | ||
| 201 | list->prev->next = head; | ||
| 202 | list->prev = head; | ||
| 203 | } | ||
| 204 | |||
| 205 | /** | ||
| 206 | * data_nodes_cmp - compare 2 data nodes. | 112 | * data_nodes_cmp - compare 2 data nodes. |
| 207 | * @priv: UBIFS file-system description object | 113 | * @priv: UBIFS file-system description object |
| 208 | * @a: first data node | 114 | * @a: first data node |
