Whamcloud - gitweb
LU-6068 misc: update Intel copyright messages 2014
[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, 2014, 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 <lustre/lustre_user.h>
37
38 #include "lfsck_internal.h"
39
40 #define LFSCK_BOOKMARK_MAGIC    0x20130C1D
41
42 static const char lfsck_bookmark_name[] = "lfsck_bookmark";
43
44 static void lfsck_bookmark_le_to_cpu(struct lfsck_bookmark *des,
45                                      struct lfsck_bookmark *src)
46 {
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);
54 }
55
56 void lfsck_bookmark_cpu_to_le(struct lfsck_bookmark *des,
57                               struct lfsck_bookmark *src)
58 {
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);
66 }
67
68 static int lfsck_bookmark_load(const struct lu_env *env,
69                                struct lfsck_instance *lfsck)
70 {
71         loff_t pos = 0;
72         int    len = sizeof(struct lfsck_bookmark);
73         int    rc;
74
75         rc = dt_record_read(env, lfsck->li_bookmark_obj,
76                             lfsck_buf_get(env, &lfsck->li_bookmark_disk, len),
77                             &pos);
78         if (rc == 0) {
79                 struct lfsck_bookmark *bm = &lfsck->li_bookmark_ram;
80
81                 lfsck_bookmark_le_to_cpu(bm, &lfsck->li_bookmark_disk);
82                 if (bm->lb_magic != LFSCK_BOOKMARK_MAGIC) {
83                         CDEBUG(D_LFSCK, "%s: invalid lfsck_bookmark magic "
84                               "%#x != %#x\n", lfsck_lfsck2name(lfsck),
85                               bm->lb_magic, LFSCK_BOOKMARK_MAGIC);
86                         /* Process it as new lfsck_bookmark. */
87                         rc = -ENODATA;
88                 }
89         } else {
90                 if (rc == -EFAULT && pos == 0)
91                         /* return -ENODATA for empty lfsck_bookmark. */
92                         rc = -ENODATA;
93                 else
94                         CDEBUG(D_LFSCK, "%s: fail to load lfsck_bookmark, "
95                                "expected = %d: rc = %d\n",
96                                lfsck_lfsck2name(lfsck), len, rc);
97         }
98         return rc;
99 }
100
101 int lfsck_bookmark_store(const struct lu_env *env, struct lfsck_instance *lfsck)
102 {
103         struct thandle    *handle;
104         struct dt_object  *obj    = lfsck->li_bookmark_obj;
105         loff_t             pos    = 0;
106         int                len    = sizeof(struct lfsck_bookmark);
107         int                rc;
108         ENTRY;
109
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                 GOTO(log, rc = PTR_ERR(handle));
115
116         rc = dt_declare_record_write(env, obj,
117                                      lfsck_buf_get(env,
118                                      &lfsck->li_bookmark_disk, len),
119                                      0, handle);
120         if (rc != 0)
121                 GOTO(out, rc);
122
123         rc = dt_trans_start_local(env, lfsck->li_bottom, handle);
124         if (rc != 0)
125                 GOTO(out, rc);
126
127         rc = dt_record_write(env, obj,
128                              lfsck_buf_get(env, &lfsck->li_bookmark_disk, len),
129                              &pos, handle);
130
131         GOTO(out, rc);
132
133 out:
134         dt_trans_stop(env, lfsck->li_bottom, handle);
135
136 log:
137         if (rc != 0)
138                 CDEBUG(D_LFSCK, "%s: fail to store lfsck_bookmark: rc = %d\n",
139                        lfsck_lfsck2name(lfsck), rc);
140         return rc;
141 }
142
143 static int lfsck_bookmark_init(const struct lu_env *env,
144                                struct lfsck_instance *lfsck)
145 {
146         struct lfsck_bookmark *mb = &lfsck->li_bookmark_ram;
147         int rc;
148
149         memset(mb, 0, sizeof(*mb));
150         mb->lb_magic = LFSCK_BOOKMARK_MAGIC;
151         mb->lb_version = LFSCK_VERSION_V2;
152         mb->lb_async_windows = LFSCK_ASYNC_WIN_DEFAULT;
153         mutex_lock(&lfsck->li_mutex);
154         rc = lfsck_bookmark_store(env, lfsck);
155         mutex_unlock(&lfsck->li_mutex);
156         return rc;
157 }
158
159 int lfsck_bookmark_setup(const struct lu_env *env,
160                          struct lfsck_instance *lfsck)
161 {
162         struct dt_object *root;
163         struct dt_object *obj;
164         int               rc;
165         ENTRY;
166
167         root = dt_locate(env, lfsck->li_bottom, &lfsck->li_local_root_fid);
168         if (IS_ERR(root))
169                 RETURN(PTR_ERR(root));
170
171         if (unlikely(!dt_try_as_dir(env, root))) {
172                 lu_object_put(env, &root->do_lu);
173
174                 RETURN(-ENOTDIR);
175         }
176
177         obj = local_file_find_or_create(env, lfsck->li_los, root,
178                                         lfsck_bookmark_name,
179                                         S_IFREG | S_IRUGO | S_IWUSR);
180         lu_object_put(env, &root->do_lu);
181         if (IS_ERR(obj))
182                 RETURN(PTR_ERR(obj));
183
184         lfsck->li_bookmark_obj = obj;
185         rc = lfsck_bookmark_load(env, lfsck);
186         if (rc == -ENODATA)
187                 rc = lfsck_bookmark_init(env, lfsck);
188
189         RETURN(rc);
190 }
191
192 int lfsck_set_param(const struct lu_env *env, struct lfsck_instance *lfsck,
193                     struct lfsck_start *start, bool reset)
194 {
195         struct lfsck_bookmark   *bk     = &lfsck->li_bookmark_ram;
196         int                      rc     = 0;
197         bool                     dirty  = false;
198
199         if (start == NULL) {
200                 LASSERT(reset);
201
202                 if (bk->lb_param & LPF_ALL_TGT) {
203                         bk->lb_param &= ~LPF_ALL_TGT;
204                         dirty = true;
205                 }
206
207                 if (bk->lb_param & LPF_CREATE_OSTOBJ) {
208                         bk->lb_param &= ~LPF_CREATE_OSTOBJ;
209                         dirty = true;
210                 }
211
212                 if (bk->lb_param & LPF_CREATE_MDTOBJ) {
213                         bk->lb_param &= ~LPF_CREATE_MDTOBJ;
214                         dirty = true;
215                 }
216
217                 if (bk->lb_param & LPF_FAILOUT) {
218                         bk->lb_param &= ~LPF_FAILOUT;
219                         dirty = true;
220                 }
221
222                 if (bk->lb_param & LPF_DRYRUN) {
223                         bk->lb_param &= ~LPF_DRYRUN;
224                         dirty = true;
225                 }
226
227                 if (bk->lb_param & LPF_OST_ORPHAN) {
228                         bk->lb_param &= ~LPF_OST_ORPHAN;
229                         dirty = true;
230                 }
231
232                 if (__lfsck_set_speed(lfsck, LFSCK_SPEED_NO_LIMIT))
233                         dirty = true;
234
235                 if (bk->lb_async_windows != LFSCK_ASYNC_WIN_DEFAULT) {
236                         bk->lb_async_windows = LFSCK_ASYNC_WIN_DEFAULT;
237                         dirty = true;
238                 }
239         } else {
240                 if ((bk->lb_param & LPF_ALL_TGT) &&
241                     !(start->ls_flags & LPF_ALL_TGT)) {
242                         bk->lb_param &= ~LPF_ALL_TGT;
243                         dirty = true;
244                 } else if (!(bk->lb_param & LPF_ALL_TGT) &&
245                            (start->ls_flags & LPF_ALL_TGT)) {
246                         bk->lb_param |= LPF_ALL_TGT;
247                         dirty = true;
248                 }
249
250                 if ((start->ls_valid & LSV_CREATE_OSTOBJ) || reset) {
251                         if ((bk->lb_param & LPF_CREATE_OSTOBJ) &&
252                             !(start->ls_valid & LSV_CREATE_OSTOBJ)) {
253                                 bk->lb_param &= ~LPF_CREATE_OSTOBJ;
254                                 dirty = true;
255                         } else if (!(bk->lb_param & LPF_CREATE_OSTOBJ) &&
256                                    (start->ls_flags & LPF_CREATE_OSTOBJ)) {
257                                 bk->lb_param |= LPF_CREATE_OSTOBJ;
258                                 dirty = true;
259                         }
260                 }
261
262                 if ((start->ls_valid & LSV_CREATE_MDTOBJ) || reset) {
263                         if ((bk->lb_param & LPF_CREATE_MDTOBJ) &&
264                             !(start->ls_valid & LSV_CREATE_MDTOBJ)) {
265                                 bk->lb_param &= ~LPF_CREATE_MDTOBJ;
266                                 dirty = true;
267                         } else if (!(bk->lb_param & LPF_CREATE_MDTOBJ) &&
268                                    (start->ls_flags & LPF_CREATE_MDTOBJ)) {
269                                 bk->lb_param |= LPF_CREATE_MDTOBJ;
270                                 dirty = true;
271                         }
272                 }
273
274                 if ((start->ls_valid & LSV_ERROR_HANDLE) || reset) {
275                         if ((bk->lb_param & LPF_FAILOUT) &&
276                             !(start->ls_valid & LSV_ERROR_HANDLE)) {
277                                 bk->lb_param &= ~LPF_FAILOUT;
278                                 dirty = true;
279                         } else if (!(start->ls_flags & LPF_FAILOUT) &&
280                                    (bk->lb_param & LPF_FAILOUT)) {
281                                 bk->lb_param &= ~LPF_FAILOUT;
282                                 dirty = true;
283                         }
284                 }
285
286                 if ((start->ls_valid & LSV_DRYRUN) || reset) {
287                         if ((bk->lb_param & LPF_DRYRUN) &&
288                            !(start->ls_valid & LSV_DRYRUN)) {
289                                 bk->lb_param &= ~LPF_DRYRUN;
290                                 dirty = true;
291                         } else if (!(start->ls_flags & LPF_DRYRUN) &&
292                                    (bk->lb_param & LPF_DRYRUN)) {
293                                 bk->lb_param &= ~LPF_DRYRUN;
294                                 lfsck->li_drop_dryrun = 1;
295                                 dirty = true;
296                         }
297                 }
298
299                 if ((bk->lb_param & LPF_OST_ORPHAN) &&
300                     !(start->ls_flags & LPF_OST_ORPHAN)) {
301                         bk->lb_param &= ~LPF_OST_ORPHAN;
302                         dirty = true;
303                 } else if (!(bk->lb_param & LPF_OST_ORPHAN) &&
304                            (start->ls_flags & LPF_OST_ORPHAN)) {
305                         bk->lb_param |= LPF_OST_ORPHAN;
306                         dirty = true;
307                 }
308
309                 if (start->ls_valid & LSV_SPEED_LIMIT) {
310                         if (__lfsck_set_speed(lfsck, start->ls_speed_limit))
311                                 dirty = true;
312                 } else if (reset) {
313                         if (__lfsck_set_speed(lfsck, LFSCK_SPEED_NO_LIMIT))
314                                 dirty = true;
315                 }
316
317                 if (start->ls_valid & LSV_ASYNC_WINDOWS) {
318                         if (bk->lb_async_windows != start->ls_async_windows) {
319                                 bk->lb_async_windows = start->ls_async_windows;
320                                 dirty = true;
321                         }
322                 } else if (reset &&
323                            bk->lb_async_windows != LFSCK_ASYNC_WIN_DEFAULT) {
324                         bk->lb_async_windows = LFSCK_ASYNC_WIN_DEFAULT;
325                         dirty = true;
326                 }
327         }
328
329         if (dirty)
330                 rc = lfsck_bookmark_store(env, lfsck);
331
332         return rc;
333 }