X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fufs%2Fballoc.c;fp=fs%2Fufs%2Fballoc.c;h=3ada9dcf55b8bd86046a95812d6ad918b9a00f2f;hb=64ba3f394c830ec48a1c31b53dcae312c56f1604;hp=b82381475779b59ecdd52685eafc05db391d6bb2;hpb=be1e6109ac94a859551f8e1774eb9a8469fe055c;p=linux-2.6.git diff --git a/fs/ufs/balloc.c b/fs/ufs/balloc.c index b82381475..3ada9dcf5 100644 --- a/fs/ufs/balloc.c +++ b/fs/ufs/balloc.c @@ -21,6 +21,14 @@ #include "swab.h" #include "util.h" +#undef UFS_BALLOC_DEBUG + +#ifdef UFS_BALLOC_DEBUG +#define UFSD(x) printk("(%s, %d), %s:", __FILE__, __LINE__, __FUNCTION__); printk x; +#else +#define UFSD(x) +#endif + static unsigned ufs_add_fragments (struct inode *, unsigned, unsigned, unsigned, int *); static unsigned ufs_alloc_fragments (struct inode *, unsigned, unsigned, unsigned, int *); static unsigned ufs_alloccg_block (struct inode *, struct ufs_cg_private_info *, unsigned, int *); @@ -31,8 +39,7 @@ static void ufs_clusteracct(struct super_block *, struct ufs_cg_private_info *, /* * Free 'count' fragments from fragment number 'fragment' */ -void ufs_free_fragments(struct inode *inode, unsigned fragment, unsigned count) -{ +void ufs_free_fragments (struct inode * inode, unsigned fragment, unsigned count) { struct super_block * sb; struct ufs_sb_private_info * uspi; struct ufs_super_block_first * usb1; @@ -44,7 +51,7 @@ void ufs_free_fragments(struct inode *inode, unsigned fragment, unsigned count) uspi = UFS_SB(sb)->s_uspi; usb1 = ubh_get_usb_first(uspi); - UFSD("ENTER, fragment %u, count %u\n", fragment, count); + UFSD(("ENTER, fragment %u, count %u\n", fragment, count)) if (ufs_fragnum(fragment) + count > uspi->s_fpg) ufs_error (sb, "ufs_free_fragments", "internal error"); @@ -61,7 +68,7 @@ void ufs_free_fragments(struct inode *inode, unsigned fragment, unsigned count) ucpi = ufs_load_cylinder (sb, cgno); if (!ucpi) goto failed; - ucg = ubh_get_ucg (UCPI_UBH(ucpi)); + ucg = ubh_get_ucg (UCPI_UBH); if (!ufs_cg_chkmagic(sb, ucg)) { ufs_panic (sb, "ufs_free_fragments", "internal error, bad magic number on cg %u", cgno); goto failed; @@ -69,11 +76,11 @@ void ufs_free_fragments(struct inode *inode, unsigned fragment, unsigned count) end_bit = bit + count; bbase = ufs_blknum (bit); - blkmap = ubh_blkmap (UCPI_UBH(ucpi), ucpi->c_freeoff, bbase); + blkmap = ubh_blkmap (UCPI_UBH, ucpi->c_freeoff, bbase); ufs_fragacct (sb, blkmap, ucg->cg_frsum, -1); for (i = bit; i < end_bit; i++) { - if (ubh_isclr (UCPI_UBH(ucpi), ucpi->c_freeoff, i)) - ubh_setbit (UCPI_UBH(ucpi), ucpi->c_freeoff, i); + if (ubh_isclr (UCPI_UBH, ucpi->c_freeoff, i)) + ubh_setbit (UCPI_UBH, ucpi->c_freeoff, i); else ufs_error (sb, "ufs_free_fragments", "bit already cleared for fragment %u", i); @@ -83,52 +90,51 @@ void ufs_free_fragments(struct inode *inode, unsigned fragment, unsigned count) fs32_add(sb, &ucg->cg_cs.cs_nffree, count); - uspi->cs_total.cs_nffree += count; + fs32_add(sb, &usb1->fs_cstotal.cs_nffree, count); fs32_add(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, count); - blkmap = ubh_blkmap (UCPI_UBH(ucpi), ucpi->c_freeoff, bbase); + blkmap = ubh_blkmap (UCPI_UBH, ucpi->c_freeoff, bbase); ufs_fragacct(sb, blkmap, ucg->cg_frsum, 1); /* * Trying to reassemble free fragments into block */ blkno = ufs_fragstoblks (bbase); - if (ubh_isblockset(UCPI_UBH(ucpi), ucpi->c_freeoff, blkno)) { + if (ubh_isblockset(UCPI_UBH, ucpi->c_freeoff, blkno)) { fs32_sub(sb, &ucg->cg_cs.cs_nffree, uspi->s_fpb); - uspi->cs_total.cs_nffree -= uspi->s_fpb; + fs32_sub(sb, &usb1->fs_cstotal.cs_nffree, uspi->s_fpb); fs32_sub(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, uspi->s_fpb); if ((UFS_SB(sb)->s_flags & UFS_CG_MASK) == UFS_CG_44BSD) ufs_clusteracct (sb, ucpi, blkno, 1); fs32_add(sb, &ucg->cg_cs.cs_nbfree, 1); - uspi->cs_total.cs_nbfree++; + fs32_add(sb, &usb1->fs_cstotal.cs_nbfree, 1); fs32_add(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nbfree, 1); cylno = ufs_cbtocylno (bbase); fs16_add(sb, &ubh_cg_blks(ucpi, cylno, ufs_cbtorpos(bbase)), 1); fs32_add(sb, &ubh_cg_blktot(ucpi, cylno), 1); } - ubh_mark_buffer_dirty (USPI_UBH(uspi)); - ubh_mark_buffer_dirty (UCPI_UBH(ucpi)); + ubh_mark_buffer_dirty (USPI_UBH); + ubh_mark_buffer_dirty (UCPI_UBH); if (sb->s_flags & MS_SYNCHRONOUS) { - ubh_ll_rw_block(SWRITE, UCPI_UBH(ucpi)); - ubh_wait_on_buffer (UCPI_UBH(ucpi)); + ubh_ll_rw_block (SWRITE, 1, (struct ufs_buffer_head **)&ucpi); + ubh_wait_on_buffer (UCPI_UBH); } sb->s_dirt = 1; unlock_super (sb); - UFSD("EXIT\n"); + UFSD(("EXIT\n")) return; failed: unlock_super (sb); - UFSD("EXIT (FAILED)\n"); + UFSD(("EXIT (FAILED)\n")) return; } /* * Free 'count' fragments from fragment number 'fragment' (free whole blocks) */ -void ufs_free_blocks(struct inode *inode, unsigned fragment, unsigned count) -{ +void ufs_free_blocks (struct inode * inode, unsigned fragment, unsigned count) { struct super_block * sb; struct ufs_sb_private_info * uspi; struct ufs_super_block_first * usb1; @@ -140,7 +146,7 @@ void ufs_free_blocks(struct inode *inode, unsigned fragment, unsigned count) uspi = UFS_SB(sb)->s_uspi; usb1 = ubh_get_usb_first(uspi); - UFSD("ENTER, fragment %u, count %u\n", fragment, count); + UFSD(("ENTER, fragment %u, count %u\n", fragment, count)) if ((fragment & uspi->s_fpbmask) || (count & uspi->s_fpbmask)) { ufs_error (sb, "ufs_free_blocks", "internal error, " @@ -156,7 +162,7 @@ do_more: bit = ufs_dtogd (fragment); if (cgno >= uspi->s_ncg) { ufs_panic (sb, "ufs_free_blocks", "freeing blocks are outside device"); - goto failed_unlock; + goto failed; } end_bit = bit + count; if (end_bit > uspi->s_fpg) { @@ -167,36 +173,36 @@ do_more: ucpi = ufs_load_cylinder (sb, cgno); if (!ucpi) - goto failed_unlock; - ucg = ubh_get_ucg (UCPI_UBH(ucpi)); + goto failed; + ucg = ubh_get_ucg (UCPI_UBH); if (!ufs_cg_chkmagic(sb, ucg)) { ufs_panic (sb, "ufs_free_blocks", "internal error, bad magic number on cg %u", cgno); - goto failed_unlock; + goto failed; } for (i = bit; i < end_bit; i += uspi->s_fpb) { blkno = ufs_fragstoblks(i); - if (ubh_isblockset(UCPI_UBH(ucpi), ucpi->c_freeoff, blkno)) { + if (ubh_isblockset(UCPI_UBH, ucpi->c_freeoff, blkno)) { ufs_error(sb, "ufs_free_blocks", "freeing free fragment"); } - ubh_setblock(UCPI_UBH(ucpi), ucpi->c_freeoff, blkno); + ubh_setblock(UCPI_UBH, ucpi->c_freeoff, blkno); if ((UFS_SB(sb)->s_flags & UFS_CG_MASK) == UFS_CG_44BSD) ufs_clusteracct (sb, ucpi, blkno, 1); DQUOT_FREE_BLOCK(inode, uspi->s_fpb); fs32_add(sb, &ucg->cg_cs.cs_nbfree, 1); - uspi->cs_total.cs_nbfree++; + fs32_add(sb, &usb1->fs_cstotal.cs_nbfree, 1); fs32_add(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nbfree, 1); cylno = ufs_cbtocylno(i); fs16_add(sb, &ubh_cg_blks(ucpi, cylno, ufs_cbtorpos(i)), 1); fs32_add(sb, &ubh_cg_blktot(ucpi, cylno), 1); } - ubh_mark_buffer_dirty (USPI_UBH(uspi)); - ubh_mark_buffer_dirty (UCPI_UBH(ucpi)); + ubh_mark_buffer_dirty (USPI_UBH); + ubh_mark_buffer_dirty (UCPI_UBH); if (sb->s_flags & MS_SYNCHRONOUS) { - ubh_ll_rw_block(SWRITE, UCPI_UBH(ucpi)); - ubh_wait_on_buffer (UCPI_UBH(ucpi)); + ubh_ll_rw_block (SWRITE, 1, (struct ufs_buffer_head **)&ucpi); + ubh_wait_on_buffer (UCPI_UBH); } if (overflow) { @@ -207,83 +213,38 @@ do_more: sb->s_dirt = 1; unlock_super (sb); - UFSD("EXIT\n"); + UFSD(("EXIT\n")) return; -failed_unlock: - unlock_super (sb); failed: - UFSD("EXIT (FAILED)\n"); + unlock_super (sb); + UFSD(("EXIT (FAILED)\n")) return; } -/* - * Modify inode page cache in such way: - * have - blocks with b_blocknr equal to oldb...oldb+count-1 - * get - blocks with b_blocknr equal to newb...newb+count-1 - * also we suppose that oldb...oldb+count-1 blocks - * situated at the end of file. - * - * We can come here from ufs_writepage or ufs_prepare_write, - * locked_page is argument of these functions, so we already lock it. - */ -static void ufs_change_blocknr(struct inode *inode, unsigned int baseblk, - unsigned int count, unsigned int oldb, - unsigned int newb, struct page *locked_page) -{ - unsigned int blk_per_page = 1 << (PAGE_CACHE_SHIFT - inode->i_blkbits); - struct address_space *mapping = inode->i_mapping; - pgoff_t index, cur_index = locked_page->index; - unsigned int i, j; - struct page *page; - struct buffer_head *head, *bh; - - UFSD("ENTER, ino %lu, count %u, oldb %u, newb %u\n", - inode->i_ino, count, oldb, newb); - - BUG_ON(!PageLocked(locked_page)); - - for (i = 0; i < count; i += blk_per_page) { - index = (baseblk+i) >> (PAGE_CACHE_SHIFT - inode->i_blkbits); - - if (likely(cur_index != index)) { - page = ufs_get_locked_page(mapping, index); - if (!page || IS_ERR(page)) /* it was truncated or EIO */ - continue; - } else - page = locked_page; - - j = i; - head = page_buffers(page); - bh = head; - do { - if (likely(bh->b_blocknr == j + oldb && j < count)) { - unmap_underlying_metadata(bh->b_bdev, - bh->b_blocknr); - bh->b_blocknr = newb + j++; - mark_buffer_dirty(bh); - } - bh = bh->b_this_page; - } while (bh != head); - set_page_dirty(page); - - if (likely(cur_index != index)) - ufs_put_locked_page(page); - } - UFSD("EXIT\n"); -} +#define NULLIFY_FRAGMENTS \ + for (i = oldcount; i < newcount; i++) { \ + bh = sb_getblk(sb, result + i); \ + memset (bh->b_data, 0, sb->s_blocksize); \ + set_buffer_uptodate(bh); \ + mark_buffer_dirty (bh); \ + if (IS_SYNC(inode)) \ + sync_dirty_buffer(bh); \ + brelse (bh); \ + } -unsigned ufs_new_fragments(struct inode * inode, __fs32 * p, unsigned fragment, - unsigned goal, unsigned count, int * err, struct page *locked_page) +unsigned ufs_new_fragments (struct inode * inode, __fs32 * p, unsigned fragment, + unsigned goal, unsigned count, int * err ) { struct super_block * sb; struct ufs_sb_private_info * uspi; struct ufs_super_block_first * usb1; - unsigned cgno, oldcount, newcount, tmp, request, result; + struct buffer_head * bh; + unsigned cgno, oldcount, newcount, tmp, request, i, result; - UFSD("ENTER, ino %lu, fragment %u, goal %u, count %u\n", inode->i_ino, fragment, goal, count); + UFSD(("ENTER, ino %lu, fragment %u, goal %u, count %u\n", inode->i_ino, fragment, goal, count)) sb = inode->i_sb; uspi = UFS_SB(sb)->s_uspi; @@ -312,14 +273,14 @@ unsigned ufs_new_fragments(struct inode * inode, __fs32 * p, unsigned fragment, return (unsigned)-1; } if (fragment < UFS_I(inode)->i_lastfrag) { - UFSD("EXIT (ALREADY ALLOCATED)\n"); + UFSD(("EXIT (ALREADY ALLOCATED)\n")) unlock_super (sb); return 0; } } else { if (tmp) { - UFSD("EXIT (ALREADY ALLOCATED)\n"); + UFSD(("EXIT (ALREADY ALLOCATED)\n")) unlock_super(sb); return 0; } @@ -328,9 +289,9 @@ unsigned ufs_new_fragments(struct inode * inode, __fs32 * p, unsigned fragment, /* * There is not enough space for user on the device */ - if (!capable(CAP_SYS_RESOURCE) && ufs_freespace(uspi, UFS_MINFREE) <= 0) { + if (!capable(CAP_SYS_RESOURCE) && ufs_freespace(usb1, UFS_MINFREE) <= 0) { unlock_super (sb); - UFSD("EXIT (FAILED)\n"); + UFSD(("EXIT (FAILED)\n")) return 0; } @@ -349,10 +310,12 @@ unsigned ufs_new_fragments(struct inode * inode, __fs32 * p, unsigned fragment, if (result) { *p = cpu_to_fs32(sb, result); *err = 0; + inode->i_blocks += count << uspi->s_nspfshift; UFS_I(inode)->i_lastfrag = max_t(u32, UFS_I(inode)->i_lastfrag, fragment + count); + NULLIFY_FRAGMENTS } unlock_super(sb); - UFSD("EXIT, result %u\n", result); + UFSD(("EXIT, result %u\n", result)) return result; } @@ -362,9 +325,11 @@ unsigned ufs_new_fragments(struct inode * inode, __fs32 * p, unsigned fragment, result = ufs_add_fragments (inode, tmp, oldcount, newcount, err); if (result) { *err = 0; + inode->i_blocks += count << uspi->s_nspfshift; UFS_I(inode)->i_lastfrag = max_t(u32, UFS_I(inode)->i_lastfrag, fragment + count); + NULLIFY_FRAGMENTS unlock_super(sb); - UFSD("EXIT, result %u\n", result); + UFSD(("EXIT, result %u\n", result)) return result; } @@ -374,8 +339,8 @@ unsigned ufs_new_fragments(struct inode * inode, __fs32 * p, unsigned fragment, switch (fs32_to_cpu(sb, usb1->fs_optim)) { case UFS_OPTSPACE: request = newcount; - if (uspi->s_minfree < 5 || uspi->cs_total.cs_nffree - > uspi->s_dsize * uspi->s_minfree / (2 * 100)) + if (uspi->s_minfree < 5 || fs32_to_cpu(sb, usb1->fs_cstotal.cs_nffree) + > uspi->s_dsize * uspi->s_minfree / (2 * 100) ) break; usb1->fs_optim = cpu_to_fs32(sb, UFS_OPTTIME); break; @@ -384,7 +349,7 @@ unsigned ufs_new_fragments(struct inode * inode, __fs32 * p, unsigned fragment, case UFS_OPTTIME: request = uspi->s_fpb; - if (uspi->cs_total.cs_nffree < uspi->s_dsize * + if (fs32_to_cpu(sb, usb1->fs_cstotal.cs_nffree) < uspi->s_dsize * (uspi->s_minfree - 2) / 100) break; usb1->fs_optim = cpu_to_fs32(sb, UFS_OPTTIME); @@ -392,22 +357,39 @@ unsigned ufs_new_fragments(struct inode * inode, __fs32 * p, unsigned fragment, } result = ufs_alloc_fragments (inode, cgno, goal, request, err); if (result) { - ufs_change_blocknr(inode, fragment - oldcount, oldcount, tmp, - result, locked_page); - + for (i = 0; i < oldcount; i++) { + bh = sb_bread(sb, tmp + i); + if(bh) + { + clear_buffer_dirty(bh); + bh->b_blocknr = result + i; + mark_buffer_dirty (bh); + if (IS_SYNC(inode)) + sync_dirty_buffer(bh); + brelse (bh); + } + else + { + printk(KERN_ERR "ufs_new_fragments: bread fail\n"); + unlock_super(sb); + return 0; + } + } *p = cpu_to_fs32(sb, result); *err = 0; + inode->i_blocks += count << uspi->s_nspfshift; UFS_I(inode)->i_lastfrag = max_t(u32, UFS_I(inode)->i_lastfrag, fragment + count); + NULLIFY_FRAGMENTS unlock_super(sb); if (newcount < request) ufs_free_fragments (inode, result + newcount, request - newcount); ufs_free_fragments (inode, tmp, oldcount); - UFSD("EXIT, result %u\n", result); + UFSD(("EXIT, result %u\n", result)) return result; } unlock_super(sb); - UFSD("EXIT (FAILED)\n"); + UFSD(("EXIT (FAILED)\n")) return 0; } @@ -422,7 +404,7 @@ ufs_add_fragments (struct inode * inode, unsigned fragment, struct ufs_cylinder_group * ucg; unsigned cgno, fragno, fragoff, count, fragsize, i; - UFSD("ENTER, fragment %u, oldcount %u, newcount %u\n", fragment, oldcount, newcount); + UFSD(("ENTER, fragment %u, oldcount %u, newcount %u\n", fragment, oldcount, newcount)) sb = inode->i_sb; uspi = UFS_SB(sb)->s_uspi; @@ -437,7 +419,7 @@ ufs_add_fragments (struct inode * inode, unsigned fragment, ucpi = ufs_load_cylinder (sb, cgno); if (!ucpi) return 0; - ucg = ubh_get_ucg (UCPI_UBH(ucpi)); + ucg = ubh_get_ucg (UCPI_UBH); if (!ufs_cg_chkmagic(sb, ucg)) { ufs_panic (sb, "ufs_add_fragments", "internal error, bad magic number on cg %u", cgno); @@ -447,14 +429,14 @@ ufs_add_fragments (struct inode * inode, unsigned fragment, fragno = ufs_dtogd (fragment); fragoff = ufs_fragnum (fragno); for (i = oldcount; i < newcount; i++) - if (ubh_isclr (UCPI_UBH(ucpi), ucpi->c_freeoff, fragno + i)) + if (ubh_isclr (UCPI_UBH, ucpi->c_freeoff, fragno + i)) return 0; /* * Block can be extended */ ucg->cg_time = cpu_to_fs32(sb, get_seconds()); for (i = newcount; i < (uspi->s_fpb - fragoff); i++) - if (ubh_isclr (UCPI_UBH(ucpi), ucpi->c_freeoff, fragno + i)) + if (ubh_isclr (UCPI_UBH, ucpi->c_freeoff, fragno + i)) break; fragsize = i - oldcount; if (!fs32_to_cpu(sb, ucg->cg_frsum[fragsize])) @@ -464,7 +446,7 @@ ufs_add_fragments (struct inode * inode, unsigned fragment, if (fragsize != count) fs32_add(sb, &ucg->cg_frsum[fragsize - count], 1); for (i = oldcount; i < newcount; i++) - ubh_clrbit (UCPI_UBH(ucpi), ucpi->c_freeoff, fragno + i); + ubh_clrbit (UCPI_UBH, ucpi->c_freeoff, fragno + i); if(DQUOT_ALLOC_BLOCK(inode, count)) { *err = -EDQUOT; return 0; @@ -472,17 +454,17 @@ ufs_add_fragments (struct inode * inode, unsigned fragment, fs32_sub(sb, &ucg->cg_cs.cs_nffree, count); fs32_sub(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, count); - uspi->cs_total.cs_nffree -= count; + fs32_sub(sb, &usb1->fs_cstotal.cs_nffree, count); - ubh_mark_buffer_dirty (USPI_UBH(uspi)); - ubh_mark_buffer_dirty (UCPI_UBH(ucpi)); + ubh_mark_buffer_dirty (USPI_UBH); + ubh_mark_buffer_dirty (UCPI_UBH); if (sb->s_flags & MS_SYNCHRONOUS) { - ubh_ll_rw_block(SWRITE, UCPI_UBH(ucpi)); - ubh_wait_on_buffer (UCPI_UBH(ucpi)); + ubh_ll_rw_block (SWRITE, 1, (struct ufs_buffer_head **)&ucpi); + ubh_wait_on_buffer (UCPI_UBH); } sb->s_dirt = 1; - UFSD("EXIT, fragment %u\n", fragment); + UFSD(("EXIT, fragment %u\n", fragment)) return fragment; } @@ -505,7 +487,7 @@ static unsigned ufs_alloc_fragments (struct inode * inode, unsigned cgno, struct ufs_cylinder_group * ucg; unsigned oldcg, i, j, k, result, allocsize; - UFSD("ENTER, ino %lu, cgno %u, goal %u, count %u\n", inode->i_ino, cgno, goal, count); + UFSD(("ENTER, ino %lu, cgno %u, goal %u, count %u\n", inode->i_ino, cgno, goal, count)) sb = inode->i_sb; uspi = UFS_SB(sb)->s_uspi; @@ -539,14 +521,14 @@ static unsigned ufs_alloc_fragments (struct inode * inode, unsigned cgno, UFS_TEST_FREE_SPACE_CG } - UFSD("EXIT (FAILED)\n"); + UFSD(("EXIT (FAILED)\n")) return 0; cg_found: ucpi = ufs_load_cylinder (sb, cgno); if (!ucpi) return 0; - ucg = ubh_get_ucg (UCPI_UBH(ucpi)); + ucg = ubh_get_ucg (UCPI_UBH); if (!ufs_cg_chkmagic(sb, ucg)) ufs_panic (sb, "ufs_alloc_fragments", "internal error, bad magic number on cg %u", cgno); @@ -569,12 +551,12 @@ cg_found: return 0; goal = ufs_dtogd (result); for (i = count; i < uspi->s_fpb; i++) - ubh_setbit (UCPI_UBH(ucpi), ucpi->c_freeoff, goal + i); + ubh_setbit (UCPI_UBH, ucpi->c_freeoff, goal + i); i = uspi->s_fpb - count; DQUOT_FREE_BLOCK(inode, i); fs32_add(sb, &ucg->cg_cs.cs_nffree, i); - uspi->cs_total.cs_nffree += i; + fs32_add(sb, &usb1->fs_cstotal.cs_nffree, i); fs32_add(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, i); fs32_add(sb, &ucg->cg_frsum[i], 1); goto succed; @@ -588,10 +570,10 @@ cg_found: return 0; } for (i = 0; i < count; i++) - ubh_clrbit (UCPI_UBH(ucpi), ucpi->c_freeoff, result + i); + ubh_clrbit (UCPI_UBH, ucpi->c_freeoff, result + i); fs32_sub(sb, &ucg->cg_cs.cs_nffree, count); - uspi->cs_total.cs_nffree -= count; + fs32_sub(sb, &usb1->fs_cstotal.cs_nffree, count); fs32_sub(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, count); fs32_sub(sb, &ucg->cg_frsum[allocsize], 1); @@ -599,16 +581,16 @@ cg_found: fs32_add(sb, &ucg->cg_frsum[allocsize - count], 1); succed: - ubh_mark_buffer_dirty (USPI_UBH(uspi)); - ubh_mark_buffer_dirty (UCPI_UBH(ucpi)); + ubh_mark_buffer_dirty (USPI_UBH); + ubh_mark_buffer_dirty (UCPI_UBH); if (sb->s_flags & MS_SYNCHRONOUS) { - ubh_ll_rw_block(SWRITE, UCPI_UBH(ucpi)); - ubh_wait_on_buffer (UCPI_UBH(ucpi)); + ubh_ll_rw_block (SWRITE, 1, (struct ufs_buffer_head **)&ucpi); + ubh_wait_on_buffer (UCPI_UBH); } sb->s_dirt = 1; result += cgno * uspi->s_fpg; - UFSD("EXIT3, result %u\n", result); + UFSD(("EXIT3, result %u\n", result)) return result; } @@ -621,12 +603,12 @@ static unsigned ufs_alloccg_block (struct inode * inode, struct ufs_cylinder_group * ucg; unsigned result, cylno, blkno; - UFSD("ENTER, goal %u\n", goal); + UFSD(("ENTER, goal %u\n", goal)) sb = inode->i_sb; uspi = UFS_SB(sb)->s_uspi; usb1 = ubh_get_usb_first(uspi); - ucg = ubh_get_ucg(UCPI_UBH(ucpi)); + ucg = ubh_get_ucg(UCPI_UBH); if (goal == 0) { goal = ucpi->c_rotor; @@ -638,7 +620,7 @@ static unsigned ufs_alloccg_block (struct inode * inode, /* * If the requested block is available, use it. */ - if (ubh_isblockset(UCPI_UBH(ucpi), ucpi->c_freeoff, ufs_fragstoblks(goal))) { + if (ubh_isblockset(UCPI_UBH, ucpi->c_freeoff, ufs_fragstoblks(goal))) { result = goal; goto gotit; } @@ -650,7 +632,7 @@ norot: ucpi->c_rotor = result; gotit: blkno = ufs_fragstoblks(result); - ubh_clrblock (UCPI_UBH(ucpi), ucpi->c_freeoff, blkno); + ubh_clrblock (UCPI_UBH, ucpi->c_freeoff, blkno); if ((UFS_SB(sb)->s_flags & UFS_CG_MASK) == UFS_CG_44BSD) ufs_clusteracct (sb, ucpi, blkno, -1); if(DQUOT_ALLOC_BLOCK(inode, uspi->s_fpb)) { @@ -659,76 +641,31 @@ gotit: } fs32_sub(sb, &ucg->cg_cs.cs_nbfree, 1); - uspi->cs_total.cs_nbfree--; + fs32_sub(sb, &usb1->fs_cstotal.cs_nbfree, 1); fs32_sub(sb, &UFS_SB(sb)->fs_cs(ucpi->c_cgx).cs_nbfree, 1); cylno = ufs_cbtocylno(result); fs16_sub(sb, &ubh_cg_blks(ucpi, cylno, ufs_cbtorpos(result)), 1); fs32_sub(sb, &ubh_cg_blktot(ucpi, cylno), 1); - UFSD("EXIT, result %u\n", result); + UFSD(("EXIT, result %u\n", result)) return result; } -static unsigned ubh_scanc(struct ufs_sb_private_info *uspi, - struct ufs_buffer_head *ubh, - unsigned begin, unsigned size, - unsigned char *table, unsigned char mask) +static unsigned ufs_bitmap_search (struct super_block * sb, + struct ufs_cg_private_info * ucpi, unsigned goal, unsigned count) { - unsigned rest, offset; - unsigned char *cp; - - - offset = begin & ~uspi->s_fmask; - begin >>= uspi->s_fshift; - for (;;) { - if ((offset + size) < uspi->s_fsize) - rest = size; - else - rest = uspi->s_fsize - offset; - size -= rest; - cp = ubh->bh[begin]->b_data + offset; - while ((table[*cp++] & mask) == 0 && --rest) - ; - if (rest || !size) - break; - begin++; - offset = 0; - } - return (size + rest); -} - -/* - * Find a block of the specified size in the specified cylinder group. - * @sp: pointer to super block - * @ucpi: pointer to cylinder group info - * @goal: near which block we want find new one - * @count: specified size - */ -static unsigned ufs_bitmap_search(struct super_block *sb, - struct ufs_cg_private_info *ucpi, - unsigned goal, unsigned count) -{ - /* - * Bit patterns for identifying fragments in the block map - * used as ((map & mask_arr) == want_arr) - */ - static const int mask_arr[9] = { - 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff, 0x1ff, 0x3ff - }; - static const int want_arr[9] = { - 0x0, 0x2, 0x6, 0xe, 0x1e, 0x3e, 0x7e, 0xfe, 0x1fe - }; - struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; - struct ufs_super_block_first *usb1; - struct ufs_cylinder_group *ucg; - unsigned start, length, loc, result; - unsigned pos, want, blockmap, mask, end; - - UFSD("ENTER, cg %u, goal %u, count %u\n", ucpi->c_cgx, goal, count); + struct ufs_sb_private_info * uspi; + struct ufs_super_block_first * usb1; + struct ufs_cylinder_group * ucg; + unsigned start, length, location, result; + unsigned possition, fragsize, blockmap, mask; + + UFSD(("ENTER, cg %u, goal %u, count %u\n", ucpi->c_cgx, goal, count)) + uspi = UFS_SB(sb)->s_uspi; usb1 = ubh_get_usb_first (uspi); - ucg = ubh_get_ucg(UCPI_UBH(ucpi)); + ucg = ubh_get_ucg(UCPI_UBH); if (goal) start = ufs_dtogd(goal) >> 3; @@ -736,50 +673,53 @@ static unsigned ufs_bitmap_search(struct super_block *sb, start = ucpi->c_frotor >> 3; length = ((uspi->s_fpg + 7) >> 3) - start; - loc = ubh_scanc(uspi, UCPI_UBH(ucpi), ucpi->c_freeoff + start, length, + location = ubh_scanc(UCPI_UBH, ucpi->c_freeoff + start, length, (uspi->s_fpb == 8) ? ufs_fragtable_8fpb : ufs_fragtable_other, 1 << (count - 1 + (uspi->s_fpb & 7))); - if (loc == 0) { + if (location == 0) { length = start + 1; - loc = ubh_scanc(uspi, UCPI_UBH(ucpi), ucpi->c_freeoff, length, - (uspi->s_fpb == 8) ? ufs_fragtable_8fpb : - ufs_fragtable_other, - 1 << (count - 1 + (uspi->s_fpb & 7))); - if (loc == 0) { - ufs_error(sb, "ufs_bitmap_search", - "bitmap corrupted on cg %u, start %u," - " length %u, count %u, freeoff %u\n", - ucpi->c_cgx, start, length, count, - ucpi->c_freeoff); + location = ubh_scanc(UCPI_UBH, ucpi->c_freeoff, length, + (uspi->s_fpb == 8) ? ufs_fragtable_8fpb : ufs_fragtable_other, + 1 << (count - 1 + (uspi->s_fpb & 7))); + if (location == 0) { + ufs_error (sb, "ufs_bitmap_search", + "bitmap corrupted on cg %u, start %u, length %u, count %u, freeoff %u\n", + ucpi->c_cgx, start, length, count, ucpi->c_freeoff); return (unsigned)-1; } start = 0; } - result = (start + length - loc) << 3; + result = (start + length - location) << 3; ucpi->c_frotor = result; /* * found the byte in the map */ - - for (end = result + 8; result < end; result += uspi->s_fpb) { - blockmap = ubh_blkmap(UCPI_UBH(ucpi), ucpi->c_freeoff, result); - blockmap <<= 1; - mask = mask_arr[count]; - want = want_arr[count]; - for (pos = 0; pos <= uspi->s_fpb - count; pos++) { - if ((blockmap & mask) == want) { - UFSD("EXIT, result %u\n", result); - return result + pos; - } - mask <<= 1; - want <<= 1; - } - } - - ufs_error(sb, "ufs_bitmap_search", "block not in map on cg %u\n", - ucpi->c_cgx); - UFSD("EXIT (FAILED)\n"); + blockmap = ubh_blkmap(UCPI_UBH, ucpi->c_freeoff, result); + fragsize = 0; + for (possition = 0, mask = 1; possition < 8; possition++, mask <<= 1) { + if (blockmap & mask) { + if (!(possition & uspi->s_fpbmask)) + fragsize = 1; + else + fragsize++; + } + else { + if (fragsize == count) { + result += possition - count; + UFSD(("EXIT, result %u\n", result)) + return result; + } + fragsize = 0; + } + } + if (fragsize == count) { + result += possition - count; + UFSD(("EXIT, result %u\n", result)) + return result; + } + ufs_error (sb, "ufs_bitmap_search", "block not in map on cg %u\n", ucpi->c_cgx); + UFSD(("EXIT (FAILED)\n")) return (unsigned)-1; } @@ -794,9 +734,9 @@ static void ufs_clusteracct(struct super_block * sb, return; if (cnt > 0) - ubh_setbit(UCPI_UBH(ucpi), ucpi->c_clusteroff, blkno); + ubh_setbit(UCPI_UBH, ucpi->c_clusteroff, blkno); else - ubh_clrbit(UCPI_UBH(ucpi), ucpi->c_clusteroff, blkno); + ubh_clrbit(UCPI_UBH, ucpi->c_clusteroff, blkno); /* * Find the size of the cluster going forward. @@ -805,7 +745,7 @@ static void ufs_clusteracct(struct super_block * sb, end = start + uspi->s_contigsumsize; if ( end >= ucpi->c_nclusterblks) end = ucpi->c_nclusterblks; - i = ubh_find_next_zero_bit (UCPI_UBH(ucpi), ucpi->c_clusteroff, end, start); + i = ubh_find_next_zero_bit (UCPI_UBH, ucpi->c_clusteroff, end, start); if (i > end) i = end; forw = i - start; @@ -817,7 +757,7 @@ static void ufs_clusteracct(struct super_block * sb, end = start - uspi->s_contigsumsize; if (end < 0 ) end = -1; - i = ubh_find_last_zero_bit (UCPI_UBH(ucpi), ucpi->c_clusteroff, start, end); + i = ubh_find_last_zero_bit (UCPI_UBH, ucpi->c_clusteroff, start, end); if ( i < end) i = end; back = start - i; @@ -829,11 +769,11 @@ static void ufs_clusteracct(struct super_block * sb, i = back + forw + 1; if (i > uspi->s_contigsumsize) i = uspi->s_contigsumsize; - fs32_add(sb, (__fs32*)ubh_get_addr(UCPI_UBH(ucpi), ucpi->c_clustersumoff + (i << 2)), cnt); + fs32_add(sb, (__fs32*)ubh_get_addr(UCPI_UBH, ucpi->c_clustersumoff + (i << 2)), cnt); if (back > 0) - fs32_sub(sb, (__fs32*)ubh_get_addr(UCPI_UBH(ucpi), ucpi->c_clustersumoff + (back << 2)), cnt); + fs32_sub(sb, (__fs32*)ubh_get_addr(UCPI_UBH, ucpi->c_clustersumoff + (back << 2)), cnt); if (forw > 0) - fs32_sub(sb, (__fs32*)ubh_get_addr(UCPI_UBH(ucpi), ucpi->c_clustersumoff + (forw << 2)), cnt); + fs32_sub(sb, (__fs32*)ubh_get_addr(UCPI_UBH, ucpi->c_clustersumoff + (forw << 2)), cnt); }