#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 *);
/*
* 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;
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");
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;
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);
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;
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, "
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) {
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) {
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;
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;
}
/*
* 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;
}
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;
}
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;
}
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;
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);
}
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;
}
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;
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);
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]))
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;
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;
}
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;
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);
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;
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);
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;
}
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;
/*
* 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;
}
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)) {
}
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;
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;
}
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.
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;
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;
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);
}