4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License version 2 for more details. A copy is
14 * included in the COPYING file that accompanied this code.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 * Copyright (c) 2013, 2015, Intel Corporation.
26 * lustre/lfsck/lfsck_bookmark.c
28 * Author: Fan, Yong <fan.yong@intel.com>
31 #define DEBUG_SUBSYSTEM S_LFSCK
33 #include <lu_object.h>
34 #include <dt_object.h>
35 #include <lustre_fid.h>
36 #include <lustre/lustre_user.h>
38 #include "lfsck_internal.h"
40 #define LFSCK_BOOKMARK_MAGIC 0x20130C1D
42 static void lfsck_bookmark_le_to_cpu(struct lfsck_bookmark *des,
43 struct lfsck_bookmark *src)
45 des->lb_magic = le32_to_cpu(src->lb_magic);
46 des->lb_version = le16_to_cpu(src->lb_version);
47 des->lb_param = le16_to_cpu(src->lb_param);
48 des->lb_speed_limit = le32_to_cpu(src->lb_speed_limit);
49 des->lb_async_windows = le16_to_cpu(src->lb_async_windows);
50 fid_le_to_cpu(&des->lb_lpf_fid, &src->lb_lpf_fid);
51 fid_le_to_cpu(&des->lb_last_fid, &src->lb_last_fid);
54 void lfsck_bookmark_cpu_to_le(struct lfsck_bookmark *des,
55 struct lfsck_bookmark *src)
57 des->lb_magic = cpu_to_le32(src->lb_magic);
58 des->lb_version = cpu_to_le16(src->lb_version);
59 des->lb_param = cpu_to_le16(src->lb_param);
60 des->lb_speed_limit = cpu_to_le32(src->lb_speed_limit);
61 des->lb_async_windows = cpu_to_le16(src->lb_async_windows);
62 fid_cpu_to_le(&des->lb_lpf_fid, &src->lb_lpf_fid);
63 fid_cpu_to_le(&des->lb_last_fid, &src->lb_last_fid);
66 static int lfsck_bookmark_load(const struct lu_env *env,
67 struct lfsck_instance *lfsck)
70 int len = sizeof(struct lfsck_bookmark);
73 rc = dt_record_read(env, lfsck->li_bookmark_obj,
74 lfsck_buf_get(env, &lfsck->li_bookmark_disk, len),
77 struct lfsck_bookmark *bm = &lfsck->li_bookmark_ram;
79 lfsck_bookmark_le_to_cpu(bm, &lfsck->li_bookmark_disk);
80 if (bm->lb_magic != LFSCK_BOOKMARK_MAGIC) {
81 CDEBUG(D_LFSCK, "%s: invalid lfsck_bookmark magic "
82 "%#x != %#x\n", lfsck_lfsck2name(lfsck),
83 bm->lb_magic, LFSCK_BOOKMARK_MAGIC);
84 /* Process it as new lfsck_bookmark. */
88 if (rc == -EFAULT && pos == 0)
89 /* return -ENODATA for empty lfsck_bookmark. */
92 CDEBUG(D_LFSCK, "%s: fail to load lfsck_bookmark, "
93 "expected = %d: rc = %d\n",
94 lfsck_lfsck2name(lfsck), len, rc);
99 int lfsck_bookmark_store(const struct lu_env *env, struct lfsck_instance *lfsck)
101 struct thandle *handle;
102 struct dt_object *obj = lfsck->li_bookmark_obj;
103 struct dt_device *dev = lfsck_obj2dev(obj);
105 int len = sizeof(struct lfsck_bookmark);
109 lfsck_bookmark_cpu_to_le(&lfsck->li_bookmark_disk,
110 &lfsck->li_bookmark_ram);
111 handle = dt_trans_create(env, dev);
113 GOTO(log, rc = PTR_ERR(handle));
115 rc = dt_declare_record_write(env, obj,
117 &lfsck->li_bookmark_disk, len),
122 rc = dt_trans_start_local(env, dev, handle);
126 rc = dt_record_write(env, obj,
127 lfsck_buf_get(env, &lfsck->li_bookmark_disk, len),
133 dt_trans_stop(env, dev, handle);
137 CDEBUG(D_LFSCK, "%s: fail to store lfsck_bookmark: rc = %d\n",
138 lfsck_lfsck2name(lfsck), rc);
142 static int lfsck_bookmark_init(const struct lu_env *env,
143 struct lfsck_instance *lfsck)
145 struct lfsck_bookmark *mb = &lfsck->li_bookmark_ram;
148 memset(mb, 0, sizeof(*mb));
149 mb->lb_magic = LFSCK_BOOKMARK_MAGIC;
150 mb->lb_version = LFSCK_VERSION_V2;
151 mb->lb_async_windows = LFSCK_ASYNC_WIN_DEFAULT;
152 mutex_lock(&lfsck->li_mutex);
153 rc = lfsck_bookmark_store(env, lfsck);
154 mutex_unlock(&lfsck->li_mutex);
158 int lfsck_bookmark_setup(const struct lu_env *env,
159 struct lfsck_instance *lfsck)
161 struct dt_object *root;
162 struct dt_object *obj;
166 root = dt_locate(env, lfsck->li_bottom, &lfsck->li_local_root_fid);
168 RETURN(PTR_ERR(root));
170 if (unlikely(!dt_try_as_dir(env, root))) {
171 lfsck_object_put(env, root);
176 obj = local_file_find_or_create(env, lfsck->li_los, root,
178 S_IFREG | S_IRUGO | S_IWUSR);
179 lfsck_object_put(env, root);
181 RETURN(PTR_ERR(obj));
183 lfsck->li_bookmark_obj = obj;
184 rc = lfsck_bookmark_load(env, lfsck);
186 struct lfsck_bookmark *mb = &lfsck->li_bookmark_ram;
188 /* It is upgraded from old release, set it as
189 * LFSCK_ASYNC_WIN_DEFAULT to avoid memory pressure. */
190 if (unlikely(mb->lb_async_windows == 0)) {
191 mb->lb_async_windows = LFSCK_ASYNC_WIN_DEFAULT;
192 mutex_lock(&lfsck->li_mutex);
193 rc = lfsck_bookmark_store(env, lfsck);
194 mutex_unlock(&lfsck->li_mutex);
196 } else if (rc == -ENODATA) {
197 rc = lfsck_bookmark_init(env, lfsck);
203 int lfsck_set_param(const struct lu_env *env, struct lfsck_instance *lfsck,
204 struct lfsck_start *start, bool reset)
206 struct lfsck_bookmark *bk = &lfsck->li_bookmark_ram;
213 if (bk->lb_param & LPF_ALL_TGT) {
214 bk->lb_param &= ~LPF_ALL_TGT;
218 if (bk->lb_param & LPF_CREATE_OSTOBJ) {
219 bk->lb_param &= ~LPF_CREATE_OSTOBJ;
223 if (bk->lb_param & LPF_CREATE_MDTOBJ) {
224 bk->lb_param &= ~LPF_CREATE_MDTOBJ;
228 if (bk->lb_param & LPF_DELAY_CREATE_OSTOBJ) {
229 bk->lb_param &= ~LPF_DELAY_CREATE_OSTOBJ;
233 if (bk->lb_param & LPF_FAILOUT) {
234 bk->lb_param &= ~LPF_FAILOUT;
238 if (bk->lb_param & LPF_DRYRUN) {
239 bk->lb_param &= ~LPF_DRYRUN;
243 if (bk->lb_param & LPF_OST_ORPHAN) {
244 bk->lb_param &= ~LPF_OST_ORPHAN;
248 if (__lfsck_set_speed(lfsck, LFSCK_SPEED_NO_LIMIT))
251 if (bk->lb_async_windows != LFSCK_ASYNC_WIN_DEFAULT) {
252 bk->lb_async_windows = LFSCK_ASYNC_WIN_DEFAULT;
256 if ((bk->lb_param & LPF_ALL_TGT) &&
257 !(start->ls_flags & LPF_ALL_TGT)) {
258 bk->lb_param &= ~LPF_ALL_TGT;
260 } else if (!(bk->lb_param & LPF_ALL_TGT) &&
261 (start->ls_flags & LPF_ALL_TGT)) {
262 bk->lb_param |= LPF_ALL_TGT;
266 if ((bk->lb_param & LPF_OST_ORPHAN) &&
267 !(start->ls_flags & LPF_OST_ORPHAN)) {
268 bk->lb_param &= ~LPF_OST_ORPHAN;
270 } else if (!(bk->lb_param & LPF_OST_ORPHAN) &&
271 (start->ls_flags & LPF_OST_ORPHAN)) {
272 bk->lb_param |= LPF_OST_ORPHAN;
276 if ((start->ls_valid & LSV_CREATE_OSTOBJ) || reset) {
277 if ((bk->lb_param & LPF_CREATE_OSTOBJ) &&
278 !(start->ls_flags & LPF_CREATE_OSTOBJ)) {
279 bk->lb_param &= ~LPF_CREATE_OSTOBJ;
281 } else if (!(bk->lb_param & LPF_CREATE_OSTOBJ) &&
282 (start->ls_flags & LPF_CREATE_OSTOBJ)) {
283 bk->lb_param |= LPF_CREATE_OSTOBJ;
288 if ((start->ls_valid & LSV_CREATE_MDTOBJ) || reset) {
289 if ((bk->lb_param & LPF_CREATE_MDTOBJ) &&
290 !(start->ls_flags & LPF_CREATE_MDTOBJ)) {
291 bk->lb_param &= ~LPF_CREATE_MDTOBJ;
293 } else if (!(bk->lb_param & LPF_CREATE_MDTOBJ) &&
294 (start->ls_flags & LPF_CREATE_MDTOBJ)) {
295 bk->lb_param |= LPF_CREATE_MDTOBJ;
300 if ((start->ls_valid & LSV_DELAY_CREATE_OSTOBJ) || reset) {
301 if ((bk->lb_param & LPF_DELAY_CREATE_OSTOBJ) &&
302 !(start->ls_flags & LPF_DELAY_CREATE_OSTOBJ)) {
303 bk->lb_param &= ~LPF_DELAY_CREATE_OSTOBJ;
305 } else if (!(bk->lb_param & LPF_DELAY_CREATE_OSTOBJ) &&
306 start->ls_flags & LPF_DELAY_CREATE_OSTOBJ) {
307 bk->lb_param |= LPF_DELAY_CREATE_OSTOBJ;
312 if ((start->ls_valid & LSV_ERROR_HANDLE) || reset) {
313 if ((bk->lb_param & LPF_FAILOUT) &&
314 !(start->ls_flags & LPF_FAILOUT)) {
315 bk->lb_param &= ~LPF_FAILOUT;
317 } else if (!(bk->lb_param & LPF_FAILOUT) &&
318 (start->ls_flags & LPF_FAILOUT)) {
319 bk->lb_param |= LPF_FAILOUT;
324 if ((start->ls_valid & LSV_DRYRUN) || reset) {
325 if ((bk->lb_param & LPF_DRYRUN) &&
326 !(start->ls_flags & LPF_DRYRUN)) {
327 bk->lb_param &= ~LPF_DRYRUN;
328 lfsck->li_drop_dryrun = 1;
330 } else if (!(bk->lb_param & LPF_DRYRUN) &&
331 (start->ls_flags & LPF_DRYRUN)) {
332 bk->lb_param |= LPF_DRYRUN;
337 if (start->ls_valid & LSV_SPEED_LIMIT) {
338 if (__lfsck_set_speed(lfsck, start->ls_speed_limit))
341 if (__lfsck_set_speed(lfsck, LFSCK_SPEED_NO_LIMIT))
345 if (start->ls_valid & LSV_ASYNC_WINDOWS) {
346 if (start->ls_async_windows < 1)
349 if (bk->lb_async_windows != start->ls_async_windows) {
350 bk->lb_async_windows = start->ls_async_windows;
354 bk->lb_async_windows != LFSCK_ASYNC_WIN_DEFAULT) {
355 bk->lb_async_windows = LFSCK_ASYNC_WIN_DEFAULT;
361 rc = lfsck_bookmark_store(env, lfsck);