Merge branches 'acpi-ec' and 'acpi-button'
[cascardo/linux.git] / drivers / staging / lustre / lustre / include / lustre_log.h
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, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; If not, see
18  * http://www.gnu.org/licenses/gpl-2.0.html
19  *
20  * GPL HEADER END
21  */
22 /*
23  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
24  * Use is subject to license terms.
25  *
26  * Copyright (c) 2012, 2015, Intel Corporation.
27  */
28 /*
29  * This file is part of Lustre, http://www.lustre.org/
30  * Lustre is a trademark of Sun Microsystems, Inc.
31  *
32  * lustre/include/lustre_log.h
33  *
34  * Generic infrastructure for managing a collection of logs.
35  * These logs are used for:
36  *
37  * - orphan recovery: OST adds record on create
38  * - mtime/size consistency: the OST adds a record on first write
39  * - open/unlinked objects: OST adds a record on destroy
40  *
41  * - mds unlink log: the MDS adds an entry upon delete
42  *
43  * - raid1 replication log between OST's
44  * - MDS replication logs
45  */
46
47 #ifndef _LUSTRE_LOG_H
48 #define _LUSTRE_LOG_H
49
50 /** \defgroup log log
51  *
52  * @{
53  */
54
55 #include "obd_class.h"
56 #include "lustre/lustre_idl.h"
57
58 #define LOG_NAME_LIMIT(logname, name)              \
59         snprintf(logname, sizeof(logname), "LOGS/%s", name)
60 #define LLOG_EEMPTY 4711
61
62 enum llog_open_param {
63         LLOG_OPEN_EXISTS        = 0x0000,
64         LLOG_OPEN_NEW           = 0x0001,
65 };
66
67 struct plain_handle_data {
68         struct list_head          phd_entry;
69         struct llog_handle *phd_cat_handle;
70         struct llog_cookie  phd_cookie; /* cookie of this log in its cat */
71 };
72
73 struct cat_handle_data {
74         struct list_head              chd_head;
75         struct llog_handle     *chd_current_log; /* currently open log */
76         struct llog_handle      *chd_next_log; /* llog to be used next */
77 };
78
79 struct llog_handle;
80
81 /* llog.c  -  general API */
82 int llog_init_handle(const struct lu_env *env, struct llog_handle *handle,
83                      int flags, struct obd_uuid *uuid);
84 int llog_process(const struct lu_env *env, struct llog_handle *loghandle,
85                  llog_cb_t cb, void *data, void *catdata);
86 int llog_process_or_fork(const struct lu_env *env,
87                          struct llog_handle *loghandle,
88                          llog_cb_t cb, void *data, void *catdata, bool fork);
89 int llog_open(const struct lu_env *env, struct llog_ctxt *ctxt,
90               struct llog_handle **lgh, struct llog_logid *logid,
91               char *name, enum llog_open_param open_param);
92 int llog_close(const struct lu_env *env, struct llog_handle *cathandle);
93
94 /* llog_process flags */
95 #define LLOG_FLAG_NODEAMON 0x0001
96
97 /* llog_cat.c - catalog api */
98 struct llog_process_data {
99         /**
100          * Any useful data needed while processing catalog. This is
101          * passed later to process callback.
102          */
103         void            *lpd_data;
104         /**
105          * Catalog process callback function, called for each record
106          * in catalog.
107          */
108         llog_cb_t           lpd_cb;
109         /**
110          * Start processing the catalog from startcat/startidx
111          */
112         int               lpd_startcat;
113         int               lpd_startidx;
114 };
115
116 struct llog_process_cat_data {
117         /**
118          * Temporary stored first_idx while scanning log.
119          */
120         int               lpcd_first_idx;
121         /**
122          * Temporary stored last_idx while scanning log.
123          */
124         int               lpcd_last_idx;
125 };
126
127 struct thandle;
128
129 int llog_cat_close(const struct lu_env *env, struct llog_handle *cathandle);
130 int llog_cat_process(const struct lu_env *env, struct llog_handle *cat_llh,
131                      llog_cb_t cb, void *data, int startcat, int startidx);
132
133 /* llog_obd.c */
134 int llog_setup(const struct lu_env *env, struct obd_device *obd,
135                struct obd_llog_group *olg, int index,
136                struct obd_device *disk_obd, struct llog_operations *op);
137 int __llog_ctxt_put(const struct lu_env *env, struct llog_ctxt *ctxt);
138 int llog_cleanup(const struct lu_env *env, struct llog_ctxt *);
139
140 /* llog_net.c */
141 int llog_initiator_connect(struct llog_ctxt *ctxt);
142
143 struct llog_operations {
144         int (*lop_next_block)(const struct lu_env *env, struct llog_handle *h,
145                               int *curr_idx, int next_idx, __u64 *offset,
146                               void *buf, int len);
147         int (*lop_prev_block)(const struct lu_env *env, struct llog_handle *h,
148                               int prev_idx, void *buf, int len);
149         int (*lop_read_header)(const struct lu_env *env,
150                                struct llog_handle *handle);
151         int (*lop_setup)(const struct lu_env *env, struct obd_device *obd,
152                          struct obd_llog_group *olg, int ctxt_idx,
153                          struct obd_device *disk_obd);
154         int (*lop_sync)(struct llog_ctxt *ctxt, struct obd_export *exp,
155                         int flags);
156         int (*lop_cleanup)(const struct lu_env *env, struct llog_ctxt *ctxt);
157         int (*lop_cancel)(const struct lu_env *env, struct llog_ctxt *ctxt,
158                           struct llog_cookie *cookies, int flags);
159         int (*lop_connect)(struct llog_ctxt *ctxt, struct llog_logid *logid,
160                            struct llog_gen *gen, struct obd_uuid *uuid);
161         /**
162          * Any llog file must be opened first using llog_open().  Llog can be
163          * opened by name, logid or without both, in last case the new logid
164          * will be generated.
165          */
166         int (*lop_open)(const struct lu_env *env, struct llog_handle *lgh,
167                         struct llog_logid *logid, char *name,
168                         enum llog_open_param);
169         /**
170          * Opened llog may not exist and this must be checked where needed using
171          * the llog_exist() call.
172          */
173         int (*lop_exist)(struct llog_handle *lgh);
174         /**
175          * Close llog file and calls llog_free_handle() implicitly.
176          * Any opened llog must be closed by llog_close() call.
177          */
178         int (*lop_close)(const struct lu_env *env, struct llog_handle *handle);
179         /**
180          * Create new llog file. The llog must be opened.
181          * Must be used only for local llog operations.
182          */
183         int (*lop_declare_create)(const struct lu_env *env,
184                                   struct llog_handle *handle,
185                                   struct thandle *th);
186         /**
187          * write new record in llog. It appends records usually but can edit
188          * existing records too.
189          */
190         int (*lop_declare_write_rec)(const struct lu_env *env,
191                                      struct llog_handle *lgh,
192                                      struct llog_rec_hdr *rec,
193                                      int idx, struct thandle *th);
194         int (*lop_write_rec)(const struct lu_env *env,
195                              struct llog_handle *loghandle,
196                              struct llog_rec_hdr *rec,
197                              struct llog_cookie *cookie, int cookiecount,
198                              void *buf, int idx, struct thandle *th);
199         /**
200          * Add new record in llog catalog. Does the same as llog_write_rec()
201          * but using llog catalog.
202          */
203         int (*lop_declare_add)(const struct lu_env *env,
204                                struct llog_handle *lgh,
205                                struct llog_rec_hdr *rec, struct thandle *th);
206         int (*lop_add)(const struct lu_env *env, struct llog_handle *lgh,
207                        struct llog_rec_hdr *rec, struct llog_cookie *cookie,
208                        void *buf, struct thandle *th);
209 };
210
211 /* In-memory descriptor for a log object or log catalog */
212 struct llog_handle {
213         struct rw_semaphore      lgh_lock;
214         spinlock_t               lgh_hdr_lock; /* protect lgh_hdr data */
215         struct llog_logid        lgh_id; /* id of this log */
216         struct llog_log_hdr     *lgh_hdr;
217         int                      lgh_last_idx;
218         int                      lgh_cur_idx; /* used during llog_process */
219         __u64                    lgh_cur_offset; /* used during llog_process */
220         struct llog_ctxt        *lgh_ctxt;
221         union {
222                 struct plain_handle_data         phd;
223                 struct cat_handle_data           chd;
224         } u;
225         char                    *lgh_name;
226         void                    *private_data;
227         struct llog_operations  *lgh_logops;
228         atomic_t                 lgh_refcount;
229 };
230
231 #define LLOG_CTXT_FLAG_UNINITIALIZED     0x00000001
232 #define LLOG_CTXT_FLAG_STOP              0x00000002
233
234 struct llog_ctxt {
235         int                   loc_idx; /* my index the obd array of ctxt's */
236         struct obd_device       *loc_obd; /* points back to the containing obd*/
237         struct obd_llog_group   *loc_olg; /* group containing that ctxt */
238         struct obd_export       *loc_exp; /* parent "disk" export (e.g. MDS) */
239         struct obd_import       *loc_imp; /* to use in RPC's: can be backward
240                                            * pointing import
241                                            */
242         struct llog_operations  *loc_logops;
243         struct llog_handle      *loc_handle;
244         struct mutex             loc_mutex; /* protect loc_imp */
245         atomic_t             loc_refcount;
246         long                 loc_flags; /* flags, see above defines */
247 };
248
249 #define LLOG_PROC_BREAK 0x0001
250 #define LLOG_DEL_RECORD 0x0002
251
252 static inline int llog_handle2ops(struct llog_handle *loghandle,
253                                   struct llog_operations **lop)
254 {
255         if (!loghandle || !loghandle->lgh_logops)
256                 return -EINVAL;
257
258         *lop = loghandle->lgh_logops;
259         return 0;
260 }
261
262 static inline struct llog_ctxt *llog_ctxt_get(struct llog_ctxt *ctxt)
263 {
264         atomic_inc(&ctxt->loc_refcount);
265         CDEBUG(D_INFO, "GETting ctxt %p : new refcount %d\n", ctxt,
266                atomic_read(&ctxt->loc_refcount));
267         return ctxt;
268 }
269
270 static inline void llog_ctxt_put(struct llog_ctxt *ctxt)
271 {
272         if (!ctxt)
273                 return;
274         LASSERT_ATOMIC_GT_LT(&ctxt->loc_refcount, 0, LI_POISON);
275         CDEBUG(D_INFO, "PUTting ctxt %p : new refcount %d\n", ctxt,
276                atomic_read(&ctxt->loc_refcount) - 1);
277         __llog_ctxt_put(NULL, ctxt);
278 }
279
280 static inline void llog_group_init(struct obd_llog_group *olg, int group)
281 {
282         init_waitqueue_head(&olg->olg_waitq);
283         spin_lock_init(&olg->olg_lock);
284         mutex_init(&olg->olg_cat_processing);
285         olg->olg_seq = group;
286 }
287
288 static inline int llog_group_set_ctxt(struct obd_llog_group *olg,
289                                       struct llog_ctxt *ctxt, int index)
290 {
291         LASSERT(index >= 0 && index < LLOG_MAX_CTXTS);
292
293         spin_lock(&olg->olg_lock);
294         if (olg->olg_ctxts[index]) {
295                 spin_unlock(&olg->olg_lock);
296                 return -EEXIST;
297         }
298         olg->olg_ctxts[index] = ctxt;
299         spin_unlock(&olg->olg_lock);
300         return 0;
301 }
302
303 static inline struct llog_ctxt *llog_group_get_ctxt(struct obd_llog_group *olg,
304                                                     int index)
305 {
306         struct llog_ctxt *ctxt;
307
308         LASSERT(index >= 0 && index < LLOG_MAX_CTXTS);
309
310         spin_lock(&olg->olg_lock);
311         if (!olg->olg_ctxts[index])
312                 ctxt = NULL;
313         else
314                 ctxt = llog_ctxt_get(olg->olg_ctxts[index]);
315         spin_unlock(&olg->olg_lock);
316         return ctxt;
317 }
318
319 static inline void llog_group_clear_ctxt(struct obd_llog_group *olg, int index)
320 {
321         LASSERT(index >= 0 && index < LLOG_MAX_CTXTS);
322         spin_lock(&olg->olg_lock);
323         olg->olg_ctxts[index] = NULL;
324         spin_unlock(&olg->olg_lock);
325 }
326
327 static inline struct llog_ctxt *llog_get_context(struct obd_device *obd,
328                                                  int index)
329 {
330         return llog_group_get_ctxt(&obd->obd_olg, index);
331 }
332
333 static inline int llog_group_ctxt_null(struct obd_llog_group *olg, int index)
334 {
335         return (!olg->olg_ctxts[index]);
336 }
337
338 static inline int llog_ctxt_null(struct obd_device *obd, int index)
339 {
340         return llog_group_ctxt_null(&obd->obd_olg, index);
341 }
342
343 static inline int llog_next_block(const struct lu_env *env,
344                                   struct llog_handle *loghandle, int *cur_idx,
345                                   int next_idx, __u64 *cur_offset, void *buf,
346                                   int len)
347 {
348         struct llog_operations *lop;
349         int rc;
350
351         rc = llog_handle2ops(loghandle, &lop);
352         if (rc)
353                 return rc;
354         if (!lop->lop_next_block)
355                 return -EOPNOTSUPP;
356
357         rc = lop->lop_next_block(env, loghandle, cur_idx, next_idx,
358                                  cur_offset, buf, len);
359         return rc;
360 }
361
362 /* llog.c */
363 int llog_declare_write_rec(const struct lu_env *env,
364                            struct llog_handle *handle,
365                            struct llog_rec_hdr *rec, int idx,
366                            struct thandle *th);
367 int llog_write_rec(const struct lu_env *env, struct llog_handle *handle,
368                    struct llog_rec_hdr *rec, struct llog_cookie *logcookies,
369                    int numcookies, void *buf, int idx, struct thandle *th);
370 int lustre_process_log(struct super_block *sb, char *logname,
371                        struct config_llog_instance *cfg);
372 int lustre_end_log(struct super_block *sb, char *logname,
373                    struct config_llog_instance *cfg);
374 /** @} log */
375
376 #endif