Whamcloud - gitweb
LU-2914 lfsck: split LFSCK code from mdd to 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) 2012, 2013, Intel Corporation.
24  */
25 /*
26  * lustre/lfsck/lfsck_bookmark.c
27  *
28  * Author: Fan, Yong <fan.yong@intel.com>
29  */
30
31 #ifndef EXPORT_SYMTAB
32 # define EXPORT_SYMTAB
33 #endif
34 #define DEBUG_SUBSYSTEM S_LFSCK
35
36 #include <lu_object.h>
37 #include <dt_object.h>
38 #include <lustre_fid.h>
39 #include <lustre/lustre_user.h>
40
41 #include "lfsck_internal.h"
42
43 #define LFSCK_BOOKMARK_MAGIC    0x20130C1D
44
45 static const char lfsck_bookmark_name[] = "lfsck_bookmark";
46
47 static void lfsck_bookmark_le_to_cpu(struct lfsck_bookmark *des,
48                                      struct lfsck_bookmark *src)
49 {
50         des->lb_magic = le32_to_cpu(src->lb_magic);
51         des->lb_version = le16_to_cpu(src->lb_version);
52         des->lb_param = le16_to_cpu(src->lb_param);
53         des->lb_speed_limit = le32_to_cpu(src->lb_speed_limit);
54 }
55
56 static 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 }
64
65 static int lfsck_bookmark_load(const struct lu_env *env,
66                                struct lfsck_instance *lfsck)
67 {
68         loff_t pos = 0;
69         int    len = sizeof(struct lfsck_bookmark);
70         int    rc;
71
72         rc = dt_record_read(env, lfsck->li_bookmark_obj,
73                             lfsck_buf_get(env, &lfsck->li_bookmark_disk, len),
74                             &pos);
75         if (rc == 0) {
76                 struct lfsck_bookmark *bm = &lfsck->li_bookmark_ram;
77
78                 lfsck_bookmark_le_to_cpu(bm, &lfsck->li_bookmark_disk);
79                 if (bm->lb_magic != LFSCK_BOOKMARK_MAGIC) {
80                         CWARN("%.16s: invalid lfsck_bookmark magic "
81                               "0x%x != 0x%x\n", lfsck_lfsck2name(lfsck),
82                               bm->lb_magic, LFSCK_BOOKMARK_MAGIC);
83                         /* Process it as new lfsck_bookmark. */
84                         rc = -ENODATA;
85                 }
86         } else {
87                 if (rc == -EFAULT && pos == 0)
88                         /* return -ENODATA for empty lfsck_bookmark. */
89                         rc = -ENODATA;
90                 else
91                         CERROR("%.16s: fail to load lfsck_bookmark, "
92                                "expected = %d, rc = %d\n",
93                                lfsck_lfsck2name(lfsck), len, rc);
94         }
95         return rc;
96 }
97
98 int lfsck_bookmark_store(const struct lu_env *env, struct lfsck_instance *lfsck)
99 {
100         struct thandle    *handle;
101         struct dt_object  *obj    = lfsck->li_bookmark_obj;
102         loff_t             pos    = 0;
103         int                len    = sizeof(struct lfsck_bookmark);
104         int                rc;
105         ENTRY;
106
107         lfsck_bookmark_cpu_to_le(&lfsck->li_bookmark_disk,
108                                  &lfsck->li_bookmark_ram);
109         handle = dt_trans_create(env, lfsck->li_bottom);
110         if (IS_ERR(handle)) {
111                 rc = PTR_ERR(handle);
112                 CERROR("%.16s: fail to create trans for storing "
113                        "lfsck_bookmark: %d\n,", lfsck_lfsck2name(lfsck), rc);
114                 RETURN(rc);
115         }
116
117         rc = dt_declare_record_write(env, obj, len, 0, handle);
118         if (rc != 0) {
119                 CERROR("%.16s: fail to declare trans for storing "
120                        "lfsck_bookmark: %d\n,", lfsck_lfsck2name(lfsck), rc);
121                 GOTO(out, rc);
122         }
123
124         rc = dt_trans_start_local(env, lfsck->li_bottom, handle);
125         if (rc != 0) {
126                 CERROR("%.16s: fail to start trans for storing "
127                        "lfsck_bookmark: %d\n,", lfsck_lfsck2name(lfsck), rc);
128                 GOTO(out, rc);
129         }
130
131         rc = dt_record_write(env, obj,
132                              lfsck_buf_get(env, &lfsck->li_bookmark_disk, len),
133                              &pos, handle);
134         if (rc != 0)
135                 CERROR("%.16s: fail to store lfsck_bookmark, expected = %d, "
136                        "rc = %d\n", lfsck_lfsck2name(lfsck), len, rc);
137
138         GOTO(out, rc);
139
140 out:
141         dt_trans_stop(env, lfsck->li_bottom, handle);
142         return rc;
143 }
144
145 static int lfsck_bookmark_init(const struct lu_env *env,
146                                struct lfsck_instance *lfsck)
147 {
148         struct lfsck_bookmark *mb = &lfsck->li_bookmark_ram;
149         int rc;
150
151         memset(mb, 0, sizeof(*mb));
152         mb->lb_magic = LFSCK_BOOKMARK_MAGIC;
153         mb->lb_version = LFSCK_VERSION_V2;
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 *obj;
164         int               rc;
165         ENTRY;
166
167         obj = local_file_find_or_create(env, lfsck->li_los,
168                                         lfsck->li_local_root,
169                                         lfsck_bookmark_name,
170                                         S_IFREG | S_IRUGO | S_IWUSR);
171         if (IS_ERR(obj))
172                 RETURN(PTR_ERR(obj));
173
174         lfsck->li_bookmark_obj = obj;
175         rc = lfsck_bookmark_load(env, lfsck);
176         if (rc == -ENODATA)
177                 rc = lfsck_bookmark_init(env, lfsck);
178
179         RETURN(rc);
180 }