aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/journal.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2006-12-05 12:01:28 -0500
committerDavid Howells <dhowells@warthog.cambridge.redhat.com>2006-12-05 12:01:28 -0500
commit9db73724453a9350e1c22dbe732d427e2939a5c9 (patch)
tree15e3ead6413ae97398a54292acc199bee0864d42 /fs/ocfs2/journal.c
parent4c1ac1b49122b805adfa4efc620592f68dccf5db (diff)
parente62438630ca37539c8cc1553710bbfaa3cf960a7 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts: drivers/ata/libata-scsi.c include/linux/libata.h Futher merge of Linus's head and compilation fixups. Signed-Off-By: David Howells <dhowells@redhat.com>
Diffstat (limited to 'fs/ocfs2/journal.c')
-rw-r--r--fs/ocfs2/journal.c271
1 files changed, 31 insertions, 240 deletions
diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c
index d95ee2720e6e..1d7f4ab1e5ed 100644
--- a/fs/ocfs2/journal.c
+++ b/fs/ocfs2/journal.c
@@ -57,9 +57,6 @@ static int ocfs2_recover_node(struct ocfs2_super *osb,
57static int __ocfs2_recovery_thread(void *arg); 57static int __ocfs2_recovery_thread(void *arg);
58static int ocfs2_commit_cache(struct ocfs2_super *osb); 58static int ocfs2_commit_cache(struct ocfs2_super *osb);
59static int ocfs2_wait_on_mount(struct ocfs2_super *osb); 59static int ocfs2_wait_on_mount(struct ocfs2_super *osb);
60static void ocfs2_handle_cleanup_locks(struct ocfs2_journal *journal,
61 struct ocfs2_journal_handle *handle);
62static void ocfs2_commit_unstarted_handle(struct ocfs2_journal_handle *handle);
63static int ocfs2_journal_toggle_dirty(struct ocfs2_super *osb, 60static int ocfs2_journal_toggle_dirty(struct ocfs2_super *osb,
64 int dirty); 61 int dirty);
65static int ocfs2_trylock_journal(struct ocfs2_super *osb, 62static int ocfs2_trylock_journal(struct ocfs2_super *osb,
@@ -113,46 +110,18 @@ finally:
113 return status; 110 return status;
114} 111}
115 112
116struct ocfs2_journal_handle *ocfs2_alloc_handle(struct ocfs2_super *osb)
117{
118 struct ocfs2_journal_handle *retval = NULL;
119
120 retval = kcalloc(1, sizeof(*retval), GFP_NOFS);
121 if (!retval) {
122 mlog(ML_ERROR, "Failed to allocate memory for journal "
123 "handle!\n");
124 return NULL;
125 }
126
127 retval->max_buffs = 0;
128 retval->num_locks = 0;
129 retval->k_handle = NULL;
130
131 INIT_LIST_HEAD(&retval->locks);
132 INIT_LIST_HEAD(&retval->inode_list);
133 retval->journal = osb->journal;
134
135 return retval;
136}
137
138/* pass it NULL and it will allocate a new handle object for you. If 113/* pass it NULL and it will allocate a new handle object for you. If
139 * you pass it a handle however, it may still return error, in which 114 * you pass it a handle however, it may still return error, in which
140 * case it has free'd the passed handle for you. */ 115 * case it has free'd the passed handle for you. */
141struct ocfs2_journal_handle *ocfs2_start_trans(struct ocfs2_super *osb, 116handle_t *ocfs2_start_trans(struct ocfs2_super *osb, int max_buffs)
142 struct ocfs2_journal_handle *handle,
143 int max_buffs)
144{ 117{
145 int ret;
146 journal_t *journal = osb->journal->j_journal; 118 journal_t *journal = osb->journal->j_journal;
147 119 handle_t *handle;
148 mlog_entry("(max_buffs = %d)\n", max_buffs);
149 120
150 BUG_ON(!osb || !osb->journal->j_journal); 121 BUG_ON(!osb || !osb->journal->j_journal);
151 122
152 if (ocfs2_is_hard_readonly(osb)) { 123 if (ocfs2_is_hard_readonly(osb))
153 ret = -EROFS; 124 return ERR_PTR(-EROFS);
154 goto done_free;
155 }
156 125
157 BUG_ON(osb->journal->j_state == OCFS2_JOURNAL_FREE); 126 BUG_ON(osb->journal->j_state == OCFS2_JOURNAL_FREE);
158 BUG_ON(max_buffs <= 0); 127 BUG_ON(max_buffs <= 0);
@@ -163,154 +132,39 @@ struct ocfs2_journal_handle *ocfs2_start_trans(struct ocfs2_super *osb,
163 BUG(); 132 BUG();
164 } 133 }
165 134
166 if (!handle)
167 handle = ocfs2_alloc_handle(osb);
168 if (!handle) {
169 ret = -ENOMEM;
170 mlog(ML_ERROR, "Failed to allocate memory for journal "
171 "handle!\n");
172 goto done_free;
173 }
174
175 handle->max_buffs = max_buffs;
176
177 down_read(&osb->journal->j_trans_barrier); 135 down_read(&osb->journal->j_trans_barrier);
178 136
179 /* actually start the transaction now */ 137 handle = journal_start(journal, max_buffs);
180 handle->k_handle = journal_start(journal, max_buffs); 138 if (IS_ERR(handle)) {
181 if (IS_ERR(handle->k_handle)) {
182 up_read(&osb->journal->j_trans_barrier); 139 up_read(&osb->journal->j_trans_barrier);
183 140
184 ret = PTR_ERR(handle->k_handle); 141 mlog_errno(PTR_ERR(handle));
185 handle->k_handle = NULL;
186 mlog_errno(ret);
187 142
188 if (is_journal_aborted(journal)) { 143 if (is_journal_aborted(journal)) {
189 ocfs2_abort(osb->sb, "Detected aborted journal"); 144 ocfs2_abort(osb->sb, "Detected aborted journal");
190 ret = -EROFS; 145 handle = ERR_PTR(-EROFS);
191 } 146 }
192 goto done_free; 147 } else
193 } 148 atomic_inc(&(osb->journal->j_num_trans));
194
195 atomic_inc(&(osb->journal->j_num_trans));
196 handle->flags |= OCFS2_HANDLE_STARTED;
197 149
198 mlog_exit_ptr(handle);
199 return handle; 150 return handle;
200
201done_free:
202 if (handle)
203 ocfs2_commit_unstarted_handle(handle); /* will kfree handle */
204
205 mlog_exit(ret);
206 return ERR_PTR(ret);
207}
208
209void ocfs2_handle_add_inode(struct ocfs2_journal_handle *handle,
210 struct inode *inode)
211{
212 BUG_ON(!handle);
213 BUG_ON(!inode);
214
215 atomic_inc(&inode->i_count);
216
217 /* we're obviously changing it... */
218 mutex_lock(&inode->i_mutex);
219
220 /* sanity check */
221 BUG_ON(OCFS2_I(inode)->ip_handle);
222 BUG_ON(!list_empty(&OCFS2_I(inode)->ip_handle_list));
223
224 OCFS2_I(inode)->ip_handle = handle;
225 list_move_tail(&(OCFS2_I(inode)->ip_handle_list), &(handle->inode_list));
226}
227
228static void ocfs2_handle_unlock_inodes(struct ocfs2_journal_handle *handle)
229{
230 struct list_head *p, *n;
231 struct inode *inode;
232 struct ocfs2_inode_info *oi;
233
234 list_for_each_safe(p, n, &handle->inode_list) {
235 oi = list_entry(p, struct ocfs2_inode_info,
236 ip_handle_list);
237 inode = &oi->vfs_inode;
238
239 OCFS2_I(inode)->ip_handle = NULL;
240 list_del_init(&OCFS2_I(inode)->ip_handle_list);
241
242 mutex_unlock(&inode->i_mutex);
243 iput(inode);
244 }
245}
246
247/* This is trivial so we do it out of the main commit
248 * paths. Beware, it can be called from start_trans too! */
249static void ocfs2_commit_unstarted_handle(struct ocfs2_journal_handle *handle)
250{
251 mlog_entry_void();
252
253 BUG_ON(handle->flags & OCFS2_HANDLE_STARTED);
254
255 ocfs2_handle_unlock_inodes(handle);
256 /* You are allowed to add journal locks before the transaction
257 * has started. */
258 ocfs2_handle_cleanup_locks(handle->journal, handle);
259
260 kfree(handle);
261
262 mlog_exit_void();
263} 151}
264 152
265void ocfs2_commit_trans(struct ocfs2_journal_handle *handle) 153int ocfs2_commit_trans(struct ocfs2_super *osb,
154 handle_t *handle)
266{ 155{
267 handle_t *jbd_handle; 156 int ret;
268 int retval; 157 struct ocfs2_journal *journal = osb->journal;
269 struct ocfs2_journal *journal = handle->journal;
270
271 mlog_entry_void();
272 158
273 BUG_ON(!handle); 159 BUG_ON(!handle);
274 160
275 if (!(handle->flags & OCFS2_HANDLE_STARTED)) { 161 ret = journal_stop(handle);
276 ocfs2_commit_unstarted_handle(handle); 162 if (ret < 0)
277 mlog_exit_void(); 163 mlog_errno(ret);
278 return;
279 }
280
281 /* release inode semaphores we took during this transaction */
282 ocfs2_handle_unlock_inodes(handle);
283
284 /* ocfs2_extend_trans may have had to call journal_restart
285 * which will always commit the transaction, but may return
286 * error for any number of reasons. If this is the case, we
287 * clear k_handle as it's not valid any more. */
288 if (handle->k_handle) {
289 jbd_handle = handle->k_handle;
290
291 if (handle->flags & OCFS2_HANDLE_SYNC)
292 jbd_handle->h_sync = 1;
293 else
294 jbd_handle->h_sync = 0;
295
296 /* actually stop the transaction. if we've set h_sync,
297 * it'll have been committed when we return */
298 retval = journal_stop(jbd_handle);
299 if (retval < 0) {
300 mlog_errno(retval);
301 mlog(ML_ERROR, "Could not commit transaction\n");
302 BUG();
303 }
304
305 handle->k_handle = NULL; /* it's been free'd in journal_stop */
306 }
307
308 ocfs2_handle_cleanup_locks(journal, handle);
309 164
310 up_read(&journal->j_trans_barrier); 165 up_read(&journal->j_trans_barrier);
311 166
312 kfree(handle); 167 return ret;
313 mlog_exit_void();
314} 168}
315 169
316/* 170/*
@@ -326,20 +180,18 @@ void ocfs2_commit_trans(struct ocfs2_journal_handle *handle)
326 * good because transaction ids haven't yet been recorded on the 180 * good because transaction ids haven't yet been recorded on the
327 * cluster locks associated with this handle. 181 * cluster locks associated with this handle.
328 */ 182 */
329int ocfs2_extend_trans(struct ocfs2_journal_handle *handle, 183int ocfs2_extend_trans(handle_t *handle, int nblocks)
330 int nblocks)
331{ 184{
332 int status; 185 int status;
333 186
334 BUG_ON(!handle); 187 BUG_ON(!handle);
335 BUG_ON(!(handle->flags & OCFS2_HANDLE_STARTED));
336 BUG_ON(!nblocks); 188 BUG_ON(!nblocks);
337 189
338 mlog_entry_void(); 190 mlog_entry_void();
339 191
340 mlog(0, "Trying to extend transaction by %d blocks\n", nblocks); 192 mlog(0, "Trying to extend transaction by %d blocks\n", nblocks);
341 193
342 status = journal_extend(handle->k_handle, nblocks); 194 status = journal_extend(handle, nblocks);
343 if (status < 0) { 195 if (status < 0) {
344 mlog_errno(status); 196 mlog_errno(status);
345 goto bail; 197 goto bail;
@@ -347,15 +199,12 @@ int ocfs2_extend_trans(struct ocfs2_journal_handle *handle,
347 199
348 if (status > 0) { 200 if (status > 0) {
349 mlog(0, "journal_extend failed, trying journal_restart\n"); 201 mlog(0, "journal_extend failed, trying journal_restart\n");
350 status = journal_restart(handle->k_handle, nblocks); 202 status = journal_restart(handle, nblocks);
351 if (status < 0) { 203 if (status < 0) {
352 handle->k_handle = NULL;
353 mlog_errno(status); 204 mlog_errno(status);
354 goto bail; 205 goto bail;
355 } 206 }
356 handle->max_buffs = nblocks; 207 }
357 } else
358 handle->max_buffs += nblocks;
359 208
360 status = 0; 209 status = 0;
361bail: 210bail:
@@ -364,7 +213,7 @@ bail:
364 return status; 213 return status;
365} 214}
366 215
367int ocfs2_journal_access(struct ocfs2_journal_handle *handle, 216int ocfs2_journal_access(handle_t *handle,
368 struct inode *inode, 217 struct inode *inode,
369 struct buffer_head *bh, 218 struct buffer_head *bh,
370 int type) 219 int type)
@@ -374,7 +223,6 @@ int ocfs2_journal_access(struct ocfs2_journal_handle *handle,
374 BUG_ON(!inode); 223 BUG_ON(!inode);
375 BUG_ON(!handle); 224 BUG_ON(!handle);
376 BUG_ON(!bh); 225 BUG_ON(!bh);
377 BUG_ON(!(handle->flags & OCFS2_HANDLE_STARTED));
378 226
379 mlog_entry("bh->b_blocknr=%llu, type=%d (\"%s\"), bh->b_size = %zu\n", 227 mlog_entry("bh->b_blocknr=%llu, type=%d (\"%s\"), bh->b_size = %zu\n",
380 (unsigned long long)bh->b_blocknr, type, 228 (unsigned long long)bh->b_blocknr, type,
@@ -403,11 +251,11 @@ int ocfs2_journal_access(struct ocfs2_journal_handle *handle,
403 switch (type) { 251 switch (type) {
404 case OCFS2_JOURNAL_ACCESS_CREATE: 252 case OCFS2_JOURNAL_ACCESS_CREATE:
405 case OCFS2_JOURNAL_ACCESS_WRITE: 253 case OCFS2_JOURNAL_ACCESS_WRITE:
406 status = journal_get_write_access(handle->k_handle, bh); 254 status = journal_get_write_access(handle, bh);
407 break; 255 break;
408 256
409 case OCFS2_JOURNAL_ACCESS_UNDO: 257 case OCFS2_JOURNAL_ACCESS_UNDO:
410 status = journal_get_undo_access(handle->k_handle, bh); 258 status = journal_get_undo_access(handle, bh);
411 break; 259 break;
412 260
413 default: 261 default:
@@ -424,17 +272,15 @@ int ocfs2_journal_access(struct ocfs2_journal_handle *handle,
424 return status; 272 return status;
425} 273}
426 274
427int ocfs2_journal_dirty(struct ocfs2_journal_handle *handle, 275int ocfs2_journal_dirty(handle_t *handle,
428 struct buffer_head *bh) 276 struct buffer_head *bh)
429{ 277{
430 int status; 278 int status;
431 279
432 BUG_ON(!(handle->flags & OCFS2_HANDLE_STARTED));
433
434 mlog_entry("(bh->b_blocknr=%llu)\n", 280 mlog_entry("(bh->b_blocknr=%llu)\n",
435 (unsigned long long)bh->b_blocknr); 281 (unsigned long long)bh->b_blocknr);
436 282
437 status = journal_dirty_metadata(handle->k_handle, bh); 283 status = journal_dirty_metadata(handle, bh);
438 if (status < 0) 284 if (status < 0)
439 mlog(ML_ERROR, "Could not dirty metadata buffer. " 285 mlog(ML_ERROR, "Could not dirty metadata buffer. "
440 "(bh->b_blocknr=%llu)\n", 286 "(bh->b_blocknr=%llu)\n",
@@ -456,59 +302,6 @@ int ocfs2_journal_dirty_data(handle_t *handle,
456 return err; 302 return err;
457} 303}
458 304
459/* We always assume you're adding a metadata lock at level 'ex' */
460int ocfs2_handle_add_lock(struct ocfs2_journal_handle *handle,
461 struct inode *inode)
462{
463 int status;
464 struct ocfs2_journal_lock *lock;
465
466 BUG_ON(!inode);
467
468 lock = kmem_cache_alloc(ocfs2_lock_cache, GFP_NOFS);
469 if (!lock) {
470 status = -ENOMEM;
471 mlog_errno(-ENOMEM);
472 goto bail;
473 }
474
475 if (!igrab(inode))
476 BUG();
477 lock->jl_inode = inode;
478
479 list_add_tail(&(lock->jl_lock_list), &(handle->locks));
480 handle->num_locks++;
481
482 status = 0;
483bail:
484 mlog_exit(status);
485 return status;
486}
487
488static void ocfs2_handle_cleanup_locks(struct ocfs2_journal *journal,
489 struct ocfs2_journal_handle *handle)
490{
491 struct list_head *p, *n;
492 struct ocfs2_journal_lock *lock;
493 struct inode *inode;
494
495 list_for_each_safe(p, n, &(handle->locks)) {
496 lock = list_entry(p, struct ocfs2_journal_lock,
497 jl_lock_list);
498 list_del(&lock->jl_lock_list);
499 handle->num_locks--;
500
501 inode = lock->jl_inode;
502 ocfs2_meta_unlock(inode, 1);
503 if (atomic_read(&inode->i_count) == 1)
504 mlog(ML_ERROR,
505 "Inode %llu, I'm doing a last iput for!",
506 (unsigned long long)OCFS2_I(inode)->ip_blkno);
507 iput(inode);
508 kmem_cache_free(ocfs2_lock_cache, lock);
509 }
510}
511
512#define OCFS2_DEFAULT_COMMIT_INTERVAL (HZ * 5) 305#define OCFS2_DEFAULT_COMMIT_INTERVAL (HZ * 5)
513 306
514void ocfs2_set_journal_params(struct ocfs2_super *osb) 307void ocfs2_set_journal_params(struct ocfs2_super *osb)
@@ -562,8 +355,7 @@ int ocfs2_journal_init(struct ocfs2_journal *journal, int *dirty)
562 /* Skip recovery waits here - journal inode metadata never 355 /* Skip recovery waits here - journal inode metadata never
563 * changes in a live cluster so it can be considered an 356 * changes in a live cluster so it can be considered an
564 * exception to the rule. */ 357 * exception to the rule. */
565 status = ocfs2_meta_lock_full(inode, NULL, &bh, 1, 358 status = ocfs2_meta_lock_full(inode, &bh, 1, OCFS2_META_LOCK_RECOVERY);
566 OCFS2_META_LOCK_RECOVERY);
567 if (status < 0) { 359 if (status < 0) {
568 if (status != -ERESTARTSYS) 360 if (status != -ERESTARTSYS)
569 mlog(ML_ERROR, "Could not get lock on journal!\n"); 361 mlog(ML_ERROR, "Could not get lock on journal!\n");
@@ -1161,8 +953,7 @@ static int ocfs2_replay_journal(struct ocfs2_super *osb,
1161 } 953 }
1162 SET_INODE_JOURNAL(inode); 954 SET_INODE_JOURNAL(inode);
1163 955
1164 status = ocfs2_meta_lock_full(inode, NULL, &bh, 1, 956 status = ocfs2_meta_lock_full(inode, &bh, 1, OCFS2_META_LOCK_RECOVERY);
1165 OCFS2_META_LOCK_RECOVERY);
1166 if (status < 0) { 957 if (status < 0) {
1167 mlog(0, "status returned from ocfs2_meta_lock=%d\n", status); 958 mlog(0, "status returned from ocfs2_meta_lock=%d\n", status);
1168 if (status != -ERESTARTSYS) 959 if (status != -ERESTARTSYS)
@@ -1351,7 +1142,7 @@ static int ocfs2_trylock_journal(struct ocfs2_super *osb,
1351 SET_INODE_JOURNAL(inode); 1142 SET_INODE_JOURNAL(inode);
1352 1143
1353 flags = OCFS2_META_LOCK_RECOVERY | OCFS2_META_LOCK_NOQUEUE; 1144 flags = OCFS2_META_LOCK_RECOVERY | OCFS2_META_LOCK_NOQUEUE;
1354 status = ocfs2_meta_lock_full(inode, NULL, NULL, 1, flags); 1145 status = ocfs2_meta_lock_full(inode, NULL, 1, flags);
1355 if (status < 0) { 1146 if (status < 0) {
1356 if (status != -EAGAIN) 1147 if (status != -EAGAIN)
1357 mlog_errno(status); 1148 mlog_errno(status);
@@ -1434,7 +1225,7 @@ static int ocfs2_queue_orphans(struct ocfs2_super *osb,
1434 } 1225 }
1435 1226
1436 mutex_lock(&orphan_dir_inode->i_mutex); 1227 mutex_lock(&orphan_dir_inode->i_mutex);
1437 status = ocfs2_meta_lock(orphan_dir_inode, NULL, NULL, 0); 1228 status = ocfs2_meta_lock(orphan_dir_inode, NULL, 0);
1438 if (status < 0) { 1229 if (status < 0) {
1439 mlog_errno(status); 1230 mlog_errno(status);
1440 goto out; 1231 goto out;