Whamcloud - gitweb
LU-6142 lfsck: Fix style issues under lustre/lfsck
[fs/lustre-release.git] / lustre / lfsck / lfsck_bookmark.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
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.
9
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.
15
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
19  *
20  * GPL HEADER END
21  */
22 /*
23  * Copyright (c) 2013, 2017, Intel Corporation.
24  */
25 /*
26  * lustre/lfsck/lfsck_bookmark.c
27  *
28  * Author: Fan, Yong <fan.yong@intel.com>
29  */
30
31 #define DEBUG_SUBSYSTEM S_LFSCK
32
33 #include <lu_object.h>
34 #include <dt_object.h>
35 #include <lustre_fid.h>
36 #include <lu_target.h>
37
38 #include "lfsck_internal.h"
39
40 #define LFSCK_BOOKMARK_MAGIC    0x20130C1D
41
42 static void lfsck_bookmark_le_to_cpu(struct lfsck_bookmark *des,
43                                      struct lfsck_bookmark *src)
44 {
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);
52 }
53
54 void lfsck_bookmark_cpu_to_le(struct lfsck_bookmark *des,
55                               struct lfsck_bookmark *src)
56 {
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);
64 }
65
66 static int lfsck_bookmark_load(const struct lu_env *env,
67                                struct lfsck_instance *lfsck)
68 {
69         loff_t pos = 0;
70         int len = sizeof(struct lfsck_bookmark);
71         int rc;
72
73         rc = dt_record_read(env, lfsck->li_bookmark_obj,
74                             lfsck_buf_get(env, &lfsck->li_bookmark_disk, len),
75                             &pos);
76         if (rc == 0) {
77                 struct lfsck_bookmark *bm = &lfsck->li_bookmark_ram;
78
79                 lfsck_bookmark_le_to_cpu(bm, &lfsck->li_bookmark_disk);
80                 if (bm->lb_magic != LFSCK_BOOKMARK_MAGIC) {
81                         CDEBUG(D_LFSCK,
82                                "%s: invalid lfsck_bookmark magic %#x != %#x\n",
83                                lfsck_lfsck2name(lfsck), bm->lb_magic,
84                                LFSCK_BOOKMARK_MAGIC);
85                         /* Process it as new lfsck_bookmark. */
86                         rc = -ENODATA;
87                 }
88         } else {
89                 if (rc == -EFAULT && pos == 0)
90                         /* return -ENODATA for empty lfsck_bookmark. */
91                         rc = -ENODATA;
92                 else
93                         CDEBUG(D_LFSCK,
94                                "%s: fail to load lfsck_bookmark, expected = %d: rc = %d\n",
95                                lfsck_lfsck2name(lfsck), len, rc);
96         }
97         return rc;
98 }
99
100 int lfsck_bookmark_store(const struct lu_env *env, struct lfsck_instance *lfsck)
101 {
102         struct thandle *handle;
103         struct dt_object *obj = lfsck->li_bookmark_obj;
104         struct dt_device *dev = lfsck_obj2dev(obj);
105         loff_t pos = 0;
106         int len = sizeof(struct lfsck_bookmark);
107         int rc;
108
109         ENTRY;
110
111         lfsck_bookmark_cpu_to_le(&lfsck->li_bookmark_disk,
112                                  &lfsck->li_bookmark_ram);
113         handle = dt_trans_create(env, dev);
114         if (IS_ERR(handle))
115                 GOTO(log, rc = PTR_ERR(handle));
116
117         rc = dt_declare_record_write(env, obj,
118                                      lfsck_buf_get(env,
119                                      &lfsck->li_bookmark_disk, len),
120                                      0, handle);
121         if (rc != 0)
122                 GOTO(out, rc);
123
124         rc = dt_trans_start_local(env, dev, handle);
125         if (rc != 0)
126                 GOTO(out, rc);
127
128         rc = dt_record_write(env, obj,
129                              lfsck_buf_get(env, &lfsck->li_bookmark_disk, len),
130                              &pos, handle);
131
132         GOTO(out, rc);
133
134 out:
135         dt_trans_stop(env, dev, handle);
136
137 log:
138         if (rc != 0)
139                 CDEBUG(D_LFSCK, "%s: fail to store lfsck_bookmark: rc = %d\n",
140                        lfsck_lfsck2name(lfsck), rc);
141         return rc;
142 }
143
144 static int lfsck_bookmark_init(const struct lu_env *env,
145                                struct lfsck_instance *lfsck)
146 {
147         struct lfsck_bookmark *mb = &lfsck->li_bookmark_ram;
148         int rc;
149
150         memset(mb, 0, sizeof(*mb));
151         mb->lb_magic = LFSCK_BOOKMARK_MAGIC;
152         mb->lb_version = LFSCK_VERSION_V2;
153         mb->lb_async_windows = LFSCK_ASYNC_WIN_DEFAULT;
154         mutex_lock(&lfsck->li_mutex);
155         rc = lfsck_bookmark_store(env, lfsck);
156         mutex_unlock(&lfsck->li_mutex);
157         return rc;
158 }
159
160 int lfsck_bookmark_setup(const struct lu_env *env,
161                          struct lfsck_instance *lfsck)
162 {
163         struct dt_object *root;
164         struct dt_object *obj;
165         int rc;
166
167         ENTRY;
168         root = dt_locate(env, lfsck->li_bottom, &lfsck->li_local_root_fid);
169         if (IS_ERR(root))
170                 RETURN(PTR_ERR(root));
171
172         if (unlikely(!dt_try_as_dir(env, root, true))) {
173                 lfsck_object_put(env, root);
174
175                 RETURN(-ENOTDIR);
176         }
177
178         obj = local_file_find_or_create(env, lfsck->li_los, root,
179                                         LFSCK_BOOKMARK,
180                                         S_IFREG | S_IRUGO | S_IWUSR);
181         lfsck_object_put(env, root);
182         if (IS_ERR(obj))
183                 RETURN(PTR_ERR(obj));
184
185         lfsck->li_bookmark_obj = obj;
186         rc = lfsck_bookmark_load(env, lfsck);
187         if (rc == 0) {
188                 struct lfsck_bookmark *mb = &lfsck->li_bookmark_ram;
189
190                 /* It is upgraded from old release, set it as
191                  * LFSCK_ASYNC_WIN_DEFAULT to avoid memory pressure.
192                  */
193                 if (unlikely(mb->lb_async_windows == 0)) {
194                         mb->lb_async_windows = LFSCK_ASYNC_WIN_DEFAULT;
195                         mutex_lock(&lfsck->li_mutex);
196                         rc = lfsck_bookmark_store(env, lfsck);
197                         mutex_unlock(&lfsck->li_mutex);
198                 }
199         } else if (rc == -ENODATA) {
200                 rc = lfsck_bookmark_init(env, lfsck);
201         }
202
203         RETURN(rc);
204 }
205
206 int lfsck_set_param(const struct lu_env *env, struct lfsck_instance *lfsck,
207                     struct lfsck_start *start, bool reset)
208 {
209         struct lfsck_bookmark *bk = &lfsck->li_bookmark_ram;
210         int rc = 0;
211         bool dirty = false;
212
213         if (start == NULL) {
214                 LASSERT(reset);
215
216                 if (bk->lb_param & LPF_ALL_TGT) {
217                         bk->lb_param &= ~LPF_ALL_TGT;
218                         dirty = true;
219                 }
220
221                 if (bk->lb_param & LPF_CREATE_OSTOBJ) {
222                         bk->lb_param &= ~LPF_CREATE_OSTOBJ;
223                         dirty = true;
224                 }
225
226                 if (bk->lb_param & LPF_CREATE_MDTOBJ) {
227                         bk->lb_param &= ~LPF_CREATE_MDTOBJ;
228                         dirty = true;
229                 }
230
231                 if (bk->lb_param & LPF_DELAY_CREATE_OSTOBJ) {
232                         bk->lb_param &= ~LPF_DELAY_CREATE_OSTOBJ;
233                         dirty = true;
234                 }
235
236                 if (bk->lb_param & LPF_FAILOUT) {
237                         bk->lb_param &= ~LPF_FAILOUT;
238                         dirty = true;
239                 }
240
241                 if (bk->lb_param & LPF_DRYRUN) {
242                         bk->lb_param &= ~LPF_DRYRUN;
243                         dirty = true;
244                 }
245
246                 if (bk->lb_param & LPF_OST_ORPHAN) {
247                         bk->lb_param &= ~LPF_OST_ORPHAN;
248                         dirty = true;
249                 }
250
251                 if (__lfsck_set_speed(lfsck, LFSCK_SPEED_NO_LIMIT))
252                         dirty = true;
253
254                 if (bk->lb_async_windows != LFSCK_ASYNC_WIN_DEFAULT) {
255                         bk->lb_async_windows = LFSCK_ASYNC_WIN_DEFAULT;
256                         dirty = true;
257                 }
258         } else {
259                 if ((bk->lb_param & LPF_ALL_TGT) &&
260                     !(start->ls_flags & LPF_ALL_TGT)) {
261                         bk->lb_param &= ~LPF_ALL_TGT;
262                         dirty = true;
263                 } else if (!(bk->lb_param & LPF_ALL_TGT) &&
264                            (start->ls_flags & LPF_ALL_TGT)) {
265                         bk->lb_param |= LPF_ALL_TGT;
266                         dirty = true;
267                 }
268
269                 if ((bk->lb_param & LPF_OST_ORPHAN) &&
270                     !(start->ls_flags & LPF_OST_ORPHAN)) {
271                         bk->lb_param &= ~LPF_OST_ORPHAN;
272                         dirty = true;
273                 } else if (!(bk->lb_param & LPF_OST_ORPHAN) &&
274                            (start->ls_flags & LPF_OST_ORPHAN)) {
275                         bk->lb_param |= LPF_OST_ORPHAN;
276                         dirty = true;
277                 }
278
279                 if ((start->ls_valid & LSV_CREATE_OSTOBJ) || reset) {
280                         if ((bk->lb_param & LPF_CREATE_OSTOBJ) &&
281                             !(start->ls_flags & LPF_CREATE_OSTOBJ)) {
282                                 bk->lb_param &= ~LPF_CREATE_OSTOBJ;
283                                 dirty = true;
284                         } else if (!(bk->lb_param & LPF_CREATE_OSTOBJ) &&
285                                    (start->ls_flags & LPF_CREATE_OSTOBJ)) {
286                                 bk->lb_param |= LPF_CREATE_OSTOBJ;
287                                 dirty = true;
288                         }
289                 }
290
291                 if ((start->ls_valid & LSV_CREATE_MDTOBJ) || reset) {
292                         if ((bk->lb_param & LPF_CREATE_MDTOBJ) &&
293                             !(start->ls_flags & LPF_CREATE_MDTOBJ)) {
294                                 bk->lb_param &= ~LPF_CREATE_MDTOBJ;
295                                 dirty = true;
296                         } else if (!(bk->lb_param & LPF_CREATE_MDTOBJ) &&
297                                    (start->ls_flags & LPF_CREATE_MDTOBJ)) {
298                                 bk->lb_param |= LPF_CREATE_MDTOBJ;
299                                 dirty = true;
300                         }
301                 }
302
303                 if ((start->ls_valid & LSV_DELAY_CREATE_OSTOBJ) || reset) {
304                         if ((bk->lb_param & LPF_DELAY_CREATE_OSTOBJ) &&
305                             !(start->ls_flags & LPF_DELAY_CREATE_OSTOBJ)) {
306                                 bk->lb_param &= ~LPF_DELAY_CREATE_OSTOBJ;
307                                 dirty = true;
308                         } else if (!(bk->lb_param & LPF_DELAY_CREATE_OSTOBJ) &&
309                                    start->ls_flags & LPF_DELAY_CREATE_OSTOBJ) {
310                                 bk->lb_param |= LPF_DELAY_CREATE_OSTOBJ;
311                                 dirty = true;
312                         }
313                 }
314
315                 if ((start->ls_valid & LSV_ERROR_HANDLE) || reset) {
316                         if ((bk->lb_param & LPF_FAILOUT) &&
317                             !(start->ls_flags & LPF_FAILOUT)) {
318                                 bk->lb_param &= ~LPF_FAILOUT;
319                                 dirty = true;
320                         } else if (!(bk->lb_param & LPF_FAILOUT) &&
321                                    (start->ls_flags & LPF_FAILOUT)) {
322                                 bk->lb_param |= LPF_FAILOUT;
323                                 dirty = true;
324                         }
325                 }
326
327                 if ((start->ls_valid & LSV_DRYRUN) || reset) {
328                         if ((bk->lb_param & LPF_DRYRUN) &&
329                             !(start->ls_flags & LPF_DRYRUN)) {
330                                 bk->lb_param &= ~LPF_DRYRUN;
331                                 lfsck->li_drop_dryrun = 1;
332                                 dirty = true;
333                         } else if (!(bk->lb_param & LPF_DRYRUN) &&
334                                    (start->ls_flags & LPF_DRYRUN)) {
335                                 bk->lb_param |= LPF_DRYRUN;
336                                 dirty = true;
337                         }
338                 }
339
340                 if (start->ls_valid & LSV_SPEED_LIMIT) {
341                         if (__lfsck_set_speed(lfsck, start->ls_speed_limit))
342                                 dirty = true;
343                 } else if (reset) {
344                         if (__lfsck_set_speed(lfsck, LFSCK_SPEED_NO_LIMIT))
345                                 dirty = true;
346                 }
347
348                 if (start->ls_valid & LSV_ASYNC_WINDOWS) {
349                         if (start->ls_async_windows < 1)
350                                 return -EINVAL;
351
352                         if (bk->lb_async_windows != start->ls_async_windows) {
353                                 bk->lb_async_windows = start->ls_async_windows;
354                                 dirty = true;
355                         }
356                 } else if (reset &&
357                            bk->lb_async_windows != LFSCK_ASYNC_WIN_DEFAULT) {
358                         bk->lb_async_windows = LFSCK_ASYNC_WIN_DEFAULT;
359                         dirty = true;
360                 }
361         }
362
363         if (dirty)
364                 rc = lfsck_bookmark_store(env, lfsck);
365
366         return rc;
367 }