aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2')
-rw-r--r--fs/gfs2/glops.c4
-rw-r--r--fs/gfs2/log.c6
-rw-r--r--fs/gfs2/ops_address.c132
-rw-r--r--fs/gfs2/ops_fstype.c2
4 files changed, 24 insertions, 120 deletions
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
index 777ca46010e8..88342e0b4bc7 100644
--- a/fs/gfs2/glops.c
+++ b/fs/gfs2/glops.c
@@ -156,9 +156,11 @@ static void inode_go_sync(struct gfs2_glock *gl)
156 ip = NULL; 156 ip = NULL;
157 157
158 if (test_bit(GLF_DIRTY, &gl->gl_flags)) { 158 if (test_bit(GLF_DIRTY, &gl->gl_flags)) {
159 if (ip) 159 if (ip && !gfs2_is_jdata(ip))
160 filemap_fdatawrite(ip->i_inode.i_mapping); 160 filemap_fdatawrite(ip->i_inode.i_mapping);
161 gfs2_log_flush(gl->gl_sbd, gl); 161 gfs2_log_flush(gl->gl_sbd, gl);
162 if (ip && gfs2_is_jdata(ip))
163 filemap_fdatawrite(ip->i_inode.i_mapping);
162 gfs2_meta_sync(gl); 164 gfs2_meta_sync(gl);
163 if (ip) { 165 if (ip) {
164 struct address_space *mapping = ip->i_inode.i_mapping; 166 struct address_space *mapping = ip->i_inode.i_mapping;
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
index 00ab6c070a15..d0e6b42c86e1 100644
--- a/fs/gfs2/log.c
+++ b/fs/gfs2/log.c
@@ -229,8 +229,10 @@ static void gfs2_ail2_empty_one(struct gfs2_sbd *sdp, struct gfs2_ail *ai)
229 list_del(&bd->bd_ail_st_list); 229 list_del(&bd->bd_ail_st_list);
230 list_del(&bd->bd_ail_gl_list); 230 list_del(&bd->bd_ail_gl_list);
231 atomic_dec(&bd->bd_gl->gl_ail_count); 231 atomic_dec(&bd->bd_gl->gl_ail_count);
232 bh_ip = GFS2_I(bd->bd_bh->b_page->mapping->host); 232 if (bd->bd_bh->b_page->mapping) {
233 gfs2_meta_cache_flush(bh_ip); 233 bh_ip = GFS2_I(bd->bd_bh->b_page->mapping->host);
234 gfs2_meta_cache_flush(bh_ip);
235 }
234 brelse(bd->bd_bh); 236 brelse(bd->bd_bh);
235 } 237 }
236} 238}
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c
index 42a5f58f6fca..8407d1db4eac 100644
--- a/fs/gfs2/ops_address.c
+++ b/fs/gfs2/ops_address.c
@@ -616,58 +616,13 @@ static sector_t gfs2_bmap(struct address_space *mapping, sector_t lblock)
616 return dblock; 616 return dblock;
617} 617}
618 618
619static void discard_buffer(struct gfs2_sbd *sdp, struct buffer_head *bh)
620{
621 struct gfs2_bufdata *bd;
622
623 gfs2_log_lock(sdp);
624 bd = bh->b_private;
625 if (bd) {
626 bd->bd_bh = NULL;
627 bh->b_private = NULL;
628 if (!bd->bd_ail && list_empty(&bd->bd_le.le_list))
629 kmem_cache_free(gfs2_bufdata_cachep, bd);
630 }
631 gfs2_log_unlock(sdp);
632
633 lock_buffer(bh);
634 clear_buffer_dirty(bh);
635 bh->b_bdev = NULL;
636 clear_buffer_mapped(bh);
637 clear_buffer_req(bh);
638 clear_buffer_new(bh);
639 clear_buffer_delay(bh);
640 unlock_buffer(bh);
641}
642
643static void gfs2_invalidatepage(struct page *page, unsigned long offset) 619static void gfs2_invalidatepage(struct page *page, unsigned long offset)
644{ 620{
645 struct gfs2_sbd *sdp = GFS2_SB(page->mapping->host);
646 struct buffer_head *head, *bh, *next;
647 unsigned int curr_off = 0;
648
649 BUG_ON(!PageLocked(page)); 621 BUG_ON(!PageLocked(page));
650 if (offset == 0) 622 if (offset == 0)
651 ClearPageChecked(page); 623 ClearPageChecked(page);
652 if (!page_has_buffers(page))
653 return;
654 624
655 bh = head = page_buffers(page); 625 block_invalidatepage(page, offset);
656 do {
657 unsigned int next_off = curr_off + bh->b_size;
658 next = bh->b_this_page;
659
660 if (offset <= curr_off)
661 discard_buffer(sdp, bh);
662
663 curr_off = next_off;
664 bh = next;
665 } while (bh != head);
666
667 if (!offset)
668 try_to_release_page(page, 0);
669
670 return;
671} 626}
672 627
673/** 628/**
@@ -736,59 +691,6 @@ out:
736} 691}
737 692
738/** 693/**
739 * stuck_releasepage - We're stuck in gfs2_releasepage(). Print stuff out.
740 * @bh: the buffer we're stuck on
741 *
742 */
743
744static void stuck_releasepage(struct buffer_head *bh)
745{
746 struct inode *inode = bh->b_page->mapping->host;
747 struct gfs2_sbd *sdp = inode->i_sb->s_fs_info;
748 struct gfs2_bufdata *bd = bh->b_private;
749 struct gfs2_glock *gl;
750static unsigned limit = 0;
751
752 if (limit > 3)
753 return;
754 limit++;
755
756 fs_warn(sdp, "stuck in gfs2_releasepage() %p\n", inode);
757 fs_warn(sdp, "blkno = %llu, bh->b_count = %d\n",
758 (unsigned long long)bh->b_blocknr, atomic_read(&bh->b_count));
759 fs_warn(sdp, "pinned = %u\n", buffer_pinned(bh));
760 fs_warn(sdp, "bh->b_private = %s\n", (bd) ? "!NULL" : "NULL");
761
762 if (!bd)
763 return;
764
765 gl = bd->bd_gl;
766
767 fs_warn(sdp, "gl = (%u, %llu)\n",
768 gl->gl_name.ln_type, (unsigned long long)gl->gl_name.ln_number);
769
770 fs_warn(sdp, "bd_list_tr = %s, bd_le.le_list = %s\n",
771 (list_empty(&bd->bd_list_tr)) ? "no" : "yes",
772 (list_empty(&bd->bd_le.le_list)) ? "no" : "yes");
773
774 if (gl->gl_ops == &gfs2_inode_glops) {
775 struct gfs2_inode *ip = gl->gl_object;
776 unsigned int x;
777
778 if (!ip)
779 return;
780
781 fs_warn(sdp, "ip = %llu %llu\n",
782 (unsigned long long)ip->i_no_formal_ino,
783 (unsigned long long)ip->i_no_addr);
784
785 for (x = 0; x < GFS2_MAX_META_HEIGHT; x++)
786 fs_warn(sdp, "ip->i_cache[%u] = %s\n",
787 x, (ip->i_cache[x]) ? "!NULL" : "NULL");
788 }
789}
790
791/**
792 * gfs2_releasepage - free the metadata associated with a page 694 * gfs2_releasepage - free the metadata associated with a page
793 * @page: the page that's being released 695 * @page: the page that's being released
794 * @gfp_mask: passed from Linux VFS, ignored by us 696 * @gfp_mask: passed from Linux VFS, ignored by us
@@ -805,38 +707,31 @@ int gfs2_releasepage(struct page *page, gfp_t gfp_mask)
805 struct gfs2_sbd *sdp = aspace->i_sb->s_fs_info; 707 struct gfs2_sbd *sdp = aspace->i_sb->s_fs_info;
806 struct buffer_head *bh, *head; 708 struct buffer_head *bh, *head;
807 struct gfs2_bufdata *bd; 709 struct gfs2_bufdata *bd;
808 unsigned long t = jiffies + gfs2_tune_get(sdp, gt_stall_secs) * HZ;
809 710
810 if (!page_has_buffers(page)) 711 if (!page_has_buffers(page))
811 goto out; 712 goto out;
812 713
714 gfs2_log_lock(sdp);
813 head = bh = page_buffers(page); 715 head = bh = page_buffers(page);
814 do { 716 do {
815 while (atomic_read(&bh->b_count)) { 717 if (atomic_read(&bh->b_count))
816 if (!atomic_read(&aspace->i_writecount)) 718 goto cannot_release;
817 return 0; 719 bd = bh->b_private;
818 720 if (bd && bd->bd_ail)
819 if (!(gfp_mask & __GFP_WAIT)) 721 goto cannot_release;
820 return 0;
821
822 if (time_after_eq(jiffies, t)) {
823 stuck_releasepage(bh);
824 /* should we withdraw here? */
825 return 0;
826 }
827
828 yield();
829 }
830
831 gfs2_assert_warn(sdp, !buffer_pinned(bh)); 722 gfs2_assert_warn(sdp, !buffer_pinned(bh));
832 gfs2_assert_warn(sdp, !buffer_dirty(bh)); 723 gfs2_assert_warn(sdp, !buffer_dirty(bh));
724 bh = bh->b_this_page;
725 } while(bh != head);
726 gfs2_log_unlock(sdp);
833 727
728 head = bh = page_buffers(page);
729 do {
834 gfs2_log_lock(sdp); 730 gfs2_log_lock(sdp);
835 bd = bh->b_private; 731 bd = bh->b_private;
836 if (bd) { 732 if (bd) {
837 gfs2_assert_warn(sdp, bd->bd_bh == bh); 733 gfs2_assert_warn(sdp, bd->bd_bh == bh);
838 gfs2_assert_warn(sdp, list_empty(&bd->bd_list_tr)); 734 gfs2_assert_warn(sdp, list_empty(&bd->bd_list_tr));
839 gfs2_assert_warn(sdp, !bd->bd_ail);
840 bd->bd_bh = NULL; 735 bd->bd_bh = NULL;
841 if (!list_empty(&bd->bd_le.le_list)) 736 if (!list_empty(&bd->bd_le.le_list))
842 bd = NULL; 737 bd = NULL;
@@ -851,6 +746,9 @@ int gfs2_releasepage(struct page *page, gfp_t gfp_mask)
851 746
852out: 747out:
853 return try_to_free_buffers(page); 748 return try_to_free_buffers(page);
749cannot_release:
750 gfs2_log_unlock(sdp);
751 return 0;
854} 752}
855 753
856const struct address_space_operations gfs2_file_aops = { 754const struct address_space_operations gfs2_file_aops = {
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index c1c6672ebb83..9e0e9be1e41d 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -35,6 +35,7 @@
35#include "super.h" 35#include "super.h"
36#include "sys.h" 36#include "sys.h"
37#include "util.h" 37#include "util.h"
38#include "log.h"
38 39
39#define DO 0 40#define DO 0
40#define UNDO 1 41#define UNDO 1
@@ -887,6 +888,7 @@ error:
887static void gfs2_kill_sb(struct super_block *sb) 888static void gfs2_kill_sb(struct super_block *sb)
888{ 889{
889 gfs2_delete_debugfs_file(sb->s_fs_info); 890 gfs2_delete_debugfs_file(sb->s_fs_info);
891 gfs2_meta_syncfs(sb->s_fs_info);
890 kill_block_super(sb); 892 kill_block_super(sb);
891} 893}
892 894