From fd88de569b802c4a04aaa6ee74667775f4aed8c6 Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Fri, 5 May 2006 16:59:11 -0400 Subject: [GFS2] Readpages support This adds readpages support (and also corrects a small bug in the readpage error path at the same time). Hopefully this will improve performance by allowing GFS to submit larger lumps of I/O at a time. In order to simplify the setting of BH_Boundary, it currently gets set when we hit the end of a indirect pointer block. There is always a boundary at this point with the current allocation code. It doesn't get all the boundaries right though, so there is still room for improvement in this. See comments in fs/gfs2/ops_address.c for further information about readpages with GFS2. Signed-off-by: Steven Whitehouse diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index cfe1a42..474b9a1 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c @@ -314,13 +314,17 @@ static void find_metapath(struct gfs2_inode *ip, uint64_t block, * metadata tree. */ -static inline uint64_t *metapointer(struct buffer_head *bh, - unsigned int height, struct metapath *mp) +static inline u64 *metapointer(struct buffer_head *bh, int *boundary, + unsigned int height, const struct metapath *mp) { unsigned int head_size = (height > 0) ? sizeof(struct gfs2_meta_header) : sizeof(struct gfs2_dinode); - - return ((uint64_t *)(bh->b_data + head_size)) + mp->mp_list[height]; + u64 *ptr; + *boundary = 0; + ptr = ((u64 *)(bh->b_data + head_size)) + mp->mp_list[height]; + if (ptr + 1 == (u64*)(bh->b_data + bh->b_size)) + *boundary = 1; + return ptr; } /** @@ -339,24 +343,24 @@ static inline uint64_t *metapointer(struct buffer_head *bh, * */ -static void lookup_block(struct gfs2_inode *ip, struct buffer_head *bh, - unsigned int height, struct metapath *mp, int create, - int *new, uint64_t *block) +static int lookup_block(struct gfs2_inode *ip, struct buffer_head *bh, + unsigned int height, struct metapath *mp, int create, + int *new, uint64_t *block) { - uint64_t *ptr = metapointer(bh, height, mp); + int boundary; + uint64_t *ptr = metapointer(bh, &boundary, height, mp); if (*ptr) { *block = be64_to_cpu(*ptr); - return; + return boundary; } *block = 0; if (!create) - return; + return 0; - if (height == ip->i_di.di_height - 1 && - !gfs2_is_dir(ip)) + if (height == ip->i_di.di_height - 1 && !gfs2_is_dir(ip)) *block = gfs2_alloc_data(ip); else *block = gfs2_alloc_meta(ip); @@ -367,15 +371,16 @@ static void lookup_block(struct gfs2_inode *ip, struct buffer_head *bh, ip->i_di.di_blocks++; *new = 1; + return 0; } /** - * gfs2_block_map - Map a block from an inode to a disk block - * @ip: The GFS2 inode + * gfs2_block_pointers - Map a block from an inode to a disk block + * @inode: The inode * @lblock: The logical block number * @new: Value/Result argument (1 = may create/did create new blocks) - * @dblock: the disk block number of the start of an extent - * @extlen: the size of the extent + * @boundary: gets set if we've hit a block boundary + * @mp: metapath to use * * Find the block number on the current device which corresponds to an * inode's block. If the block had to be created, "new" will be set. @@ -383,12 +388,14 @@ static void lookup_block(struct gfs2_inode *ip, struct buffer_head *bh, * Returns: errno */ -int gfs2_block_map(struct gfs2_inode *ip, uint64_t lblock, int *new, - uint64_t *dblock, uint32_t *extlen) +static struct buffer_head *gfs2_block_pointers(struct inode *inode, u64 lblock, + int *new, u64 *dblock, + int *boundary, + struct metapath *mp) { + struct gfs2_inode *ip = inode->u.generic_ip; struct gfs2_sbd *sdp = ip->i_sbd; struct buffer_head *bh; - struct metapath mp; int create = *new; unsigned int bsize; unsigned int height; @@ -398,13 +405,6 @@ int gfs2_block_map(struct gfs2_inode *ip, uint64_t lblock, int *new, *new = 0; *dblock = 0; - if (extlen) - *extlen = 0; - - if (create) - down_write(&ip->i_rw_mutex); - else - down_read(&ip->i_rw_mutex); if (gfs2_assert_warn(sdp, !gfs2_is_stuffed(ip))) goto out; @@ -421,7 +421,7 @@ int gfs2_block_map(struct gfs2_inode *ip, uint64_t lblock, int *new, goto out; } - find_metapath(ip, lblock, &mp); + find_metapath(ip, lblock, mp); end_of_metadata = ip->i_di.di_height - 1; error = gfs2_meta_inode_buffer(ip, &bh); @@ -429,7 +429,7 @@ int gfs2_block_map(struct gfs2_inode *ip, uint64_t lblock, int *new, goto out; for (x = 0; x < end_of_metadata; x++) { - lookup_block(ip, bh, x, &mp, create, new, dblock); + lookup_block(ip, bh, x, mp, create, new, dblock); brelse(bh); if (!*dblock) goto out; @@ -439,49 +439,95 @@ int gfs2_block_map(struct gfs2_inode *ip, uint64_t lblock, int *new, goto out; } - lookup_block(ip, bh, end_of_metadata, &mp, create, new, dblock); - - if (extlen && *dblock) { - *extlen = 1; - - if (!*new) { - uint64_t tmp_dblock; - int tmp_new; - unsigned int nptrs; - - nptrs = (end_of_metadata) ? sdp->sd_inptrs : - sdp->sd_diptrs; - - while (++mp.mp_list[end_of_metadata] < nptrs) { - lookup_block(ip, bh, end_of_metadata, &mp, - 0, &tmp_new, &tmp_dblock); - - if (*dblock + *extlen != tmp_dblock) - break; - - (*extlen)++; - } - } - } - - brelse(bh); - + *boundary = lookup_block(ip, bh, end_of_metadata, mp, create, new, dblock); if (*new) { - error = gfs2_meta_inode_buffer(ip, &bh); + struct buffer_head *dibh; + error = gfs2_meta_inode_buffer(ip, &dibh); if (!error) { - gfs2_trans_add_bh(ip->i_gl, bh, 1); - gfs2_dinode_out(&ip->i_di, bh->b_data); - brelse(bh); + gfs2_trans_add_bh(ip->i_gl, dibh, 1); + gfs2_dinode_out(&ip->i_di, dibh->b_data); + brelse(dibh); } } + return bh; +out: + return ERR_PTR(error); +} - out: + +static inline void bmap_lock(struct inode *inode, int create) +{ + struct gfs2_inode *ip = inode->u.generic_ip; + if (create) + down_write(&ip->i_rw_mutex); + else + down_read(&ip->i_rw_mutex); +} + +static inline void bmap_unlock(struct inode *inode, int create) +{ + struct gfs2_inode *ip = inode->u.generic_ip; if (create) up_write(&ip->i_rw_mutex); else up_read(&ip->i_rw_mutex); +} - return error; +int gfs2_block_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, int *boundary) +{ + struct metapath mp; + struct buffer_head *bh; + int create = *new; + + bmap_lock(inode, create); + bh = gfs2_block_pointers(inode, lblock, new, dblock, boundary, &mp); + bmap_unlock(inode, create); + if (!bh) + return 0; + if (IS_ERR(bh)) + return PTR_ERR(bh); + brelse(bh); + return 0; +} + +int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsigned *extlen) +{ + struct gfs2_inode *ip = inode->u.generic_ip; + struct gfs2_sbd *sdp = ip->i_sbd; + struct metapath mp; + struct buffer_head *bh; + int boundary; + int create = *new; + + BUG_ON(!extlen); + BUG_ON(!dblock); + BUG_ON(!new); + + bmap_lock(inode, create); + bh = gfs2_block_pointers(inode, lblock, new, dblock, &boundary, &mp); + *extlen = 1; + + if (bh && !IS_ERR(bh) && *dblock && !*new) { + u64 tmp_dblock; + int tmp_new; + unsigned int nptrs; + unsigned end_of_metadata = ip->i_di.di_height - 1; + + nptrs = (end_of_metadata) ? sdp->sd_inptrs : sdp->sd_diptrs; + while (++mp.mp_list[end_of_metadata] < nptrs) { + lookup_block(ip, bh, end_of_metadata, &mp, 0, &tmp_new, &tmp_dblock); + if (*dblock + *extlen != tmp_dblock) + break; + (*extlen)++; + } + } + bmap_unlock(inode, create); + if (!bh) + return 0; + if (IS_ERR(bh)) + return PTR_ERR(bh); + brelse(bh); + return 0; } /** @@ -1053,7 +1099,7 @@ int gfs2_write_alloc_required(struct gfs2_inode *ip, uint64_t offset, } for (; lblock < lblock_stop; lblock += extlen) { - error = gfs2_block_map(ip, lblock, &new, &dblock, &extlen); + error = gfs2_extent_map(ip->i_vnode, lblock, &new, &dblock, &extlen); if (error) return error; diff --git a/fs/gfs2/bmap.h b/fs/gfs2/bmap.h index 23fb658..bc46c11 100644 --- a/fs/gfs2/bmap.h +++ b/fs/gfs2/bmap.h @@ -16,9 +16,8 @@ typedef int (*gfs2_unstuffer_t) (struct gfs2_inode * ip, int gfs2_unstuff_dinode(struct gfs2_inode *ip, gfs2_unstuffer_t unstuffer, void *private); -int gfs2_block_map(struct gfs2_inode *ip, - uint64_t lblock, int *new, - uint64_t *dblock, uint32_t *extlen); +int gfs2_block_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, int *boundary); +int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsigned *extlen); int gfs2_truncatei(struct gfs2_inode *ip, uint64_t size); int gfs2_truncatei_resume(struct gfs2_inode *ip); diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c index 0404783..7f8b27e 100644 --- a/fs/gfs2/dir.c +++ b/fs/gfs2/dir.c @@ -197,8 +197,8 @@ static int gfs2_dir_write_data(struct gfs2_inode *ip, const char *buf, if (!extlen) { new = 1; - error = gfs2_block_map(ip, lblock, &new, &dblock, - &extlen); + error = gfs2_extent_map(ip->i_vnode, lblock, &new, + &dblock, &extlen); if (error) goto fail; error = -EIO; @@ -314,8 +314,8 @@ static int gfs2_dir_read_data(struct gfs2_inode *ip, char *buf, if (!extlen) { new = 0; - error = gfs2_block_map(ip, lblock, &new, &dblock, - &extlen); + error = gfs2_extent_map(ip->i_vnode, lblock, &new, + &dblock, &extlen); if (error) goto fail; } diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 4fb8066..9d4ae09 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -2125,7 +2125,7 @@ void gfs2_gl_hash_clear(struct gfs2_sbd *sdp, int wait) mutex_lock(&sdp->sd_invalidate_inodes_mutex); invalidate_inodes(sdp->sd_vfs); mutex_unlock(&sdp->sd_invalidate_inodes_mutex); - yield(); + msleep(10); } } diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 9084d60..0817f6e 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -1606,9 +1606,8 @@ int gfs2_glock_nq_atime(struct gfs2_holder *gh) curtime = get_seconds(); if (curtime - ip->i_di.di_atime >= quantum) { gfs2_glock_dq(gh); - gfs2_holder_reinit(LM_ST_EXCLUSIVE, - gh->gh_flags & ~LM_FLAG_ANY, - gh); + gfs2_holder_reinit(LM_ST_EXCLUSIVE, gh->gh_flags & ~LM_FLAG_ANY, + gh); error = gfs2_glock_nq(gh); if (error) return error; diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index 134fc57..02d31e3 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c @@ -211,9 +211,9 @@ static uint64_t log_bmap(struct gfs2_sbd *sdp, unsigned int lbn) int new = 0; uint64_t dbn; int error; + int bdy; - error = gfs2_block_map(sdp->sd_jdesc->jd_inode->u.generic_ip, - lbn, &new, &dbn, NULL); + error = gfs2_block_map(sdp->sd_jdesc->jd_inode, lbn, &new, &dbn, &bdy); gfs2_assert_withdraw(sdp, !error && dbn); return dbn; diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c index afcc12a..d89179b 100644 --- a/fs/gfs2/ops_address.c +++ b/fs/gfs2/ops_address.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -47,12 +48,12 @@ int gfs2_get_block(struct inode *inode, sector_t lblock, struct buffer_head *bh_result, int create) { - struct gfs2_inode *ip = inode->u.generic_ip; int new = create; uint64_t dblock; int error; + int boundary; - error = gfs2_block_map(ip, lblock, &new, &dblock, NULL); + error = gfs2_block_map(inode, lblock, &new, &dblock, &boundary); if (error) return error; @@ -62,6 +63,8 @@ int gfs2_get_block(struct inode *inode, sector_t lblock, map_bh(bh_result, inode->i_sb, dblock); if (new) set_buffer_new(bh_result); + if (boundary) + set_buffer_boundary(bh_result); return 0; } @@ -83,8 +86,9 @@ static int get_block_noalloc(struct inode *inode, sector_t lblock, int new = 0; uint64_t dblock; int error; + int boundary; - error = gfs2_block_map(ip, lblock, &new, &dblock, NULL); + error = gfs2_block_map(inode, lblock, &new, &dblock, &boundary); if (error) return error; @@ -92,6 +96,8 @@ static int get_block_noalloc(struct inode *inode, sector_t lblock, map_bh(bh_result, inode->i_sb, dblock); else if (gfs2_assert_withdraw(ip->i_sbd, !create)) error = -EIO; + if (boundary) + set_buffer_boundary(bh_result); return error; } @@ -151,6 +157,19 @@ out_ignore: return 0; } +static int zero_readpage(struct page *page) +{ + void *kaddr; + + kaddr = kmap_atomic(page, KM_USER0); + memset(kaddr, 0, PAGE_CACHE_SIZE); + kunmap_atomic(page, KM_USER0); + + SetPageUptodate(page); + + return 0; +} + /** * stuffed_readpage - Fill in a Linux page with stuffed file data * @ip: the inode @@ -165,17 +184,18 @@ static int stuffed_readpage(struct gfs2_inode *ip, struct page *page) void *kaddr; int error; + /* Only the first page of a stuffed file might contain data */ + if (unlikely(page->index)) + return zero_readpage(page); + error = gfs2_meta_inode_buffer(ip, &dibh); if (error) return error; kaddr = kmap_atomic(page, KM_USER0); - memcpy((char *)kaddr, - dibh->b_data + sizeof(struct gfs2_dinode), + memcpy(kaddr, dibh->b_data + sizeof(struct gfs2_dinode), ip->i_di.di_size); - memset((char *)kaddr + ip->i_di.di_size, - 0, - PAGE_CACHE_SIZE - ip->i_di.di_size); + memset(kaddr + ip->i_di.di_size, 0, PAGE_CACHE_SIZE - ip->i_di.di_size); kunmap_atomic(page, KM_USER0); brelse(dibh); @@ -185,19 +205,6 @@ static int stuffed_readpage(struct gfs2_inode *ip, struct page *page) return 0; } -static int zero_readpage(struct page *page) -{ - void *kaddr; - - kaddr = kmap_atomic(page, KM_USER0); - memset(kaddr, 0, PAGE_CACHE_SIZE); - kunmap_atomic(page, KM_USER0); - - SetPageUptodate(page); - unlock_page(page); - - return 0; -} /** * gfs2_readpage - readpage with locking @@ -215,19 +222,16 @@ static int gfs2_readpage(struct file *file, struct page *page) struct gfs2_holder gh; int error; - if (file != &gfs2_internal_file_sentinal) { + if (likely(file != &gfs2_internal_file_sentinal)) { gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME|GL_AOP, &gh); error = gfs2_glock_nq_m_atime(1, &gh); - if (error) + if (unlikely(error)) goto out_unlock; } if (gfs2_is_stuffed(ip)) { - if (!page->index) { - error = stuffed_readpage(ip, page); - unlock_page(page); - } else - error = zero_readpage(page); + error = stuffed_readpage(ip, page); + unlock_page(page); } else error = mpage_readpage(page, gfs2_get_block); @@ -242,6 +246,90 @@ out: return error; out_unlock: unlock_page(page); + if (file != &gfs2_internal_file_sentinal) + gfs2_holder_uninit(&gh); + goto out; +} + +#define list_to_page(head) (list_entry((head)->prev, struct page, lru)) + +/** + * gfs2_readpages - Read a bunch of pages at once + * + * Some notes: + * 1. This is only for readahead, so we can simply ignore any things + * which are slightly inconvenient (such as locking conflicts between + * the page lock and the glock) and return having done no I/O. Its + * obviously not something we'd want to do on too regular a basis. + * Any I/O we ignore at this time will be done via readpage later. + * 2. We have to handle stuffed files here too. + * 3. mpage_readpages() does most of the heavy lifting in the common case. + * 4. gfs2_get_block() is relied upon to set BH_Boundary in the right places. + * 5. We use LM_FLAG_TRY_1CB here, effectively we then have lock-ahead as + * well as read-ahead. + */ +static int gfs2_readpages(struct file *file, struct address_space *mapping, + struct list_head *pages, unsigned nr_pages) +{ + struct inode *inode = mapping->host; + struct gfs2_inode *ip = inode->u.generic_ip; + struct gfs2_sbd *sdp = ip->i_sbd; + struct gfs2_holder gh; + unsigned page_idx; + int ret; + + if (likely(file != &gfs2_internal_file_sentinal)) { + gfs2_holder_init(ip->i_gl, LM_ST_SHARED, + LM_FLAG_TRY_1CB|GL_ATIME|GL_AOP, &gh); + ret = gfs2_glock_nq_m_atime(1, &gh); + if (ret == GLR_TRYFAILED) + goto out_noerror; + if (unlikely(ret)) + goto out_unlock; + } + + if (gfs2_is_stuffed(ip)) { + struct pagevec lru_pvec; + pagevec_init(&lru_pvec, 0); + for (page_idx = 0; page_idx < nr_pages; page_idx++) { + struct page *page = list_to_page(pages); + list_del(&page->lru); + if (!add_to_page_cache(page, mapping, + page->index, GFP_KERNEL)) { + ret = stuffed_readpage(ip, page); + unlock_page(page); + if (!pagevec_add(&lru_pvec, page)) + __pagevec_lru_add(&lru_pvec); + } + page_cache_release(page); + } + pagevec_lru_add(&lru_pvec); + ret = 0; + } else { + /* What we really want to do .... */ + ret = mpage_readpages(mapping, pages, nr_pages, gfs2_get_block); + } + + if (likely(file != &gfs2_internal_file_sentinal)) { + gfs2_glock_dq_m(1, &gh); + gfs2_holder_uninit(&gh); + } +out: + if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + ret = -EIO; + return ret; +out_noerror: + ret = 0; +out_unlock: + /* unlock all pages, we can't do any I/O right now */ + for (page_idx = 0; page_idx < nr_pages; page_idx++) { + struct page *page = list_to_page(pages); + list_del(&page->lru); + unlock_page(page); + page_cache_release(page); + } + if (likely(file != &gfs2_internal_file_sentinal)) + gfs2_holder_uninit(&gh); goto out; } @@ -572,6 +660,7 @@ static ssize_t gfs2_direct_IO(int rw, struct kiocb *iocb, struct address_space_operations gfs2_file_aops = { .writepage = gfs2_writepage, .readpage = gfs2_readpage, + .readpages = gfs2_readpages, .sync_page = block_sync_page, .prepare_write = gfs2_prepare_write, .commit_write = gfs2_commit_write, diff --git a/fs/gfs2/ops_super.c b/fs/gfs2/ops_super.c index 60bf256..5910c7b 100644 --- a/fs/gfs2/ops_super.c +++ b/fs/gfs2/ops_super.c @@ -92,7 +92,6 @@ static void gfs2_put_super(struct super_block *sb) if (error) gfs2_io_error(sdp); } - /* At this point, we're through modifying the disk */ /* Release stuff */ @@ -125,12 +124,10 @@ static void gfs2_put_super(struct super_block *sb) gfs2_jindex_free(sdp); /* Take apart glock structures and buffer lists */ gfs2_gl_hash_clear(sdp, WAIT); - /* Unmount the locking protocol */ gfs2_lm_unmount(sdp); /* At this point, we're through participating in the lockspace */ - gfs2_sys_fs_del(sdp); vfree(sdp); sb->s_fs_info = NULL; diff --git a/fs/gfs2/ops_vm.c b/fs/gfs2/ops_vm.c index dbc5707..d67248c 100644 --- a/fs/gfs2/ops_vm.c +++ b/fs/gfs2/ops_vm.c @@ -90,8 +90,7 @@ static int alloc_page_backing(struct gfs2_inode *ip, struct page *page) 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,8 +98,7 @@ 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) @@ -117,7 +115,7 @@ static int alloc_page_backing(struct gfs2_inode *ip, struct page *page) unsigned int extlen; int new = 1; - error = gfs2_block_map(ip, lblock, &new, &dblock, &extlen); + error = gfs2_extent_map(ip->i_vnode, lblock, &new, &dblock, &extlen); if (error) goto out_trans; diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index 942c4c8..d49ff43 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c @@ -255,6 +255,7 @@ static int bh_get(struct gfs2_quota_data *qd) int new = 0; struct buffer_head *bh; int error; + int boundary; mutex_lock(&sdp->sd_quota_mutex); @@ -266,7 +267,7 @@ static int bh_get(struct gfs2_quota_data *qd) block = qd->qd_slot / sdp->sd_qc_per_block; offset = qd->qd_slot % sdp->sd_qc_per_block;; - error = gfs2_block_map(ip, block, &new, &dblock, NULL); + error = gfs2_block_map(ip->i_vnode, block, &new, &dblock, &boundary); if (error) goto fail; error = gfs2_meta_read(ip->i_gl, dblock, DIO_START | DIO_WAIT, &bh); @@ -1162,7 +1163,7 @@ int gfs2_quota_init(struct gfs2_sbd *sdp) if (!extlen) { int new = 0; - error = gfs2_block_map(ip, x, &new, &dblock, &extlen); + error = gfs2_extent_map(ip->i_vnode, x, &new, &dblock, &extlen); if (error) goto fail; } diff --git a/fs/gfs2/recovery.c b/fs/gfs2/recovery.c index d916817..87adebe 100644 --- a/fs/gfs2/recovery.c +++ b/fs/gfs2/recovery.c @@ -40,8 +40,7 @@ int gfs2_replay_read_block(struct gfs2_jdesc *jd, unsigned int blk, uint32_t extlen; int error; - error = gfs2_block_map(ip, blk, &new, &dblock, - &extlen); + error = gfs2_extent_map(ip->i_vnode, blk, &new, &dblock, &extlen); if (error) return error; if (!dblock) { @@ -378,10 +377,11 @@ static int clean_journal(struct gfs2_jdesc *jd, struct gfs2_log_header *head) uint32_t hash; struct buffer_head *bh; int error; - + int boundary; + lblock = head->lh_blkno; gfs2_replay_incr_blk(sdp, &lblock); - error = gfs2_block_map(ip, lblock, &new, &dblock, NULL); + error = gfs2_block_map(ip->i_vnode, lblock, &new, &dblock, &boundary); if (error) return error; if (!dblock) { diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 4ae5596..15c326c 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c @@ -956,8 +956,7 @@ static uint32_t rgblk_search(struct gfs2_rgrpd *rgd, uint32_t goal, search in the first part of our first-searched bit block. */ for (x = 0; x <= length; x++) { if (bi->bi_clone) - blk = gfs2_bitfit(rgd, - bi->bi_clone + bi->bi_offset, + blk = gfs2_bitfit(rgd, bi->bi_clone + bi->bi_offset, bi->bi_len, goal, old_state); else blk = gfs2_bitfit(rgd, @@ -976,12 +975,10 @@ static uint32_t rgblk_search(struct gfs2_rgrpd *rgd, uint32_t goal, blk = 0; gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1); - gfs2_setbit(rgd, - bi->bi_bh->b_data + bi->bi_offset, + gfs2_setbit(rgd, bi->bi_bh->b_data + bi->bi_offset, bi->bi_len, blk, new_state); if (bi->bi_clone) - gfs2_setbit(rgd, - bi->bi_clone + bi->bi_offset, + gfs2_setbit(rgd, bi->bi_clone + bi->bi_offset, bi->bi_len, blk, new_state); return bi->bi_start * GFS2_NBBY + blk; @@ -1064,8 +1061,7 @@ uint64_t gfs2_alloc_data(struct gfs2_inode *ip) else goal = rgd->rd_last_alloc_data; - blk = rgblk_search(rgd, goal, - GFS2_BLKST_FREE, GFS2_BLKST_USED); + blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, GFS2_BLKST_USED); rgd->rd_last_alloc_data = blk; block = rgd->rd_ri.ri_data0 + blk; @@ -1109,8 +1105,7 @@ uint64_t gfs2_alloc_meta(struct gfs2_inode *ip) else goal = rgd->rd_last_alloc_meta; - blk = rgblk_search(rgd, goal, - GFS2_BLKST_FREE, GFS2_BLKST_USED); + blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, GFS2_BLKST_USED); rgd->rd_last_alloc_meta = blk; block = rgd->rd_ri.ri_data0 + blk; diff --git a/fs/gfs2/unlinked.c b/fs/gfs2/unlinked.c index 24b91c2..0d2314a 100644 --- a/fs/gfs2/unlinked.c +++ b/fs/gfs2/unlinked.c @@ -35,11 +35,12 @@ static int munge_ondisk(struct gfs2_sbd *sdp, unsigned int slot, int new = 0; struct buffer_head *bh; int error; + int boundary; block = slot / sdp->sd_ut_per_block; offset = slot % sdp->sd_ut_per_block; - error = gfs2_block_map(ip, block, &new, &dblock, NULL); + error = gfs2_block_map(ip->i_vnode, block, &new, &dblock, &boundary); if (error) return error; error = gfs2_meta_read(ip->i_gl, dblock, DIO_START | DIO_WAIT, &bh); @@ -354,7 +355,7 @@ int gfs2_unlinked_init(struct gfs2_sbd *sdp) if (!extlen) { int new = 0; - error = gfs2_block_map(ip, x, &new, &dblock, &extlen); + error = gfs2_extent_map(ip->i_vnode, x, &new, &dblock, &extlen); if (error) goto fail; } -- cgit v0.10.2