aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/ops_address.c
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2006-07-11 09:46:33 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2006-07-11 09:46:33 -0400
commit4340fe62531f7d1dafb6f5359ffe0378bdb0db80 (patch)
tree95ee3f2ace3b07e2fa89a9a01ccd5ac40a556eee /fs/gfs2/ops_address.c
parentffeb874b2b893aea7d10b0b088e06a7b1ded2a3e (diff)
[GFS2] Add generation number
This adds a generation number for the eventual use of NFS to the ondisk inode. Its backward compatible with the current code since it doesn't really matter what the generation number is to start with, and indeed since its set to zero, due to it being taken from padding in both the inode and rgrp header, it should be fine. The eventual plan is to use this rather than no_formal_ino in the NFS filehandles. At that point no_formal_ino will be unused. At the same time we also add a releasepages call back to the "normal" address space for gfs2 inodes. Also I've removed a one-linrer function thats not required any more. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/ops_address.c')
-rw-r--r--fs/gfs2/ops_address.c111
1 files changed, 111 insertions, 0 deletions
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c
index 2c4ec5cf21f..031270ad55e 100644
--- a/fs/gfs2/ops_address.c
+++ b/fs/gfs2/ops_address.c
@@ -33,6 +33,7 @@
33#include "rgrp.h" 33#include "rgrp.h"
34#include "ops_file.h" 34#include "ops_file.h"
35#include "util.h" 35#include "util.h"
36#include "glops.h"
36 37
37/** 38/**
38 * gfs2_get_block - Fills in a buffer head with details about a block 39 * gfs2_get_block - Fills in a buffer head with details about a block
@@ -659,6 +660,115 @@ static ssize_t gfs2_direct_IO(int rw, struct kiocb *iocb,
659 return ret; 660 return ret;
660} 661}
661 662
663/**
664 * stuck_releasepage - We're stuck in gfs2_releasepage(). Print stuff out.
665 * @bh: the buffer we're stuck on
666 *
667 */
668
669static void stuck_releasepage(struct buffer_head *bh)
670{
671 struct inode *inode = bh->b_page->mapping->host;
672 struct gfs2_sbd *sdp = inode->i_sb->s_fs_info;
673 struct gfs2_bufdata *bd = bh->b_private;
674 struct gfs2_glock *gl;
675
676 fs_warn(sdp, "stuck in gfs2_releasepage() %p\n", inode);
677 fs_warn(sdp, "blkno = %llu, bh->b_count = %d\n",
678 (unsigned long long)bh->b_blocknr, atomic_read(&bh->b_count));
679 fs_warn(sdp, "pinned = %u\n", buffer_pinned(bh));
680 fs_warn(sdp, "bh->b_private = %s\n", (bd) ? "!NULL" : "NULL");
681
682 if (!bd)
683 return;
684
685 gl = bd->bd_gl;
686
687 fs_warn(sdp, "gl = (%u, %llu)\n",
688 gl->gl_name.ln_type, (unsigned long long)gl->gl_name.ln_number);
689
690 fs_warn(sdp, "bd_list_tr = %s, bd_le.le_list = %s\n",
691 (list_empty(&bd->bd_list_tr)) ? "no" : "yes",
692 (list_empty(&bd->bd_le.le_list)) ? "no" : "yes");
693
694 if (gl->gl_ops == &gfs2_inode_glops) {
695 struct gfs2_inode *ip = gl->gl_object;
696 unsigned int x;
697
698 if (!ip)
699 return;
700
701 fs_warn(sdp, "ip = %llu %llu\n",
702 (unsigned long long)ip->i_num.no_formal_ino,
703 (unsigned long long)ip->i_num.no_addr);
704
705 for (x = 0; x < GFS2_MAX_META_HEIGHT; x++)
706 fs_warn(sdp, "ip->i_cache[%u] = %s\n",
707 x, (ip->i_cache[x]) ? "!NULL" : "NULL");
708 }
709}
710
711/**
712 * gfs2_aspace_releasepage - free the metadata associated with a page
713 * @page: the page that's being released
714 * @gfp_mask: passed from Linux VFS, ignored by us
715 *
716 * Call try_to_free_buffers() if the buffers in this page can be
717 * released.
718 *
719 * Returns: 0
720 */
721
722int gfs2_releasepage(struct page *page, gfp_t gfp_mask)
723{
724 struct inode *aspace = page->mapping->host;
725 struct gfs2_sbd *sdp = aspace->i_sb->s_fs_info;
726 struct buffer_head *bh, *head;
727 struct gfs2_bufdata *bd;
728 unsigned long t;
729
730 if (!page_has_buffers(page))
731 goto out;
732
733 head = bh = page_buffers(page);
734 do {
735 t = jiffies;
736
737 while (atomic_read(&bh->b_count)) {
738 if (atomic_read(&aspace->i_writecount)) {
739 if (time_after_eq(jiffies, t +
740 gfs2_tune_get(sdp, gt_stall_secs) * HZ)) {
741 stuck_releasepage(bh);
742 t = jiffies;
743 }
744
745 yield();
746 continue;
747 }
748
749 return 0;
750 }
751
752 gfs2_assert_warn(sdp, !buffer_pinned(bh));
753
754 bd = bh->b_private;
755 if (bd) {
756 gfs2_assert_warn(sdp, bd->bd_bh == bh);
757 gfs2_assert_warn(sdp, list_empty(&bd->bd_list_tr));
758 gfs2_assert_warn(sdp, list_empty(&bd->bd_le.le_list));
759 gfs2_assert_warn(sdp, !bd->bd_ail);
760 kmem_cache_free(gfs2_bufdata_cachep, bd);
761 bh->b_private = NULL;
762 }
763
764 bh = bh->b_this_page;
765 }
766 while (bh != head);
767
768 out:
769 return try_to_free_buffers(page);
770}
771
662const struct address_space_operations gfs2_file_aops = { 772const struct address_space_operations gfs2_file_aops = {
663 .writepage = gfs2_writepage, 773 .writepage = gfs2_writepage,
664 .readpage = gfs2_readpage, 774 .readpage = gfs2_readpage,
@@ -668,6 +778,7 @@ const struct address_space_operations gfs2_file_aops = {
668 .commit_write = gfs2_commit_write, 778 .commit_write = gfs2_commit_write,
669 .bmap = gfs2_bmap, 779 .bmap = gfs2_bmap,
670 .invalidatepage = gfs2_invalidatepage, 780 .invalidatepage = gfs2_invalidatepage,
781 .releasepage = gfs2_releasepage,
671 .direct_IO = gfs2_direct_IO, 782 .direct_IO = gfs2_direct_IO,
672}; 783};
673 784