X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=fs%2Fgfs2%2Fops_vm.c;h=aa0dbd2aac1bd31bdd3cb4ebf8265fe9b874d47d;hb=920841d8d1d61bc12b43f95a579a5374f6d98f81;hp=dbc57071e7bb4c7131931321f896591b2af23a0c;hpb=a748422ee45725e04e1d3792fa19dfa90ddfd116;p=linux-2.6-omap-h63xx.git diff --git a/fs/gfs2/ops_vm.c b/fs/gfs2/ops_vm.c index dbc57071e7b..aa0dbd2aac1 100644 --- a/fs/gfs2/ops_vm.c +++ b/fs/gfs2/ops_vm.c @@ -1,13 +1,12 @@ /* * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. - * Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. + * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. * * This copyrighted material is made available to anyone wishing to use, * modify, copy, or redistribute it subject to the terms and conditions - * of the GNU General Public License v.2. + * of the GNU General Public License version 2. */ -#include #include #include #include @@ -15,64 +14,33 @@ #include #include #include -#include +#include #include "gfs2.h" -#include "lm_interface.h" #include "incore.h" #include "bmap.h" #include "glock.h" #include "inode.h" #include "ops_vm.h" -#include "page.h" #include "quota.h" #include "rgrp.h" #include "trans.h" #include "util.h" -static void pfault_be_greedy(struct gfs2_inode *ip) -{ - unsigned int time; - - spin_lock(&ip->i_spin); - time = ip->i_greedy; - ip->i_last_pfault = jiffies; - spin_unlock(&ip->i_spin); - - gfs2_inode_hold(ip); - if (gfs2_glock_be_greedy(ip->i_gl, time)) - gfs2_inode_put(ip); -} - static struct page *gfs2_private_nopage(struct vm_area_struct *area, unsigned long address, int *type) { - struct gfs2_inode *ip = area->vm_file->f_mapping->host->u.generic_ip; - struct gfs2_holder i_gh; - struct page *result; - int error; - - error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, 0, &i_gh); - if (error) - return NULL; + struct gfs2_inode *ip = GFS2_I(area->vm_file->f_mapping->host); set_bit(GIF_PAGED, &ip->i_flags); - - result = filemap_nopage(area, address, type); - - if (result && result != NOPAGE_OOM) - pfault_be_greedy(ip); - - gfs2_glock_dq_uninit(&i_gh); - - return result; + return filemap_nopage(area, address, type); } static int alloc_page_backing(struct gfs2_inode *ip, struct page *page) { - struct gfs2_sbd *sdp = ip->i_sbd; + struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); unsigned long index = page->index; - uint64_t lblock = index << (PAGE_CACHE_SHIFT - + u64 lblock = index << (PAGE_CACHE_SHIFT - sdp->sd_sb.sb_bsize_shift); unsigned int blocks = PAGE_CACHE_SIZE >> sdp->sd_sb.sb_bsize_shift; struct gfs2_alloc *al; @@ -86,12 +54,11 @@ static int alloc_page_backing(struct gfs2_inode *ip, struct page *page) if (error) goto out; - error = gfs2_quota_check(ip, ip->i_di.di_uid, ip->i_di.di_gid); + error = gfs2_quota_check(ip, ip->i_inode.i_uid, ip->i_inode.i_gid); if (error) goto out_gunlock_q; - gfs2_write_calc_reserv(ip, PAGE_CACHE_SIZE, - &data_blocks, &ind_blocks); + gfs2_write_calc_reserv(ip, PAGE_CACHE_SIZE, &data_blocks, &ind_blocks); al->al_requested = data_blocks + ind_blocks; @@ -99,25 +66,24 @@ static int alloc_page_backing(struct gfs2_inode *ip, struct page *page) if (error) goto out_gunlock_q; - error = gfs2_trans_begin(sdp, - al->al_rgd->rd_ri.ri_length + + error = gfs2_trans_begin(sdp, al->al_rgd->rd_ri.ri_length + ind_blocks + RES_DINODE + RES_STATFS + RES_QUOTA, 0); if (error) goto out_ipres; if (gfs2_is_stuffed(ip)) { - error = gfs2_unstuff_dinode(ip, gfs2_unstuffer_page, NULL); + error = gfs2_unstuff_dinode(ip, NULL); if (error) goto out_trans; } for (x = 0; x < blocks; ) { - uint64_t dblock; + u64 dblock; unsigned int extlen; int new = 1; - error = gfs2_block_map(ip, lblock, &new, &dblock, &extlen); + error = gfs2_extent_map(&ip->i_inode, lblock, &new, &dblock, &extlen); if (error) goto out_trans; @@ -127,25 +93,23 @@ static int alloc_page_backing(struct gfs2_inode *ip, struct page *page) gfs2_assert_warn(sdp, al->al_alloced); - out_trans: +out_trans: gfs2_trans_end(sdp); - - out_ipres: +out_ipres: gfs2_inplace_release(ip); - - out_gunlock_q: +out_gunlock_q: gfs2_quota_unlock(ip); - - out: +out: gfs2_alloc_put(ip); - return error; } static struct page *gfs2_sharewrite_nopage(struct vm_area_struct *area, unsigned long address, int *type) { - struct gfs2_inode *ip = area->vm_file->f_mapping->host->u.generic_ip; + struct file *file = area->vm_file; + struct gfs2_file *gf = file->private_data; + struct gfs2_inode *ip = GFS2_I(file->f_mapping->host); struct gfs2_holder i_gh; struct page *result = NULL; unsigned long index = ((address - area->vm_start) >> PAGE_CACHE_SHIFT) + @@ -160,13 +124,14 @@ static struct page *gfs2_sharewrite_nopage(struct vm_area_struct *area, set_bit(GIF_PAGED, &ip->i_flags); set_bit(GIF_SW_PAGED, &ip->i_flags); - error = gfs2_write_alloc_required(ip, - (uint64_t)index << PAGE_CACHE_SHIFT, + error = gfs2_write_alloc_required(ip, (u64)index << PAGE_CACHE_SHIFT, PAGE_CACHE_SIZE, &alloc_required); if (error) goto out; + set_bit(GFF_EXLOCK, &gf->f_flags); result = filemap_nopage(area, address, type); + clear_bit(GFF_EXLOCK, &gf->f_flags); if (!result || result == NOPAGE_OOM) goto out; @@ -180,9 +145,7 @@ static struct page *gfs2_sharewrite_nopage(struct vm_area_struct *area, set_page_dirty(result); } - pfault_be_greedy(ip); - - out: +out: gfs2_glock_dq_uninit(&i_gh); return result;