~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/u-boot/fs/ubifs/lpt_commit.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * This file is part of UBIFS.
 
3
 *
 
4
 * Copyright (C) 2006-2008 Nokia Corporation.
 
5
 *
 
6
 * This program is free software; you can redistribute it and/or modify it
 
7
 * under the terms of the GNU General Public License version 2 as published by
 
8
 * the Free Software Foundation.
 
9
 *
 
10
 * This program is distributed in the hope that it will be useful, but WITHOUT
 
11
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 
12
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 
13
 * more details.
 
14
 *
 
15
 * You should have received a copy of the GNU General Public License along with
 
16
 * this program; if not, write to the Free Software Foundation, Inc., 51
 
17
 * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 
18
 *
 
19
 * Authors: Adrian Hunter
 
20
 *          Artem Bityutskiy (Битюцкий Артём)
 
21
 */
 
22
 
 
23
/*
 
24
 * This file implements commit-related functionality of the LEB properties
 
25
 * subsystem.
 
26
 */
 
27
 
 
28
#include "crc16.h"
 
29
#include "ubifs.h"
 
30
 
 
31
/**
 
32
 * free_obsolete_cnodes - free obsolete cnodes for commit end.
 
33
 * @c: UBIFS file-system description object
 
34
 */
 
35
static void free_obsolete_cnodes(struct ubifs_info *c)
 
36
{
 
37
        struct ubifs_cnode *cnode, *cnext;
 
38
 
 
39
        cnext = c->lpt_cnext;
 
40
        if (!cnext)
 
41
                return;
 
42
        do {
 
43
                cnode = cnext;
 
44
                cnext = cnode->cnext;
 
45
                if (test_bit(OBSOLETE_CNODE, &cnode->flags))
 
46
                        kfree(cnode);
 
47
                else
 
48
                        cnode->cnext = NULL;
 
49
        } while (cnext != c->lpt_cnext);
 
50
        c->lpt_cnext = NULL;
 
51
}
 
52
 
 
53
/**
 
54
 * first_nnode - find the first nnode in memory.
 
55
 * @c: UBIFS file-system description object
 
56
 * @hght: height of tree where nnode found is returned here
 
57
 *
 
58
 * This function returns a pointer to the nnode found or %NULL if no nnode is
 
59
 * found. This function is a helper to 'ubifs_lpt_free()'.
 
60
 */
 
61
static struct ubifs_nnode *first_nnode(struct ubifs_info *c, int *hght)
 
62
{
 
63
        struct ubifs_nnode *nnode;
 
64
        int h, i, found;
 
65
 
 
66
        nnode = c->nroot;
 
67
        *hght = 0;
 
68
        if (!nnode)
 
69
                return NULL;
 
70
        for (h = 1; h < c->lpt_hght; h++) {
 
71
                found = 0;
 
72
                for (i = 0; i < UBIFS_LPT_FANOUT; i++) {
 
73
                        if (nnode->nbranch[i].nnode) {
 
74
                                found = 1;
 
75
                                nnode = nnode->nbranch[i].nnode;
 
76
                                *hght = h;
 
77
                                break;
 
78
                        }
 
79
                }
 
80
                if (!found)
 
81
                        break;
 
82
        }
 
83
        return nnode;
 
84
}
 
85
 
 
86
/**
 
87
 * next_nnode - find the next nnode in memory.
 
88
 * @c: UBIFS file-system description object
 
89
 * @nnode: nnode from which to start.
 
90
 * @hght: height of tree where nnode is, is passed and returned here
 
91
 *
 
92
 * This function returns a pointer to the nnode found or %NULL if no nnode is
 
93
 * found. This function is a helper to 'ubifs_lpt_free()'.
 
94
 */
 
95
static struct ubifs_nnode *next_nnode(struct ubifs_info *c,
 
96
                                      struct ubifs_nnode *nnode, int *hght)
 
97
{
 
98
        struct ubifs_nnode *parent;
 
99
        int iip, h, i, found;
 
100
 
 
101
        parent = nnode->parent;
 
102
        if (!parent)
 
103
                return NULL;
 
104
        if (nnode->iip == UBIFS_LPT_FANOUT - 1) {
 
105
                *hght -= 1;
 
106
                return parent;
 
107
        }
 
108
        for (iip = nnode->iip + 1; iip < UBIFS_LPT_FANOUT; iip++) {
 
109
                nnode = parent->nbranch[iip].nnode;
 
110
                if (nnode)
 
111
                        break;
 
112
        }
 
113
        if (!nnode) {
 
114
                *hght -= 1;
 
115
                return parent;
 
116
        }
 
117
        for (h = *hght + 1; h < c->lpt_hght; h++) {
 
118
                found = 0;
 
119
                for (i = 0; i < UBIFS_LPT_FANOUT; i++) {
 
120
                        if (nnode->nbranch[i].nnode) {
 
121
                                found = 1;
 
122
                                nnode = nnode->nbranch[i].nnode;
 
123
                                *hght = h;
 
124
                                break;
 
125
                        }
 
126
                }
 
127
                if (!found)
 
128
                        break;
 
129
        }
 
130
        return nnode;
 
131
}
 
132
 
 
133
/**
 
134
 * ubifs_lpt_free - free resources owned by the LPT.
 
135
 * @c: UBIFS file-system description object
 
136
 * @wr_only: free only resources used for writing
 
137
 */
 
138
void ubifs_lpt_free(struct ubifs_info *c, int wr_only)
 
139
{
 
140
        struct ubifs_nnode *nnode;
 
141
        int i, hght;
 
142
 
 
143
        /* Free write-only things first */
 
144
 
 
145
        free_obsolete_cnodes(c); /* Leftover from a failed commit */
 
146
 
 
147
        vfree(c->ltab_cmt);
 
148
        c->ltab_cmt = NULL;
 
149
        vfree(c->lpt_buf);
 
150
        c->lpt_buf = NULL;
 
151
        kfree(c->lsave);
 
152
        c->lsave = NULL;
 
153
 
 
154
        if (wr_only)
 
155
                return;
 
156
 
 
157
        /* Now free the rest */
 
158
 
 
159
        nnode = first_nnode(c, &hght);
 
160
        while (nnode) {
 
161
                for (i = 0; i < UBIFS_LPT_FANOUT; i++)
 
162
                        kfree(nnode->nbranch[i].nnode);
 
163
                nnode = next_nnode(c, nnode, &hght);
 
164
        }
 
165
        for (i = 0; i < LPROPS_HEAP_CNT; i++)
 
166
                kfree(c->lpt_heap[i].arr);
 
167
        kfree(c->dirty_idx.arr);
 
168
        kfree(c->nroot);
 
169
        vfree(c->ltab);
 
170
        kfree(c->lpt_nod_buf);
 
171
}