2
* Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
2
* Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
4
* This program is free software; you can redistribute it and/or modify it
5
* under the terms of version 2 of the GNU General Public License as
5
* This program is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU General Public License as
6
7
* published by the Free Software Foundation.
8
* This program is distributed in the hope that it would be useful, but
9
* WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
* Further, this software is distributed without any warranty that it is
13
* free of the rightful claim of any third person regarding infringement
14
* or the like. Any license provided herein, whether implied or
15
* otherwise, applies only to this software file. Patent licenses, if
16
* any, provided herein do not apply to combinations of this program with
17
* other software, or any other product whatsoever.
19
* You should have received a copy of the GNU General Public License along
20
* with this program; if not, write the Free Software Foundation, Inc., 59
21
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
23
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24
* Mountain View, CA 94043, or:
28
* For further information regarding this notice, see:
30
* http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
9
* This program is distributed in the hope that it would be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write the Free Software Foundation,
16
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
32
18
#ifndef __XFS_LOG_PRIV_H__
33
19
#define __XFS_LOG_PRIV_H__
77
#define ASSIGN_LSN_CYCLE(lsn,cycle,arch) \
78
INT_SET(((uint *)&(lsn))[LSN_FIELD_CYCLE(arch)], arch, (cycle));
79
#define ASSIGN_LSN_BLOCK(lsn,block,arch) \
80
INT_SET(((uint *)&(lsn))[LSN_FIELD_BLOCK(arch)], arch, (block));
81
#define ASSIGN_ANY_LSN(lsn,cycle,block,arch) \
83
ASSIGN_LSN_CYCLE(lsn,cycle,arch); \
84
ASSIGN_LSN_BLOCK(lsn,block,arch); \
86
#define ASSIGN_LSN(lsn,log,arch) \
87
ASSIGN_ANY_LSN(lsn,(log)->l_curr_cycle,(log)->l_curr_block,arch);
64
#define ASSIGN_ANY_LSN_HOST(lsn,cycle,block) \
66
(lsn) = ((xfs_lsn_t)(cycle)<<32)|(block); \
68
#define ASSIGN_ANY_LSN_DISK(lsn,cycle,block) \
70
INT_SET(((uint *)&(lsn))[0], ARCH_CONVERT, (cycle)); \
71
INT_SET(((uint *)&(lsn))[1], ARCH_CONVERT, (block)); \
73
#define ASSIGN_LSN(lsn,log) \
74
ASSIGN_ANY_LSN_DISK(lsn,(log)->l_curr_cycle,(log)->l_curr_block);
89
76
#define XLOG_SET(f,b) (((f) & (b)) == (b))
123
#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XLOG_GRANT_SUB_SPACE)
124
void xlog_grant_sub_space(struct log *log, int bytes, int type);
125
#define XLOG_GRANT_SUB_SPACE(log,bytes,type) \
126
xlog_grant_sub_space(log,bytes,type)
128
#define XLOG_GRANT_SUB_SPACE(log,bytes,type) \
131
(log)->l_grant_write_bytes -= (bytes); \
132
if ((log)->l_grant_write_bytes < 0) { \
133
(log)->l_grant_write_bytes += (log)->l_logsize; \
134
(log)->l_grant_write_cycle--; \
137
(log)->l_grant_reserve_bytes -= (bytes); \
138
if ((log)->l_grant_reserve_bytes < 0) { \
139
(log)->l_grant_reserve_bytes += (log)->l_logsize;\
140
(log)->l_grant_reserve_cycle--; \
145
#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XLOG_GRANT_ADD_SPACE)
146
void xlog_grant_add_space(struct log *log, int bytes, int type);
147
#define XLOG_GRANT_ADD_SPACE(log,bytes,type) \
148
xlog_grant_add_space(log,bytes,type)
150
#define XLOG_GRANT_ADD_SPACE(log,bytes,type) \
153
(log)->l_grant_write_bytes += (bytes); \
154
if ((log)->l_grant_write_bytes > (log)->l_logsize) { \
155
(log)->l_grant_write_bytes -= (log)->l_logsize; \
156
(log)->l_grant_write_cycle++; \
159
(log)->l_grant_reserve_bytes += (bytes); \
160
if ((log)->l_grant_reserve_bytes > (log)->l_logsize) { \
161
(log)->l_grant_reserve_bytes -= (log)->l_logsize;\
162
(log)->l_grant_reserve_cycle++; \
167
#define XLOG_INS_TICKETQ(q,tic) \
170
(tic)->t_next = (q); \
171
(tic)->t_prev = (q)->t_prev; \
172
(q)->t_prev->t_next = (tic); \
173
(q)->t_prev = (tic); \
175
(tic)->t_prev = (tic)->t_next = (tic); \
178
(tic)->t_flags |= XLOG_TIC_IN_Q; \
180
#define XLOG_DEL_TICKETQ(q,tic) \
182
if ((tic) == (tic)->t_next) { \
185
(q) = (tic)->t_next; \
186
(tic)->t_next->t_prev = (tic)->t_prev; \
187
(tic)->t_prev->t_next = (tic)->t_next; \
189
(tic)->t_next = (tic)->t_prev = NULL; \
190
(tic)->t_flags &= ~XLOG_TIC_IN_Q; \
194
110
#define GRANT_LOCK(log) mutex_spinlock(&(log)->l_grant_lock)
195
111
#define GRANT_UNLOCK(log, s) mutex_spinunlock(&(log)->l_grant_lock, s)
196
112
#define LOG_LOCK(log) mutex_spinlock(&(log)->l_icloglock)
336
252
#define XLOG_COVER_OPS 5
255
/* Ticket reservation region accounting */
256
#if defined(XFS_LOG_RES_DEBUG)
257
#define XLOG_TIC_LEN_MAX 15
258
#define XLOG_TIC_RESET_RES(t) ((t)->t_res_num = \
259
(t)->t_res_arr_sum = (t)->t_res_num_ophdrs = 0)
260
#define XLOG_TIC_ADD_OPHDR(t) ((t)->t_res_num_ophdrs++)
261
#define XLOG_TIC_ADD_REGION(t, len, type) \
263
if ((t)->t_res_num == XLOG_TIC_LEN_MAX) { \
264
/* add to overflow and start again */ \
265
(t)->t_res_o_flow += (t)->t_res_arr_sum; \
266
(t)->t_res_num = 0; \
267
(t)->t_res_arr_sum = 0; \
269
(t)->t_res_arr[(t)->t_res_num].r_len = (len); \
270
(t)->t_res_arr[(t)->t_res_num].r_type = (type); \
271
(t)->t_res_arr_sum += (len); \
277
* As would be stored in xfs_log_iovec but without the i_addr which
278
* we don't care about.
280
typedef struct xlog_res {
285
#define XLOG_TIC_RESET_RES(t)
286
#define XLOG_TIC_ADD_OPHDR(t)
287
#define XLOG_TIC_ADD_REGION(t, len, type)
338
291
typedef struct xlog_ticket {
339
sv_t t_sema; /* sleep on this semaphore :20 */
340
struct xlog_ticket *t_next; /* : 4 */
341
struct xlog_ticket *t_prev; /* : 4 */
342
xlog_tid_t t_tid; /* transaction identifier : 4 */
343
int t_curr_res; /* current reservation in bytes : 4 */
344
int t_unit_res; /* unit reservation in bytes : 4 */
345
__uint8_t t_ocnt; /* original count : 1 */
346
__uint8_t t_cnt; /* current count : 1 */
347
__uint8_t t_clientid; /* who does this belong to; : 1 */
348
__uint8_t t_flags; /* properties of reservation : 1 */
292
sv_t t_sema; /* sleep on this semaphore : 20 */
293
struct xlog_ticket *t_next; /* :4|8 */
294
struct xlog_ticket *t_prev; /* :4|8 */
295
xlog_tid_t t_tid; /* transaction identifier : 4 */
296
int t_curr_res; /* current reservation in bytes : 4 */
297
int t_unit_res; /* unit reservation in bytes : 4 */
298
char t_ocnt; /* original count : 1 */
299
char t_cnt; /* current count : 1 */
300
char t_clientid; /* who does this belong to; : 1 */
301
char t_flags; /* properties of reservation : 1 */
302
uint t_trans_type; /* transaction type : 4 */
304
#if defined (XFS_LOG_RES_DEBUG)
305
/* reservation array fields */
306
uint t_res_num; /* num in array : 4 */
307
xlog_res_t t_res_arr[XLOG_TIC_LEN_MAX]; /* array of res : X */
308
uint t_res_num_ophdrs; /* num op hdrs : 4 */
309
uint t_res_arr_sum; /* array sum : 4 */
310
uint t_res_o_flow; /* sum overflow : 4 */
366
330
#define XLOG_FMT_IRIX_BE 3
369
#if __BYTE_ORDER == __LITTLE_ENDIAN
333
#ifdef XFS_NATIVE_HOST
334
#define XLOG_FMT XLOG_FMT_LINUX_BE
370
336
#define XLOG_FMT XLOG_FMT_LINUX_LE
372
#if __BYTE_ORDER == __BIG_ENDIAN
373
#define XLOG_FMT XLOG_FMT_LINUX_BE
375
#error unknown byte order
379
339
typedef struct xlog_rec_header {
532
492
* alignment mask */
495
#define XLOG_FORCED_SHUTDOWN(log) ((log)->l_flags & XLOG_IO_ERROR)
497
#define XLOG_GRANT_SUB_SPACE(log,bytes,type) \
498
xlog_grant_sub_space(log,bytes,type)
499
static inline void xlog_grant_sub_space(struct log *log, int bytes, int type)
502
(log)->l_grant_write_bytes -= (bytes); \
503
if ((log)->l_grant_write_bytes < 0) { \
504
(log)->l_grant_write_bytes += (log)->l_logsize; \
505
(log)->l_grant_write_cycle--; \
508
(log)->l_grant_reserve_bytes -= (bytes); \
509
if ((log)->l_grant_reserve_bytes < 0) { \
510
(log)->l_grant_reserve_bytes += (log)->l_logsize;\
511
(log)->l_grant_reserve_cycle--; \
516
#define XLOG_GRANT_ADD_SPACE(log,bytes,type) \
517
xlog_grant_add_space(log,bytes,type)
519
xlog_grant_add_space(struct log *log, int bytes, int type)
522
(log)->l_grant_write_bytes += (bytes); \
523
if ((log)->l_grant_write_bytes > (log)->l_logsize) { \
524
(log)->l_grant_write_bytes -= (log)->l_logsize; \
525
(log)->l_grant_write_cycle++; \
528
(log)->l_grant_reserve_bytes += (bytes); \
529
if ((log)->l_grant_reserve_bytes > (log)->l_logsize) { \
530
(log)->l_grant_reserve_bytes -= (log)->l_logsize;\
531
(log)->l_grant_reserve_cycle++; \
536
#define XLOG_INS_TICKETQ(q, tic) xlog_ins_ticketq(q, tic)
538
xlog_ins_ticketq(struct xlog_ticket *q, struct xlog_ticket *tic)
541
(tic)->t_next = (q); \
542
(tic)->t_prev = (q)->t_prev; \
543
(q)->t_prev->t_next = (tic); \
544
(q)->t_prev = (tic); \
546
(tic)->t_prev = (tic)->t_next = (tic); \
549
(tic)->t_flags |= XLOG_TIC_IN_Q; \
552
#define XLOG_DEL_TICKETQ(q, tic) xlog_del_ticketq(q, tic)
554
xlog_del_ticketq(struct xlog_ticket *q, struct xlog_ticket *tic)
556
if ((tic) == (tic)->t_next) { \
559
(q) = (tic)->t_next; \
560
(tic)->t_next->t_prev = (tic)->t_prev; \
561
(tic)->t_prev->t_next = (tic)->t_next; \
563
(tic)->t_next = (tic)->t_prev = NULL; \
564
(tic)->t_flags &= ~XLOG_TIC_IN_Q; \
536
567
/* common routines */
537
568
extern xfs_lsn_t xlog_assign_tail_lsn(struct xfs_mount *mp);
538
extern int xlog_find_head(xlog_t *log, xfs_daddr_t *head_blk);
539
569
extern int xlog_find_tail(xlog_t *log,
540
570
xfs_daddr_t *head_blk,
541
571
xfs_daddr_t *tail_blk,
548
578
extern struct xfs_buf *xlog_get_bp(xlog_t *, int);
549
579
extern void xlog_put_bp(struct xfs_buf *);
550
580
extern int xlog_bread(xlog_t *, xfs_daddr_t, int, struct xfs_buf *);
551
extern xfs_caddr_t xlog_align(xlog_t *, xfs_daddr_t, int, struct xfs_buf *);
553
582
/* iclog tracing */
554
583
#define XLOG_TRACE_GRAB_FLUSH 1