diff options
Diffstat (limited to 'fs/ocfs2/journal.h')
-rw-r--r-- | fs/ocfs2/journal.h | 94 |
1 files changed, 62 insertions, 32 deletions
diff --git a/fs/ocfs2/journal.h b/fs/ocfs2/journal.h index 2c3222aec622..3f74e09b0d80 100644 --- a/fs/ocfs2/journal.h +++ b/fs/ocfs2/journal.h | |||
@@ -90,56 +90,66 @@ static inline unsigned long ocfs2_inc_trans_id(struct ocfs2_journal *j) | |||
90 | return old_id; | 90 | return old_id; |
91 | } | 91 | } |
92 | 92 | ||
93 | static inline void ocfs2_set_inode_lock_trans(struct ocfs2_journal *journal, | 93 | static inline void ocfs2_set_ci_lock_trans(struct ocfs2_journal *journal, |
94 | struct inode *inode) | 94 | struct ocfs2_caching_info *ci) |
95 | { | 95 | { |
96 | spin_lock(&trans_inc_lock); | 96 | spin_lock(&trans_inc_lock); |
97 | OCFS2_I(inode)->ip_last_trans = journal->j_trans_id; | 97 | ci->ci_last_trans = journal->j_trans_id; |
98 | spin_unlock(&trans_inc_lock); | 98 | spin_unlock(&trans_inc_lock); |
99 | } | 99 | } |
100 | 100 | ||
101 | /* Used to figure out whether it's safe to drop a metadata lock on an | 101 | /* Used to figure out whether it's safe to drop a metadata lock on an |
102 | * inode. Returns true if all the inodes changes have been | 102 | * cached object. Returns true if all the object's changes have been |
103 | * checkpointed to disk. You should be holding the spinlock on the | 103 | * checkpointed to disk. You should be holding the spinlock on the |
104 | * metadata lock while calling this to be sure that nobody can take | 104 | * metadata lock while calling this to be sure that nobody can take |
105 | * the lock and put it on another transaction. */ | 105 | * the lock and put it on another transaction. */ |
106 | static inline int ocfs2_inode_fully_checkpointed(struct inode *inode) | 106 | static inline int ocfs2_ci_fully_checkpointed(struct ocfs2_caching_info *ci) |
107 | { | 107 | { |
108 | int ret; | 108 | int ret; |
109 | struct ocfs2_journal *journal = OCFS2_SB(inode->i_sb)->journal; | 109 | struct ocfs2_journal *journal = |
110 | OCFS2_SB(ocfs2_metadata_cache_get_super(ci))->journal; | ||
110 | 111 | ||
111 | spin_lock(&trans_inc_lock); | 112 | spin_lock(&trans_inc_lock); |
112 | ret = time_after(journal->j_trans_id, OCFS2_I(inode)->ip_last_trans); | 113 | ret = time_after(journal->j_trans_id, ci->ci_last_trans); |
113 | spin_unlock(&trans_inc_lock); | 114 | spin_unlock(&trans_inc_lock); |
114 | return ret; | 115 | return ret; |
115 | } | 116 | } |
116 | 117 | ||
117 | /* convenience function to check if an inode is still new (has never | 118 | /* convenience function to check if an object backed by struct |
118 | * hit disk) Will do you a favor and set created_trans = 0 when you've | 119 | * ocfs2_caching_info is still new (has never hit disk) Will do you a |
119 | * been checkpointed. returns '1' if the inode is still new. */ | 120 | * favor and set created_trans = 0 when you've |
120 | static inline int ocfs2_inode_is_new(struct inode *inode) | 121 | * been checkpointed. returns '1' if the ci is still new. */ |
122 | static inline int ocfs2_ci_is_new(struct ocfs2_caching_info *ci) | ||
121 | { | 123 | { |
122 | int ret; | 124 | int ret; |
125 | struct ocfs2_journal *journal = | ||
126 | OCFS2_SB(ocfs2_metadata_cache_get_super(ci))->journal; | ||
123 | 127 | ||
128 | spin_lock(&trans_inc_lock); | ||
129 | ret = !(time_after(journal->j_trans_id, ci->ci_created_trans)); | ||
130 | if (!ret) | ||
131 | ci->ci_created_trans = 0; | ||
132 | spin_unlock(&trans_inc_lock); | ||
133 | return ret; | ||
134 | } | ||
135 | |||
136 | /* Wrapper for inodes so we can check system files */ | ||
137 | static inline int ocfs2_inode_is_new(struct inode *inode) | ||
138 | { | ||
124 | /* System files are never "new" as they're written out by | 139 | /* System files are never "new" as they're written out by |
125 | * mkfs. This helps us early during mount, before we have the | 140 | * mkfs. This helps us early during mount, before we have the |
126 | * journal open and j_trans_id could be junk. */ | 141 | * journal open and j_trans_id could be junk. */ |
127 | if (OCFS2_I(inode)->ip_flags & OCFS2_INODE_SYSTEM_FILE) | 142 | if (OCFS2_I(inode)->ip_flags & OCFS2_INODE_SYSTEM_FILE) |
128 | return 0; | 143 | return 0; |
129 | spin_lock(&trans_inc_lock); | 144 | |
130 | ret = !(time_after(OCFS2_SB(inode->i_sb)->journal->j_trans_id, | 145 | return ocfs2_ci_is_new(INODE_CACHE(inode)); |
131 | OCFS2_I(inode)->ip_created_trans)); | ||
132 | if (!ret) | ||
133 | OCFS2_I(inode)->ip_created_trans = 0; | ||
134 | spin_unlock(&trans_inc_lock); | ||
135 | return ret; | ||
136 | } | 146 | } |
137 | 147 | ||
138 | static inline void ocfs2_inode_set_new(struct ocfs2_super *osb, | 148 | static inline void ocfs2_ci_set_new(struct ocfs2_super *osb, |
139 | struct inode *inode) | 149 | struct ocfs2_caching_info *ci) |
140 | { | 150 | { |
141 | spin_lock(&trans_inc_lock); | 151 | spin_lock(&trans_inc_lock); |
142 | OCFS2_I(inode)->ip_created_trans = osb->journal->j_trans_id; | 152 | ci->ci_created_trans = osb->journal->j_trans_id; |
143 | spin_unlock(&trans_inc_lock); | 153 | spin_unlock(&trans_inc_lock); |
144 | } | 154 | } |
145 | 155 | ||
@@ -200,7 +210,7 @@ static inline void ocfs2_checkpoint_inode(struct inode *inode) | |||
200 | if (ocfs2_mount_local(osb)) | 210 | if (ocfs2_mount_local(osb)) |
201 | return; | 211 | return; |
202 | 212 | ||
203 | if (!ocfs2_inode_fully_checkpointed(inode)) { | 213 | if (!ocfs2_ci_fully_checkpointed(INODE_CACHE(inode))) { |
204 | /* WARNING: This only kicks off a single | 214 | /* WARNING: This only kicks off a single |
205 | * checkpoint. If someone races you and adds more | 215 | * checkpoint. If someone races you and adds more |
206 | * metadata to the journal, you won't know, and will | 216 | * metadata to the journal, you won't know, and will |
@@ -210,7 +220,7 @@ static inline void ocfs2_checkpoint_inode(struct inode *inode) | |||
210 | ocfs2_start_checkpoint(osb); | 220 | ocfs2_start_checkpoint(osb); |
211 | 221 | ||
212 | wait_event(osb->journal->j_checkpointed, | 222 | wait_event(osb->journal->j_checkpointed, |
213 | ocfs2_inode_fully_checkpointed(inode)); | 223 | ocfs2_ci_fully_checkpointed(INODE_CACHE(inode))); |
214 | } | 224 | } |
215 | } | 225 | } |
216 | 226 | ||
@@ -266,31 +276,34 @@ int ocfs2_extend_trans(handle_t *handle, int nblocks); | |||
266 | 276 | ||
267 | 277 | ||
268 | /* ocfs2_inode */ | 278 | /* ocfs2_inode */ |
269 | int ocfs2_journal_access_di(handle_t *handle, struct inode *inode, | 279 | int ocfs2_journal_access_di(handle_t *handle, struct ocfs2_caching_info *ci, |
270 | struct buffer_head *bh, int type); | 280 | struct buffer_head *bh, int type); |
271 | /* ocfs2_extent_block */ | 281 | /* ocfs2_extent_block */ |
272 | int ocfs2_journal_access_eb(handle_t *handle, struct inode *inode, | 282 | int ocfs2_journal_access_eb(handle_t *handle, struct ocfs2_caching_info *ci, |
283 | struct buffer_head *bh, int type); | ||
284 | /* ocfs2_refcount_block */ | ||
285 | int ocfs2_journal_access_rb(handle_t *handle, struct ocfs2_caching_info *ci, | ||
273 | struct buffer_head *bh, int type); | 286 | struct buffer_head *bh, int type); |
274 | /* ocfs2_group_desc */ | 287 | /* ocfs2_group_desc */ |
275 | int ocfs2_journal_access_gd(handle_t *handle, struct inode *inode, | 288 | int ocfs2_journal_access_gd(handle_t *handle, struct ocfs2_caching_info *ci, |
276 | struct buffer_head *bh, int type); | 289 | struct buffer_head *bh, int type); |
277 | /* ocfs2_xattr_block */ | 290 | /* ocfs2_xattr_block */ |
278 | int ocfs2_journal_access_xb(handle_t *handle, struct inode *inode, | 291 | int ocfs2_journal_access_xb(handle_t *handle, struct ocfs2_caching_info *ci, |
279 | struct buffer_head *bh, int type); | 292 | struct buffer_head *bh, int type); |
280 | /* quota blocks */ | 293 | /* quota blocks */ |
281 | int ocfs2_journal_access_dq(handle_t *handle, struct inode *inode, | 294 | int ocfs2_journal_access_dq(handle_t *handle, struct ocfs2_caching_info *ci, |
282 | struct buffer_head *bh, int type); | 295 | struct buffer_head *bh, int type); |
283 | /* dirblock */ | 296 | /* dirblock */ |
284 | int ocfs2_journal_access_db(handle_t *handle, struct inode *inode, | 297 | int ocfs2_journal_access_db(handle_t *handle, struct ocfs2_caching_info *ci, |
285 | struct buffer_head *bh, int type); | 298 | struct buffer_head *bh, int type); |
286 | /* ocfs2_dx_root_block */ | 299 | /* ocfs2_dx_root_block */ |
287 | int ocfs2_journal_access_dr(handle_t *handle, struct inode *inode, | 300 | int ocfs2_journal_access_dr(handle_t *handle, struct ocfs2_caching_info *ci, |
288 | struct buffer_head *bh, int type); | 301 | struct buffer_head *bh, int type); |
289 | /* ocfs2_dx_leaf */ | 302 | /* ocfs2_dx_leaf */ |
290 | int ocfs2_journal_access_dl(handle_t *handle, struct inode *inode, | 303 | int ocfs2_journal_access_dl(handle_t *handle, struct ocfs2_caching_info *ci, |
291 | struct buffer_head *bh, int type); | 304 | struct buffer_head *bh, int type); |
292 | /* Anything that has no ecc */ | 305 | /* Anything that has no ecc */ |
293 | int ocfs2_journal_access(handle_t *handle, struct inode *inode, | 306 | int ocfs2_journal_access(handle_t *handle, struct ocfs2_caching_info *ci, |
294 | struct buffer_head *bh, int type); | 307 | struct buffer_head *bh, int type); |
295 | 308 | ||
296 | /* | 309 | /* |
@@ -477,6 +490,23 @@ static inline int ocfs2_calc_dxi_expand_credits(struct super_block *sb) | |||
477 | return credits; | 490 | return credits; |
478 | } | 491 | } |
479 | 492 | ||
493 | /* inode update, new refcount block and its allocation credits. */ | ||
494 | #define OCFS2_REFCOUNT_TREE_CREATE_CREDITS (OCFS2_INODE_UPDATE_CREDITS + 1 \ | ||
495 | + OCFS2_SUBALLOC_ALLOC) | ||
496 | |||
497 | /* inode and the refcount block update. */ | ||
498 | #define OCFS2_REFCOUNT_TREE_SET_CREDITS (OCFS2_INODE_UPDATE_CREDITS + 1) | ||
499 | |||
500 | /* | ||
501 | * inode and the refcount block update. | ||
502 | * It doesn't include the credits for sub alloc change. | ||
503 | * So if we need to free the bit, OCFS2_SUBALLOC_FREE needs to be added. | ||
504 | */ | ||
505 | #define OCFS2_REFCOUNT_TREE_REMOVE_CREDITS (OCFS2_INODE_UPDATE_CREDITS + 1) | ||
506 | |||
507 | /* 2 metadata alloc, 2 new blocks and root refcount block */ | ||
508 | #define OCFS2_EXPAND_REFCOUNT_TREE_CREDITS (OCFS2_SUBALLOC_ALLOC * 2 + 3) | ||
509 | |||
480 | /* | 510 | /* |
481 | * Please note that the caller must make sure that root_el is the root | 511 | * Please note that the caller must make sure that root_el is the root |
482 | * of extent tree. So for an inode, it should be &fe->id2.i_list. Otherwise | 512 | * of extent tree. So for an inode, it should be &fe->id2.i_list. Otherwise |