diff options
author | Joel Becker <joel.becker@oracle.com> | 2009-02-12 19:41:25 -0500 |
---|---|---|
committer | Joel Becker <joel.becker@oracle.com> | 2009-09-04 19:07:50 -0400 |
commit | 0cf2f7632b1789b811ab20b611c4156e6de2b055 (patch) | |
tree | 34f7cf3584e4fa2bc187d4b75ce052cb98739b0e /fs/ocfs2/journal.h | |
parent | 292dd27ec76b96cebcef576f330ab121f59ccf05 (diff) |
ocfs2: Pass struct ocfs2_caching_info to the journal functions.
The next step in divorcing metadata I/O management from struct inode is
to pass struct ocfs2_caching_info to the journal functions. Thus the
journal locks a metadata cache with the cache io_lock function. It also
can compare ci_last_trans and ci_created_trans directly.
This is a large patch because of all the places we change
ocfs2_journal_access..(handle, inode, ...) to
ocfs2_journal_access..(handle, INODE_CACHE(inode), ...).
Signed-off-by: Joel Becker <joel.becker@oracle.com>
Diffstat (limited to 'fs/ocfs2/journal.h')
-rw-r--r-- | fs/ocfs2/journal.h | 75 |
1 files changed, 42 insertions, 33 deletions
diff --git a/fs/ocfs2/journal.h b/fs/ocfs2/journal.h index 0bb6754c73f4..6163f28badda 100644 --- a/fs/ocfs2/journal.h +++ b/fs/ocfs2/journal.h | |||
@@ -90,57 +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 | INODE_CACHE(inode)->ci_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, | 113 | ret = time_after(journal->j_trans_id, ci->ci_last_trans); |
113 | INODE_CACHE(inode)->ci_last_trans); | ||
114 | spin_unlock(&trans_inc_lock); | 114 | spin_unlock(&trans_inc_lock); |
115 | return ret; | 115 | return ret; |
116 | } | 116 | } |
117 | 117 | ||
118 | /* convenience function to check if an inode is still new (has never | 118 | /* convenience function to check if an object backed by struct |
119 | * 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 |
120 | * been checkpointed. returns '1' if the inode is still new. */ | 120 | * favor and set created_trans = 0 when you've |
121 | 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) | ||
122 | { | 123 | { |
123 | int ret; | 124 | int ret; |
125 | struct ocfs2_journal *journal = | ||
126 | OCFS2_SB(ocfs2_metadata_cache_get_super(ci))->journal; | ||
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 | } | ||
124 | 135 | ||
136 | /* Wrapper for inodes so we can check system files */ | ||
137 | static inline int ocfs2_inode_is_new(struct inode *inode) | ||
138 | { | ||
125 | /* System files are never "new" as they're written out by | 139 | /* System files are never "new" as they're written out by |
126 | * mkfs. This helps us early during mount, before we have the | 140 | * mkfs. This helps us early during mount, before we have the |
127 | * journal open and j_trans_id could be junk. */ | 141 | * journal open and j_trans_id could be junk. */ |
128 | if (OCFS2_I(inode)->ip_flags & OCFS2_INODE_SYSTEM_FILE) | 142 | if (OCFS2_I(inode)->ip_flags & OCFS2_INODE_SYSTEM_FILE) |
129 | return 0; | 143 | return 0; |
130 | spin_lock(&trans_inc_lock); | 144 | |
131 | ret = !(time_after(OCFS2_SB(inode->i_sb)->journal->j_trans_id, | 145 | return ocfs2_ci_is_new(INODE_CACHE(inode)); |
132 | INODE_CACHE(inode)->ci_created_trans)); | ||
133 | if (!ret) | ||
134 | INODE_CACHE(inode)->ci_created_trans = 0; | ||
135 | spin_unlock(&trans_inc_lock); | ||
136 | return ret; | ||
137 | } | 146 | } |
138 | 147 | ||
139 | static inline void ocfs2_inode_set_new(struct ocfs2_super *osb, | 148 | static inline void ocfs2_ci_set_new(struct ocfs2_super *osb, |
140 | struct inode *inode) | 149 | struct ocfs2_caching_info *ci) |
141 | { | 150 | { |
142 | spin_lock(&trans_inc_lock); | 151 | spin_lock(&trans_inc_lock); |
143 | INODE_CACHE(inode)->ci_created_trans = osb->journal->j_trans_id; | 152 | ci->ci_created_trans = osb->journal->j_trans_id; |
144 | spin_unlock(&trans_inc_lock); | 153 | spin_unlock(&trans_inc_lock); |
145 | } | 154 | } |
146 | 155 | ||
@@ -201,7 +210,7 @@ static inline void ocfs2_checkpoint_inode(struct inode *inode) | |||
201 | if (ocfs2_mount_local(osb)) | 210 | if (ocfs2_mount_local(osb)) |
202 | return; | 211 | return; |
203 | 212 | ||
204 | if (!ocfs2_inode_fully_checkpointed(inode)) { | 213 | if (!ocfs2_ci_fully_checkpointed(INODE_CACHE(inode))) { |
205 | /* WARNING: This only kicks off a single | 214 | /* WARNING: This only kicks off a single |
206 | * checkpoint. If someone races you and adds more | 215 | * checkpoint. If someone races you and adds more |
207 | * metadata to the journal, you won't know, and will | 216 | * metadata to the journal, you won't know, and will |
@@ -211,7 +220,7 @@ static inline void ocfs2_checkpoint_inode(struct inode *inode) | |||
211 | ocfs2_start_checkpoint(osb); | 220 | ocfs2_start_checkpoint(osb); |
212 | 221 | ||
213 | wait_event(osb->journal->j_checkpointed, | 222 | wait_event(osb->journal->j_checkpointed, |
214 | ocfs2_inode_fully_checkpointed(inode)); | 223 | ocfs2_ci_fully_checkpointed(INODE_CACHE(inode))); |
215 | } | 224 | } |
216 | } | 225 | } |
217 | 226 | ||
@@ -267,31 +276,31 @@ int ocfs2_extend_trans(handle_t *handle, int nblocks); | |||
267 | 276 | ||
268 | 277 | ||
269 | /* ocfs2_inode */ | 278 | /* ocfs2_inode */ |
270 | 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, |
271 | struct buffer_head *bh, int type); | 280 | struct buffer_head *bh, int type); |
272 | /* ocfs2_extent_block */ | 281 | /* ocfs2_extent_block */ |
273 | 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, |
274 | struct buffer_head *bh, int type); | 283 | struct buffer_head *bh, int type); |
275 | /* ocfs2_group_desc */ | 284 | /* ocfs2_group_desc */ |
276 | int ocfs2_journal_access_gd(handle_t *handle, struct inode *inode, | 285 | int ocfs2_journal_access_gd(handle_t *handle, struct ocfs2_caching_info *ci, |
277 | struct buffer_head *bh, int type); | 286 | struct buffer_head *bh, int type); |
278 | /* ocfs2_xattr_block */ | 287 | /* ocfs2_xattr_block */ |
279 | int ocfs2_journal_access_xb(handle_t *handle, struct inode *inode, | 288 | int ocfs2_journal_access_xb(handle_t *handle, struct ocfs2_caching_info *ci, |
280 | struct buffer_head *bh, int type); | 289 | struct buffer_head *bh, int type); |
281 | /* quota blocks */ | 290 | /* quota blocks */ |
282 | int ocfs2_journal_access_dq(handle_t *handle, struct inode *inode, | 291 | int ocfs2_journal_access_dq(handle_t *handle, struct ocfs2_caching_info *ci, |
283 | struct buffer_head *bh, int type); | 292 | struct buffer_head *bh, int type); |
284 | /* dirblock */ | 293 | /* dirblock */ |
285 | int ocfs2_journal_access_db(handle_t *handle, struct inode *inode, | 294 | int ocfs2_journal_access_db(handle_t *handle, struct ocfs2_caching_info *ci, |
286 | struct buffer_head *bh, int type); | 295 | struct buffer_head *bh, int type); |
287 | /* ocfs2_dx_root_block */ | 296 | /* ocfs2_dx_root_block */ |
288 | int ocfs2_journal_access_dr(handle_t *handle, struct inode *inode, | 297 | int ocfs2_journal_access_dr(handle_t *handle, struct ocfs2_caching_info *ci, |
289 | struct buffer_head *bh, int type); | 298 | struct buffer_head *bh, int type); |
290 | /* ocfs2_dx_leaf */ | 299 | /* ocfs2_dx_leaf */ |
291 | int ocfs2_journal_access_dl(handle_t *handle, struct inode *inode, | 300 | int ocfs2_journal_access_dl(handle_t *handle, struct ocfs2_caching_info *ci, |
292 | struct buffer_head *bh, int type); | 301 | struct buffer_head *bh, int type); |
293 | /* Anything that has no ecc */ | 302 | /* Anything that has no ecc */ |
294 | int ocfs2_journal_access(handle_t *handle, struct inode *inode, | 303 | int ocfs2_journal_access(handle_t *handle, struct ocfs2_caching_info *ci, |
295 | struct buffer_head *bh, int type); | 304 | struct buffer_head *bh, int type); |
296 | 305 | ||
297 | /* | 306 | /* |