Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 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 | |
Jan Kara | 1f54587 | 2005-06-23 22:01:04 -0700 | [diff] [blame] | 45 | #define EXT3_DATA_TRANS_BLOCKS(sb) (EXT3_SINGLEDATA_TRANS_BLOCKS + \ |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 46 | EXT3_XATTR_TRANS_BLOCKS - 2 + \ |
Jan Kara | 1f54587 | 2005-06-23 22:01:04 -0700 | [diff] [blame] | 47 | 2*EXT3_QUOTA_TRANS_BLOCKS(sb)) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 48 | |
| 49 | /* Delete operations potentially hit one directory's namespace plus an |
| 50 | * entire inode, plus arbitrary amounts of bitmap/indirection data. Be |
| 51 | * generous. We can grow the delete transaction later if necessary. */ |
| 52 | |
Jan Kara | 1f54587 | 2005-06-23 22:01:04 -0700 | [diff] [blame] | 53 | #define EXT3_DELETE_TRANS_BLOCKS(sb) (2 * EXT3_DATA_TRANS_BLOCKS(sb) + 64) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 54 | |
| 55 | /* Define an arbitrary limit for the amount of data we will anticipate |
| 56 | * writing to any given transaction. For unbounded transactions such as |
| 57 | * write(2) and truncate(2) we can write more than this, but we always |
| 58 | * start off at the maximum transaction size and grow the transaction |
| 59 | * optimistically as we go. */ |
| 60 | |
| 61 | #define EXT3_MAX_TRANS_DATA 64U |
| 62 | |
| 63 | /* We break up a large truncate or write transaction once the handle's |
| 64 | * buffer credits gets this low, we need either to extend the |
| 65 | * transaction or to start a new one. Reserve enough space here for |
| 66 | * inode, bitmap, superblock, group and indirection updates for at least |
| 67 | * one block, plus two quota updates. Quota allocations are not |
| 68 | * needed. */ |
| 69 | |
| 70 | #define EXT3_RESERVE_TRANS_BLOCKS 12U |
| 71 | |
| 72 | #define EXT3_INDEX_EXTRA_TRANS_BLOCKS 8 |
| 73 | |
| 74 | #ifdef CONFIG_QUOTA |
| 75 | /* Amount of blocks needed for quota update - we know that the structure was |
| 76 | * allocated so we need to update only inode+data */ |
Jan Kara | 1f54587 | 2005-06-23 22:01:04 -0700 | [diff] [blame] | 77 | #define EXT3_QUOTA_TRANS_BLOCKS(sb) (test_opt(sb, QUOTA) ? 2 : 0) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 78 | /* Amount of blocks needed for quota insert/delete - we do some block writes |
| 79 | * but inode, sb and group updates are done only once */ |
Jan Kara | 1f54587 | 2005-06-23 22:01:04 -0700 | [diff] [blame] | 80 | #define EXT3_QUOTA_INIT_BLOCKS(sb) (test_opt(sb, QUOTA) ? (DQUOT_INIT_ALLOC*\ |
| 81 | (EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3+DQUOT_INIT_REWRITE) : 0) |
| 82 | #define EXT3_QUOTA_DEL_BLOCKS(sb) (test_opt(sb, QUOTA) ? (DQUOT_DEL_ALLOC*\ |
| 83 | (EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3+DQUOT_DEL_REWRITE) : 0) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 84 | #else |
Jan Kara | 1f54587 | 2005-06-23 22:01:04 -0700 | [diff] [blame] | 85 | #define EXT3_QUOTA_TRANS_BLOCKS(sb) 0 |
| 86 | #define EXT3_QUOTA_INIT_BLOCKS(sb) 0 |
| 87 | #define EXT3_QUOTA_DEL_BLOCKS(sb) 0 |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 88 | #endif |
| 89 | |
| 90 | int |
| 91 | ext3_mark_iloc_dirty(handle_t *handle, |
| 92 | struct inode *inode, |
| 93 | struct ext3_iloc *iloc); |
| 94 | |
| 95 | /* |
| 96 | * On success, We end up with an outstanding reference count against |
| 97 | * iloc->bh. This _must_ be cleaned up later. |
| 98 | */ |
| 99 | |
| 100 | int ext3_reserve_inode_write(handle_t *handle, struct inode *inode, |
| 101 | struct ext3_iloc *iloc); |
| 102 | |
| 103 | int ext3_mark_inode_dirty(handle_t *handle, struct inode *inode); |
| 104 | |
| 105 | /* |
| 106 | * Wrapper functions with which ext3 calls into JBD. The intent here is |
| 107 | * to allow these to be turned into appropriate stubs so ext3 can control |
| 108 | * ext2 filesystems, so ext2+ext3 systems only nee one fs. This work hasn't |
| 109 | * been done yet. |
| 110 | */ |
| 111 | |
| 112 | void ext3_journal_abort_handle(const char *caller, const char *err_fn, |
| 113 | struct buffer_head *bh, handle_t *handle, int err); |
| 114 | |
| 115 | static inline int |
| 116 | __ext3_journal_get_undo_access(const char *where, handle_t *handle, |
| 117 | struct buffer_head *bh) |
| 118 | { |
| 119 | int err = journal_get_undo_access(handle, bh); |
| 120 | if (err) |
| 121 | ext3_journal_abort_handle(where, __FUNCTION__, bh, handle,err); |
| 122 | return err; |
| 123 | } |
| 124 | |
| 125 | static inline int |
| 126 | __ext3_journal_get_write_access(const char *where, handle_t *handle, |
| 127 | struct buffer_head *bh) |
| 128 | { |
| 129 | int err = journal_get_write_access(handle, bh); |
| 130 | if (err) |
| 131 | ext3_journal_abort_handle(where, __FUNCTION__, bh, handle,err); |
| 132 | return err; |
| 133 | } |
| 134 | |
| 135 | static inline void |
| 136 | ext3_journal_release_buffer(handle_t *handle, struct buffer_head *bh) |
| 137 | { |
| 138 | journal_release_buffer(handle, bh); |
| 139 | } |
| 140 | |
| 141 | static inline int |
| 142 | __ext3_journal_forget(const char *where, handle_t *handle, struct buffer_head *bh) |
| 143 | { |
| 144 | int err = journal_forget(handle, bh); |
| 145 | if (err) |
| 146 | ext3_journal_abort_handle(where, __FUNCTION__, bh, handle,err); |
| 147 | return err; |
| 148 | } |
| 149 | |
| 150 | static inline int |
| 151 | __ext3_journal_revoke(const char *where, handle_t *handle, |
| 152 | unsigned long blocknr, struct buffer_head *bh) |
| 153 | { |
| 154 | int err = journal_revoke(handle, blocknr, bh); |
| 155 | if (err) |
| 156 | ext3_journal_abort_handle(where, __FUNCTION__, bh, handle,err); |
| 157 | return err; |
| 158 | } |
| 159 | |
| 160 | static inline int |
| 161 | __ext3_journal_get_create_access(const char *where, |
| 162 | handle_t *handle, struct buffer_head *bh) |
| 163 | { |
| 164 | int err = journal_get_create_access(handle, bh); |
| 165 | if (err) |
| 166 | ext3_journal_abort_handle(where, __FUNCTION__, bh, handle,err); |
| 167 | return err; |
| 168 | } |
| 169 | |
| 170 | static inline int |
| 171 | __ext3_journal_dirty_metadata(const char *where, |
| 172 | handle_t *handle, struct buffer_head *bh) |
| 173 | { |
| 174 | int err = journal_dirty_metadata(handle, bh); |
| 175 | if (err) |
| 176 | ext3_journal_abort_handle(where, __FUNCTION__, bh, handle,err); |
| 177 | return err; |
| 178 | } |
| 179 | |
| 180 | |
| 181 | #define ext3_journal_get_undo_access(handle, bh) \ |
| 182 | __ext3_journal_get_undo_access(__FUNCTION__, (handle), (bh)) |
| 183 | #define ext3_journal_get_write_access(handle, bh) \ |
| 184 | __ext3_journal_get_write_access(__FUNCTION__, (handle), (bh)) |
| 185 | #define ext3_journal_revoke(handle, blocknr, bh) \ |
| 186 | __ext3_journal_revoke(__FUNCTION__, (handle), (blocknr), (bh)) |
| 187 | #define ext3_journal_get_create_access(handle, bh) \ |
| 188 | __ext3_journal_get_create_access(__FUNCTION__, (handle), (bh)) |
| 189 | #define ext3_journal_dirty_metadata(handle, bh) \ |
| 190 | __ext3_journal_dirty_metadata(__FUNCTION__, (handle), (bh)) |
| 191 | #define ext3_journal_forget(handle, bh) \ |
| 192 | __ext3_journal_forget(__FUNCTION__, (handle), (bh)) |
| 193 | |
| 194 | int ext3_journal_dirty_data(handle_t *handle, struct buffer_head *bh); |
| 195 | |
| 196 | handle_t *ext3_journal_start_sb(struct super_block *sb, int nblocks); |
| 197 | int __ext3_journal_stop(const char *where, handle_t *handle); |
| 198 | |
| 199 | static inline handle_t *ext3_journal_start(struct inode *inode, int nblocks) |
| 200 | { |
| 201 | return ext3_journal_start_sb(inode->i_sb, nblocks); |
| 202 | } |
| 203 | |
| 204 | #define ext3_journal_stop(handle) \ |
| 205 | __ext3_journal_stop(__FUNCTION__, (handle)) |
| 206 | |
| 207 | static inline handle_t *ext3_journal_current_handle(void) |
| 208 | { |
| 209 | return journal_current_handle(); |
| 210 | } |
| 211 | |
| 212 | static inline int ext3_journal_extend(handle_t *handle, int nblocks) |
| 213 | { |
| 214 | return journal_extend(handle, nblocks); |
| 215 | } |
| 216 | |
| 217 | static inline int ext3_journal_restart(handle_t *handle, int nblocks) |
| 218 | { |
| 219 | return journal_restart(handle, nblocks); |
| 220 | } |
| 221 | |
| 222 | static inline int ext3_journal_blocks_per_page(struct inode *inode) |
| 223 | { |
| 224 | return journal_blocks_per_page(inode); |
| 225 | } |
| 226 | |
| 227 | static inline int ext3_journal_force_commit(journal_t *journal) |
| 228 | { |
| 229 | return journal_force_commit(journal); |
| 230 | } |
| 231 | |
| 232 | /* super.c */ |
| 233 | int ext3_force_commit(struct super_block *sb); |
| 234 | |
| 235 | static inline int ext3_should_journal_data(struct inode *inode) |
| 236 | { |
| 237 | if (!S_ISREG(inode->i_mode)) |
| 238 | return 1; |
| 239 | if (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_JOURNAL_DATA) |
| 240 | return 1; |
| 241 | if (EXT3_I(inode)->i_flags & EXT3_JOURNAL_DATA_FL) |
| 242 | return 1; |
| 243 | return 0; |
| 244 | } |
| 245 | |
| 246 | static inline int ext3_should_order_data(struct inode *inode) |
| 247 | { |
| 248 | if (!S_ISREG(inode->i_mode)) |
| 249 | return 0; |
| 250 | if (EXT3_I(inode)->i_flags & EXT3_JOURNAL_DATA_FL) |
| 251 | return 0; |
| 252 | if (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA) |
| 253 | return 1; |
| 254 | return 0; |
| 255 | } |
| 256 | |
| 257 | static inline int ext3_should_writeback_data(struct inode *inode) |
| 258 | { |
| 259 | if (!S_ISREG(inode->i_mode)) |
| 260 | return 0; |
| 261 | if (EXT3_I(inode)->i_flags & EXT3_JOURNAL_DATA_FL) |
| 262 | return 0; |
| 263 | if (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_WRITEBACK_DATA) |
| 264 | return 1; |
| 265 | return 0; |
| 266 | } |
| 267 | |
| 268 | #endif /* _LINUX_EXT3_JBD_H */ |