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) 2012, 2013, 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 const char lfsck_bookmark_name[] = "lfsck_bookmark";
44 static void lfsck_bookmark_le_to_cpu(struct lfsck_bookmark *des,
45 struct lfsck_bookmark *src)
47 des->lb_magic = le32_to_cpu(src->lb_magic);
48 des->lb_version = le16_to_cpu(src->lb_version);
49 des->lb_param = le16_to_cpu(src->lb_param);
50 des->lb_speed_limit = le32_to_cpu(src->lb_speed_limit);
51 des->lb_async_windows = le16_to_cpu(src->lb_async_windows);
52 fid_le_to_cpu(&des->lb_lpf_fid, &src->lb_lpf_fid);
53 fid_le_to_cpu(&des->lb_last_fid, &src->lb_last_fid);
56 void lfsck_bookmark_cpu_to_le(struct lfsck_bookmark *des,
57 struct lfsck_bookmark *src)
59 des->lb_magic = cpu_to_le32(src->lb_magic);
60 des->lb_version = cpu_to_le16(src->lb_version);
61 des->lb_param = cpu_to_le16(src->lb_param);
62 des->lb_speed_limit = cpu_to_le32(src->lb_speed_limit);
63 des->lb_async_windows = cpu_to_le16(src->lb_async_windows);
64 fid_cpu_to_le(&des->lb_lpf_fid, &src->lb_lpf_fid);
65 fid_cpu_to_le(&des->lb_last_fid, &src->lb_last_fid);
68 static int lfsck_bookmark_load(const struct lu_env *env,
69 struct lfsck_instance *lfsck)
72 int len = sizeof(struct lfsck_bookmark);
75 rc = dt_record_read(env, lfsck->li_bookmark_obj,
76 lfsck_buf_get(env, &lfsck->li_bookmark_disk, len),
79 struct lfsck_bookmark *bm = &lfsck->li_bookmark_ram;
81 lfsck_bookmark_le_to_cpu(bm, &lfsck->li_bookmark_disk);
82 if (bm->lb_magic != LFSCK_BOOKMARK_MAGIC) {
83 CWARN("%s: invalid lfsck_bookmark magic %#x != %#x\n",
84 lfsck_lfsck2name(lfsck), bm->lb_magic,
85 LFSCK_BOOKMARK_MAGIC);
86 /* Process it as new lfsck_bookmark. */
90 if (rc == -EFAULT && pos == 0)
91 /* return -ENODATA for empty lfsck_bookmark. */
94 CERROR("%s: fail to load lfsck_bookmark: "
95 "expected = %d, rc = %d\n",
96 lfsck_lfsck2name(lfsck), len, rc);
101 int lfsck_bookmark_store(const struct lu_env *env, struct lfsck_instance *lfsck)
103 struct thandle *handle;
104 struct dt_object *obj = lfsck->li_bookmark_obj;
106 int len = sizeof(struct lfsck_bookmark);
110 lfsck_bookmark_cpu_to_le(&lfsck->li_bookmark_disk,
111 &lfsck->li_bookmark_ram);
112 handle = dt_trans_create(env, lfsck->li_bottom);
113 if (IS_ERR(handle)) {
114 rc = PTR_ERR(handle);
115 CERROR("%s: fail to create trans for storing lfsck_bookmark: "
116 "rc = %d\n", lfsck_lfsck2name(lfsck), rc);
120 rc = dt_declare_record_write(env, obj,
122 &lfsck->li_bookmark_disk, len),
125 CERROR("%s: fail to declare trans for storing lfsck_bookmark: "
126 "rc = %d\n", lfsck_lfsck2name(lfsck), rc);
130 rc = dt_trans_start_local(env, lfsck->li_bottom, handle);
132 CERROR("%s: fail to start trans for storing lfsck_bookmark: "
133 "rc = %d\n", lfsck_lfsck2name(lfsck), rc);
137 rc = dt_record_write(env, obj,
138 lfsck_buf_get(env, &lfsck->li_bookmark_disk, len),
141 CERROR("%s: fail to store lfsck_bookmark: expected = %d, "
142 "rc = %d\n", lfsck_lfsck2name(lfsck), len, rc);
147 dt_trans_stop(env, lfsck->li_bottom, handle);
151 static int lfsck_bookmark_init(const struct lu_env *env,
152 struct lfsck_instance *lfsck)
154 struct lfsck_bookmark *mb = &lfsck->li_bookmark_ram;
157 memset(mb, 0, sizeof(*mb));
158 mb->lb_magic = LFSCK_BOOKMARK_MAGIC;
159 mb->lb_version = LFSCK_VERSION_V2;
160 mb->lb_async_windows = LFSCK_ASYNC_WIN_DEFAULT;
161 mutex_lock(&lfsck->li_mutex);
162 rc = lfsck_bookmark_store(env, lfsck);
163 mutex_unlock(&lfsck->li_mutex);
167 int lfsck_bookmark_setup(const struct lu_env *env,
168 struct lfsck_instance *lfsck)
170 struct dt_object *root;
171 struct dt_object *obj;
175 root = dt_locate(env, lfsck->li_bottom, &lfsck->li_local_root_fid);
177 RETURN(PTR_ERR(root));
179 if (unlikely(!dt_try_as_dir(env, root))) {
180 lu_object_put(env, &root->do_lu);
185 obj = local_file_find_or_create(env, lfsck->li_los, root,
187 S_IFREG | S_IRUGO | S_IWUSR);
188 lu_object_put(env, &root->do_lu);
190 RETURN(PTR_ERR(obj));
192 lfsck->li_bookmark_obj = obj;
193 rc = lfsck_bookmark_load(env, lfsck);
195 rc = lfsck_bookmark_init(env, lfsck);
200 int lfsck_set_param(const struct lu_env *env, struct lfsck_instance *lfsck,
201 struct lfsck_start *start, bool reset)
203 struct lfsck_bookmark *bk = &lfsck->li_bookmark_ram;
210 if (bk->lb_param & LPF_ALL_TGT) {
211 bk->lb_param &= ~LPF_ALL_TGT;
215 if (bk->lb_param & LPF_CREATE_OSTOBJ) {
216 bk->lb_param &= ~LPF_CREATE_OSTOBJ;
220 if (bk->lb_param & LPF_FAILOUT) {
221 bk->lb_param &= ~LPF_FAILOUT;
225 if (bk->lb_param & LPF_DRYRUN) {
226 bk->lb_param &= ~LPF_DRYRUN;
230 if (bk->lb_param & LPF_ORPHAN) {
231 bk->lb_param &= ~LPF_ORPHAN;
235 if (__lfsck_set_speed(lfsck, LFSCK_SPEED_NO_LIMIT))
238 if (bk->lb_async_windows != LFSCK_ASYNC_WIN_DEFAULT) {
239 bk->lb_async_windows = LFSCK_ASYNC_WIN_DEFAULT;
243 if ((bk->lb_param & LPF_ALL_TGT) &&
244 !(start->ls_flags & LPF_ALL_TGT)) {
245 bk->lb_param &= ~LPF_ALL_TGT;
247 } else if (!(bk->lb_param & LPF_ALL_TGT) &&
248 (start->ls_flags & LPF_ALL_TGT)) {
249 bk->lb_param |= LPF_ALL_TGT;
253 if ((start->ls_valid & LSV_CREATE_OSTOBJ) || reset) {
254 if ((bk->lb_param & LPF_CREATE_OSTOBJ) &&
255 !(start->ls_valid & LSV_CREATE_OSTOBJ)) {
256 bk->lb_param &= ~LPF_CREATE_OSTOBJ;
258 } else if (!(bk->lb_param & LPF_CREATE_OSTOBJ) &&
259 (start->ls_flags & LPF_CREATE_OSTOBJ)) {
260 bk->lb_param |= LPF_CREATE_OSTOBJ;
265 if ((start->ls_valid & LSV_ERROR_HANDLE) || reset) {
266 if ((bk->lb_param & LPF_FAILOUT) &&
267 !(start->ls_valid & LSV_ERROR_HANDLE)) {
268 bk->lb_param &= ~LPF_FAILOUT;
270 } else if (!(start->ls_flags & LPF_FAILOUT) &&
271 (bk->lb_param & LPF_FAILOUT)) {
272 bk->lb_param &= ~LPF_FAILOUT;
277 if ((start->ls_valid & LSV_DRYRUN) || reset) {
278 if ((bk->lb_param & LPF_DRYRUN) &&
279 !(start->ls_valid & LSV_DRYRUN)) {
280 bk->lb_param &= ~LPF_DRYRUN;
282 } else if (!(start->ls_flags & LPF_DRYRUN) &&
283 (bk->lb_param & LPF_DRYRUN)) {
284 bk->lb_param &= ~LPF_DRYRUN;
285 lfsck->li_drop_dryrun = 1;
290 if ((bk->lb_param & LPF_ORPHAN) &&
291 !(start->ls_flags & LPF_ORPHAN)) {
292 bk->lb_param &= ~LPF_ORPHAN;
294 } else if (!(bk->lb_param & LPF_ORPHAN) &&
295 (start->ls_flags & LPF_ORPHAN)) {
296 bk->lb_param |= LPF_ORPHAN;
300 if (start->ls_valid & LSV_SPEED_LIMIT) {
301 if (__lfsck_set_speed(lfsck, start->ls_speed_limit))
304 if (__lfsck_set_speed(lfsck, LFSCK_SPEED_NO_LIMIT))
308 if (start->ls_valid & LSV_ASYNC_WINDOWS) {
309 if (bk->lb_async_windows != start->ls_async_windows) {
310 bk->lb_async_windows = start->ls_async_windows;
314 bk->lb_async_windows != LFSCK_ASYNC_WIN_DEFAULT) {
315 bk->lb_async_windows = LFSCK_ASYNC_WIN_DEFAULT;
321 rc = lfsck_bookmark_store(env, lfsck);