Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0-only
2 : /*
3 : * This file is part of UBIFS.
4 : *
5 : * Copyright (C) 2006-2008 Nokia Corporation.
6 : *
7 : * Authors: Adrian Hunter
8 : * Artem Bityutskiy (Битюцкий Артём)
9 : */
10 :
11 : /*
12 : * This file implements functions that manage the running of the commit process.
13 : * Each affected module has its own functions to accomplish their part in the
14 : * commit and those functions are called here.
15 : *
16 : * The commit is the process whereby all updates to the index and LEB properties
17 : * are written out together and the journal becomes empty. This keeps the
18 : * file system consistent - at all times the state can be recreated by reading
19 : * the index and LEB properties and then replaying the journal.
20 : *
21 : * The commit is split into two parts named "commit start" and "commit end".
22 : * During commit start, the commit process has exclusive access to the journal
23 : * by holding the commit semaphore down for writing. As few I/O operations as
24 : * possible are performed during commit start, instead the nodes that are to be
25 : * written are merely identified. During commit end, the commit semaphore is no
26 : * longer held and the journal is again in operation, allowing users to continue
27 : * to use the file system while the bulk of the commit I/O is performed. The
28 : * purpose of this two-step approach is to prevent the commit from causing any
29 : * latency blips. Note that in any case, the commit does not prevent lookups
30 : * (as permitted by the TNC mutex), or access to VFS data structures e.g. page
31 : * cache.
32 : */
33 :
34 : #include "linux_err.h"
35 : #include "bitops.h"
36 : #include "kmem.h"
37 : #include "ubifs.h"
38 : #include "debug.h"
39 : #include "defs.h"
40 : #include "misc.h"
41 :
42 : /*
43 : * nothing_to_commit - check if there is nothing to commit.
44 : * @c: UBIFS file-system description object
45 : *
46 : * This is a helper function which checks if there is anything to commit. It is
47 : * used as an optimization to avoid starting the commit if it is not really
48 : * necessary. Indeed, the commit operation always assumes flash I/O (e.g.,
49 : * writing the commit start node to the log), and it is better to avoid doing
50 : * this unnecessarily. E.g., 'ubifs_sync_fs()' runs the commit, but if there is
51 : * nothing to commit, it is more optimal to avoid any flash I/O.
52 : *
53 : * This function has to be called with @c->commit_sem locked for writing -
54 : * this function does not take LPT/TNC locks because the @c->commit_sem
55 : * guarantees that we have exclusive access to the TNC and LPT data structures.
56 : *
57 : * This function returns %1 if there is nothing to commit and %0 otherwise.
58 : */
59 3532 : static int nothing_to_commit(struct ubifs_info *c)
60 : {
61 : /*
62 : * During mounting or remounting from R/O mode to R/W mode we may
63 : * commit for various recovery-related reasons.
64 : */
65 3532 : if (c->mounting || c->remounting_rw)
66 : return 0;
67 :
68 : /*
69 : * If the root TNC node is dirty, we definitely have something to
70 : * commit.
71 : */
72 3736 : if (c->zroot.znode && ubifs_zn_dirty(c->zroot.znode))
73 : return 0;
74 :
75 : /*
76 : * Increasing @c->dirty_pn_cnt/@c->dirty_nn_cnt and marking
77 : * nnodes/pnodes as dirty in run_gc() could race with following
78 : * checking, which leads inconsistent states between @c->nroot
79 : * and @c->dirty_pn_cnt/@c->dirty_nn_cnt, holding @c->lp_mutex
80 : * to avoid that.
81 : */
82 1325 : mutex_lock(&c->lp_mutex);
83 : /*
84 : * Even though the TNC is clean, the LPT tree may have dirty nodes. For
85 : * example, this may happen if the budgeting subsystem invoked GC to
86 : * make some free space, and the GC found an LEB with only dirty and
87 : * free space. In this case GC would just change the lprops of this
88 : * LEB (by turning all space into free space) and unmap it.
89 : */
90 2650 : if (c->nroot && test_bit(DIRTY_CNODE, &c->nroot->flags)) {
91 1220 : mutex_unlock(&c->lp_mutex);
92 1220 : return 0;
93 : }
94 :
95 105 : ubifs_assert(c, atomic_long_read(&c->dirty_zn_cnt) == 0);
96 105 : ubifs_assert(c, c->dirty_pn_cnt == 0);
97 105 : ubifs_assert(c, c->dirty_nn_cnt == 0);
98 105 : mutex_unlock(&c->lp_mutex);
99 :
100 105 : return 1;
101 : }
102 :
103 : /**
104 : * do_commit - commit the journal.
105 : * @c: UBIFS file-system description object
106 : *
107 : * This function implements UBIFS commit. It has to be called with commit lock
108 : * locked. Returns zero in case of success and a negative error code in case of
109 : * failure.
110 : */
111 3532 : static int do_commit(struct ubifs_info *c)
112 : {
113 : int err, new_ltail_lnum, old_ltail_lnum, i;
114 : struct ubifs_zbranch zroot;
115 : struct ubifs_lp_stats lst;
116 :
117 3532 : dbg_cmt("start");
118 3532 : ubifs_assert(c, !c->ro_media && !c->ro_mount);
119 :
120 3532 : if (c->ro_error) {
121 : err = -EROFS;
122 : goto out_up;
123 : }
124 :
125 3532 : if (nothing_to_commit(c)) {
126 105 : up_write(&c->commit_sem);
127 105 : err = 0;
128 105 : goto out_cancel;
129 : }
130 :
131 : /* Sync all write buffers (necessary for recovery) */
132 10281 : for (i = 0; i < c->jhead_cnt; i++) {
133 10281 : err = ubifs_wbuf_sync(&c->jheads[i].wbuf);
134 10281 : if (err)
135 : goto out_up;
136 : }
137 :
138 3427 : c->cmt_no += 1;
139 3427 : err = ubifs_gc_start_commit(c);
140 3427 : if (err)
141 : goto out_up;
142 3427 : err = dbg_check_lprops(c);
143 : if (err)
144 : goto out_up;
145 3427 : err = ubifs_log_start_commit(c, &new_ltail_lnum);
146 3427 : if (err)
147 : goto out_up;
148 3427 : err = ubifs_tnc_start_commit(c, &zroot);
149 3427 : if (err)
150 : goto out_up;
151 3427 : err = ubifs_lpt_start_commit(c);
152 3427 : if (err)
153 : goto out_up;
154 3427 : err = ubifs_orphan_start_commit(c);
155 3427 : if (err)
156 : goto out_up;
157 :
158 3427 : ubifs_get_lp_stats(c, &lst);
159 :
160 3427 : up_write(&c->commit_sem);
161 :
162 3427 : err = ubifs_tnc_end_commit(c);
163 3427 : if (err)
164 : goto out;
165 3400 : err = ubifs_lpt_end_commit(c);
166 3400 : if (err)
167 : goto out;
168 3398 : err = ubifs_orphan_end_commit(c);
169 3398 : if (err)
170 : goto out;
171 3398 : err = dbg_check_old_index(c, &zroot);
172 : if (err)
173 : goto out;
174 :
175 3398 : c->mst_node->cmt_no = cpu_to_le64(c->cmt_no);
176 3398 : c->mst_node->log_lnum = cpu_to_le32(new_ltail_lnum);
177 3398 : c->mst_node->root_lnum = cpu_to_le32(zroot.lnum);
178 3398 : c->mst_node->root_offs = cpu_to_le32(zroot.offs);
179 3398 : c->mst_node->root_len = cpu_to_le32(zroot.len);
180 3398 : c->mst_node->ihead_lnum = cpu_to_le32(c->ihead_lnum);
181 3398 : c->mst_node->ihead_offs = cpu_to_le32(c->ihead_offs);
182 3398 : c->mst_node->index_size = cpu_to_le64(c->bi.old_idx_sz);
183 3398 : c->mst_node->lpt_lnum = cpu_to_le32(c->lpt_lnum);
184 3398 : c->mst_node->lpt_offs = cpu_to_le32(c->lpt_offs);
185 3398 : c->mst_node->nhead_lnum = cpu_to_le32(c->nhead_lnum);
186 3398 : c->mst_node->nhead_offs = cpu_to_le32(c->nhead_offs);
187 3398 : c->mst_node->ltab_lnum = cpu_to_le32(c->ltab_lnum);
188 3398 : c->mst_node->ltab_offs = cpu_to_le32(c->ltab_offs);
189 3398 : c->mst_node->lsave_lnum = cpu_to_le32(c->lsave_lnum);
190 3398 : c->mst_node->lsave_offs = cpu_to_le32(c->lsave_offs);
191 3398 : c->mst_node->lscan_lnum = cpu_to_le32(c->lscan_lnum);
192 3398 : c->mst_node->empty_lebs = cpu_to_le32(lst.empty_lebs);
193 3398 : c->mst_node->idx_lebs = cpu_to_le32(lst.idx_lebs);
194 3398 : c->mst_node->total_free = cpu_to_le64(lst.total_free);
195 3398 : c->mst_node->total_dirty = cpu_to_le64(lst.total_dirty);
196 3398 : c->mst_node->total_used = cpu_to_le64(lst.total_used);
197 3398 : c->mst_node->total_dead = cpu_to_le64(lst.total_dead);
198 3398 : c->mst_node->total_dark = cpu_to_le64(lst.total_dark);
199 3398 : if (c->no_orphs)
200 3398 : c->mst_node->flags |= cpu_to_le32(UBIFS_MST_NO_ORPHS);
201 : else
202 0 : c->mst_node->flags &= ~cpu_to_le32(UBIFS_MST_NO_ORPHS);
203 :
204 3398 : old_ltail_lnum = c->ltail_lnum;
205 3398 : err = ubifs_log_end_commit(c, new_ltail_lnum);
206 3398 : if (err)
207 : goto out;
208 :
209 3398 : err = ubifs_log_post_commit(c, old_ltail_lnum);
210 3398 : if (err)
211 : goto out;
212 3398 : err = ubifs_gc_end_commit(c);
213 3398 : if (err)
214 : goto out;
215 3398 : err = ubifs_lpt_post_commit(c);
216 3398 : if (err)
217 : goto out;
218 :
219 3398 : out_cancel:
220 3503 : spin_lock(&c->cs_lock);
221 3503 : c->cmt_state = COMMIT_RESTING;
222 3503 : dbg_cmt("commit end");
223 3503 : spin_unlock(&c->cs_lock);
224 3503 : return 0;
225 :
226 0 : out_up:
227 0 : up_write(&c->commit_sem);
228 58 : out:
229 29 : ubifs_err(c, "commit failed, error %d", err);
230 29 : spin_lock(&c->cs_lock);
231 29 : c->cmt_state = COMMIT_BROKEN;
232 29 : spin_unlock(&c->cs_lock);
233 29 : ubifs_ro_mode(c, err);
234 29 : return err;
235 : }
236 :
237 : /**
238 : * ubifs_commit_required - set commit state to "required".
239 : * @c: UBIFS file-system description object
240 : *
241 : * This function is called if a commit is required but cannot be done from the
242 : * calling function, so it is just flagged instead.
243 : */
244 0 : void ubifs_commit_required(struct ubifs_info *c)
245 : {
246 0 : spin_lock(&c->cs_lock);
247 0 : switch (c->cmt_state) {
248 0 : case COMMIT_RESTING:
249 : case COMMIT_BACKGROUND:
250 0 : dbg_cmt("old: %s, new: %s", dbg_cstate(c->cmt_state),
251 : dbg_cstate(COMMIT_REQUIRED));
252 0 : c->cmt_state = COMMIT_REQUIRED;
253 0 : break;
254 0 : case COMMIT_RUNNING_BACKGROUND:
255 0 : dbg_cmt("old: %s, new: %s", dbg_cstate(c->cmt_state),
256 : dbg_cstate(COMMIT_RUNNING_REQUIRED));
257 0 : c->cmt_state = COMMIT_RUNNING_REQUIRED;
258 0 : break;
259 : case COMMIT_REQUIRED:
260 : case COMMIT_RUNNING_REQUIRED:
261 : case COMMIT_BROKEN:
262 : break;
263 : }
264 0 : spin_unlock(&c->cs_lock);
265 0 : }
266 :
267 : /**
268 : * ubifs_request_bg_commit - notify the background thread to do a commit.
269 : * @c: UBIFS file-system description object
270 : *
271 : * This function is called if the journal is full enough to make a commit
272 : * worthwhile, so background thread is kicked to start it.
273 : */
274 0 : void ubifs_request_bg_commit(__unused struct ubifs_info *c)
275 : {
276 0 : }
277 :
278 : /**
279 : * wait_for_commit - wait for commit.
280 : * @c: UBIFS file-system description object
281 : *
282 : * This function sleeps until the commit operation is no longer running.
283 : */
284 : static int wait_for_commit(struct ubifs_info *c)
285 : {
286 : /*
287 : * All commit operations are executed in synchronization context,
288 : * so it is impossible that more than one threads doing commit.
289 : */
290 0 : ubifs_assert(c, 0);
291 : return 0;
292 : }
293 :
294 : /**
295 : * ubifs_run_commit - run or wait for commit.
296 : * @c: UBIFS file-system description object
297 : *
298 : * This function runs commit and returns zero in case of success and a negative
299 : * error code in case of failure.
300 : */
301 3532 : int ubifs_run_commit(struct ubifs_info *c)
302 : {
303 3532 : int err = 0;
304 :
305 3532 : spin_lock(&c->cs_lock);
306 3532 : if (c->cmt_state == COMMIT_BROKEN) {
307 : err = -EROFS;
308 : goto out;
309 : }
310 :
311 3532 : if (c->cmt_state == COMMIT_RUNNING_BACKGROUND)
312 : /*
313 : * We set the commit state to 'running required' to indicate
314 : * that we want it to complete as quickly as possible.
315 : */
316 0 : c->cmt_state = COMMIT_RUNNING_REQUIRED;
317 :
318 3532 : if (c->cmt_state == COMMIT_RUNNING_REQUIRED) {
319 0 : spin_unlock(&c->cs_lock);
320 0 : return wait_for_commit(c);
321 : }
322 3532 : spin_unlock(&c->cs_lock);
323 :
324 : /* Ok, the commit is indeed needed */
325 :
326 3532 : down_write(&c->commit_sem);
327 3532 : spin_lock(&c->cs_lock);
328 : /*
329 : * Since we unlocked 'c->cs_lock', the state may have changed, so
330 : * re-check it.
331 : */
332 3532 : if (c->cmt_state == COMMIT_BROKEN) {
333 0 : err = -EROFS;
334 : goto out_cmt_unlock;
335 : }
336 :
337 3532 : if (c->cmt_state == COMMIT_RUNNING_BACKGROUND)
338 0 : c->cmt_state = COMMIT_RUNNING_REQUIRED;
339 :
340 3532 : if (c->cmt_state == COMMIT_RUNNING_REQUIRED) {
341 0 : up_write(&c->commit_sem);
342 0 : spin_unlock(&c->cs_lock);
343 0 : return wait_for_commit(c);
344 : }
345 3532 : c->cmt_state = COMMIT_RUNNING_REQUIRED;
346 3532 : spin_unlock(&c->cs_lock);
347 :
348 3532 : err = do_commit(c);
349 3532 : return err;
350 :
351 0 : out_cmt_unlock:
352 0 : up_write(&c->commit_sem);
353 0 : out:
354 0 : spin_unlock(&c->cs_lock);
355 0 : return err;
356 : }
357 :
358 : /**
359 : * ubifs_gc_should_commit - determine if it is time for GC to run commit.
360 : * @c: UBIFS file-system description object
361 : *
362 : * This function is called by garbage collection to determine if commit should
363 : * be run. If commit state is @COMMIT_BACKGROUND, which means that the journal
364 : * is full enough to start commit, this function returns true. It is not
365 : * absolutely necessary to commit yet, but it feels like this should be better
366 : * then to keep doing GC. This function returns %1 if GC has to initiate commit
367 : * and %0 if not.
368 : */
369 0 : int ubifs_gc_should_commit(struct ubifs_info *c)
370 : {
371 0 : int ret = 0;
372 :
373 0 : spin_lock(&c->cs_lock);
374 0 : if (c->cmt_state == COMMIT_BACKGROUND) {
375 0 : dbg_cmt("commit required now");
376 0 : c->cmt_state = COMMIT_REQUIRED;
377 : } else
378 0 : dbg_cmt("commit not requested");
379 0 : if (c->cmt_state == COMMIT_REQUIRED)
380 0 : ret = 1;
381 0 : spin_unlock(&c->cs_lock);
382 0 : return ret;
383 : }
|