Rev 422 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
422 | giacomo | 1 | /* |
2 | * linux/include/linux/ext3_jbd.h |
||
3 | * |
||
4 | * Written by Stephen C. Tweedie <sct@redhat.com>, 1999 |
||
5 | * |
||
6 | * Copyright 1998--1999 Red Hat corp --- All Rights Reserved |
||
7 | * |
||
8 | * This file is part of the Linux kernel and is made available under |
||
9 | * the terms of the GNU General Public License, version 2, or at your |
||
10 | * option, any later version, incorporated herein by reference. |
||
11 | * |
||
12 | * Ext3-specific journaling extensions. |
||
13 | */ |
||
14 | |||
15 | #ifndef _LINUX_EXT3_JBD_H |
||
16 | #define _LINUX_EXT3_JBD_H |
||
17 | |||
18 | #include <linux/fs.h> |
||
19 | #include <linux/jbd.h> |
||
20 | #include <linux/ext3_fs.h> |
||
21 | |||
22 | #define EXT3_JOURNAL(inode) (EXT3_SB((inode)->i_sb)->s_journal) |
||
23 | |||
24 | /* Define the number of blocks we need to account to a transaction to |
||
25 | * modify one block of data. |
||
26 | * |
||
27 | * We may have to touch one inode, one bitmap buffer, up to three |
||
28 | * indirection blocks, the group and superblock summaries, and the data |
||
29 | * block to complete the transaction. */ |
||
30 | |||
31 | #define EXT3_SINGLEDATA_TRANS_BLOCKS 8U |
||
32 | |||
33 | /* Extended attribute operations touch at most two data buffers, |
||
34 | * two bitmap buffers, and two group summaries, in addition to the inode |
||
35 | * and the superblock, which are already accounted for. */ |
||
36 | |||
37 | #define EXT3_XATTR_TRANS_BLOCKS 6U |
||
38 | |||
39 | /* Define the minimum size for a transaction which modifies data. This |
||
40 | * needs to take into account the fact that we may end up modifying two |
||
41 | * quota files too (one for the group, one for the user quota). The |
||
42 | * superblock only gets updated once, of course, so don't bother |
||
43 | * counting that again for the quota updates. */ |
||
44 | |||
45 | #define EXT3_DATA_TRANS_BLOCKS (3 * EXT3_SINGLEDATA_TRANS_BLOCKS + \ |
||
46 | EXT3_XATTR_TRANS_BLOCKS - 2) |
||
47 | |||
48 | extern int ext3_writepage_trans_blocks(struct inode *inode); |
||
49 | |||
50 | /* Delete operations potentially hit one directory's namespace plus an |
||
51 | * entire inode, plus arbitrary amounts of bitmap/indirection data. Be |
||
52 | * generous. We can grow the delete transaction later if necessary. */ |
||
53 | |||
54 | #define EXT3_DELETE_TRANS_BLOCKS (2 * EXT3_DATA_TRANS_BLOCKS + 64) |
||
55 | |||
56 | /* Define an arbitrary limit for the amount of data we will anticipate |
||
57 | * writing to any given transaction. For unbounded transactions such as |
||
58 | * write(2) and truncate(2) we can write more than this, but we always |
||
59 | * start off at the maximum transaction size and grow the transaction |
||
60 | * optimistically as we go. */ |
||
61 | |||
62 | #define EXT3_MAX_TRANS_DATA 64U |
||
63 | |||
64 | /* We break up a large truncate or write transaction once the handle's |
||
65 | * buffer credits gets this low, we need either to extend the |
||
66 | * transaction or to start a new one. Reserve enough space here for |
||
67 | * inode, bitmap, superblock, group and indirection updates for at least |
||
68 | * one block, plus two quota updates. Quota allocations are not |
||
69 | * needed. */ |
||
70 | |||
71 | #define EXT3_RESERVE_TRANS_BLOCKS 12U |
||
72 | |||
73 | #define EXT3_INDEX_EXTRA_TRANS_BLOCKS 8 |
||
74 | |||
75 | int |
||
76 | ext3_mark_iloc_dirty(handle_t *handle, |
||
77 | struct inode *inode, |
||
78 | struct ext3_iloc *iloc); |
||
79 | |||
80 | /* |
||
81 | * On success, We end up with an outstanding reference count against |
||
82 | * iloc->bh. This _must_ be cleaned up later. |
||
83 | */ |
||
84 | |||
85 | int ext3_reserve_inode_write(handle_t *handle, struct inode *inode, |
||
86 | struct ext3_iloc *iloc); |
||
87 | |||
88 | int ext3_mark_inode_dirty(handle_t *handle, struct inode *inode); |
||
89 | |||
90 | /* |
||
91 | * Wrapper functions with which ext3 calls into JBD. The intent here is |
||
92 | * to allow these to be turned into appropriate stubs so ext3 can control |
||
93 | * ext2 filesystems, so ext2+ext3 systems only nee one fs. This work hasn't |
||
94 | * been done yet. |
||
95 | */ |
||
96 | |||
97 | void ext3_journal_abort_handle(const char *caller, const char *err_fn, |
||
98 | struct buffer_head *bh, handle_t *handle, int err); |
||
99 | |||
100 | static inline int |
||
101 | __ext3_journal_get_undo_access(const char *where, handle_t *handle, |
||
102 | struct buffer_head *bh, int *credits) |
||
103 | { |
||
104 | int err = journal_get_undo_access(handle, bh, credits); |
||
105 | if (err) |
||
106 | ext3_journal_abort_handle(where, __FUNCTION__, bh, handle,err); |
||
107 | return err; |
||
108 | } |
||
109 | |||
110 | static inline int |
||
111 | __ext3_journal_get_write_access(const char *where, handle_t *handle, |
||
112 | struct buffer_head *bh, int *credits) |
||
113 | { |
||
114 | int err = journal_get_write_access(handle, bh, credits); |
||
115 | if (err) |
||
116 | ext3_journal_abort_handle(where, __FUNCTION__, bh, handle,err); |
||
117 | return err; |
||
118 | } |
||
119 | |||
120 | static inline void |
||
121 | ext3_journal_release_buffer(handle_t *handle, struct buffer_head *bh, |
||
122 | int credits) |
||
123 | { |
||
124 | journal_release_buffer(handle, bh, credits); |
||
125 | } |
||
126 | |||
127 | static inline void |
||
128 | ext3_journal_forget(handle_t *handle, struct buffer_head *bh) |
||
129 | { |
||
130 | journal_forget(handle, bh); |
||
131 | } |
||
132 | |||
133 | static inline int |
||
134 | __ext3_journal_revoke(const char *where, handle_t *handle, |
||
135 | unsigned long blocknr, struct buffer_head *bh) |
||
136 | { |
||
137 | int err = journal_revoke(handle, blocknr, bh); |
||
138 | if (err) |
||
139 | ext3_journal_abort_handle(where, __FUNCTION__, bh, handle,err); |
||
140 | return err; |
||
141 | } |
||
142 | |||
143 | static inline int |
||
144 | __ext3_journal_get_create_access(const char *where, |
||
145 | handle_t *handle, struct buffer_head *bh) |
||
146 | { |
||
147 | int err = journal_get_create_access(handle, bh); |
||
148 | if (err) |
||
149 | ext3_journal_abort_handle(where, __FUNCTION__, bh, handle,err); |
||
150 | return err; |
||
151 | } |
||
152 | |||
153 | static inline int |
||
154 | __ext3_journal_dirty_metadata(const char *where, |
||
155 | handle_t *handle, struct buffer_head *bh) |
||
156 | { |
||
157 | int err = journal_dirty_metadata(handle, bh); |
||
158 | if (err) |
||
159 | ext3_journal_abort_handle(where, __FUNCTION__, bh, handle,err); |
||
160 | return err; |
||
161 | } |
||
162 | |||
163 | |||
164 | #define ext3_journal_get_undo_access(handle, bh, credits) \ |
||
165 | __ext3_journal_get_undo_access(__FUNCTION__, (handle), (bh), (credits)) |
||
166 | #define ext3_journal_get_write_access(handle, bh) \ |
||
167 | __ext3_journal_get_write_access(__FUNCTION__, (handle), (bh), NULL) |
||
168 | #define ext3_journal_get_write_access_credits(handle, bh, credits) \ |
||
169 | __ext3_journal_get_write_access(__FUNCTION__, (handle), (bh), (credits)) |
||
170 | #define ext3_journal_revoke(handle, blocknr, bh) \ |
||
171 | __ext3_journal_revoke(__FUNCTION__, (handle), (blocknr), (bh)) |
||
172 | #define ext3_journal_get_create_access(handle, bh) \ |
||
173 | __ext3_journal_get_create_access(__FUNCTION__, (handle), (bh)) |
||
174 | #define ext3_journal_dirty_metadata(handle, bh) \ |
||
175 | __ext3_journal_dirty_metadata(__FUNCTION__, (handle), (bh)) |
||
176 | |||
177 | handle_t *ext3_journal_start(struct inode *inode, int nblocks); |
||
178 | int __ext3_journal_stop(const char *where, handle_t *handle); |
||
179 | |||
180 | #define ext3_journal_stop(handle) \ |
||
181 | __ext3_journal_stop(__FUNCTION__, (handle)) |
||
182 | |||
183 | static inline handle_t *ext3_journal_current_handle(void) |
||
184 | { |
||
185 | return journal_current_handle(); |
||
186 | } |
||
187 | |||
188 | static inline int ext3_journal_extend(handle_t *handle, int nblocks) |
||
189 | { |
||
190 | return journal_extend(handle, nblocks); |
||
191 | } |
||
192 | |||
193 | static inline int ext3_journal_restart(handle_t *handle, int nblocks) |
||
194 | { |
||
195 | return journal_restart(handle, nblocks); |
||
196 | } |
||
197 | |||
198 | static inline int ext3_journal_blocks_per_page(struct inode *inode) |
||
199 | { |
||
200 | return journal_blocks_per_page(inode); |
||
201 | } |
||
202 | |||
203 | static inline int ext3_journal_force_commit(journal_t *journal) |
||
204 | { |
||
205 | return journal_force_commit(journal); |
||
206 | } |
||
207 | |||
208 | /* super.c */ |
||
209 | int ext3_force_commit(struct super_block *sb); |
||
210 | |||
211 | static inline int ext3_should_journal_data(struct inode *inode) |
||
212 | { |
||
213 | if (!S_ISREG(inode->i_mode)) |
||
214 | return 1; |
||
215 | if (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_JOURNAL_DATA) |
||
216 | return 1; |
||
217 | if (EXT3_I(inode)->i_flags & EXT3_JOURNAL_DATA_FL) |
||
218 | return 1; |
||
219 | return 0; |
||
220 | } |
||
221 | |||
222 | static inline int ext3_should_order_data(struct inode *inode) |
||
223 | { |
||
224 | return (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA); |
||
225 | } |
||
226 | |||
227 | static inline int ext3_should_writeback_data(struct inode *inode) |
||
228 | { |
||
229 | return !ext3_should_journal_data(inode) && |
||
230 | !ext3_should_order_data(inode); |
||
231 | } |
||
232 | |||
233 | #endif /* _LINUX_EXT3_JBD_H */ |