diff options
| -rw-r--r-- | fs/gfs2/aops.c | 2 | ||||
| -rw-r--r-- | fs/gfs2/bmap.c | 8 | ||||
| -rw-r--r-- | fs/gfs2/file.c | 12 | ||||
| -rw-r--r-- | fs/gfs2/glops.c | 51 | ||||
| -rw-r--r-- | fs/gfs2/glops.h | 2 | ||||
| -rw-r--r-- | fs/gfs2/incore.h | 14 | ||||
| -rw-r--r-- | fs/gfs2/inode.c | 40 | ||||
| -rw-r--r-- | fs/gfs2/log.c | 93 | ||||
| -rw-r--r-- | fs/gfs2/log.h | 11 | ||||
| -rw-r--r-- | fs/gfs2/lops.c | 2 | ||||
| -rw-r--r-- | fs/gfs2/ops_fstype.c | 25 | ||||
| -rw-r--r-- | fs/gfs2/quota.c | 3 | ||||
| -rw-r--r-- | fs/gfs2/recovery.c | 22 | ||||
| -rw-r--r-- | fs/gfs2/rgrp.c | 2 | ||||
| -rw-r--r-- | fs/gfs2/super.c | 69 | ||||
| -rw-r--r-- | fs/gfs2/sys.c | 7 | ||||
| -rw-r--r-- | fs/gfs2/trans.c | 44 | ||||
| -rw-r--r-- | include/uapi/linux/gfs2_ondisk.h | 2 |
18 files changed, 246 insertions, 163 deletions
diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c index ce62dcac90b6..5a49b037da81 100644 --- a/fs/gfs2/aops.c +++ b/fs/gfs2/aops.c | |||
| @@ -431,7 +431,7 @@ static int gfs2_jdata_writepages(struct address_space *mapping, | |||
| 431 | 431 | ||
| 432 | ret = gfs2_write_cache_jdata(mapping, wbc); | 432 | ret = gfs2_write_cache_jdata(mapping, wbc); |
| 433 | if (ret == 0 && wbc->sync_mode == WB_SYNC_ALL) { | 433 | if (ret == 0 && wbc->sync_mode == WB_SYNC_ALL) { |
| 434 | gfs2_log_flush(sdp, ip->i_gl); | 434 | gfs2_log_flush(sdp, ip->i_gl, NORMAL_FLUSH); |
| 435 | ret = gfs2_write_cache_jdata(mapping, wbc); | 435 | ret = gfs2_write_cache_jdata(mapping, wbc); |
| 436 | } | 436 | } |
| 437 | return ret; | 437 | return ret; |
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index c62d4b9f51dc..e6ee5b6e8d99 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c | |||
| @@ -707,7 +707,7 @@ int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsi | |||
| 707 | * @top: The first pointer in the buffer | 707 | * @top: The first pointer in the buffer |
| 708 | * @bottom: One more than the last pointer | 708 | * @bottom: One more than the last pointer |
| 709 | * @height: the height this buffer is at | 709 | * @height: the height this buffer is at |
| 710 | * @data: a pointer to a struct strip_mine | 710 | * @sm: a pointer to a struct strip_mine |
| 711 | * | 711 | * |
| 712 | * Returns: errno | 712 | * Returns: errno |
| 713 | */ | 713 | */ |
| @@ -992,6 +992,8 @@ unlock: | |||
| 992 | return err; | 992 | return err; |
| 993 | } | 993 | } |
| 994 | 994 | ||
| 995 | #define GFS2_JTRUNC_REVOKES 8192 | ||
| 996 | |||
| 995 | /** | 997 | /** |
| 996 | * gfs2_journaled_truncate - Wrapper for truncate_pagecache for jdata files | 998 | * gfs2_journaled_truncate - Wrapper for truncate_pagecache for jdata files |
| 997 | * @inode: The inode being truncated | 999 | * @inode: The inode being truncated |
| @@ -1003,8 +1005,6 @@ unlock: | |||
| 1003 | * if the number of pages being truncated gets too large. | 1005 | * if the number of pages being truncated gets too large. |
| 1004 | */ | 1006 | */ |
| 1005 | 1007 | ||
| 1006 | #define GFS2_JTRUNC_REVOKES 8192 | ||
| 1007 | |||
| 1008 | static int gfs2_journaled_truncate(struct inode *inode, u64 oldsize, u64 newsize) | 1008 | static int gfs2_journaled_truncate(struct inode *inode, u64 oldsize, u64 newsize) |
| 1009 | { | 1009 | { |
| 1010 | struct gfs2_sbd *sdp = GFS2_SB(inode); | 1010 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
| @@ -1348,7 +1348,7 @@ void gfs2_free_journal_extents(struct gfs2_jdesc *jd) | |||
| 1348 | * gfs2_add_jextent - Add or merge a new extent to extent cache | 1348 | * gfs2_add_jextent - Add or merge a new extent to extent cache |
| 1349 | * @jd: The journal descriptor | 1349 | * @jd: The journal descriptor |
| 1350 | * @lblock: The logical block at start of new extent | 1350 | * @lblock: The logical block at start of new extent |
| 1351 | * @pblock: The physical block at start of new extent | 1351 | * @dblock: The physical block at start of new extent |
| 1352 | * @blocks: Size of extent in fs blocks | 1352 | * @blocks: Size of extent in fs blocks |
| 1353 | * | 1353 | * |
| 1354 | * Returns: 0 on success or -ENOMEM | 1354 | * Returns: 0 on success or -ENOMEM |
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index 80d67253623c..6ab0cfb2e891 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c | |||
| @@ -203,9 +203,9 @@ void gfs2_set_inode_flags(struct inode *inode) | |||
| 203 | GFS2_DIF_INHERIT_JDATA) | 203 | GFS2_DIF_INHERIT_JDATA) |
| 204 | 204 | ||
| 205 | /** | 205 | /** |
| 206 | * gfs2_set_flags - set flags on an inode | 206 | * do_gfs2_set_flags - set flags on an inode |
| 207 | * @inode: The inode | 207 | * @filp: file pointer |
| 208 | * @flags: The flags to set | 208 | * @reqflags: The flags to set |
| 209 | * @mask: Indicates which flags are valid | 209 | * @mask: Indicates which flags are valid |
| 210 | * | 210 | * |
| 211 | */ | 211 | */ |
| @@ -256,7 +256,7 @@ static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask) | |||
| 256 | } | 256 | } |
| 257 | if ((flags ^ new_flags) & GFS2_DIF_JDATA) { | 257 | if ((flags ^ new_flags) & GFS2_DIF_JDATA) { |
| 258 | if (flags & GFS2_DIF_JDATA) | 258 | if (flags & GFS2_DIF_JDATA) |
| 259 | gfs2_log_flush(sdp, ip->i_gl); | 259 | gfs2_log_flush(sdp, ip->i_gl, NORMAL_FLUSH); |
| 260 | error = filemap_fdatawrite(inode->i_mapping); | 260 | error = filemap_fdatawrite(inode->i_mapping); |
| 261 | if (error) | 261 | if (error) |
| 262 | goto out; | 262 | goto out; |
| @@ -318,7 +318,7 @@ static long gfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
| 318 | 318 | ||
| 319 | /** | 319 | /** |
| 320 | * gfs2_size_hint - Give a hint to the size of a write request | 320 | * gfs2_size_hint - Give a hint to the size of a write request |
| 321 | * @file: The struct file | 321 | * @filep: The struct file |
| 322 | * @offset: The file offset of the write | 322 | * @offset: The file offset of the write |
| 323 | * @size: The length of the write | 323 | * @size: The length of the write |
| 324 | * | 324 | * |
| @@ -371,7 +371,7 @@ static int gfs2_allocate_page_backing(struct page *page) | |||
| 371 | /** | 371 | /** |
| 372 | * gfs2_page_mkwrite - Make a shared, mmap()ed, page writable | 372 | * gfs2_page_mkwrite - Make a shared, mmap()ed, page writable |
| 373 | * @vma: The virtual memory area | 373 | * @vma: The virtual memory area |
| 374 | * @page: The page which is about to become writable | 374 | * @vmf: The virtual memory fault containing the page to become writable |
| 375 | * | 375 | * |
| 376 | * When the page becomes writable, we need to ensure that we have | 376 | * When the page becomes writable, we need to ensure that we have |
| 377 | * blocks allocated on disk to back that page. | 377 | * blocks allocated on disk to back that page. |
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c index 74d9a3dbf16f..fc1100781bbc 100644 --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c | |||
| @@ -89,18 +89,23 @@ static void gfs2_ail_empty_gl(struct gfs2_glock *gl) | |||
| 89 | if (!tr.tr_revokes) | 89 | if (!tr.tr_revokes) |
| 90 | return; | 90 | return; |
| 91 | 91 | ||
| 92 | /* A shortened, inline version of gfs2_trans_begin() */ | 92 | /* A shortened, inline version of gfs2_trans_begin() |
| 93 | * tr->alloced is not set since the transaction structure is | ||
| 94 | * on the stack */ | ||
| 93 | tr.tr_reserved = 1 + gfs2_struct2blk(sdp, tr.tr_revokes, sizeof(u64)); | 95 | tr.tr_reserved = 1 + gfs2_struct2blk(sdp, tr.tr_revokes, sizeof(u64)); |
| 94 | tr.tr_ip = (unsigned long)__builtin_return_address(0); | 96 | tr.tr_ip = (unsigned long)__builtin_return_address(0); |
| 95 | sb_start_intwrite(sdp->sd_vfs); | 97 | sb_start_intwrite(sdp->sd_vfs); |
| 96 | gfs2_log_reserve(sdp, tr.tr_reserved); | 98 | if (gfs2_log_reserve(sdp, tr.tr_reserved) < 0) { |
| 99 | sb_end_intwrite(sdp->sd_vfs); | ||
| 100 | return; | ||
| 101 | } | ||
| 97 | WARN_ON_ONCE(current->journal_info); | 102 | WARN_ON_ONCE(current->journal_info); |
| 98 | current->journal_info = &tr; | 103 | current->journal_info = &tr; |
| 99 | 104 | ||
| 100 | __gfs2_ail_flush(gl, 0, tr.tr_revokes); | 105 | __gfs2_ail_flush(gl, 0, tr.tr_revokes); |
| 101 | 106 | ||
| 102 | gfs2_trans_end(sdp); | 107 | gfs2_trans_end(sdp); |
| 103 | gfs2_log_flush(sdp, NULL); | 108 | gfs2_log_flush(sdp, NULL, NORMAL_FLUSH); |
| 104 | } | 109 | } |
| 105 | 110 | ||
| 106 | void gfs2_ail_flush(struct gfs2_glock *gl, bool fsync) | 111 | void gfs2_ail_flush(struct gfs2_glock *gl, bool fsync) |
| @@ -121,7 +126,7 @@ void gfs2_ail_flush(struct gfs2_glock *gl, bool fsync) | |||
| 121 | return; | 126 | return; |
| 122 | __gfs2_ail_flush(gl, fsync, max_revokes); | 127 | __gfs2_ail_flush(gl, fsync, max_revokes); |
| 123 | gfs2_trans_end(sdp); | 128 | gfs2_trans_end(sdp); |
| 124 | gfs2_log_flush(sdp, NULL); | 129 | gfs2_log_flush(sdp, NULL, NORMAL_FLUSH); |
| 125 | } | 130 | } |
| 126 | 131 | ||
| 127 | /** | 132 | /** |
| @@ -144,7 +149,7 @@ static void rgrp_go_sync(struct gfs2_glock *gl) | |||
| 144 | return; | 149 | return; |
| 145 | GLOCK_BUG_ON(gl, gl->gl_state != LM_ST_EXCLUSIVE); | 150 | GLOCK_BUG_ON(gl, gl->gl_state != LM_ST_EXCLUSIVE); |
| 146 | 151 | ||
| 147 | gfs2_log_flush(sdp, gl); | 152 | gfs2_log_flush(sdp, gl, NORMAL_FLUSH); |
| 148 | filemap_fdatawrite_range(mapping, gl->gl_vm.start, gl->gl_vm.end); | 153 | filemap_fdatawrite_range(mapping, gl->gl_vm.start, gl->gl_vm.end); |
| 149 | error = filemap_fdatawait_range(mapping, gl->gl_vm.start, gl->gl_vm.end); | 154 | error = filemap_fdatawait_range(mapping, gl->gl_vm.start, gl->gl_vm.end); |
| 150 | mapping_set_error(mapping, error); | 155 | mapping_set_error(mapping, error); |
| @@ -206,7 +211,7 @@ static void inode_go_sync(struct gfs2_glock *gl) | |||
| 206 | 211 | ||
| 207 | GLOCK_BUG_ON(gl, gl->gl_state != LM_ST_EXCLUSIVE); | 212 | GLOCK_BUG_ON(gl, gl->gl_state != LM_ST_EXCLUSIVE); |
| 208 | 213 | ||
| 209 | gfs2_log_flush(gl->gl_sbd, gl); | 214 | gfs2_log_flush(gl->gl_sbd, gl, NORMAL_FLUSH); |
| 210 | filemap_fdatawrite(metamapping); | 215 | filemap_fdatawrite(metamapping); |
| 211 | if (ip) { | 216 | if (ip) { |
| 212 | struct address_space *mapping = ip->i_inode.i_mapping; | 217 | struct address_space *mapping = ip->i_inode.i_mapping; |
| @@ -253,7 +258,7 @@ static void inode_go_inval(struct gfs2_glock *gl, int flags) | |||
| 253 | } | 258 | } |
| 254 | 259 | ||
| 255 | if (ip == GFS2_I(gl->gl_sbd->sd_rindex)) { | 260 | if (ip == GFS2_I(gl->gl_sbd->sd_rindex)) { |
| 256 | gfs2_log_flush(gl->gl_sbd, NULL); | 261 | gfs2_log_flush(gl->gl_sbd, NULL, NORMAL_FLUSH); |
| 257 | gl->gl_sbd->sd_rindex_uptodate = 0; | 262 | gl->gl_sbd->sd_rindex_uptodate = 0; |
| 258 | } | 263 | } |
| 259 | if (ip && S_ISREG(ip->i_inode.i_mode)) | 264 | if (ip && S_ISREG(ip->i_inode.i_mode)) |
| @@ -455,31 +460,39 @@ static void inode_go_dump(struct seq_file *seq, const struct gfs2_glock *gl) | |||
| 455 | } | 460 | } |
| 456 | 461 | ||
| 457 | /** | 462 | /** |
| 458 | * trans_go_sync - promote/demote the transaction glock | 463 | * freeze_go_sync - promote/demote the freeze glock |
| 459 | * @gl: the glock | 464 | * @gl: the glock |
| 460 | * @state: the requested state | 465 | * @state: the requested state |
| 461 | * @flags: | 466 | * @flags: |
| 462 | * | 467 | * |
| 463 | */ | 468 | */ |
| 464 | 469 | ||
| 465 | static void trans_go_sync(struct gfs2_glock *gl) | 470 | static void freeze_go_sync(struct gfs2_glock *gl) |
| 466 | { | 471 | { |
| 467 | struct gfs2_sbd *sdp = gl->gl_sbd; | 472 | struct gfs2_sbd *sdp = gl->gl_sbd; |
| 473 | DEFINE_WAIT(wait); | ||
| 468 | 474 | ||
| 469 | if (gl->gl_state != LM_ST_UNLOCKED && | 475 | if (gl->gl_state == LM_ST_SHARED && |
| 470 | test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) { | 476 | test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) { |
| 471 | gfs2_meta_syncfs(sdp); | 477 | atomic_set(&sdp->sd_log_freeze, 1); |
| 472 | gfs2_log_shutdown(sdp); | 478 | wake_up(&sdp->sd_logd_waitq); |
| 479 | do { | ||
| 480 | prepare_to_wait(&sdp->sd_log_frozen_wait, &wait, | ||
| 481 | TASK_UNINTERRUPTIBLE); | ||
| 482 | if (atomic_read(&sdp->sd_log_freeze)) | ||
| 483 | io_schedule(); | ||
| 484 | } while(atomic_read(&sdp->sd_log_freeze)); | ||
| 485 | finish_wait(&sdp->sd_log_frozen_wait, &wait); | ||
| 473 | } | 486 | } |
| 474 | } | 487 | } |
| 475 | 488 | ||
| 476 | /** | 489 | /** |
| 477 | * trans_go_xmote_bh - After promoting/demoting the transaction glock | 490 | * freeze_go_xmote_bh - After promoting/demoting the freeze glock |
| 478 | * @gl: the glock | 491 | * @gl: the glock |
| 479 | * | 492 | * |
| 480 | */ | 493 | */ |
| 481 | 494 | ||
| 482 | static int trans_go_xmote_bh(struct gfs2_glock *gl, struct gfs2_holder *gh) | 495 | static int freeze_go_xmote_bh(struct gfs2_glock *gl, struct gfs2_holder *gh) |
| 483 | { | 496 | { |
| 484 | struct gfs2_sbd *sdp = gl->gl_sbd; | 497 | struct gfs2_sbd *sdp = gl->gl_sbd; |
| 485 | struct gfs2_inode *ip = GFS2_I(sdp->sd_jdesc->jd_inode); | 498 | struct gfs2_inode *ip = GFS2_I(sdp->sd_jdesc->jd_inode); |
| @@ -512,7 +525,7 @@ static int trans_go_xmote_bh(struct gfs2_glock *gl, struct gfs2_holder *gh) | |||
| 512 | * Always returns 0 | 525 | * Always returns 0 |
| 513 | */ | 526 | */ |
| 514 | 527 | ||
| 515 | static int trans_go_demote_ok(const struct gfs2_glock *gl) | 528 | static int freeze_go_demote_ok(const struct gfs2_glock *gl) |
| 516 | { | 529 | { |
| 517 | return 0; | 530 | return 0; |
| 518 | } | 531 | } |
| @@ -563,10 +576,10 @@ const struct gfs2_glock_operations gfs2_rgrp_glops = { | |||
| 563 | .go_flags = GLOF_LVB, | 576 | .go_flags = GLOF_LVB, |
| 564 | }; | 577 | }; |
| 565 | 578 | ||
| 566 | const struct gfs2_glock_operations gfs2_trans_glops = { | 579 | const struct gfs2_glock_operations gfs2_freeze_glops = { |
| 567 | .go_sync = trans_go_sync, | 580 | .go_sync = freeze_go_sync, |
| 568 | .go_xmote_bh = trans_go_xmote_bh, | 581 | .go_xmote_bh = freeze_go_xmote_bh, |
| 569 | .go_demote_ok = trans_go_demote_ok, | 582 | .go_demote_ok = freeze_go_demote_ok, |
| 570 | .go_type = LM_TYPE_NONDISK, | 583 | .go_type = LM_TYPE_NONDISK, |
| 571 | }; | 584 | }; |
| 572 | 585 | ||
diff --git a/fs/gfs2/glops.h b/fs/gfs2/glops.h index bf95a2dc1662..7455d2629bcb 100644 --- a/fs/gfs2/glops.h +++ b/fs/gfs2/glops.h | |||
| @@ -15,7 +15,7 @@ | |||
| 15 | extern const struct gfs2_glock_operations gfs2_meta_glops; | 15 | extern const struct gfs2_glock_operations gfs2_meta_glops; |
| 16 | extern const struct gfs2_glock_operations gfs2_inode_glops; | 16 | extern const struct gfs2_glock_operations gfs2_inode_glops; |
| 17 | extern const struct gfs2_glock_operations gfs2_rgrp_glops; | 17 | extern const struct gfs2_glock_operations gfs2_rgrp_glops; |
| 18 | extern const struct gfs2_glock_operations gfs2_trans_glops; | 18 | extern const struct gfs2_glock_operations gfs2_freeze_glops; |
| 19 | extern const struct gfs2_glock_operations gfs2_iopen_glops; | 19 | extern const struct gfs2_glock_operations gfs2_iopen_glops; |
| 20 | extern const struct gfs2_glock_operations gfs2_flock_glops; | 20 | extern const struct gfs2_glock_operations gfs2_flock_glops; |
| 21 | extern const struct gfs2_glock_operations gfs2_nondisk_glops; | 21 | extern const struct gfs2_glock_operations gfs2_nondisk_glops; |
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index bdf70c18610c..67d310c9ada3 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h | |||
| @@ -465,9 +465,7 @@ struct gfs2_trans { | |||
| 465 | unsigned int tr_reserved; | 465 | unsigned int tr_reserved; |
| 466 | unsigned int tr_touched:1; | 466 | unsigned int tr_touched:1; |
| 467 | unsigned int tr_attached:1; | 467 | unsigned int tr_attached:1; |
| 468 | 468 | unsigned int tr_alloced:1; | |
| 469 | struct gfs2_holder tr_t_gh; | ||
| 470 | |||
| 471 | 469 | ||
| 472 | unsigned int tr_num_buf_new; | 470 | unsigned int tr_num_buf_new; |
| 473 | unsigned int tr_num_databuf_new; | 471 | unsigned int tr_num_databuf_new; |
| @@ -682,7 +680,7 @@ struct gfs2_sbd { | |||
| 682 | struct lm_lockstruct sd_lockstruct; | 680 | struct lm_lockstruct sd_lockstruct; |
| 683 | struct gfs2_holder sd_live_gh; | 681 | struct gfs2_holder sd_live_gh; |
| 684 | struct gfs2_glock *sd_rename_gl; | 682 | struct gfs2_glock *sd_rename_gl; |
| 685 | struct gfs2_glock *sd_trans_gl; | 683 | struct gfs2_glock *sd_freeze_gl; |
| 686 | wait_queue_head_t sd_glock_wait; | 684 | wait_queue_head_t sd_glock_wait; |
| 687 | atomic_t sd_glock_disposal; | 685 | atomic_t sd_glock_disposal; |
| 688 | struct completion sd_locking_init; | 686 | struct completion sd_locking_init; |
| @@ -730,6 +728,8 @@ struct gfs2_sbd { | |||
| 730 | struct gfs2_holder sd_sc_gh; | 728 | struct gfs2_holder sd_sc_gh; |
| 731 | struct gfs2_holder sd_qc_gh; | 729 | struct gfs2_holder sd_qc_gh; |
| 732 | 730 | ||
| 731 | struct completion sd_journal_ready; | ||
| 732 | |||
| 733 | /* Daemon stuff */ | 733 | /* Daemon stuff */ |
| 734 | 734 | ||
| 735 | struct task_struct *sd_logd_process; | 735 | struct task_struct *sd_logd_process; |
| @@ -794,6 +794,12 @@ struct gfs2_sbd { | |||
| 794 | 794 | ||
| 795 | /* For quiescing the filesystem */ | 795 | /* For quiescing the filesystem */ |
| 796 | struct gfs2_holder sd_freeze_gh; | 796 | struct gfs2_holder sd_freeze_gh; |
| 797 | struct gfs2_holder sd_freeze_root_gh; | ||
| 798 | struct gfs2_holder sd_thaw_gh; | ||
| 799 | atomic_t sd_log_freeze; | ||
| 800 | atomic_t sd_frozen_root; | ||
| 801 | wait_queue_head_t sd_frozen_root_wait; | ||
| 802 | wait_queue_head_t sd_log_frozen_wait; | ||
| 797 | 803 | ||
| 798 | char sd_fsname[GFS2_FSNAME_LEN]; | 804 | char sd_fsname[GFS2_FSNAME_LEN]; |
| 799 | char sd_table_name[GFS2_FSNAME_LEN]; | 805 | char sd_table_name[GFS2_FSNAME_LEN]; |
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 28cc7bf6575a..e62e59477884 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
| @@ -1613,18 +1613,26 @@ int gfs2_permission(struct inode *inode, int mask) | |||
| 1613 | { | 1613 | { |
| 1614 | struct gfs2_inode *ip; | 1614 | struct gfs2_inode *ip; |
| 1615 | struct gfs2_holder i_gh; | 1615 | struct gfs2_holder i_gh; |
| 1616 | struct gfs2_sbd *sdp = GFS2_SB(inode); | ||
| 1616 | int error; | 1617 | int error; |
| 1617 | int unlock = 0; | 1618 | int unlock = 0; |
| 1619 | int frozen_root = 0; | ||
| 1618 | 1620 | ||
| 1619 | 1621 | ||
| 1620 | ip = GFS2_I(inode); | 1622 | ip = GFS2_I(inode); |
| 1621 | if (gfs2_glock_is_locked_by_me(ip->i_gl) == NULL) { | 1623 | if (gfs2_glock_is_locked_by_me(ip->i_gl) == NULL) { |
| 1622 | if (mask & MAY_NOT_BLOCK) | 1624 | if (unlikely(gfs2_glock_is_held_excl(sdp->sd_freeze_gl) && |
| 1623 | return -ECHILD; | 1625 | inode == sdp->sd_root_dir->d_inode && |
| 1624 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); | 1626 | atomic_inc_not_zero(&sdp->sd_frozen_root))) |
| 1625 | if (error) | 1627 | frozen_root = 1; |
| 1626 | return error; | 1628 | else { |
| 1627 | unlock = 1; | 1629 | if (mask & MAY_NOT_BLOCK) |
| 1630 | return -ECHILD; | ||
| 1631 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); | ||
| 1632 | if (error) | ||
| 1633 | return error; | ||
| 1634 | unlock = 1; | ||
| 1635 | } | ||
| 1628 | } | 1636 | } |
| 1629 | 1637 | ||
| 1630 | if ((mask & MAY_WRITE) && IS_IMMUTABLE(inode)) | 1638 | if ((mask & MAY_WRITE) && IS_IMMUTABLE(inode)) |
| @@ -1633,6 +1641,8 @@ int gfs2_permission(struct inode *inode, int mask) | |||
| 1633 | error = generic_permission(inode, mask); | 1641 | error = generic_permission(inode, mask); |
| 1634 | if (unlock) | 1642 | if (unlock) |
| 1635 | gfs2_glock_dq_uninit(&i_gh); | 1643 | gfs2_glock_dq_uninit(&i_gh); |
| 1644 | else if (frozen_root && atomic_dec_and_test(&sdp->sd_frozen_root)) | ||
| 1645 | wake_up(&sdp->sd_frozen_root_wait); | ||
| 1636 | 1646 | ||
| 1637 | return error; | 1647 | return error; |
| 1638 | } | 1648 | } |
| @@ -1805,19 +1815,29 @@ static int gfs2_getattr(struct vfsmount *mnt, struct dentry *dentry, | |||
| 1805 | struct inode *inode = dentry->d_inode; | 1815 | struct inode *inode = dentry->d_inode; |
| 1806 | struct gfs2_inode *ip = GFS2_I(inode); | 1816 | struct gfs2_inode *ip = GFS2_I(inode); |
| 1807 | struct gfs2_holder gh; | 1817 | struct gfs2_holder gh; |
| 1818 | struct gfs2_sbd *sdp = GFS2_SB(inode); | ||
| 1808 | int error; | 1819 | int error; |
| 1809 | int unlock = 0; | 1820 | int unlock = 0; |
| 1821 | int frozen_root = 0; | ||
| 1810 | 1822 | ||
| 1811 | if (gfs2_glock_is_locked_by_me(ip->i_gl) == NULL) { | 1823 | if (gfs2_glock_is_locked_by_me(ip->i_gl) == NULL) { |
| 1812 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &gh); | 1824 | if (unlikely(gfs2_glock_is_held_excl(sdp->sd_freeze_gl) && |
| 1813 | if (error) | 1825 | inode == sdp->sd_root_dir->d_inode && |
| 1814 | return error; | 1826 | atomic_inc_not_zero(&sdp->sd_frozen_root))) |
| 1815 | unlock = 1; | 1827 | frozen_root = 1; |
| 1828 | else { | ||
| 1829 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &gh); | ||
| 1830 | if (error) | ||
| 1831 | return error; | ||
| 1832 | unlock = 1; | ||
| 1833 | } | ||
| 1816 | } | 1834 | } |
| 1817 | 1835 | ||
| 1818 | generic_fillattr(inode, stat); | 1836 | generic_fillattr(inode, stat); |
| 1819 | if (unlock) | 1837 | if (unlock) |
| 1820 | gfs2_glock_dq_uninit(&gh); | 1838 | gfs2_glock_dq_uninit(&gh); |
| 1839 | else if (frozen_root && atomic_dec_and_test(&sdp->sd_frozen_root)) | ||
| 1840 | wake_up(&sdp->sd_frozen_root_wait); | ||
| 1821 | 1841 | ||
| 1822 | return 0; | 1842 | return 0; |
| 1823 | } | 1843 | } |
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index 4a14d504ef83..3966fadbcebd 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c | |||
| @@ -301,6 +301,23 @@ static void ail2_empty(struct gfs2_sbd *sdp, unsigned int new_tail) | |||
| 301 | } | 301 | } |
| 302 | 302 | ||
| 303 | /** | 303 | /** |
| 304 | * gfs2_log_release - Release a given number of log blocks | ||
| 305 | * @sdp: The GFS2 superblock | ||
| 306 | * @blks: The number of blocks | ||
| 307 | * | ||
| 308 | */ | ||
| 309 | |||
| 310 | void gfs2_log_release(struct gfs2_sbd *sdp, unsigned int blks) | ||
| 311 | { | ||
| 312 | |||
| 313 | atomic_add(blks, &sdp->sd_log_blks_free); | ||
| 314 | trace_gfs2_log_blocks(sdp, blks); | ||
| 315 | gfs2_assert_withdraw(sdp, atomic_read(&sdp->sd_log_blks_free) <= | ||
| 316 | sdp->sd_jdesc->jd_blocks); | ||
| 317 | up_read(&sdp->sd_log_flush_lock); | ||
| 318 | } | ||
| 319 | |||
| 320 | /** | ||
| 304 | * gfs2_log_reserve - Make a log reservation | 321 | * gfs2_log_reserve - Make a log reservation |
| 305 | * @sdp: The GFS2 superblock | 322 | * @sdp: The GFS2 superblock |
| 306 | * @blks: The number of blocks to reserve | 323 | * @blks: The number of blocks to reserve |
| @@ -358,7 +375,10 @@ retry: | |||
| 358 | wake_up(&sdp->sd_log_waitq); | 375 | wake_up(&sdp->sd_log_waitq); |
| 359 | 376 | ||
| 360 | down_read(&sdp->sd_log_flush_lock); | 377 | down_read(&sdp->sd_log_flush_lock); |
| 361 | 378 | if (unlikely(!test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags))) { | |
| 379 | gfs2_log_release(sdp, blks); | ||
| 380 | return -EROFS; | ||
| 381 | } | ||
| 362 | return 0; | 382 | return 0; |
| 363 | } | 383 | } |
| 364 | 384 | ||
| @@ -671,7 +691,8 @@ static void log_write_header(struct gfs2_sbd *sdp, u32 flags) | |||
| 671 | * | 691 | * |
| 672 | */ | 692 | */ |
| 673 | 693 | ||
| 674 | void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl) | 694 | void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, |
| 695 | enum gfs2_flush_type type) | ||
| 675 | { | 696 | { |
| 676 | struct gfs2_trans *tr; | 697 | struct gfs2_trans *tr; |
| 677 | 698 | ||
| @@ -723,6 +744,42 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl) | |||
| 723 | } | 744 | } |
| 724 | spin_unlock(&sdp->sd_ail_lock); | 745 | spin_unlock(&sdp->sd_ail_lock); |
| 725 | gfs2_log_unlock(sdp); | 746 | gfs2_log_unlock(sdp); |
| 747 | |||
| 748 | if (atomic_read(&sdp->sd_log_freeze)) | ||
| 749 | type = FREEZE_FLUSH; | ||
| 750 | if (type != NORMAL_FLUSH) { | ||
| 751 | if (!sdp->sd_log_idle) { | ||
| 752 | for (;;) { | ||
| 753 | gfs2_ail1_start(sdp); | ||
| 754 | gfs2_ail1_wait(sdp); | ||
| 755 | if (gfs2_ail1_empty(sdp)) | ||
| 756 | break; | ||
| 757 | } | ||
| 758 | atomic_dec(&sdp->sd_log_blks_free); /* Adjust for unreserved buffer */ | ||
| 759 | trace_gfs2_log_blocks(sdp, -1); | ||
| 760 | sdp->sd_log_flush_wrapped = 0; | ||
| 761 | log_write_header(sdp, 0); | ||
| 762 | sdp->sd_log_head = sdp->sd_log_flush_head; | ||
| 763 | } | ||
| 764 | if (type == SHUTDOWN_FLUSH || type == FREEZE_FLUSH) | ||
| 765 | gfs2_log_shutdown(sdp); | ||
| 766 | if (type == FREEZE_FLUSH) { | ||
| 767 | int error; | ||
| 768 | |||
| 769 | atomic_set(&sdp->sd_log_freeze, 0); | ||
| 770 | wake_up(&sdp->sd_log_frozen_wait); | ||
| 771 | error = gfs2_glock_nq_init(sdp->sd_freeze_gl, | ||
| 772 | LM_ST_SHARED, 0, | ||
| 773 | &sdp->sd_thaw_gh); | ||
| 774 | if (error) { | ||
| 775 | printk(KERN_INFO "GFS2: couln't get freeze lock : %d\n", error); | ||
| 776 | gfs2_assert_withdraw(sdp, 0); | ||
| 777 | } | ||
| 778 | else | ||
| 779 | gfs2_glock_dq_uninit(&sdp->sd_thaw_gh); | ||
| 780 | } | ||
| 781 | } | ||
| 782 | |||
| 726 | trace_gfs2_log_flush(sdp, 0); | 783 | trace_gfs2_log_flush(sdp, 0); |
| 727 | up_write(&sdp->sd_log_flush_lock); | 784 | up_write(&sdp->sd_log_flush_lock); |
| 728 | 785 | ||
| @@ -761,7 +818,7 @@ static void log_refund(struct gfs2_sbd *sdp, struct gfs2_trans *tr) | |||
| 761 | if (sdp->sd_log_tr) { | 818 | if (sdp->sd_log_tr) { |
| 762 | gfs2_merge_trans(sdp->sd_log_tr, tr); | 819 | gfs2_merge_trans(sdp->sd_log_tr, tr); |
| 763 | } else if (tr->tr_num_buf_new || tr->tr_num_databuf_new) { | 820 | } else if (tr->tr_num_buf_new || tr->tr_num_databuf_new) { |
| 764 | gfs2_assert_withdraw(sdp, tr->tr_t_gh.gh_gl); | 821 | gfs2_assert_withdraw(sdp, tr->tr_alloced); |
| 765 | sdp->sd_log_tr = tr; | 822 | sdp->sd_log_tr = tr; |
| 766 | tr->tr_attached = 1; | 823 | tr->tr_attached = 1; |
| 767 | } | 824 | } |
| @@ -813,8 +870,6 @@ void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr) | |||
| 813 | 870 | ||
| 814 | void gfs2_log_shutdown(struct gfs2_sbd *sdp) | 871 | void gfs2_log_shutdown(struct gfs2_sbd *sdp) |
| 815 | { | 872 | { |
| 816 | down_write(&sdp->sd_log_flush_lock); | ||
| 817 | |||
| 818 | gfs2_assert_withdraw(sdp, !sdp->sd_log_blks_reserved); | 873 | gfs2_assert_withdraw(sdp, !sdp->sd_log_blks_reserved); |
| 819 | gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke); | 874 | gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke); |
| 820 | gfs2_assert_withdraw(sdp, list_empty(&sdp->sd_ail1_list)); | 875 | gfs2_assert_withdraw(sdp, list_empty(&sdp->sd_ail1_list)); |
| @@ -824,38 +879,16 @@ void gfs2_log_shutdown(struct gfs2_sbd *sdp) | |||
| 824 | 879 | ||
| 825 | log_write_header(sdp, GFS2_LOG_HEAD_UNMOUNT); | 880 | log_write_header(sdp, GFS2_LOG_HEAD_UNMOUNT); |
| 826 | 881 | ||
| 827 | gfs2_assert_warn(sdp, atomic_read(&sdp->sd_log_blks_free) == sdp->sd_jdesc->jd_blocks); | ||
| 828 | gfs2_assert_warn(sdp, sdp->sd_log_head == sdp->sd_log_tail); | 882 | gfs2_assert_warn(sdp, sdp->sd_log_head == sdp->sd_log_tail); |
| 829 | gfs2_assert_warn(sdp, list_empty(&sdp->sd_ail2_list)); | 883 | gfs2_assert_warn(sdp, list_empty(&sdp->sd_ail2_list)); |
| 830 | 884 | ||
| 831 | sdp->sd_log_head = sdp->sd_log_flush_head; | 885 | sdp->sd_log_head = sdp->sd_log_flush_head; |
| 832 | sdp->sd_log_tail = sdp->sd_log_head; | 886 | sdp->sd_log_tail = sdp->sd_log_head; |
| 833 | |||
| 834 | up_write(&sdp->sd_log_flush_lock); | ||
| 835 | } | ||
| 836 | |||
| 837 | |||
| 838 | /** | ||
| 839 | * gfs2_meta_syncfs - sync all the buffers in a filesystem | ||
| 840 | * @sdp: the filesystem | ||
| 841 | * | ||
| 842 | */ | ||
| 843 | |||
| 844 | void gfs2_meta_syncfs(struct gfs2_sbd *sdp) | ||
| 845 | { | ||
| 846 | gfs2_log_flush(sdp, NULL); | ||
| 847 | for (;;) { | ||
| 848 | gfs2_ail1_start(sdp); | ||
| 849 | gfs2_ail1_wait(sdp); | ||
| 850 | if (gfs2_ail1_empty(sdp)) | ||
| 851 | break; | ||
| 852 | } | ||
| 853 | gfs2_log_flush(sdp, NULL); | ||
| 854 | } | 887 | } |
| 855 | 888 | ||
| 856 | static inline int gfs2_jrnl_flush_reqd(struct gfs2_sbd *sdp) | 889 | static inline int gfs2_jrnl_flush_reqd(struct gfs2_sbd *sdp) |
| 857 | { | 890 | { |
| 858 | return (atomic_read(&sdp->sd_log_pinned) >= atomic_read(&sdp->sd_log_thresh1)); | 891 | return (atomic_read(&sdp->sd_log_pinned) >= atomic_read(&sdp->sd_log_thresh1) || atomic_read(&sdp->sd_log_freeze)); |
| 859 | } | 892 | } |
| 860 | 893 | ||
| 861 | static inline int gfs2_ail_flush_reqd(struct gfs2_sbd *sdp) | 894 | static inline int gfs2_ail_flush_reqd(struct gfs2_sbd *sdp) |
| @@ -882,14 +915,14 @@ int gfs2_logd(void *data) | |||
| 882 | 915 | ||
| 883 | if (gfs2_jrnl_flush_reqd(sdp) || t == 0) { | 916 | if (gfs2_jrnl_flush_reqd(sdp) || t == 0) { |
| 884 | gfs2_ail1_empty(sdp); | 917 | gfs2_ail1_empty(sdp); |
| 885 | gfs2_log_flush(sdp, NULL); | 918 | gfs2_log_flush(sdp, NULL, NORMAL_FLUSH); |
| 886 | } | 919 | } |
| 887 | 920 | ||
| 888 | if (gfs2_ail_flush_reqd(sdp)) { | 921 | if (gfs2_ail_flush_reqd(sdp)) { |
| 889 | gfs2_ail1_start(sdp); | 922 | gfs2_ail1_start(sdp); |
| 890 | gfs2_ail1_wait(sdp); | 923 | gfs2_ail1_wait(sdp); |
| 891 | gfs2_ail1_empty(sdp); | 924 | gfs2_ail1_empty(sdp); |
| 892 | gfs2_log_flush(sdp, NULL); | 925 | gfs2_log_flush(sdp, NULL, NORMAL_FLUSH); |
| 893 | } | 926 | } |
| 894 | 927 | ||
| 895 | if (!gfs2_ail_flush_reqd(sdp)) | 928 | if (!gfs2_ail_flush_reqd(sdp)) |
diff --git a/fs/gfs2/log.h b/fs/gfs2/log.h index 37216634f0aa..9499a6049212 100644 --- a/fs/gfs2/log.h +++ b/fs/gfs2/log.h | |||
| @@ -63,14 +63,21 @@ extern void gfs2_ordered_del_inode(struct gfs2_inode *ip); | |||
| 63 | extern unsigned int gfs2_struct2blk(struct gfs2_sbd *sdp, unsigned int nstruct, | 63 | extern unsigned int gfs2_struct2blk(struct gfs2_sbd *sdp, unsigned int nstruct, |
| 64 | unsigned int ssize); | 64 | unsigned int ssize); |
| 65 | 65 | ||
| 66 | extern void gfs2_log_release(struct gfs2_sbd *sdp, unsigned int blks); | ||
| 66 | extern int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks); | 67 | extern int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks); |
| 67 | extern void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl); | 68 | enum gfs2_flush_type { |
| 69 | NORMAL_FLUSH = 0, | ||
| 70 | SYNC_FLUSH, | ||
| 71 | SHUTDOWN_FLUSH, | ||
| 72 | FREEZE_FLUSH | ||
| 73 | }; | ||
| 74 | extern void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, | ||
| 75 | enum gfs2_flush_type type); | ||
| 68 | extern void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *trans); | 76 | extern void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *trans); |
| 69 | extern void gfs2_remove_from_ail(struct gfs2_bufdata *bd); | 77 | extern void gfs2_remove_from_ail(struct gfs2_bufdata *bd); |
| 70 | extern void gfs2_ail1_flush(struct gfs2_sbd *sdp, struct writeback_control *wbc); | 78 | extern void gfs2_ail1_flush(struct gfs2_sbd *sdp, struct writeback_control *wbc); |
| 71 | 79 | ||
| 72 | extern void gfs2_log_shutdown(struct gfs2_sbd *sdp); | 80 | extern void gfs2_log_shutdown(struct gfs2_sbd *sdp); |
| 73 | extern void gfs2_meta_syncfs(struct gfs2_sbd *sdp); | ||
| 74 | extern int gfs2_logd(void *data); | 81 | extern int gfs2_logd(void *data); |
| 75 | extern void gfs2_add_revoke(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd); | 82 | extern void gfs2_add_revoke(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd); |
| 76 | extern void gfs2_write_revokes(struct gfs2_sbd *sdp); | 83 | extern void gfs2_write_revokes(struct gfs2_sbd *sdp); |
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c index a294d8d8bcd4..2c1ae861dc94 100644 --- a/fs/gfs2/lops.c +++ b/fs/gfs2/lops.c | |||
| @@ -75,7 +75,7 @@ static void maybe_release_space(struct gfs2_bufdata *bd) | |||
| 75 | unsigned int index = bd->bd_bh->b_blocknr - gl->gl_name.ln_number; | 75 | unsigned int index = bd->bd_bh->b_blocknr - gl->gl_name.ln_number; |
| 76 | struct gfs2_bitmap *bi = rgd->rd_bits + index; | 76 | struct gfs2_bitmap *bi = rgd->rd_bits + index; |
| 77 | 77 | ||
| 78 | if (bi->bi_clone == 0) | 78 | if (bi->bi_clone == NULL) |
| 79 | return; | 79 | return; |
| 80 | if (sdp->sd_args.ar_discard) | 80 | if (sdp->sd_args.ar_discard) |
| 81 | gfs2_rgrp_send_discards(sdp, rgd->rd_data0, bd->bd_bh, bi, 1, NULL); | 81 | gfs2_rgrp_send_discards(sdp, rgd->rd_data0, bd->bd_bh, bi, 1, NULL); |
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index 22f954051bb8..bc564c0d6d16 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c | |||
| @@ -94,6 +94,7 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb) | |||
| 94 | INIT_LIST_HEAD(&sdp->sd_jindex_list); | 94 | INIT_LIST_HEAD(&sdp->sd_jindex_list); |
| 95 | spin_lock_init(&sdp->sd_jindex_spin); | 95 | spin_lock_init(&sdp->sd_jindex_spin); |
| 96 | mutex_init(&sdp->sd_jindex_mutex); | 96 | mutex_init(&sdp->sd_jindex_mutex); |
| 97 | init_completion(&sdp->sd_journal_ready); | ||
| 97 | 98 | ||
| 98 | INIT_LIST_HEAD(&sdp->sd_quota_list); | 99 | INIT_LIST_HEAD(&sdp->sd_quota_list); |
| 99 | mutex_init(&sdp->sd_quota_mutex); | 100 | mutex_init(&sdp->sd_quota_mutex); |
| @@ -129,6 +130,10 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb) | |||
| 129 | init_rwsem(&sdp->sd_log_flush_lock); | 130 | init_rwsem(&sdp->sd_log_flush_lock); |
| 130 | atomic_set(&sdp->sd_log_in_flight, 0); | 131 | atomic_set(&sdp->sd_log_in_flight, 0); |
| 131 | init_waitqueue_head(&sdp->sd_log_flush_wait); | 132 | init_waitqueue_head(&sdp->sd_log_flush_wait); |
| 133 | init_waitqueue_head(&sdp->sd_log_frozen_wait); | ||
| 134 | atomic_set(&sdp->sd_log_freeze, 0); | ||
| 135 | atomic_set(&sdp->sd_frozen_root, 0); | ||
| 136 | init_waitqueue_head(&sdp->sd_frozen_root_wait); | ||
| 132 | 137 | ||
| 133 | return sdp; | 138 | return sdp; |
| 134 | } | 139 | } |
| @@ -419,8 +424,8 @@ static int init_locking(struct gfs2_sbd *sdp, struct gfs2_holder *mount_gh, | |||
| 419 | goto fail_live; | 424 | goto fail_live; |
| 420 | } | 425 | } |
| 421 | 426 | ||
| 422 | error = gfs2_glock_get(sdp, GFS2_TRANS_LOCK, &gfs2_trans_glops, | 427 | error = gfs2_glock_get(sdp, GFS2_FREEZE_LOCK, &gfs2_freeze_glops, |
| 423 | CREATE, &sdp->sd_trans_gl); | 428 | CREATE, &sdp->sd_freeze_gl); |
| 424 | if (error) { | 429 | if (error) { |
| 425 | fs_err(sdp, "can't create transaction glock: %d\n", error); | 430 | fs_err(sdp, "can't create transaction glock: %d\n", error); |
| 426 | goto fail_rename; | 431 | goto fail_rename; |
| @@ -429,7 +434,7 @@ static int init_locking(struct gfs2_sbd *sdp, struct gfs2_holder *mount_gh, | |||
| 429 | return 0; | 434 | return 0; |
| 430 | 435 | ||
| 431 | fail_trans: | 436 | fail_trans: |
| 432 | gfs2_glock_put(sdp->sd_trans_gl); | 437 | gfs2_glock_put(sdp->sd_freeze_gl); |
| 433 | fail_rename: | 438 | fail_rename: |
| 434 | gfs2_glock_put(sdp->sd_rename_gl); | 439 | gfs2_glock_put(sdp->sd_rename_gl); |
| 435 | fail_live: | 440 | fail_live: |
| @@ -755,7 +760,15 @@ static int init_journal(struct gfs2_sbd *sdp, int undo) | |||
| 755 | set_bit(SDF_JOURNAL_CHECKED, &sdp->sd_flags); | 760 | set_bit(SDF_JOURNAL_CHECKED, &sdp->sd_flags); |
| 756 | gfs2_glock_dq_uninit(&ji_gh); | 761 | gfs2_glock_dq_uninit(&ji_gh); |
| 757 | jindex = 0; | 762 | jindex = 0; |
| 758 | 763 | if (!sdp->sd_args.ar_spectator) { | |
| 764 | error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED, 0, | ||
| 765 | &sdp->sd_thaw_gh); | ||
| 766 | if (error) { | ||
| 767 | fs_err(sdp, "can't acquire freeze glock: %d\n", error); | ||
| 768 | goto fail_jinode_gh; | ||
| 769 | } | ||
| 770 | } | ||
| 771 | gfs2_glock_dq_uninit(&sdp->sd_thaw_gh); | ||
| 759 | return 0; | 772 | return 0; |
| 760 | 773 | ||
| 761 | fail_jinode_gh: | 774 | fail_jinode_gh: |
| @@ -784,6 +797,7 @@ static int init_inodes(struct gfs2_sbd *sdp, int undo) | |||
| 784 | goto fail_qinode; | 797 | goto fail_qinode; |
| 785 | 798 | ||
| 786 | error = init_journal(sdp, undo); | 799 | error = init_journal(sdp, undo); |
| 800 | complete_all(&sdp->sd_journal_ready); | ||
| 787 | if (error) | 801 | if (error) |
| 788 | goto fail; | 802 | goto fail; |
| 789 | 803 | ||
| @@ -1200,6 +1214,7 @@ fail_sb: | |||
| 1200 | fail_locking: | 1214 | fail_locking: |
| 1201 | init_locking(sdp, &mount_gh, UNDO); | 1215 | init_locking(sdp, &mount_gh, UNDO); |
| 1202 | fail_lm: | 1216 | fail_lm: |
| 1217 | complete_all(&sdp->sd_journal_ready); | ||
| 1203 | gfs2_gl_hash_clear(sdp); | 1218 | gfs2_gl_hash_clear(sdp); |
| 1204 | gfs2_lm_unmount(sdp); | 1219 | gfs2_lm_unmount(sdp); |
| 1205 | fail_debug: | 1220 | fail_debug: |
| @@ -1380,7 +1395,7 @@ static void gfs2_kill_sb(struct super_block *sb) | |||
| 1380 | return; | 1395 | return; |
| 1381 | } | 1396 | } |
| 1382 | 1397 | ||
| 1383 | gfs2_meta_syncfs(sdp); | 1398 | gfs2_log_flush(sdp, NULL, SYNC_FLUSH); |
| 1384 | dput(sdp->sd_root_dir); | 1399 | dput(sdp->sd_root_dir); |
| 1385 | dput(sdp->sd_master_dir); | 1400 | dput(sdp->sd_master_dir); |
| 1386 | sdp->sd_root_dir = NULL; | 1401 | sdp->sd_root_dir = NULL; |
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index c4effff7cf55..64b29f7f6b4c 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c | |||
| @@ -778,6 +778,7 @@ get_a_page: | |||
| 778 | i_size_write(inode, size); | 778 | i_size_write(inode, size); |
| 779 | inode->i_mtime = inode->i_atime = CURRENT_TIME; | 779 | inode->i_mtime = inode->i_atime = CURRENT_TIME; |
| 780 | mark_inode_dirty(inode); | 780 | mark_inode_dirty(inode); |
| 781 | set_bit(QDF_REFRESH, &qd->qd_flags); | ||
| 781 | return 0; | 782 | return 0; |
| 782 | 783 | ||
| 783 | unlock_out: | 784 | unlock_out: |
| @@ -879,7 +880,7 @@ out: | |||
| 879 | gfs2_glock_dq_uninit(&ghs[qx]); | 880 | gfs2_glock_dq_uninit(&ghs[qx]); |
| 880 | mutex_unlock(&ip->i_inode.i_mutex); | 881 | mutex_unlock(&ip->i_inode.i_mutex); |
| 881 | kfree(ghs); | 882 | kfree(ghs); |
| 882 | gfs2_log_flush(ip->i_gl->gl_sbd, ip->i_gl); | 883 | gfs2_log_flush(ip->i_gl->gl_sbd, ip->i_gl, NORMAL_FLUSH); |
| 883 | return error; | 884 | return error; |
| 884 | } | 885 | } |
| 885 | 886 | ||
diff --git a/fs/gfs2/recovery.c b/fs/gfs2/recovery.c index fe7a56fb6084..94555d4c5698 100644 --- a/fs/gfs2/recovery.c +++ b/fs/gfs2/recovery.c | |||
| @@ -454,7 +454,7 @@ void gfs2_recover_func(struct work_struct *work) | |||
| 454 | struct gfs2_inode *ip = GFS2_I(jd->jd_inode); | 454 | struct gfs2_inode *ip = GFS2_I(jd->jd_inode); |
| 455 | struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode); | 455 | struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode); |
| 456 | struct gfs2_log_header_host head; | 456 | struct gfs2_log_header_host head; |
| 457 | struct gfs2_holder j_gh, ji_gh, t_gh; | 457 | struct gfs2_holder j_gh, ji_gh, thaw_gh; |
| 458 | unsigned long t; | 458 | unsigned long t; |
| 459 | int ro = 0; | 459 | int ro = 0; |
| 460 | unsigned int pass; | 460 | unsigned int pass; |
| @@ -508,11 +508,11 @@ void gfs2_recover_func(struct work_struct *work) | |||
| 508 | 508 | ||
| 509 | t = jiffies; | 509 | t = jiffies; |
| 510 | 510 | ||
| 511 | /* Acquire a shared hold on the transaction lock */ | 511 | /* Acquire a shared hold on the freeze lock */ |
| 512 | 512 | ||
| 513 | error = gfs2_glock_nq_init(sdp->sd_trans_gl, LM_ST_SHARED, | 513 | error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED, |
| 514 | LM_FLAG_NOEXP | LM_FLAG_PRIORITY | | 514 | LM_FLAG_NOEXP | LM_FLAG_PRIORITY, |
| 515 | GL_NOCACHE, &t_gh); | 515 | &thaw_gh); |
| 516 | if (error) | 516 | if (error) |
| 517 | goto fail_gunlock_ji; | 517 | goto fail_gunlock_ji; |
| 518 | 518 | ||
| @@ -538,7 +538,7 @@ void gfs2_recover_func(struct work_struct *work) | |||
| 538 | fs_warn(sdp, "jid=%u: Can't replay: read-only block " | 538 | fs_warn(sdp, "jid=%u: Can't replay: read-only block " |
| 539 | "device\n", jd->jd_jid); | 539 | "device\n", jd->jd_jid); |
| 540 | error = -EROFS; | 540 | error = -EROFS; |
| 541 | goto fail_gunlock_tr; | 541 | goto fail_gunlock_thaw; |
| 542 | } | 542 | } |
| 543 | 543 | ||
| 544 | fs_info(sdp, "jid=%u: Replaying journal...\n", jd->jd_jid); | 544 | fs_info(sdp, "jid=%u: Replaying journal...\n", jd->jd_jid); |
| @@ -549,14 +549,14 @@ void gfs2_recover_func(struct work_struct *work) | |||
| 549 | head.lh_blkno, pass); | 549 | head.lh_blkno, pass); |
| 550 | lops_after_scan(jd, error, pass); | 550 | lops_after_scan(jd, error, pass); |
| 551 | if (error) | 551 | if (error) |
| 552 | goto fail_gunlock_tr; | 552 | goto fail_gunlock_thaw; |
| 553 | } | 553 | } |
| 554 | 554 | ||
| 555 | error = clean_journal(jd, &head); | 555 | error = clean_journal(jd, &head); |
| 556 | if (error) | 556 | if (error) |
| 557 | goto fail_gunlock_tr; | 557 | goto fail_gunlock_thaw; |
| 558 | 558 | ||
| 559 | gfs2_glock_dq_uninit(&t_gh); | 559 | gfs2_glock_dq_uninit(&thaw_gh); |
| 560 | t = DIV_ROUND_UP(jiffies - t, HZ); | 560 | t = DIV_ROUND_UP(jiffies - t, HZ); |
| 561 | fs_info(sdp, "jid=%u: Journal replayed in %lus\n", | 561 | fs_info(sdp, "jid=%u: Journal replayed in %lus\n", |
| 562 | jd->jd_jid, t); | 562 | jd->jd_jid, t); |
| @@ -572,8 +572,8 @@ void gfs2_recover_func(struct work_struct *work) | |||
| 572 | fs_info(sdp, "jid=%u: Done\n", jd->jd_jid); | 572 | fs_info(sdp, "jid=%u: Done\n", jd->jd_jid); |
| 573 | goto done; | 573 | goto done; |
| 574 | 574 | ||
| 575 | fail_gunlock_tr: | 575 | fail_gunlock_thaw: |
| 576 | gfs2_glock_dq_uninit(&t_gh); | 576 | gfs2_glock_dq_uninit(&thaw_gh); |
| 577 | fail_gunlock_ji: | 577 | fail_gunlock_ji: |
| 578 | if (jlocked) { | 578 | if (jlocked) { |
| 579 | gfs2_glock_dq_uninit(&ji_gh); | 579 | gfs2_glock_dq_uninit(&ji_gh); |
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 281a7716e3f3..db629d1bd1bd 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c | |||
| @@ -2001,7 +2001,7 @@ next_rgrp: | |||
| 2001 | } | 2001 | } |
| 2002 | /* Flushing the log may release space */ | 2002 | /* Flushing the log may release space */ |
| 2003 | if (loops == 2) | 2003 | if (loops == 2) |
| 2004 | gfs2_log_flush(sdp, NULL); | 2004 | gfs2_log_flush(sdp, NULL, NORMAL_FLUSH); |
| 2005 | } | 2005 | } |
| 2006 | 2006 | ||
| 2007 | return -ENOSPC; | 2007 | return -ENOSPC; |
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index de8afad89e51..1319b5c4ec68 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c | |||
| @@ -399,7 +399,7 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp) | |||
| 399 | { | 399 | { |
| 400 | struct gfs2_inode *ip = GFS2_I(sdp->sd_jdesc->jd_inode); | 400 | struct gfs2_inode *ip = GFS2_I(sdp->sd_jdesc->jd_inode); |
| 401 | struct gfs2_glock *j_gl = ip->i_gl; | 401 | struct gfs2_glock *j_gl = ip->i_gl; |
| 402 | struct gfs2_holder t_gh; | 402 | struct gfs2_holder thaw_gh; |
| 403 | struct gfs2_log_header_host head; | 403 | struct gfs2_log_header_host head; |
| 404 | int error; | 404 | int error; |
| 405 | 405 | ||
| @@ -407,7 +407,8 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp) | |||
| 407 | if (error) | 407 | if (error) |
| 408 | return error; | 408 | return error; |
| 409 | 409 | ||
| 410 | error = gfs2_glock_nq_init(sdp->sd_trans_gl, LM_ST_SHARED, 0, &t_gh); | 410 | error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED, 0, |
| 411 | &thaw_gh); | ||
| 411 | if (error) | 412 | if (error) |
| 412 | goto fail_threads; | 413 | goto fail_threads; |
| 413 | 414 | ||
| @@ -433,13 +434,13 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp) | |||
| 433 | 434 | ||
| 434 | set_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags); | 435 | set_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags); |
| 435 | 436 | ||
| 436 | gfs2_glock_dq_uninit(&t_gh); | 437 | gfs2_glock_dq_uninit(&thaw_gh); |
| 437 | 438 | ||
| 438 | return 0; | 439 | return 0; |
| 439 | 440 | ||
| 440 | fail: | 441 | fail: |
| 441 | t_gh.gh_flags |= GL_NOCACHE; | 442 | thaw_gh.gh_flags |= GL_NOCACHE; |
| 442 | gfs2_glock_dq_uninit(&t_gh); | 443 | gfs2_glock_dq_uninit(&thaw_gh); |
| 443 | fail_threads: | 444 | fail_threads: |
| 444 | kthread_stop(sdp->sd_quotad_process); | 445 | kthread_stop(sdp->sd_quotad_process); |
| 445 | kthread_stop(sdp->sd_logd_process); | 446 | kthread_stop(sdp->sd_logd_process); |
| @@ -635,15 +636,21 @@ struct lfcc { | |||
| 635 | */ | 636 | */ |
| 636 | 637 | ||
| 637 | static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp, | 638 | static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp, |
| 638 | struct gfs2_holder *t_gh) | 639 | struct gfs2_holder *freeze_gh) |
| 639 | { | 640 | { |
| 640 | struct gfs2_inode *ip; | 641 | struct gfs2_inode *ip; |
| 641 | struct gfs2_jdesc *jd; | 642 | struct gfs2_jdesc *jd; |
| 642 | struct lfcc *lfcc; | 643 | struct lfcc *lfcc; |
| 643 | LIST_HEAD(list); | 644 | LIST_HEAD(list); |
| 644 | struct gfs2_log_header_host lh; | 645 | struct gfs2_log_header_host lh; |
| 646 | struct gfs2_inode *dip = GFS2_I(sdp->sd_root_dir->d_inode); | ||
| 645 | int error; | 647 | int error; |
| 646 | 648 | ||
| 649 | error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, | ||
| 650 | &sdp->sd_freeze_root_gh); | ||
| 651 | if (error) | ||
| 652 | return error; | ||
| 653 | atomic_set(&sdp->sd_frozen_root, 1); | ||
| 647 | list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) { | 654 | list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) { |
| 648 | lfcc = kmalloc(sizeof(struct lfcc), GFP_KERNEL); | 655 | lfcc = kmalloc(sizeof(struct lfcc), GFP_KERNEL); |
| 649 | if (!lfcc) { | 656 | if (!lfcc) { |
| @@ -659,8 +666,8 @@ static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp, | |||
| 659 | list_add(&lfcc->list, &list); | 666 | list_add(&lfcc->list, &list); |
| 660 | } | 667 | } |
| 661 | 668 | ||
| 662 | error = gfs2_glock_nq_init(sdp->sd_trans_gl, LM_ST_DEFERRED, | 669 | error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_EXCLUSIVE, |
| 663 | GL_NOCACHE, t_gh); | 670 | GL_NOCACHE, freeze_gh); |
| 664 | 671 | ||
| 665 | list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) { | 672 | list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) { |
| 666 | error = gfs2_jdesc_check(jd); | 673 | error = gfs2_jdesc_check(jd); |
| @@ -676,7 +683,7 @@ static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp, | |||
| 676 | } | 683 | } |
| 677 | 684 | ||
| 678 | if (error) | 685 | if (error) |
| 679 | gfs2_glock_dq_uninit(t_gh); | 686 | gfs2_glock_dq_uninit(freeze_gh); |
| 680 | 687 | ||
| 681 | out: | 688 | out: |
| 682 | while (!list_empty(&list)) { | 689 | while (!list_empty(&list)) { |
| @@ -685,6 +692,11 @@ out: | |||
| 685 | gfs2_glock_dq_uninit(&lfcc->gh); | 692 | gfs2_glock_dq_uninit(&lfcc->gh); |
| 686 | kfree(lfcc); | 693 | kfree(lfcc); |
| 687 | } | 694 | } |
| 695 | if (error) { | ||
| 696 | atomic_dec(&sdp->sd_frozen_root); | ||
| 697 | wait_event(sdp->sd_frozen_root_wait, atomic_read(&sdp->sd_frozen_root) == 0); | ||
| 698 | gfs2_glock_dq_uninit(&sdp->sd_freeze_root_gh); | ||
| 699 | } | ||
| 688 | return error; | 700 | return error; |
| 689 | } | 701 | } |
| 690 | 702 | ||
| @@ -742,7 +754,7 @@ static int gfs2_write_inode(struct inode *inode, struct writeback_control *wbc) | |||
| 742 | int ret = 0; | 754 | int ret = 0; |
| 743 | 755 | ||
| 744 | if (wbc->sync_mode == WB_SYNC_ALL) | 756 | if (wbc->sync_mode == WB_SYNC_ALL) |
| 745 | gfs2_log_flush(GFS2_SB(inode), ip->i_gl); | 757 | gfs2_log_flush(GFS2_SB(inode), ip->i_gl, NORMAL_FLUSH); |
| 746 | if (bdi->dirty_exceeded) | 758 | if (bdi->dirty_exceeded) |
| 747 | gfs2_ail1_flush(sdp, wbc); | 759 | gfs2_ail1_flush(sdp, wbc); |
| 748 | else | 760 | else |
| @@ -822,9 +834,18 @@ out: | |||
| 822 | 834 | ||
| 823 | static int gfs2_make_fs_ro(struct gfs2_sbd *sdp) | 835 | static int gfs2_make_fs_ro(struct gfs2_sbd *sdp) |
| 824 | { | 836 | { |
| 825 | struct gfs2_holder t_gh; | 837 | struct gfs2_holder thaw_gh; |
| 826 | int error; | 838 | int error; |
| 827 | 839 | ||
| 840 | error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED, GL_NOCACHE, | ||
| 841 | &thaw_gh); | ||
| 842 | if (error && !test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) | ||
| 843 | return error; | ||
| 844 | |||
| 845 | down_write(&sdp->sd_log_flush_lock); | ||
| 846 | clear_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags); | ||
| 847 | up_write(&sdp->sd_log_flush_lock); | ||
| 848 | |||
| 828 | kthread_stop(sdp->sd_quotad_process); | 849 | kthread_stop(sdp->sd_quotad_process); |
| 829 | kthread_stop(sdp->sd_logd_process); | 850 | kthread_stop(sdp->sd_logd_process); |
| 830 | 851 | ||
| @@ -832,18 +853,11 @@ static int gfs2_make_fs_ro(struct gfs2_sbd *sdp) | |||
| 832 | gfs2_quota_sync(sdp->sd_vfs, 0); | 853 | gfs2_quota_sync(sdp->sd_vfs, 0); |
| 833 | gfs2_statfs_sync(sdp->sd_vfs, 0); | 854 | gfs2_statfs_sync(sdp->sd_vfs, 0); |
| 834 | 855 | ||
| 835 | error = gfs2_glock_nq_init(sdp->sd_trans_gl, LM_ST_SHARED, GL_NOCACHE, | 856 | gfs2_log_flush(sdp, NULL, SHUTDOWN_FLUSH); |
| 836 | &t_gh); | 857 | gfs2_assert_warn(sdp, atomic_read(&sdp->sd_log_blks_free) == sdp->sd_jdesc->jd_blocks); |
| 837 | if (error && !test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) | ||
| 838 | return error; | ||
| 839 | |||
| 840 | gfs2_meta_syncfs(sdp); | ||
| 841 | gfs2_log_shutdown(sdp); | ||
| 842 | |||
| 843 | clear_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags); | ||
| 844 | 858 | ||
| 845 | if (t_gh.gh_gl) | 859 | if (thaw_gh.gh_gl) |
| 846 | gfs2_glock_dq_uninit(&t_gh); | 860 | gfs2_glock_dq_uninit(&thaw_gh); |
| 847 | 861 | ||
| 848 | gfs2_quota_cleanup(sdp); | 862 | gfs2_quota_cleanup(sdp); |
| 849 | 863 | ||
| @@ -900,7 +914,7 @@ restart: | |||
| 900 | iput(sdp->sd_quota_inode); | 914 | iput(sdp->sd_quota_inode); |
| 901 | 915 | ||
| 902 | gfs2_glock_put(sdp->sd_rename_gl); | 916 | gfs2_glock_put(sdp->sd_rename_gl); |
| 903 | gfs2_glock_put(sdp->sd_trans_gl); | 917 | gfs2_glock_put(sdp->sd_freeze_gl); |
| 904 | 918 | ||
| 905 | if (!sdp->sd_args.ar_spectator) { | 919 | if (!sdp->sd_args.ar_spectator) { |
| 906 | gfs2_glock_dq_uninit(&sdp->sd_journal_gh); | 920 | gfs2_glock_dq_uninit(&sdp->sd_journal_gh); |
| @@ -935,8 +949,8 @@ static int gfs2_sync_fs(struct super_block *sb, int wait) | |||
| 935 | struct gfs2_sbd *sdp = sb->s_fs_info; | 949 | struct gfs2_sbd *sdp = sb->s_fs_info; |
| 936 | 950 | ||
| 937 | gfs2_quota_sync(sb, -1); | 951 | gfs2_quota_sync(sb, -1); |
| 938 | if (wait && sdp) | 952 | if (wait && sdp && !atomic_read(&sdp->sd_log_freeze)) |
| 939 | gfs2_log_flush(sdp, NULL); | 953 | gfs2_log_flush(sdp, NULL, NORMAL_FLUSH); |
| 940 | return 0; | 954 | return 0; |
| 941 | } | 955 | } |
| 942 | 956 | ||
| @@ -986,6 +1000,9 @@ static int gfs2_unfreeze(struct super_block *sb) | |||
| 986 | struct gfs2_sbd *sdp = sb->s_fs_info; | 1000 | struct gfs2_sbd *sdp = sb->s_fs_info; |
| 987 | 1001 | ||
| 988 | gfs2_glock_dq_uninit(&sdp->sd_freeze_gh); | 1002 | gfs2_glock_dq_uninit(&sdp->sd_freeze_gh); |
| 1003 | atomic_dec(&sdp->sd_frozen_root); | ||
| 1004 | wait_event(sdp->sd_frozen_root_wait, atomic_read(&sdp->sd_frozen_root) == 0); | ||
| 1005 | gfs2_glock_dq_uninit(&sdp->sd_freeze_root_gh); | ||
| 989 | return 0; | 1006 | return 0; |
| 990 | } | 1007 | } |
| 991 | 1008 | ||
| @@ -1525,7 +1542,7 @@ static void gfs2_evict_inode(struct inode *inode) | |||
| 1525 | goto out_unlock; | 1542 | goto out_unlock; |
| 1526 | 1543 | ||
| 1527 | out_truncate: | 1544 | out_truncate: |
| 1528 | gfs2_log_flush(sdp, ip->i_gl); | 1545 | gfs2_log_flush(sdp, ip->i_gl, NORMAL_FLUSH); |
| 1529 | if (test_bit(GLF_DIRTY, &ip->i_gl->gl_flags)) { | 1546 | if (test_bit(GLF_DIRTY, &ip->i_gl->gl_flags)) { |
| 1530 | struct address_space *metamapping = gfs2_glock2aspace(ip->i_gl); | 1547 | struct address_space *metamapping = gfs2_glock2aspace(ip->i_gl); |
| 1531 | filemap_fdatawrite(metamapping); | 1548 | filemap_fdatawrite(metamapping); |
diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c index 529d9a9eb897..3ab566ba5696 100644 --- a/fs/gfs2/sys.c +++ b/fs/gfs2/sys.c | |||
| @@ -240,8 +240,8 @@ static ssize_t demote_rq_store(struct gfs2_sbd *sdp, const char *buf, size_t len | |||
| 240 | 240 | ||
| 241 | if (gltype > LM_TYPE_JOURNAL) | 241 | if (gltype > LM_TYPE_JOURNAL) |
| 242 | return -EINVAL; | 242 | return -EINVAL; |
| 243 | if (gltype == LM_TYPE_NONDISK && glnum == GFS2_TRANS_LOCK) | 243 | if (gltype == LM_TYPE_NONDISK && glnum == GFS2_FREEZE_LOCK) |
| 244 | glops = &gfs2_trans_glops; | 244 | glops = &gfs2_freeze_glops; |
| 245 | else | 245 | else |
| 246 | glops = gfs2_glops_list[gltype]; | 246 | glops = gfs2_glops_list[gltype]; |
| 247 | if (glops == NULL) | 247 | if (glops == NULL) |
| @@ -407,6 +407,9 @@ int gfs2_recover_set(struct gfs2_sbd *sdp, unsigned jid) | |||
| 407 | struct gfs2_jdesc *jd; | 407 | struct gfs2_jdesc *jd; |
| 408 | int rv; | 408 | int rv; |
| 409 | 409 | ||
| 410 | /* Wait for our primary journal to be initialized */ | ||
| 411 | wait_for_completion(&sdp->sd_journal_ready); | ||
| 412 | |||
| 410 | spin_lock(&sdp->sd_jindex_spin); | 413 | spin_lock(&sdp->sd_jindex_spin); |
| 411 | rv = -EBUSY; | 414 | rv = -EBUSY; |
| 412 | if (sdp->sd_jdesc->jd_jid == jid) | 415 | if (sdp->sd_jdesc->jd_jid == jid) |
diff --git a/fs/gfs2/trans.c b/fs/gfs2/trans.c index bead90d27bad..0546ab4e28e8 100644 --- a/fs/gfs2/trans.c +++ b/fs/gfs2/trans.c | |||
| @@ -48,6 +48,7 @@ int gfs2_trans_begin(struct gfs2_sbd *sdp, unsigned int blocks, | |||
| 48 | tr->tr_blocks = blocks; | 48 | tr->tr_blocks = blocks; |
| 49 | tr->tr_revokes = revokes; | 49 | tr->tr_revokes = revokes; |
| 50 | tr->tr_reserved = 1; | 50 | tr->tr_reserved = 1; |
| 51 | tr->tr_alloced = 1; | ||
| 51 | if (blocks) | 52 | if (blocks) |
| 52 | tr->tr_reserved += 6 + blocks; | 53 | tr->tr_reserved += 6 + blocks; |
| 53 | if (revokes) | 54 | if (revokes) |
| @@ -57,48 +58,22 @@ int gfs2_trans_begin(struct gfs2_sbd *sdp, unsigned int blocks, | |||
| 57 | INIT_LIST_HEAD(&tr->tr_buf); | 58 | INIT_LIST_HEAD(&tr->tr_buf); |
| 58 | 59 | ||
| 59 | sb_start_intwrite(sdp->sd_vfs); | 60 | sb_start_intwrite(sdp->sd_vfs); |
| 60 | gfs2_holder_init(sdp->sd_trans_gl, LM_ST_SHARED, 0, &tr->tr_t_gh); | ||
| 61 | |||
| 62 | error = gfs2_glock_nq(&tr->tr_t_gh); | ||
| 63 | if (error) | ||
| 64 | goto fail_holder_uninit; | ||
| 65 | 61 | ||
| 66 | error = gfs2_log_reserve(sdp, tr->tr_reserved); | 62 | error = gfs2_log_reserve(sdp, tr->tr_reserved); |
| 67 | if (error) | 63 | if (error) |
| 68 | goto fail_gunlock; | 64 | goto fail; |
| 69 | 65 | ||
| 70 | current->journal_info = tr; | 66 | current->journal_info = tr; |
| 71 | 67 | ||
| 72 | return 0; | 68 | return 0; |
| 73 | 69 | ||
| 74 | fail_gunlock: | 70 | fail: |
| 75 | gfs2_glock_dq(&tr->tr_t_gh); | ||
| 76 | |||
| 77 | fail_holder_uninit: | ||
| 78 | sb_end_intwrite(sdp->sd_vfs); | 71 | sb_end_intwrite(sdp->sd_vfs); |
| 79 | gfs2_holder_uninit(&tr->tr_t_gh); | ||
| 80 | kfree(tr); | 72 | kfree(tr); |
| 81 | 73 | ||
| 82 | return error; | 74 | return error; |
| 83 | } | 75 | } |
| 84 | 76 | ||
| 85 | /** | ||
| 86 | * gfs2_log_release - Release a given number of log blocks | ||
| 87 | * @sdp: The GFS2 superblock | ||
| 88 | * @blks: The number of blocks | ||
| 89 | * | ||
| 90 | */ | ||
| 91 | |||
| 92 | static void gfs2_log_release(struct gfs2_sbd *sdp, unsigned int blks) | ||
| 93 | { | ||
| 94 | |||
| 95 | atomic_add(blks, &sdp->sd_log_blks_free); | ||
| 96 | trace_gfs2_log_blocks(sdp, blks); | ||
| 97 | gfs2_assert_withdraw(sdp, atomic_read(&sdp->sd_log_blks_free) <= | ||
| 98 | sdp->sd_jdesc->jd_blocks); | ||
| 99 | up_read(&sdp->sd_log_flush_lock); | ||
| 100 | } | ||
| 101 | |||
| 102 | static void gfs2_print_trans(const struct gfs2_trans *tr) | 77 | static void gfs2_print_trans(const struct gfs2_trans *tr) |
| 103 | { | 78 | { |
| 104 | pr_warn("Transaction created at: %pSR\n", (void *)tr->tr_ip); | 79 | pr_warn("Transaction created at: %pSR\n", (void *)tr->tr_ip); |
| @@ -119,11 +94,8 @@ void gfs2_trans_end(struct gfs2_sbd *sdp) | |||
| 119 | 94 | ||
| 120 | if (!tr->tr_touched) { | 95 | if (!tr->tr_touched) { |
| 121 | gfs2_log_release(sdp, tr->tr_reserved); | 96 | gfs2_log_release(sdp, tr->tr_reserved); |
| 122 | if (tr->tr_t_gh.gh_gl) { | 97 | if (tr->tr_alloced) |
| 123 | gfs2_glock_dq(&tr->tr_t_gh); | ||
| 124 | gfs2_holder_uninit(&tr->tr_t_gh); | ||
| 125 | kfree(tr); | 98 | kfree(tr); |
| 126 | } | ||
| 127 | sb_end_intwrite(sdp->sd_vfs); | 99 | sb_end_intwrite(sdp->sd_vfs); |
| 128 | return; | 100 | return; |
| 129 | } | 101 | } |
| @@ -137,16 +109,12 @@ void gfs2_trans_end(struct gfs2_sbd *sdp) | |||
| 137 | gfs2_print_trans(tr); | 109 | gfs2_print_trans(tr); |
| 138 | 110 | ||
| 139 | gfs2_log_commit(sdp, tr); | 111 | gfs2_log_commit(sdp, tr); |
| 140 | if (tr->tr_t_gh.gh_gl) { | 112 | if (tr->tr_alloced && !tr->tr_attached) |
| 141 | gfs2_glock_dq(&tr->tr_t_gh); | ||
| 142 | gfs2_holder_uninit(&tr->tr_t_gh); | ||
| 143 | if (!tr->tr_attached) | ||
| 144 | kfree(tr); | 113 | kfree(tr); |
| 145 | } | ||
| 146 | up_read(&sdp->sd_log_flush_lock); | 114 | up_read(&sdp->sd_log_flush_lock); |
| 147 | 115 | ||
| 148 | if (sdp->sd_vfs->s_flags & MS_SYNCHRONOUS) | 116 | if (sdp->sd_vfs->s_flags & MS_SYNCHRONOUS) |
| 149 | gfs2_log_flush(sdp, NULL); | 117 | gfs2_log_flush(sdp, NULL, NORMAL_FLUSH); |
| 150 | sb_end_intwrite(sdp->sd_vfs); | 118 | sb_end_intwrite(sdp->sd_vfs); |
| 151 | } | 119 | } |
| 152 | 120 | ||
diff --git a/include/uapi/linux/gfs2_ondisk.h b/include/uapi/linux/gfs2_ondisk.h index db3fdd083882..1a763eaae0bb 100644 --- a/include/uapi/linux/gfs2_ondisk.h +++ b/include/uapi/linux/gfs2_ondisk.h | |||
| @@ -20,7 +20,7 @@ | |||
| 20 | 20 | ||
| 21 | #define GFS2_MOUNT_LOCK 0 | 21 | #define GFS2_MOUNT_LOCK 0 |
| 22 | #define GFS2_LIVE_LOCK 1 | 22 | #define GFS2_LIVE_LOCK 1 |
| 23 | #define GFS2_TRANS_LOCK 2 | 23 | #define GFS2_FREEZE_LOCK 2 |
| 24 | #define GFS2_RENAME_LOCK 3 | 24 | #define GFS2_RENAME_LOCK 3 |
| 25 | #define GFS2_CONTROL_LOCK 4 | 25 | #define GFS2_CONTROL_LOCK 4 |
| 26 | #define GFS2_MOUNTED_LOCK 5 | 26 | #define GFS2_MOUNTED_LOCK 5 |
